Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "chrome/browser/local_discovery/privet_url_fetcher.h" | 5 #include "chrome/browser/local_discovery/privet_url_fetcher.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/json/json_reader.h" | 10 #include "base/json/json_reader.h" |
| 11 #include "base/message_loop/message_loop.h" | 11 #include "base/message_loop/message_loop.h" |
| 12 #include "base/rand_util.h" | 12 #include "base/rand_util.h" |
| 13 #include "chrome/browser/browser_process.h" | 13 #include "chrome/browser/browser_process.h" |
| 14 #include "chrome/browser/local_discovery/privet_constants.h" | 14 #include "chrome/browser/local_discovery/privet_constants.h" |
| 15 #include "content/public/browser/browser_thread.h" | 15 #include "content/public/browser/browser_thread.h" |
| 16 #include "net/http/http_status_code.h" | 16 #include "net/http/http_status_code.h" |
| 17 #include "net/url_request/url_request_status.h" | 17 #include "net/url_request/url_request_status.h" |
| 18 | 18 |
| 19 namespace local_discovery { | 19 namespace local_discovery { |
| 20 | 20 |
| 21 namespace { | 21 namespace { |
|
Vitaly Buka (NO REVIEWS)
2014/02/14 22:57:46
empty line after { and before } below
Noam Samuel
2014/02/14 23:26:12
Done.
| |
| 22 typedef std::map<std::string, std::string> TokenMap; | |
| 23 | |
| 22 const char kXPrivetTokenHeaderPrefix[] = "X-Privet-Token: "; | 24 const char kXPrivetTokenHeaderPrefix[] = "X-Privet-Token: "; |
| 23 const char kXPrivetEmptyToken[] = "\"\""; | 25 const char kXPrivetEmptyToken[] = "\"\""; |
| 24 const int kPrivetMaxRetries = 20; | 26 const int kPrivetMaxRetries = 20; |
| 25 const int kPrivetTimeoutOnError = 5; | 27 const int kPrivetTimeoutOnError = 5; |
| 28 | |
| 29 TokenMap* g_token_map = NULL; | |
| 26 } | 30 } |
| 27 | 31 |
| 28 void PrivetURLFetcher::Delegate::OnNeedPrivetToken( | 32 void PrivetURLFetcher::Delegate::OnNeedPrivetToken( |
| 29 PrivetURLFetcher* fetcher, | 33 PrivetURLFetcher* fetcher, |
| 30 const TokenCallback& callback) { | 34 const TokenCallback& callback) { |
| 31 OnError(fetcher, TOKEN_ERROR); | 35 OnError(fetcher, TOKEN_ERROR); |
| 32 } | 36 } |
| 33 | 37 |
| 34 PrivetURLFetcher::PrivetURLFetcher( | 38 PrivetURLFetcher::PrivetURLFetcher( |
| 35 const std::string& token, | |
| 36 const GURL& url, | 39 const GURL& url, |
| 37 net::URLFetcher::RequestType request_type, | 40 net::URLFetcher::RequestType request_type, |
| 38 net::URLRequestContextGetter* request_context, | 41 net::URLRequestContextGetter* request_context, |
| 39 PrivetURLFetcher::Delegate* delegate) | 42 PrivetURLFetcher::Delegate* delegate) |
| 40 : privet_access_token_(token), url_(url), request_type_(request_type), | 43 : url_(url), request_type_(request_type), |
| 41 request_context_(request_context), delegate_(delegate), | 44 request_context_(request_context), delegate_(delegate), |
| 42 do_not_retry_on_transient_error_(false), allow_empty_privet_token_(false), | 45 do_not_retry_on_transient_error_(false), allow_empty_privet_token_(false), |
| 43 tries_(0), weak_factory_(this) { | 46 tries_(0), weak_factory_(this) { |
| 44 } | 47 } |
| 45 | 48 |
| 46 PrivetURLFetcher::~PrivetURLFetcher() { | 49 PrivetURLFetcher::~PrivetURLFetcher() { |
| 47 } | 50 } |
| 48 | 51 |
| 52 // static | |
| 53 void PrivetURLFetcher::SetTokenForHost(const std::string& host, | |
|
Vitaly Buka (NO REVIEWS)
2014/02/14 22:57:46
double white space
Noam Samuel
2014/02/14 23:26:12
Done.
| |
| 54 const std::string& token) { | |
| 55 if (!g_token_map) g_token_map = new TokenMap(); | |
|
Vitaly Buka (NO REVIEWS)
2014/02/14 22:57:46
Can you please use Singleton for g_tocket_map?
Noam Samuel
2014/02/14 23:26:12
Done.
| |
| 56 (*g_token_map)[host] = token; | |
| 57 } | |
| 58 | |
| 59 // static | |
| 60 void PrivetURLFetcher::ResetTokenMapForTests() { | |
| 61 if (g_token_map) delete g_token_map; | |
| 62 g_token_map = NULL; | |
| 63 } | |
| 64 | |
| 49 void PrivetURLFetcher::DoNotRetryOnTransientError() { | 65 void PrivetURLFetcher::DoNotRetryOnTransientError() { |
| 50 do_not_retry_on_transient_error_ = true; | 66 do_not_retry_on_transient_error_ = true; |
| 51 } | 67 } |
| 52 | 68 |
| 53 void PrivetURLFetcher::AllowEmptyPrivetToken() { | 69 void PrivetURLFetcher::AllowEmptyPrivetToken() { |
| 54 allow_empty_privet_token_ = true; | 70 allow_empty_privet_token_ = true; |
| 55 } | 71 } |
| 56 | 72 |
| 73 std::string PrivetURLFetcher::GetPrivetAccessToken() { | |
| 74 if (!g_token_map) return std::string(); | |
| 75 TokenMap::iterator found = g_token_map->find(GetHostString()); | |
| 76 if (found != g_token_map->end()) { | |
| 77 return found->second; | |
| 78 } else { | |
| 79 return std::string(); | |
| 80 } | |
| 81 } | |
| 82 | |
| 83 std::string PrivetURLFetcher::GetHostString() { | |
| 84 return url_.GetOrigin().spec(); | |
| 85 } | |
| 86 | |
| 57 void PrivetURLFetcher::Try() { | 87 void PrivetURLFetcher::Try() { |
| 58 tries_++; | 88 tries_++; |
| 59 if (tries_ < kPrivetMaxRetries) { | 89 if (tries_ < kPrivetMaxRetries) { |
| 60 std::string token = privet_access_token_; | 90 std::string token = GetPrivetAccessToken(); |
| 61 | 91 |
| 62 if (token.empty()) | 92 if (token.empty()) |
| 63 token = kXPrivetEmptyToken; | 93 token = kXPrivetEmptyToken; |
| 64 | 94 |
| 65 url_fetcher_.reset(net::URLFetcher::Create(url_, request_type_, this)); | 95 url_fetcher_.reset(net::URLFetcher::Create(url_, request_type_, this)); |
| 66 url_fetcher_->SetRequestContext(request_context_); | 96 url_fetcher_->SetRequestContext(request_context_); |
| 67 url_fetcher_->AddExtraRequestHeader(std::string(kXPrivetTokenHeaderPrefix) + | 97 url_fetcher_->AddExtraRequestHeader(std::string(kXPrivetTokenHeaderPrefix) + |
| 68 token); | 98 token); |
| 69 | 99 |
| 70 // URLFetcher requires us to set upload data for POST requests. | 100 // URLFetcher requires us to set upload data for POST requests. |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 84 | 114 |
| 85 url_fetcher_->Start(); | 115 url_fetcher_->Start(); |
| 86 } else { | 116 } else { |
| 87 delegate_->OnError(this, RETRY_ERROR); | 117 delegate_->OnError(this, RETRY_ERROR); |
| 88 } | 118 } |
| 89 } | 119 } |
| 90 | 120 |
| 91 void PrivetURLFetcher::Start() { | 121 void PrivetURLFetcher::Start() { |
| 92 DCHECK_EQ(tries_, 0); // We haven't called |Start()| yet. | 122 DCHECK_EQ(tries_, 0); // We haven't called |Start()| yet. |
| 93 | 123 |
| 94 if (privet_access_token_.empty() && !allow_empty_privet_token_) { | 124 std::string privet_access_token = GetPrivetAccessToken(); |
| 125 if (privet_access_token.empty() && !allow_empty_privet_token_) { | |
| 95 RequestTokenRefresh(); | 126 RequestTokenRefresh(); |
| 96 } else { | 127 } else { |
| 97 Try(); | 128 Try(); |
| 98 } | 129 } |
| 99 } | 130 } |
| 100 | 131 |
| 101 void PrivetURLFetcher::SetUploadData(const std::string& upload_content_type, | 132 void PrivetURLFetcher::SetUploadData(const std::string& upload_content_type, |
| 102 const std::string& upload_data) { | 133 const std::string& upload_data) { |
| 103 DCHECK(upload_file_path_.empty()); | 134 DCHECK(upload_file_path_.empty()); |
| 104 upload_content_type_ = upload_content_type; | 135 upload_content_type_ = upload_content_type; |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 190 void PrivetURLFetcher::RequestTokenRefresh() { | 221 void PrivetURLFetcher::RequestTokenRefresh() { |
| 191 delegate_->OnNeedPrivetToken( | 222 delegate_->OnNeedPrivetToken( |
| 192 this, | 223 this, |
| 193 base::Bind(&PrivetURLFetcher::RefreshToken, weak_factory_.GetWeakPtr())); | 224 base::Bind(&PrivetURLFetcher::RefreshToken, weak_factory_.GetWeakPtr())); |
| 194 } | 225 } |
| 195 | 226 |
| 196 void PrivetURLFetcher::RefreshToken(const std::string& token) { | 227 void PrivetURLFetcher::RefreshToken(const std::string& token) { |
| 197 if (token.empty()) { | 228 if (token.empty()) { |
| 198 delegate_->OnError(this, TOKEN_ERROR); | 229 delegate_->OnError(this, TOKEN_ERROR); |
| 199 } else { | 230 } else { |
| 200 privet_access_token_ = token; | 231 SetTokenForHost(GetHostString(), token); |
| 201 Try(); | 232 Try(); |
| 202 } | 233 } |
| 203 } | 234 } |
| 204 | 235 |
| 205 bool PrivetURLFetcher::PrivetErrorTransient(const std::string& error) { | 236 bool PrivetURLFetcher::PrivetErrorTransient(const std::string& error) { |
| 206 return (error == kPrivetErrorDeviceBusy) || | 237 return (error == kPrivetErrorDeviceBusy) || |
| 207 (error == kPrivetErrorPendingUserAction) || | 238 (error == kPrivetErrorPendingUserAction) || |
| 208 (error == kPrivetErrorPrinterBusy); | 239 (error == kPrivetErrorPrinterBusy); |
| 209 } | 240 } |
| 210 | 241 |
| 211 PrivetURLFetcherFactory::PrivetURLFetcherFactory( | |
| 212 net::URLRequestContextGetter* request_context) | |
| 213 : request_context_(request_context) { | |
| 214 } | |
| 215 | |
| 216 PrivetURLFetcherFactory::~PrivetURLFetcherFactory() { | |
| 217 } | |
| 218 | |
| 219 scoped_ptr<PrivetURLFetcher> PrivetURLFetcherFactory::CreateURLFetcher( | |
| 220 const GURL& url, net::URLFetcher::RequestType request_type, | |
| 221 PrivetURLFetcher::Delegate* delegate) const { | |
| 222 return scoped_ptr<PrivetURLFetcher>( | |
| 223 new PrivetURLFetcher(token_, url, request_type, request_context_.get(), | |
| 224 delegate)); | |
| 225 } | |
| 226 | |
| 227 } // namespace local_discovery | 242 } // namespace local_discovery |
| OLD | NEW |