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/memory/singleton.h" | |
11 #include "base/message_loop/message_loop.h" | 12 #include "base/message_loop/message_loop.h" |
12 #include "base/rand_util.h" | 13 #include "base/rand_util.h" |
13 #include "chrome/browser/browser_process.h" | 14 #include "chrome/browser/browser_process.h" |
14 #include "chrome/browser/local_discovery/privet_constants.h" | 15 #include "chrome/browser/local_discovery/privet_constants.h" |
15 #include "content/public/browser/browser_thread.h" | 16 #include "content/public/browser/browser_thread.h" |
16 #include "net/http/http_status_code.h" | 17 #include "net/http/http_status_code.h" |
17 #include "net/url_request/url_request_status.h" | 18 #include "net/url_request/url_request_status.h" |
18 | 19 |
19 namespace local_discovery { | 20 namespace local_discovery { |
20 | 21 |
21 namespace { | 22 namespace { |
23 | |
24 typedef std::map<std::string, std::string> TokenMap; | |
25 | |
26 struct TokenMapHolder { | |
27 public: | |
28 static TokenMapHolder* GetInstance() { | |
29 return Singleton<TokenMapHolder>::get(); | |
30 } | |
31 | |
32 TokenMap map; | |
33 }; | |
34 | |
22 const char kXPrivetTokenHeaderPrefix[] = "X-Privet-Token: "; | 35 const char kXPrivetTokenHeaderPrefix[] = "X-Privet-Token: "; |
23 const char kXPrivetEmptyToken[] = "\"\""; | 36 const char kXPrivetEmptyToken[] = "\"\""; |
24 const int kPrivetMaxRetries = 20; | 37 const int kPrivetMaxRetries = 20; |
25 const int kPrivetTimeoutOnError = 5; | 38 const int kPrivetTimeoutOnError = 5; |
26 } | 39 |
40 } // namespace | |
27 | 41 |
28 void PrivetURLFetcher::Delegate::OnNeedPrivetToken( | 42 void PrivetURLFetcher::Delegate::OnNeedPrivetToken( |
29 PrivetURLFetcher* fetcher, | 43 PrivetURLFetcher* fetcher, |
30 const TokenCallback& callback) { | 44 const TokenCallback& callback) { |
31 OnError(fetcher, TOKEN_ERROR); | 45 OnError(fetcher, TOKEN_ERROR); |
32 } | 46 } |
33 | 47 |
34 PrivetURLFetcher::PrivetURLFetcher( | 48 PrivetURLFetcher::PrivetURLFetcher( |
35 const std::string& token, | |
36 const GURL& url, | 49 const GURL& url, |
37 net::URLFetcher::RequestType request_type, | 50 net::URLFetcher::RequestType request_type, |
38 net::URLRequestContextGetter* request_context, | 51 net::URLRequestContextGetter* request_context, |
39 PrivetURLFetcher::Delegate* delegate) | 52 PrivetURLFetcher::Delegate* delegate) |
40 : privet_access_token_(token), url_(url), request_type_(request_type), | 53 : url_(url), request_type_(request_type), |
41 request_context_(request_context), delegate_(delegate), | 54 request_context_(request_context), delegate_(delegate), |
42 do_not_retry_on_transient_error_(false), allow_empty_privet_token_(false), | 55 do_not_retry_on_transient_error_(false), allow_empty_privet_token_(false), |
43 tries_(0), weak_factory_(this) { | 56 tries_(0), weak_factory_(this) { |
44 } | 57 } |
45 | 58 |
46 PrivetURLFetcher::~PrivetURLFetcher() { | 59 PrivetURLFetcher::~PrivetURLFetcher() { |
47 } | 60 } |
48 | 61 |
62 // static | |
63 void PrivetURLFetcher::SetTokenForHost(const std::string& host, | |
64 const std::string& token) { | |
65 TokenMapHolder::GetInstance()->map[host] = token; | |
66 } | |
67 | |
68 // static | |
69 void PrivetURLFetcher::ResetTokenMapForTests() { | |
70 TokenMapHolder::GetInstance()->map.clear(); | |
71 } | |
72 | |
49 void PrivetURLFetcher::DoNotRetryOnTransientError() { | 73 void PrivetURLFetcher::DoNotRetryOnTransientError() { |
50 do_not_retry_on_transient_error_ = true; | 74 do_not_retry_on_transient_error_ = true; |
51 } | 75 } |
52 | 76 |
53 void PrivetURLFetcher::AllowEmptyPrivetToken() { | 77 void PrivetURLFetcher::AllowEmptyPrivetToken() { |
54 allow_empty_privet_token_ = true; | 78 allow_empty_privet_token_ = true; |
55 } | 79 } |
56 | 80 |
81 std::string PrivetURLFetcher::GetPrivetAccessToken() { | |
82 TokenMapHolder* token_map_holder = TokenMapHolder::GetInstance(); | |
83 TokenMap::iterator found = token_map_holder->map.find(GetHostString()); | |
84 if (found != token_map_holder->map.end()) { | |
Vitaly Buka (NO REVIEWS)
2014/02/14 23:34:12
return found != token_map_holder->map.end() ? foun
Noam Samuel
2014/02/15 00:22:15
Done.
| |
85 return found->second; | |
86 } else { | |
87 return std::string(); | |
88 } | |
89 } | |
90 | |
91 std::string PrivetURLFetcher::GetHostString() { | |
92 return url_.GetOrigin().spec(); | |
93 } | |
94 | |
57 void PrivetURLFetcher::Try() { | 95 void PrivetURLFetcher::Try() { |
58 tries_++; | 96 tries_++; |
59 if (tries_ < kPrivetMaxRetries) { | 97 if (tries_ < kPrivetMaxRetries) { |
60 std::string token = privet_access_token_; | 98 std::string token = GetPrivetAccessToken(); |
61 | 99 |
62 if (token.empty()) | 100 if (token.empty()) |
63 token = kXPrivetEmptyToken; | 101 token = kXPrivetEmptyToken; |
64 | 102 |
65 url_fetcher_.reset(net::URLFetcher::Create(url_, request_type_, this)); | 103 url_fetcher_.reset(net::URLFetcher::Create(url_, request_type_, this)); |
66 url_fetcher_->SetRequestContext(request_context_); | 104 url_fetcher_->SetRequestContext(request_context_); |
67 url_fetcher_->AddExtraRequestHeader(std::string(kXPrivetTokenHeaderPrefix) + | 105 url_fetcher_->AddExtraRequestHeader(std::string(kXPrivetTokenHeaderPrefix) + |
68 token); | 106 token); |
69 | 107 |
70 // URLFetcher requires us to set upload data for POST requests. | 108 // URLFetcher requires us to set upload data for POST requests. |
(...skipping 13 matching lines...) Expand all Loading... | |
84 | 122 |
85 url_fetcher_->Start(); | 123 url_fetcher_->Start(); |
86 } else { | 124 } else { |
87 delegate_->OnError(this, RETRY_ERROR); | 125 delegate_->OnError(this, RETRY_ERROR); |
88 } | 126 } |
89 } | 127 } |
90 | 128 |
91 void PrivetURLFetcher::Start() { | 129 void PrivetURLFetcher::Start() { |
92 DCHECK_EQ(tries_, 0); // We haven't called |Start()| yet. | 130 DCHECK_EQ(tries_, 0); // We haven't called |Start()| yet. |
93 | 131 |
94 if (privet_access_token_.empty() && !allow_empty_privet_token_) { | 132 std::string privet_access_token = GetPrivetAccessToken(); |
133 if (privet_access_token.empty() && !allow_empty_privet_token_) { | |
95 RequestTokenRefresh(); | 134 RequestTokenRefresh(); |
96 } else { | 135 } else { |
97 Try(); | 136 Try(); |
98 } | 137 } |
99 } | 138 } |
100 | 139 |
101 void PrivetURLFetcher::SetUploadData(const std::string& upload_content_type, | 140 void PrivetURLFetcher::SetUploadData(const std::string& upload_content_type, |
102 const std::string& upload_data) { | 141 const std::string& upload_data) { |
103 DCHECK(upload_file_path_.empty()); | 142 DCHECK(upload_file_path_.empty()); |
104 upload_content_type_ = upload_content_type; | 143 upload_content_type_ = upload_content_type; |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
190 void PrivetURLFetcher::RequestTokenRefresh() { | 229 void PrivetURLFetcher::RequestTokenRefresh() { |
191 delegate_->OnNeedPrivetToken( | 230 delegate_->OnNeedPrivetToken( |
192 this, | 231 this, |
193 base::Bind(&PrivetURLFetcher::RefreshToken, weak_factory_.GetWeakPtr())); | 232 base::Bind(&PrivetURLFetcher::RefreshToken, weak_factory_.GetWeakPtr())); |
194 } | 233 } |
195 | 234 |
196 void PrivetURLFetcher::RefreshToken(const std::string& token) { | 235 void PrivetURLFetcher::RefreshToken(const std::string& token) { |
197 if (token.empty()) { | 236 if (token.empty()) { |
198 delegate_->OnError(this, TOKEN_ERROR); | 237 delegate_->OnError(this, TOKEN_ERROR); |
199 } else { | 238 } else { |
200 privet_access_token_ = token; | 239 SetTokenForHost(GetHostString(), token); |
201 Try(); | 240 Try(); |
202 } | 241 } |
203 } | 242 } |
204 | 243 |
205 bool PrivetURLFetcher::PrivetErrorTransient(const std::string& error) { | 244 bool PrivetURLFetcher::PrivetErrorTransient(const std::string& error) { |
206 return (error == kPrivetErrorDeviceBusy) || | 245 return (error == kPrivetErrorDeviceBusy) || |
207 (error == kPrivetErrorPendingUserAction) || | 246 (error == kPrivetErrorPendingUserAction) || |
208 (error == kPrivetErrorPrinterBusy); | 247 (error == kPrivetErrorPrinterBusy); |
209 } | 248 } |
210 | 249 |
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 | 250 } // namespace local_discovery |
OLD | NEW |