Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / chrome / browser / local_discovery / privet_url_fetcher.cc
index d56bfe2..627278e 100644 (file)
@@ -8,6 +8,7 @@
 
 #include "base/bind.h"
 #include "base/json/json_reader.h"
+#include "base/memory/singleton.h"
 #include "base/message_loop/message_loop.h"
 #include "base/rand_util.h"
 #include "base/strings/stringprintf.h"
 namespace local_discovery {
 
 namespace {
+
+typedef std::map<std::string, std::string> TokenMap;
+
+struct TokenMapHolder {
+ public:
+  static TokenMapHolder* GetInstance() {
+    return Singleton<TokenMapHolder>::get();
+  }
+
+  TokenMap map;
+};
+
 const char kXPrivetTokenHeaderPrefix[] = "X-Privet-Token: ";
+const char kXPrivetAuthTokenHeaderPrefix[] = "X-Privet-Auth: ";
 const char kRangeHeaderFormat[] = "Range: bytes=%d-%d";
 const char kXPrivetEmptyToken[] = "\"\"";
+const char kPrivetAuthTokenUnknown[] = "Unknown";
 const int kPrivetMaxRetries = 20;
 const int kPrivetTimeoutOnError = 5;
 const int kHTTPErrorCodeInvalidXPrivetToken = 418;
@@ -42,6 +57,10 @@ void PrivetURLFetcher::Delegate::OnNeedPrivetToken(
   OnError(fetcher, TOKEN_ERROR);
 }
 
+std::string PrivetURLFetcher::Delegate::GetAuthToken() {
+  return kPrivetAuthTokenUnknown;
+}
+
 bool PrivetURLFetcher::Delegate::OnRawData(PrivetURLFetcher* fetcher,
                                            bool response_is_file,
                                            const std::string& data_string,
@@ -50,20 +69,19 @@ bool PrivetURLFetcher::Delegate::OnRawData(PrivetURLFetcher* fetcher,
 }
 
 PrivetURLFetcher::PrivetURLFetcher(
-    const std::string& token,
     const GURL& url,
     net::URLFetcher::RequestType request_type,
     net::URLRequestContextGetter* request_context,
     PrivetURLFetcher::Delegate* delegate)
-    : privet_access_token_(token),
-      url_(url),
+    : url_(url),
       request_type_(request_type),
       request_context_(request_context),
       delegate_(delegate),
       do_not_retry_on_transient_error_(false),
-      allow_empty_privet_token_(false),
+      send_empty_privet_token_(false),
       has_byte_range_(false),
       make_response_file_(false),
+      v3_mode_(false),
       byte_range_start_(0),
       byte_range_end_(0),
       tries_(0),
@@ -73,14 +91,39 @@ PrivetURLFetcher::PrivetURLFetcher(
 PrivetURLFetcher::~PrivetURLFetcher() {
 }
 
+// static
+void PrivetURLFetcher::SetTokenForHost(const std::string& host,
+                                       const std::string& token) {
+  TokenMapHolder::GetInstance()->map[host] = token;
+}
+
+// static
+void PrivetURLFetcher::ResetTokenMapForTests() {
+  TokenMapHolder::GetInstance()->map.clear();
+}
+
 void PrivetURLFetcher::DoNotRetryOnTransientError() {
   DCHECK(tries_ == 0);
   do_not_retry_on_transient_error_ = true;
 }
 
-void PrivetURLFetcher::AllowEmptyPrivetToken() {
+void PrivetURLFetcher::SendEmptyPrivetToken() {
   DCHECK(tries_ == 0);
-  allow_empty_privet_token_ = true;
+  send_empty_privet_token_ = true;
+}
+
+std::string PrivetURLFetcher::GetPrivetAccessToken() {
+  if (send_empty_privet_token_) {
+    return std::string();
+  }
+
+  TokenMapHolder* token_map_holder = TokenMapHolder::GetInstance();
+  TokenMap::iterator found = token_map_holder->map.find(GetHostString());
+  return found != token_map_holder->map.end() ? found->second : std::string();
+}
+
+std::string PrivetURLFetcher::GetHostString() {
+  return url_.GetOrigin().spec();
 }
 
 void PrivetURLFetcher::SaveResponseToFile() {
@@ -88,6 +131,10 @@ void PrivetURLFetcher::SaveResponseToFile() {
   make_response_file_ = true;
 }
 
+void PrivetURLFetcher::V3Mode() {
+  v3_mode_ = true;
+}
+
 void PrivetURLFetcher::SetByteRange(int start, int end) {
   DCHECK(tries_ == 0);
   byte_range_start_ = start;
@@ -98,15 +145,26 @@ void PrivetURLFetcher::SetByteRange(int start, int end) {
 void PrivetURLFetcher::Try() {
   tries_++;
   if (tries_ < kPrivetMaxRetries) {
-    std::string token = privet_access_token_;
 
-    if (token.empty())
-      token = kXPrivetEmptyToken;
 
     url_fetcher_.reset(net::URLFetcher::Create(url_, request_type_, this));
-    url_fetcher_->SetRequestContext(request_context_);
-    url_fetcher_->AddExtraRequestHeader(std::string(kXPrivetTokenHeaderPrefix) +
-                                        token);
+    url_fetcher_->SetRequestContext(request_context_.get());
+
+    if (v3_mode_) {
+      std::string auth_token = delegate_->GetAuthToken();
+
+      url_fetcher_->AddExtraRequestHeader(
+          std::string(kXPrivetAuthTokenHeaderPrefix) + auth_token);
+    } else {
+      std::string token = GetPrivetAccessToken();
+
+      if (token.empty())
+        token = kXPrivetEmptyToken;
+
+      url_fetcher_->AddExtraRequestHeader(
+          std::string(kXPrivetTokenHeaderPrefix) + token);
+    }
+
     if (has_byte_range_) {
       url_fetcher_->AddExtraRequestHeader(
           MakeRangeHeader(byte_range_start_, byte_range_end_));
@@ -142,11 +200,16 @@ void PrivetURLFetcher::Try() {
 void PrivetURLFetcher::Start() {
   DCHECK_EQ(tries_, 0);  // We haven't called |Start()| yet.
 
-  if (privet_access_token_.empty() && !allow_empty_privet_token_) {
-    RequestTokenRefresh();
-  } else {
-    Try();
+  if (!send_empty_privet_token_ && !v3_mode_) {
+    std::string privet_access_token;
+    privet_access_token = GetPrivetAccessToken();
+    if (privet_access_token.empty()) {
+      RequestTokenRefresh();
+      return;
+    }
   }
+
+  Try();
 }
 
 void PrivetURLFetcher::SetUploadData(const std::string& upload_content_type,
@@ -220,13 +283,16 @@ bool PrivetURLFetcher::OnURLFetchCompleteDoNotParseData(
 
 void PrivetURLFetcher::OnURLFetchCompleteParseData(
     const net::URLFetcher* source) {
-  if (source->GetResponseCode() != net::HTTP_OK) {
+  // Response contains error description.
+  bool is_error_response = false;
+  if (v3_mode_ && source->GetResponseCode() == net::HTTP_BAD_REQUEST) {
+    is_error_response = true;
+  } else if (source->GetResponseCode() != net::HTTP_OK) {
     delegate_->OnError(this, RESPONSE_CODE_ERROR);
     return;
   }
 
   std::string response_str;
-
   if (!source->GetResponseAsString(&response_str)) {
     delegate_->OnError(this, URL_FETCH_ERROR);
     return;
@@ -242,7 +308,7 @@ void PrivetURLFetcher::OnURLFetchCompleteParseData(
     return;
   }
 
-  const base::DictionaryValue* dictionary_value;
+  const base::DictionaryValue* dictionary_value = NULL;
 
   if (!value->GetAsDictionary(&dictionary_value)) {
     delegate_->OnError(this, JSON_PARSE_ERROR);
@@ -250,7 +316,7 @@ void PrivetURLFetcher::OnURLFetchCompleteParseData(
   }
 
   std::string error;
-  if (dictionary_value->GetString(kPrivetKeyError, &error)) {
+  if (!v3_mode_ && dictionary_value->GetString(kPrivetKeyError, &error)) {
     if (error == kPrivetErrorInvalidXPrivetToken) {
       RequestTokenRefresh();
       return;
@@ -266,10 +332,10 @@ void PrivetURLFetcher::OnURLFetchCompleteParseData(
         return;
       }
     }
+    is_error_response = true;
   }
 
-  delegate_->OnParsedJson(this, dictionary_value,
-                          dictionary_value->HasKey(kPrivetKeyError));
+  delegate_->OnParsedJson(this, *dictionary_value, is_error_response);
 }
 
 void PrivetURLFetcher::ScheduleRetry(int timeout_seconds) {
@@ -298,31 +364,16 @@ void PrivetURLFetcher::RefreshToken(const std::string& token) {
   if (token.empty()) {
     delegate_->OnError(this, TOKEN_ERROR);
   } else {
-    privet_access_token_ = token;
+    SetTokenForHost(GetHostString(), token);
     Try();
   }
 }
 
 bool PrivetURLFetcher::PrivetErrorTransient(const std::string& error) {
   return (error == kPrivetErrorDeviceBusy) ||
+         (error == kPrivetV3ErrorDeviceBusy) ||
          (error == kPrivetErrorPendingUserAction) ||
          (error == kPrivetErrorPrinterBusy);
 }
 
-PrivetURLFetcherFactory::PrivetURLFetcherFactory(
-    net::URLRequestContextGetter* request_context)
-    : request_context_(request_context) {
-}
-
-PrivetURLFetcherFactory::~PrivetURLFetcherFactory() {
-}
-
-scoped_ptr<PrivetURLFetcher> PrivetURLFetcherFactory::CreateURLFetcher(
-    const GURL& url, net::URLFetcher::RequestType request_type,
-    PrivetURLFetcher::Delegate* delegate) const {
-  return scoped_ptr<PrivetURLFetcher>(
-      new PrivetURLFetcher(token_, url, request_type, request_context_.get(),
-                           delegate));
-}
-
 }  // namespace local_discovery