OLD | NEW |
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 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/extensions/updater/extension_downloader.h" | 5 #include "extensions/browser/updater/extension_downloader.h" |
6 | 6 |
7 #include <utility> | 7 #include <utility> |
8 | 8 |
9 #include "base/bind.h" | 9 #include "base/bind.h" |
10 #include "base/command_line.h" | 10 #include "base/command_line.h" |
11 #include "base/files/file_path.h" | 11 #include "base/files/file_path.h" |
12 #include "base/location.h" | 12 #include "base/location.h" |
13 #include "base/logging.h" | 13 #include "base/logging.h" |
14 #include "base/metrics/histogram.h" | 14 #include "base/metrics/histogram.h" |
15 #include "base/metrics/sparse_histogram.h" | 15 #include "base/metrics/sparse_histogram.h" |
(...skipping 28 matching lines...) Expand all Loading... |
44 using base::TimeDelta; | 44 using base::TimeDelta; |
45 using content::BrowserThread; | 45 using content::BrowserThread; |
46 | 46 |
47 namespace extensions { | 47 namespace extensions { |
48 | 48 |
49 const char ExtensionDownloader::kBlacklistAppID[] = "com.google.crx.blacklist"; | 49 const char ExtensionDownloader::kBlacklistAppID[] = "com.google.crx.blacklist"; |
50 | 50 |
51 namespace { | 51 namespace { |
52 | 52 |
53 const net::BackoffEntry::Policy kDefaultBackoffPolicy = { | 53 const net::BackoffEntry::Policy kDefaultBackoffPolicy = { |
54 // Number of initial errors (in sequence) to ignore before applying | 54 // Number of initial errors (in sequence) to ignore before applying |
55 // exponential back-off rules. | 55 // exponential back-off rules. |
56 0, | 56 0, |
57 | 57 |
58 // Initial delay for exponential back-off in ms. | 58 // Initial delay for exponential back-off in ms. |
59 2000, | 59 2000, |
60 | 60 |
61 // Factor by which the waiting time will be multiplied. | 61 // Factor by which the waiting time will be multiplied. |
62 2, | 62 2, |
63 | 63 |
64 // Fuzzing percentage. ex: 10% will spread requests randomly | 64 // Fuzzing percentage. ex: 10% will spread requests randomly |
65 // between 90%-100% of the calculated time. | 65 // between 90%-100% of the calculated time. |
66 0.1, | 66 0.1, |
67 | 67 |
68 // Maximum amount of time we are willing to delay our request in ms. | 68 // Maximum amount of time we are willing to delay our request in ms. |
69 -1, | 69 -1, |
70 | 70 |
71 // Time to keep an entry from being discarded even when it | 71 // Time to keep an entry from being discarded even when it |
72 // has no significant state, -1 to never discard. | 72 // has no significant state, -1 to never discard. |
73 -1, | 73 -1, |
74 | 74 |
75 // Don't use initial delay unless the last request was an error. | 75 // Don't use initial delay unless the last request was an error. |
76 false, | 76 false, |
77 }; | 77 }; |
78 | 78 |
79 const char kAuthUserQueryKey[] = "authuser"; | 79 const char kAuthUserQueryKey[] = "authuser"; |
80 | 80 |
81 const int kMaxAuthUserValue = 10; | 81 const int kMaxAuthUserValue = 10; |
82 const int kMaxOAuth2Attempts = 3; | 82 const int kMaxOAuth2Attempts = 3; |
83 | 83 |
84 const char kNotFromWebstoreInstallSource[] = "notfromwebstore"; | 84 const char kNotFromWebstoreInstallSource[] = "notfromwebstore"; |
85 const char kDefaultInstallSource[] = ""; | 85 const char kDefaultInstallSource[] = ""; |
86 | 86 |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
141 url::Component new_query(0, new_query_string.size()); | 141 url::Component new_query(0, new_query_string.size()); |
142 url::Replacements<char> replacements; | 142 url::Replacements<char> replacements; |
143 replacements.SetQuery(new_query_string.c_str(), new_query); | 143 replacements.SetQuery(new_query_string.c_str(), new_query); |
144 *url = url->ReplaceComponents(replacements); | 144 *url = url->ReplaceComponents(replacements); |
145 return true; | 145 return true; |
146 } | 146 } |
147 | 147 |
148 } // namespace | 148 } // namespace |
149 | 149 |
150 UpdateDetails::UpdateDetails(const std::string& id, const Version& version) | 150 UpdateDetails::UpdateDetails(const std::string& id, const Version& version) |
151 : id(id), version(version) {} | 151 : id(id), version(version) { |
| 152 } |
152 | 153 |
153 UpdateDetails::~UpdateDetails() {} | 154 UpdateDetails::~UpdateDetails() { |
| 155 } |
154 | 156 |
155 ExtensionDownloader::ExtensionFetch::ExtensionFetch() | 157 ExtensionDownloader::ExtensionFetch::ExtensionFetch() |
156 : url(), credentials(CREDENTIALS_NONE) { | 158 : url(), credentials(CREDENTIALS_NONE) { |
157 } | 159 } |
158 | 160 |
159 ExtensionDownloader::ExtensionFetch::ExtensionFetch( | 161 ExtensionDownloader::ExtensionFetch::ExtensionFetch( |
160 const std::string& id, | 162 const std::string& id, |
161 const GURL& url, | 163 const GURL& url, |
162 const std::string& package_hash, | 164 const std::string& package_hash, |
163 const std::string& version, | 165 const std::string& version, |
164 const std::set<int>& request_ids) | 166 const std::set<int>& request_ids) |
165 : id(id), | 167 : id(id), |
166 url(url), | 168 url(url), |
167 package_hash(package_hash), | 169 package_hash(package_hash), |
168 version(version), | 170 version(version), |
169 request_ids(request_ids), | 171 request_ids(request_ids), |
170 credentials(CREDENTIALS_NONE), | 172 credentials(CREDENTIALS_NONE), |
171 oauth2_attempt_count(0) { | 173 oauth2_attempt_count(0) { |
172 } | 174 } |
173 | 175 |
174 ExtensionDownloader::ExtensionFetch::~ExtensionFetch() {} | 176 ExtensionDownloader::ExtensionFetch::~ExtensionFetch() { |
| 177 } |
175 | 178 |
176 ExtensionDownloader::ExtensionDownloader( | 179 ExtensionDownloader::ExtensionDownloader( |
177 ExtensionDownloaderDelegate* delegate, | 180 ExtensionDownloaderDelegate* delegate, |
178 net::URLRequestContextGetter* request_context) | 181 net::URLRequestContextGetter* request_context) |
179 : OAuth2TokenService::Consumer(kTokenServiceConsumerId), | 182 : OAuth2TokenService::Consumer(kTokenServiceConsumerId), |
180 delegate_(delegate), | 183 delegate_(delegate), |
181 request_context_(request_context), | 184 request_context_(request_context), |
182 manifests_queue_(&kDefaultBackoffPolicy, | 185 manifests_queue_(&kDefaultBackoffPolicy, |
183 base::Bind(&ExtensionDownloader::CreateManifestFetcher, | 186 base::Bind(&ExtensionDownloader::CreateManifestFetcher, |
184 base::Unretained(this))), | 187 base::Unretained(this))), |
185 extensions_queue_(&kDefaultBackoffPolicy, | 188 extensions_queue_(&kDefaultBackoffPolicy, |
186 base::Bind(&ExtensionDownloader::CreateExtensionFetcher, | 189 base::Bind(&ExtensionDownloader::CreateExtensionFetcher, |
187 base::Unretained(this))), | 190 base::Unretained(this))), |
188 extension_cache_(NULL), | 191 extension_cache_(NULL), |
189 enable_extra_update_metrics_(false), | 192 enable_extra_update_metrics_(false), |
190 weak_ptr_factory_(this) { | 193 weak_ptr_factory_(this) { |
191 DCHECK(delegate_); | 194 DCHECK(delegate_); |
192 DCHECK(request_context_.get()); | 195 DCHECK(request_context_.get()); |
193 } | 196 } |
194 | 197 |
195 ExtensionDownloader::~ExtensionDownloader() {} | 198 ExtensionDownloader::~ExtensionDownloader() { |
| 199 } |
196 | 200 |
197 bool ExtensionDownloader::AddExtension(const Extension& extension, | 201 bool ExtensionDownloader::AddExtension(const Extension& extension, |
198 int request_id) { | 202 int request_id) { |
199 // Skip extensions with empty update URLs converted from user | 203 // Skip extensions with empty update URLs converted from user |
200 // scripts. | 204 // scripts. |
201 if (extension.converted_from_user_script() && | 205 if (extension.converted_from_user_script() && |
202 ManifestURL::GetUpdateURL(&extension).is_empty()) { | 206 ManifestURL::GetUpdateURL(&extension).is_empty()) { |
203 return false; | 207 return false; |
204 } | 208 } |
205 | 209 |
206 // If the extension updates itself from the gallery, ignore any update URL | 210 // If the extension updates itself from the gallery, ignore any update URL |
207 // data. At the moment there is no extra data that an extension can | 211 // data. At the moment there is no extra data that an extension can |
208 // communicate to the the gallery update servers. | 212 // communicate to the the gallery update servers. |
209 std::string update_url_data; | 213 std::string update_url_data; |
210 if (!ManifestURL::UpdatesFromGallery(&extension)) | 214 if (!ManifestURL::UpdatesFromGallery(&extension)) |
211 update_url_data = delegate_->GetUpdateUrlData(extension.id()); | 215 update_url_data = delegate_->GetUpdateUrlData(extension.id()); |
212 | 216 |
213 std::string install_source; | 217 std::string install_source; |
214 bool force_update = delegate_->ShouldForceUpdate(extension.id(), | 218 bool force_update = |
215 &install_source); | 219 delegate_->ShouldForceUpdate(extension.id(), &install_source); |
216 return AddExtensionData(extension.id(), | 220 return AddExtensionData(extension.id(), |
217 *extension.version(), | 221 *extension.version(), |
218 extension.GetType(), | 222 extension.GetType(), |
219 ManifestURL::GetUpdateURL(&extension), | 223 ManifestURL::GetUpdateURL(&extension), |
220 update_url_data, | 224 update_url_data, |
221 request_id, | 225 request_id, |
222 force_update, | 226 force_update, |
223 install_source); | 227 install_source); |
224 } | 228 } |
225 | 229 |
(...skipping 12 matching lines...) Expand all Loading... |
238 update_url, | 242 update_url, |
239 std::string(), | 243 std::string(), |
240 request_id, | 244 request_id, |
241 false, | 245 false, |
242 std::string()); | 246 std::string()); |
243 } | 247 } |
244 | 248 |
245 void ExtensionDownloader::StartAllPending(ExtensionCache* cache) { | 249 void ExtensionDownloader::StartAllPending(ExtensionCache* cache) { |
246 if (cache) { | 250 if (cache) { |
247 extension_cache_ = cache; | 251 extension_cache_ = cache; |
248 extension_cache_->Start(base::Bind( | 252 extension_cache_->Start(base::Bind(&ExtensionDownloader::DoStartAllPending, |
249 &ExtensionDownloader::DoStartAllPending, | 253 weak_ptr_factory_.GetWeakPtr())); |
250 weak_ptr_factory_.GetWeakPtr())); | |
251 } else { | 254 } else { |
252 DoStartAllPending(); | 255 DoStartAllPending(); |
253 } | 256 } |
254 } | 257 } |
255 | 258 |
256 void ExtensionDownloader::DoStartAllPending() { | 259 void ExtensionDownloader::DoStartAllPending() { |
257 ReportStats(); | 260 ReportStats(); |
258 url_stats_ = URLStats(); | 261 url_stats_ = URLStats(); |
259 | 262 |
260 for (FetchMap::iterator it = fetches_preparing_.begin(); | 263 for (FetchMap::iterator it = fetches_preparing_.begin(); |
261 it != fetches_preparing_.end(); ++it) { | 264 it != fetches_preparing_.end(); |
262 std::vector<linked_ptr<ManifestFetchData> >& list = it->second; | 265 ++it) { |
| 266 std::vector<linked_ptr<ManifestFetchData>>& list = it->second; |
263 for (size_t i = 0; i < list.size(); ++i) { | 267 for (size_t i = 0; i < list.size(); ++i) { |
264 StartUpdateCheck(scoped_ptr<ManifestFetchData>(list[i].release())); | 268 StartUpdateCheck(scoped_ptr<ManifestFetchData>(list[i].release())); |
265 } | 269 } |
266 } | 270 } |
267 fetches_preparing_.clear(); | 271 fetches_preparing_.clear(); |
268 } | 272 } |
269 | 273 |
270 void ExtensionDownloader::StartBlacklistUpdate( | 274 void ExtensionDownloader::StartBlacklistUpdate( |
271 const std::string& version, | 275 const std::string& version, |
272 const ManifestFetchData::PingData& ping_data, | 276 const ManifestFetchData::PingData& ping_data, |
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
356 // webstore update URL. | 360 // webstore update URL. |
357 if (!extension_urls::IsWebstoreUpdateUrl(update_url) && | 361 if (!extension_urls::IsWebstoreUpdateUrl(update_url) && |
358 enable_extra_update_metrics_) { | 362 enable_extra_update_metrics_) { |
359 update_urls.push_back(extension_urls::GetWebstoreUpdateUrl()); | 363 update_urls.push_back(extension_urls::GetWebstoreUpdateUrl()); |
360 } | 364 } |
361 | 365 |
362 for (size_t i = 0; i < update_urls.size(); ++i) { | 366 for (size_t i = 0; i < update_urls.size(); ++i) { |
363 DCHECK(!update_urls[i].is_empty()); | 367 DCHECK(!update_urls[i].is_empty()); |
364 DCHECK(update_urls[i].is_valid()); | 368 DCHECK(update_urls[i].is_valid()); |
365 | 369 |
366 std::string install_source = i == 0 ? | 370 std::string install_source = |
367 kDefaultInstallSource : kNotFromWebstoreInstallSource; | 371 i == 0 ? kDefaultInstallSource : kNotFromWebstoreInstallSource; |
368 if (!install_source_override.empty()) { | 372 if (!install_source_override.empty()) { |
369 install_source = install_source_override; | 373 install_source = install_source_override; |
370 } | 374 } |
371 | 375 |
372 ManifestFetchData::PingData ping_data; | 376 ManifestFetchData::PingData ping_data; |
373 ManifestFetchData::PingData* optional_ping_data = NULL; | 377 ManifestFetchData::PingData* optional_ping_data = NULL; |
374 if (delegate_->GetPingDataForExtension(id, &ping_data)) | 378 if (delegate_->GetPingDataForExtension(id, &ping_data)) |
375 optional_ping_data = &ping_data; | 379 optional_ping_data = &ping_data; |
376 | 380 |
377 // Find or create a ManifestFetchData to add this extension to. | 381 // Find or create a ManifestFetchData to add this extension to. |
378 bool added = false; | 382 bool added = false; |
379 FetchMap::iterator existing_iter = fetches_preparing_.find( | 383 FetchMap::iterator existing_iter = |
380 std::make_pair(request_id, update_urls[i])); | 384 fetches_preparing_.find(std::make_pair(request_id, update_urls[i])); |
381 if (existing_iter != fetches_preparing_.end() && | 385 if (existing_iter != fetches_preparing_.end() && |
382 !existing_iter->second.empty()) { | 386 !existing_iter->second.empty()) { |
383 // Try to add to the ManifestFetchData at the end of the list. | 387 // Try to add to the ManifestFetchData at the end of the list. |
384 ManifestFetchData* existing_fetch = existing_iter->second.back().get(); | 388 ManifestFetchData* existing_fetch = existing_iter->second.back().get(); |
385 if (existing_fetch->AddExtension(id, version.GetString(), | 389 if (existing_fetch->AddExtension(id, |
386 optional_ping_data, update_url_data, | 390 version.GetString(), |
| 391 optional_ping_data, |
| 392 update_url_data, |
387 install_source, | 393 install_source, |
388 force_update)) { | 394 force_update)) { |
389 added = true; | 395 added = true; |
390 } | 396 } |
391 } | 397 } |
392 if (!added) { | 398 if (!added) { |
393 // Otherwise add a new element to the list, if the list doesn't exist or | 399 // Otherwise add a new element to the list, if the list doesn't exist or |
394 // if its last element is already full. | 400 // if its last element is already full. |
395 linked_ptr<ManifestFetchData> fetch( | 401 linked_ptr<ManifestFetchData> fetch( |
396 CreateManifestFetchData(update_urls[i], request_id)); | 402 CreateManifestFetchData(update_urls[i], request_id)); |
397 fetches_preparing_[std::make_pair(request_id, update_urls[i])]. | 403 fetches_preparing_[std::make_pair(request_id, update_urls[i])].push_back( |
398 push_back(fetch); | 404 fetch); |
399 added = fetch->AddExtension(id, version.GetString(), | 405 added = fetch->AddExtension(id, |
| 406 version.GetString(), |
400 optional_ping_data, | 407 optional_ping_data, |
401 update_url_data, | 408 update_url_data, |
402 install_source, | 409 install_source, |
403 force_update); | 410 force_update); |
404 DCHECK(added); | 411 DCHECK(added); |
405 } | 412 } |
406 } | 413 } |
407 | 414 |
408 return true; | 415 return true; |
409 } | 416 } |
410 | 417 |
411 void ExtensionDownloader::ReportStats() const { | 418 void ExtensionDownloader::ReportStats() const { |
412 UMA_HISTOGRAM_COUNTS_100("Extensions.UpdateCheckExtension", | 419 UMA_HISTOGRAM_COUNTS_100("Extensions.UpdateCheckExtension", |
413 url_stats_.extension_count); | 420 url_stats_.extension_count); |
414 UMA_HISTOGRAM_COUNTS_100("Extensions.UpdateCheckTheme", | 421 UMA_HISTOGRAM_COUNTS_100("Extensions.UpdateCheckTheme", |
415 url_stats_.theme_count); | 422 url_stats_.theme_count); |
416 UMA_HISTOGRAM_COUNTS_100("Extensions.UpdateCheckApp", | 423 UMA_HISTOGRAM_COUNTS_100("Extensions.UpdateCheckApp", url_stats_.app_count); |
417 url_stats_.app_count); | |
418 UMA_HISTOGRAM_COUNTS_100("Extensions.UpdateCheckPackagedApp", | 424 UMA_HISTOGRAM_COUNTS_100("Extensions.UpdateCheckPackagedApp", |
419 url_stats_.platform_app_count); | 425 url_stats_.platform_app_count); |
420 UMA_HISTOGRAM_COUNTS_100("Extensions.UpdateCheckPending", | 426 UMA_HISTOGRAM_COUNTS_100("Extensions.UpdateCheckPending", |
421 url_stats_.pending_count); | 427 url_stats_.pending_count); |
422 UMA_HISTOGRAM_COUNTS_100("Extensions.UpdateCheckGoogleUrl", | 428 UMA_HISTOGRAM_COUNTS_100("Extensions.UpdateCheckGoogleUrl", |
423 url_stats_.google_url_count); | 429 url_stats_.google_url_count); |
424 UMA_HISTOGRAM_COUNTS_100("Extensions.UpdateCheckOtherUrl", | 430 UMA_HISTOGRAM_COUNTS_100("Extensions.UpdateCheckOtherUrl", |
425 url_stats_.other_url_count); | 431 url_stats_.other_url_count); |
426 UMA_HISTOGRAM_COUNTS_100("Extensions.UpdateCheckNoUrl", | 432 UMA_HISTOGRAM_COUNTS_100("Extensions.UpdateCheckNoUrl", |
427 url_stats_.no_url_count); | 433 url_stats_.no_url_count); |
(...skipping 15 matching lines...) Expand all Loading... |
443 // This url is already scheduled to be fetched. | 449 // This url is already scheduled to be fetched. |
444 i->Merge(*fetch_data); | 450 i->Merge(*fetch_data); |
445 return; | 451 return; |
446 } | 452 } |
447 } | 453 } |
448 | 454 |
449 if (manifests_queue_.active_request() && | 455 if (manifests_queue_.active_request() && |
450 manifests_queue_.active_request()->full_url() == fetch_data->full_url()) { | 456 manifests_queue_.active_request()->full_url() == fetch_data->full_url()) { |
451 manifests_queue_.active_request()->Merge(*fetch_data); | 457 manifests_queue_.active_request()->Merge(*fetch_data); |
452 } else { | 458 } else { |
453 UMA_HISTOGRAM_COUNTS("Extensions.UpdateCheckUrlLength", | 459 UMA_HISTOGRAM_COUNTS( |
| 460 "Extensions.UpdateCheckUrlLength", |
454 fetch_data->full_url().possibly_invalid_spec().length()); | 461 fetch_data->full_url().possibly_invalid_spec().length()); |
455 | 462 |
456 manifests_queue_.ScheduleRequest(fetch_data.Pass()); | 463 manifests_queue_.ScheduleRequest(fetch_data.Pass()); |
457 } | 464 } |
458 } | 465 } |
459 | 466 |
460 void ExtensionDownloader::CreateManifestFetcher() { | 467 void ExtensionDownloader::CreateManifestFetcher() { |
461 if (VLOG_IS_ON(2)) { | 468 if (VLOG_IS_ON(2)) { |
462 std::vector<std::string> id_vector( | 469 std::vector<std::string> id_vector( |
463 manifests_queue_.active_request()->extension_ids().begin(), | 470 manifests_queue_.active_request()->extension_ids().begin(), |
464 manifests_queue_.active_request()->extension_ids().end()); | 471 manifests_queue_.active_request()->extension_ids().end()); |
465 std::string id_list = JoinString(id_vector, ','); | 472 std::string id_list = JoinString(id_vector, ','); |
466 VLOG(2) << "Fetching " << manifests_queue_.active_request()->full_url() | 473 VLOG(2) << "Fetching " << manifests_queue_.active_request()->full_url() |
467 << " for " << id_list; | 474 << " for " << id_list; |
468 } | 475 } |
469 | 476 |
470 manifest_fetcher_.reset(net::URLFetcher::Create( | 477 manifest_fetcher_.reset( |
471 kManifestFetcherId, manifests_queue_.active_request()->full_url(), | 478 net::URLFetcher::Create(kManifestFetcherId, |
472 net::URLFetcher::GET, this)); | 479 manifests_queue_.active_request()->full_url(), |
| 480 net::URLFetcher::GET, |
| 481 this)); |
473 manifest_fetcher_->SetRequestContext(request_context_.get()); | 482 manifest_fetcher_->SetRequestContext(request_context_.get()); |
474 manifest_fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES | | 483 manifest_fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES | |
475 net::LOAD_DO_NOT_SAVE_COOKIES | | 484 net::LOAD_DO_NOT_SAVE_COOKIES | |
476 net::LOAD_DISABLE_CACHE); | 485 net::LOAD_DISABLE_CACHE); |
477 // Update checks can be interrupted if a network change is detected; this is | 486 // Update checks can be interrupted if a network change is detected; this is |
478 // common for the retail mode AppPack on ChromeOS. Retrying once should be | 487 // common for the retail mode AppPack on ChromeOS. Retrying once should be |
479 // enough to recover in those cases; let the fetcher retry up to 3 times | 488 // enough to recover in those cases; let the fetcher retry up to 3 times |
480 // just in case. http://crosbug.com/130602 | 489 // just in case. http://crosbug.com/130602 |
481 manifest_fetcher_->SetAutomaticallyRetryOnNetworkChanges(3); | 490 manifest_fetcher_->SetAutomaticallyRetryOnNetworkChanges(3); |
482 manifest_fetcher_->Start(); | 491 manifest_fetcher_->Start(); |
483 } | 492 } |
484 | 493 |
485 void ExtensionDownloader::OnURLFetchComplete( | 494 void ExtensionDownloader::OnURLFetchComplete(const net::URLFetcher* source) { |
486 const net::URLFetcher* source) { | |
487 // TODO(vadimt): Remove ScopedProfile below once crbug.com/422577 is fixed. | 495 // TODO(vadimt): Remove ScopedProfile below once crbug.com/422577 is fixed. |
488 tracked_objects::ScopedProfile tracking_profile( | 496 tracked_objects::ScopedProfile tracking_profile( |
489 FROM_HERE_WITH_EXPLICIT_FUNCTION( | 497 FROM_HERE_WITH_EXPLICIT_FUNCTION( |
490 "422577 ExtensionDownloader::OnURLFetchComplete")); | 498 "422577 ExtensionDownloader::OnURLFetchComplete")); |
491 | 499 |
492 VLOG(2) << source->GetResponseCode() << " " << source->GetURL(); | 500 VLOG(2) << source->GetResponseCode() << " " << source->GetURL(); |
493 | 501 |
494 if (source == manifest_fetcher_.get()) { | 502 if (source == manifest_fetcher_.get()) { |
495 std::string data; | 503 std::string data; |
496 source->GetResponseAsString(&data); | 504 source->GetResponseAsString(&data); |
(...skipping 17 matching lines...) Expand all Loading... |
514 const GURL& url, | 522 const GURL& url, |
515 const net::URLRequestStatus& status, | 523 const net::URLRequestStatus& status, |
516 int response_code, | 524 int response_code, |
517 const base::TimeDelta& backoff_delay, | 525 const base::TimeDelta& backoff_delay, |
518 const std::string& data) { | 526 const std::string& data) { |
519 // We want to try parsing the manifest, and if it indicates updates are | 527 // We want to try parsing the manifest, and if it indicates updates are |
520 // available, we want to fire off requests to fetch those updates. | 528 // available, we want to fire off requests to fetch those updates. |
521 if (status.status() == net::URLRequestStatus::SUCCESS && | 529 if (status.status() == net::URLRequestStatus::SUCCESS && |
522 (response_code == 200 || (url.SchemeIsFile() && data.length() > 0))) { | 530 (response_code == 200 || (url.SchemeIsFile() && data.length() > 0))) { |
523 RETRY_HISTOGRAM("ManifestFetchSuccess", | 531 RETRY_HISTOGRAM("ManifestFetchSuccess", |
524 manifests_queue_.active_request_failure_count(), url); | 532 manifests_queue_.active_request_failure_count(), |
| 533 url); |
525 VLOG(2) << "beginning manifest parse for " << url; | 534 VLOG(2) << "beginning manifest parse for " << url; |
526 scoped_refptr<SafeManifestParser> safe_parser( | 535 scoped_refptr<SafeManifestParser> safe_parser(new SafeManifestParser( |
527 new SafeManifestParser( | 536 data, |
528 data, | 537 manifests_queue_.reset_active_request().release(), |
529 manifests_queue_.reset_active_request().release(), | 538 base::Bind(&ExtensionDownloader::HandleManifestResults, |
530 base::Bind(&ExtensionDownloader::HandleManifestResults, | 539 weak_ptr_factory_.GetWeakPtr()))); |
531 weak_ptr_factory_.GetWeakPtr()))); | |
532 safe_parser->Start(); | 540 safe_parser->Start(); |
533 } else { | 541 } else { |
534 VLOG(1) << "Failed to fetch manifest '" << url.possibly_invalid_spec() | 542 VLOG(1) << "Failed to fetch manifest '" << url.possibly_invalid_spec() |
535 << "' response code:" << response_code; | 543 << "' response code:" << response_code; |
536 if (ShouldRetryRequest(status, response_code) && | 544 if (ShouldRetryRequest(status, response_code) && |
537 manifests_queue_.active_request_failure_count() < kMaxRetries) { | 545 manifests_queue_.active_request_failure_count() < kMaxRetries) { |
538 manifests_queue_.RetryRequest(backoff_delay); | 546 manifests_queue_.RetryRequest(backoff_delay); |
539 } else { | 547 } else { |
540 RETRY_HISTOGRAM("ManifestFetchFailure", | 548 RETRY_HISTOGRAM("ManifestFetchFailure", |
541 manifests_queue_.active_request_failure_count(), url); | 549 manifests_queue_.active_request_failure_count(), |
| 550 url); |
542 NotifyExtensionsDownloadFailed( | 551 NotifyExtensionsDownloadFailed( |
543 manifests_queue_.active_request()->extension_ids(), | 552 manifests_queue_.active_request()->extension_ids(), |
544 manifests_queue_.active_request()->request_ids(), | 553 manifests_queue_.active_request()->request_ids(), |
545 ExtensionDownloaderDelegate::MANIFEST_FETCH_FAILED); | 554 ExtensionDownloaderDelegate::MANIFEST_FETCH_FAILED); |
546 } | 555 } |
547 } | 556 } |
548 manifest_fetcher_.reset(); | 557 manifest_fetcher_.reset(); |
549 manifests_queue_.reset_active_request(); | 558 manifests_queue_.reset_active_request(); |
550 | 559 |
551 // If we have any pending manifest requests, fire off the next one. | 560 // If we have any pending manifest requests, fire off the next one. |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
586 | 595 |
587 // Force https (crbug.com/129587). | 596 // Force https (crbug.com/129587). |
588 if (!crx_url.SchemeIsSecure()) { | 597 if (!crx_url.SchemeIsSecure()) { |
589 url::Replacements<char> replacements; | 598 url::Replacements<char> replacements; |
590 std::string scheme("https"); | 599 std::string scheme("https"); |
591 replacements.SetScheme(scheme.c_str(), | 600 replacements.SetScheme(scheme.c_str(), |
592 url::Component(0, scheme.size())); | 601 url::Component(0, scheme.size())); |
593 crx_url = crx_url.ReplaceComponents(replacements); | 602 crx_url = crx_url.ReplaceComponents(replacements); |
594 } | 603 } |
595 } | 604 } |
596 scoped_ptr<ExtensionFetch> fetch(new ExtensionFetch( | 605 scoped_ptr<ExtensionFetch> fetch( |
597 update->extension_id, crx_url, update->package_hash, | 606 new ExtensionFetch(update->extension_id, |
598 update->version, fetch_data.request_ids())); | 607 crx_url, |
| 608 update->package_hash, |
| 609 update->version, |
| 610 fetch_data.request_ids())); |
599 FetchUpdatedExtension(fetch.Pass()); | 611 FetchUpdatedExtension(fetch.Pass()); |
600 } | 612 } |
601 | 613 |
602 // If the manifest response included a <daystart> element, we want to save | 614 // If the manifest response included a <daystart> element, we want to save |
603 // that value for any extensions which had sent a ping in the request. | 615 // that value for any extensions which had sent a ping in the request. |
604 if (fetch_data.base_url().DomainIs(kGoogleDotCom) && | 616 if (fetch_data.base_url().DomainIs(kGoogleDotCom) && |
605 results->daystart_elapsed_seconds >= 0) { | 617 results->daystart_elapsed_seconds >= 0) { |
606 Time day_start = | 618 Time day_start = |
607 Time::Now() - TimeDelta::FromSeconds(results->daystart_elapsed_seconds); | 619 Time::Now() - TimeDelta::FromSeconds(results->daystart_elapsed_seconds); |
608 | 620 |
(...skipping 23 matching lines...) Expand all Loading... |
632 | 644 |
633 if (!fetch_data.Includes(id)) { | 645 if (!fetch_data.Includes(id)) { |
634 VLOG(2) << "Ignoring " << id << " from this manifest"; | 646 VLOG(2) << "Ignoring " << id << " from this manifest"; |
635 continue; | 647 continue; |
636 } | 648 } |
637 | 649 |
638 if (VLOG_IS_ON(2)) { | 650 if (VLOG_IS_ON(2)) { |
639 if (update->version.empty()) | 651 if (update->version.empty()) |
640 VLOG(2) << "manifest indicates " << id << " has no update"; | 652 VLOG(2) << "manifest indicates " << id << " has no update"; |
641 else | 653 else |
642 VLOG(2) << "manifest indicates " << id | 654 VLOG(2) << "manifest indicates " << id << " latest version is '" |
643 << " latest version is '" << update->version << "'"; | 655 << update->version << "'"; |
644 } | 656 } |
645 | 657 |
646 if (!delegate_->IsExtensionPending(id)) { | 658 if (!delegate_->IsExtensionPending(id)) { |
647 // If we're not installing pending extension, and the update | 659 // If we're not installing pending extension, and the update |
648 // version is the same or older than what's already installed, | 660 // version is the same or older than what's already installed, |
649 // we don't want it. | 661 // we don't want it. |
650 std::string version; | 662 std::string version; |
651 if (!delegate_->GetExtensionExistingVersion(id, &version)) { | 663 if (!delegate_->GetExtensionExistingVersion(id, &version)) { |
652 VLOG(2) << id << " is not installed"; | 664 VLOG(2) << id << " is not installed"; |
653 continue; | 665 continue; |
(...skipping 21 matching lines...) Expand all Loading... |
675 LOG(WARNING) << "Updated version of extension " << id | 687 LOG(WARNING) << "Updated version of extension " << id |
676 << " available, but requires chrome version " | 688 << " available, but requires chrome version " |
677 << update->browser_min_version; | 689 << update->browser_min_version; |
678 continue; | 690 continue; |
679 } | 691 } |
680 VLOG(2) << "will try to update " << id; | 692 VLOG(2) << "will try to update " << id; |
681 result->push_back(i); | 693 result->push_back(i); |
682 } | 694 } |
683 } | 695 } |
684 | 696 |
685 // Begins (or queues up) download of an updated extension. | 697 // Begins (or queues up) download of an updated extension. |
686 void ExtensionDownloader::FetchUpdatedExtension( | 698 void ExtensionDownloader::FetchUpdatedExtension( |
687 scoped_ptr<ExtensionFetch> fetch_data) { | 699 scoped_ptr<ExtensionFetch> fetch_data) { |
688 if (!fetch_data->url.is_valid()) { | 700 if (!fetch_data->url.is_valid()) { |
689 // TODO(asargent): This can sometimes be invalid. See crbug.com/130881. | 701 // TODO(asargent): This can sometimes be invalid. See crbug.com/130881. |
690 LOG(ERROR) << "Invalid URL: '" << fetch_data->url.possibly_invalid_spec() | 702 LOG(ERROR) << "Invalid URL: '" << fetch_data->url.possibly_invalid_spec() |
691 << "' for extension " << fetch_data->id; | 703 << "' for extension " << fetch_data->id; |
692 return; | 704 return; |
693 } | 705 } |
694 | 706 |
695 for (RequestQueue<ExtensionFetch>::iterator iter = | 707 for (RequestQueue<ExtensionFetch>::iterator iter = extensions_queue_.begin(); |
696 extensions_queue_.begin(); | 708 iter != extensions_queue_.end(); |
697 iter != extensions_queue_.end(); ++iter) { | 709 ++iter) { |
698 if (iter->id == fetch_data->id || iter->url == fetch_data->url) { | 710 if (iter->id == fetch_data->id || iter->url == fetch_data->url) { |
699 iter->request_ids.insert(fetch_data->request_ids.begin(), | 711 iter->request_ids.insert(fetch_data->request_ids.begin(), |
700 fetch_data->request_ids.end()); | 712 fetch_data->request_ids.end()); |
701 return; // already scheduled | 713 return; // already scheduled |
702 } | 714 } |
703 } | 715 } |
704 | 716 |
705 if (extensions_queue_.active_request() && | 717 if (extensions_queue_.active_request() && |
706 extensions_queue_.active_request()->url == fetch_data->url) { | 718 extensions_queue_.active_request()->url == fetch_data->url) { |
707 extensions_queue_.active_request()->request_ids.insert( | 719 extensions_queue_.active_request()->request_ids.insert( |
(...skipping 10 matching lines...) Expand all Loading... |
718 } else { | 730 } else { |
719 extensions_queue_.ScheduleRequest(fetch_data.Pass()); | 731 extensions_queue_.ScheduleRequest(fetch_data.Pass()); |
720 } | 732 } |
721 } | 733 } |
722 } | 734 } |
723 | 735 |
724 void ExtensionDownloader::NotifyDelegateDownloadFinished( | 736 void ExtensionDownloader::NotifyDelegateDownloadFinished( |
725 scoped_ptr<ExtensionFetch> fetch_data, | 737 scoped_ptr<ExtensionFetch> fetch_data, |
726 const base::FilePath& crx_path, | 738 const base::FilePath& crx_path, |
727 bool file_ownership_passed) { | 739 bool file_ownership_passed) { |
728 delegate_->OnExtensionDownloadFinished(fetch_data->id, crx_path, | 740 delegate_->OnExtensionDownloadFinished(fetch_data->id, |
729 file_ownership_passed, fetch_data->url, fetch_data->version, | 741 crx_path, |
730 ping_results_[fetch_data->id], fetch_data->request_ids); | 742 file_ownership_passed, |
| 743 fetch_data->url, |
| 744 fetch_data->version, |
| 745 ping_results_[fetch_data->id], |
| 746 fetch_data->request_ids); |
731 ping_results_.erase(fetch_data->id); | 747 ping_results_.erase(fetch_data->id); |
732 } | 748 } |
733 | 749 |
734 void ExtensionDownloader::CreateExtensionFetcher() { | 750 void ExtensionDownloader::CreateExtensionFetcher() { |
735 const ExtensionFetch* fetch = extensions_queue_.active_request(); | 751 const ExtensionFetch* fetch = extensions_queue_.active_request(); |
736 extension_fetcher_.reset(net::URLFetcher::Create( | 752 extension_fetcher_.reset(net::URLFetcher::Create( |
737 kExtensionFetcherId, fetch->url, net::URLFetcher::GET, this)); | 753 kExtensionFetcherId, fetch->url, net::URLFetcher::GET, this)); |
738 extension_fetcher_->SetRequestContext(request_context_.get()); | 754 extension_fetcher_->SetRequestContext(request_context_.get()); |
739 extension_fetcher_->SetAutomaticallyRetryOnNetworkChanges(3); | 755 extension_fetcher_->SetAutomaticallyRetryOnNetworkChanges(3); |
740 | 756 |
741 int load_flags = net::LOAD_DISABLE_CACHE; | 757 int load_flags = net::LOAD_DISABLE_CACHE; |
742 bool is_secure = fetch->url.SchemeIsSecure(); | 758 bool is_secure = fetch->url.SchemeIsSecure(); |
743 if (fetch->credentials != ExtensionFetch::CREDENTIALS_COOKIES || !is_secure) { | 759 if (fetch->credentials != ExtensionFetch::CREDENTIALS_COOKIES || !is_secure) { |
744 load_flags |= net::LOAD_DO_NOT_SEND_COOKIES | | 760 load_flags |= net::LOAD_DO_NOT_SEND_COOKIES | net::LOAD_DO_NOT_SAVE_COOKIES; |
745 net::LOAD_DO_NOT_SAVE_COOKIES; | |
746 } | 761 } |
747 extension_fetcher_->SetLoadFlags(load_flags); | 762 extension_fetcher_->SetLoadFlags(load_flags); |
748 | 763 |
749 // Download CRX files to a temp file. The blacklist is small and will be | 764 // Download CRX files to a temp file. The blacklist is small and will be |
750 // processed in memory, so it is fetched into a string. | 765 // processed in memory, so it is fetched into a string. |
751 if (fetch->id != kBlacklistAppID) { | 766 if (fetch->id != kBlacklistAppID) { |
752 extension_fetcher_->SaveResponseToTemporaryFile( | 767 extension_fetcher_->SaveResponseToTemporaryFile( |
753 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE)); | 768 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE)); |
754 } | 769 } |
755 | 770 |
756 if (fetch->credentials == ExtensionFetch::CREDENTIALS_OAUTH2_TOKEN && | 771 if (fetch->credentials == ExtensionFetch::CREDENTIALS_OAUTH2_TOKEN && |
757 is_secure) { | 772 is_secure) { |
758 if (access_token_.empty()) { | 773 if (access_token_.empty()) { |
759 // We should try OAuth2, but we have no token cached. This | 774 // We should try OAuth2, but we have no token cached. This |
760 // ExtensionFetcher will be started once the token fetch is complete, | 775 // ExtensionFetcher will be started once the token fetch is complete, |
761 // in either OnTokenFetchSuccess or OnTokenFetchFailure. | 776 // in either OnTokenFetchSuccess or OnTokenFetchFailure. |
762 DCHECK(identity_provider_.get()); | 777 DCHECK(identity_provider_.get()); |
763 OAuth2TokenService::ScopeSet webstore_scopes; | 778 OAuth2TokenService::ScopeSet webstore_scopes; |
764 webstore_scopes.insert(kWebstoreOAuth2Scope); | 779 webstore_scopes.insert(kWebstoreOAuth2Scope); |
765 access_token_request_ = | 780 access_token_request_ = |
766 identity_provider_->GetTokenService()->StartRequest( | 781 identity_provider_->GetTokenService()->StartRequest( |
767 identity_provider_->GetActiveAccountId(), | 782 identity_provider_->GetActiveAccountId(), webstore_scopes, this); |
768 webstore_scopes, | |
769 this); | |
770 return; | 783 return; |
771 } | 784 } |
772 extension_fetcher_->AddExtraRequestHeader( | 785 extension_fetcher_->AddExtraRequestHeader( |
773 base::StringPrintf("%s: Bearer %s", | 786 base::StringPrintf("%s: Bearer %s", |
774 net::HttpRequestHeaders::kAuthorization, | 787 net::HttpRequestHeaders::kAuthorization, |
775 access_token_.c_str())); | 788 access_token_.c_str())); |
776 } | 789 } |
777 | 790 |
778 VLOG(2) << "Starting fetch of " << fetch->url << " for " << fetch->id; | 791 VLOG(2) << "Starting fetch of " << fetch->url << " for " << fetch->id; |
779 extension_fetcher_->Start(); | 792 extension_fetcher_->Start(); |
780 } | 793 } |
781 | 794 |
782 void ExtensionDownloader::OnCRXFetchComplete( | 795 void ExtensionDownloader::OnCRXFetchComplete( |
783 const net::URLFetcher* source, | 796 const net::URLFetcher* source, |
784 const GURL& url, | 797 const GURL& url, |
785 const net::URLRequestStatus& status, | 798 const net::URLRequestStatus& status, |
786 int response_code, | 799 int response_code, |
787 const base::TimeDelta& backoff_delay) { | 800 const base::TimeDelta& backoff_delay) { |
788 ExtensionFetch& active_request = *extensions_queue_.active_request(); | 801 ExtensionFetch& active_request = *extensions_queue_.active_request(); |
789 const std::string& id = active_request.id; | 802 const std::string& id = active_request.id; |
790 if (status.status() == net::URLRequestStatus::SUCCESS && | 803 if (status.status() == net::URLRequestStatus::SUCCESS && |
791 (response_code == 200 || url.SchemeIsFile())) { | 804 (response_code == 200 || url.SchemeIsFile())) { |
792 RETRY_HISTOGRAM("CrxFetchSuccess", | 805 RETRY_HISTOGRAM("CrxFetchSuccess", |
793 extensions_queue_.active_request_failure_count(), url); | 806 extensions_queue_.active_request_failure_count(), |
| 807 url); |
794 base::FilePath crx_path; | 808 base::FilePath crx_path; |
795 // Take ownership of the file at |crx_path|. | 809 // Take ownership of the file at |crx_path|. |
796 CHECK(source->GetResponseAsFilePath(true, &crx_path)); | 810 CHECK(source->GetResponseAsFilePath(true, &crx_path)); |
797 scoped_ptr<ExtensionFetch> fetch_data = | 811 scoped_ptr<ExtensionFetch> fetch_data = |
798 extensions_queue_.reset_active_request(); | 812 extensions_queue_.reset_active_request(); |
799 if (extension_cache_) { | 813 if (extension_cache_) { |
800 const std::string& version = fetch_data->version; | 814 const std::string& version = fetch_data->version; |
801 extension_cache_->PutExtension(id, crx_path, version, | 815 extension_cache_->PutExtension( |
| 816 id, |
| 817 crx_path, |
| 818 version, |
802 base::Bind(&ExtensionDownloader::NotifyDelegateDownloadFinished, | 819 base::Bind(&ExtensionDownloader::NotifyDelegateDownloadFinished, |
803 weak_ptr_factory_.GetWeakPtr(), | 820 weak_ptr_factory_.GetWeakPtr(), |
804 base::Passed(&fetch_data))); | 821 base::Passed(&fetch_data))); |
805 } else { | 822 } else { |
806 NotifyDelegateDownloadFinished(fetch_data.Pass(), crx_path, true); | 823 NotifyDelegateDownloadFinished(fetch_data.Pass(), crx_path, true); |
807 } | 824 } |
808 } else if (IterateFetchCredentialsAfterFailure( | 825 } else if (IterateFetchCredentialsAfterFailure( |
809 &active_request, | 826 &active_request, status, response_code)) { |
810 status, | |
811 response_code)) { | |
812 extensions_queue_.RetryRequest(backoff_delay); | 827 extensions_queue_.RetryRequest(backoff_delay); |
813 } else { | 828 } else { |
814 const std::set<int>& request_ids = active_request.request_ids; | 829 const std::set<int>& request_ids = active_request.request_ids; |
815 const ExtensionDownloaderDelegate::PingResult& ping = ping_results_[id]; | 830 const ExtensionDownloaderDelegate::PingResult& ping = ping_results_[id]; |
816 VLOG(1) << "Failed to fetch extension '" << url.possibly_invalid_spec() | 831 VLOG(1) << "Failed to fetch extension '" << url.possibly_invalid_spec() |
817 << "' response code:" << response_code; | 832 << "' response code:" << response_code; |
818 if (ShouldRetryRequest(status, response_code) && | 833 if (ShouldRetryRequest(status, response_code) && |
819 extensions_queue_.active_request_failure_count() < kMaxRetries) { | 834 extensions_queue_.active_request_failure_count() < kMaxRetries) { |
820 extensions_queue_.RetryRequest(backoff_delay); | 835 extensions_queue_.RetryRequest(backoff_delay); |
821 } else { | 836 } else { |
822 RETRY_HISTOGRAM("CrxFetchFailure", | 837 RETRY_HISTOGRAM("CrxFetchFailure", |
823 extensions_queue_.active_request_failure_count(), url); | 838 extensions_queue_.active_request_failure_count(), |
| 839 url); |
824 // status.error() is 0 (net::OK) or negative. (See net/base/net_errors.h) | 840 // status.error() is 0 (net::OK) or negative. (See net/base/net_errors.h) |
825 UMA_HISTOGRAM_SPARSE_SLOWLY("Extensions.CrxFetchError", -status.error()); | 841 UMA_HISTOGRAM_SPARSE_SLOWLY("Extensions.CrxFetchError", -status.error()); |
826 delegate_->OnExtensionDownloadFailed( | 842 delegate_->OnExtensionDownloadFailed( |
827 id, ExtensionDownloaderDelegate::CRX_FETCH_FAILED, ping, request_ids); | 843 id, ExtensionDownloaderDelegate::CRX_FETCH_FAILED, ping, request_ids); |
828 } | 844 } |
829 ping_results_.erase(id); | 845 ping_results_.erase(id); |
830 extensions_queue_.reset_active_request(); | 846 extensions_queue_.reset_active_request(); |
831 } | 847 } |
832 | 848 |
833 extension_fetcher_.reset(); | 849 extension_fetcher_.reset(); |
834 | 850 |
835 // If there are any pending downloads left, start the next one. | 851 // If there are any pending downloads left, start the next one. |
836 extensions_queue_.StartNextRequest(); | 852 extensions_queue_.StartNextRequest(); |
837 } | 853 } |
838 | 854 |
839 void ExtensionDownloader::NotifyExtensionsDownloadFailed( | 855 void ExtensionDownloader::NotifyExtensionsDownloadFailed( |
840 const std::set<std::string>& extension_ids, | 856 const std::set<std::string>& extension_ids, |
841 const std::set<int>& request_ids, | 857 const std::set<int>& request_ids, |
842 ExtensionDownloaderDelegate::Error error) { | 858 ExtensionDownloaderDelegate::Error error) { |
843 for (std::set<std::string>::const_iterator it = extension_ids.begin(); | 859 for (std::set<std::string>::const_iterator it = extension_ids.begin(); |
844 it != extension_ids.end(); ++it) { | 860 it != extension_ids.end(); |
| 861 ++it) { |
845 const ExtensionDownloaderDelegate::PingResult& ping = ping_results_[*it]; | 862 const ExtensionDownloaderDelegate::PingResult& ping = ping_results_[*it]; |
846 delegate_->OnExtensionDownloadFailed(*it, error, ping, request_ids); | 863 delegate_->OnExtensionDownloadFailed(*it, error, ping, request_ids); |
847 ping_results_.erase(*it); | 864 ping_results_.erase(*it); |
848 } | 865 } |
849 } | 866 } |
850 | 867 |
851 void ExtensionDownloader::NotifyUpdateFound(const std::string& id, | 868 void ExtensionDownloader::NotifyUpdateFound(const std::string& id, |
852 const std::string& version) { | 869 const std::string& version) { |
853 UpdateDetails updateInfo(id, Version(version)); | 870 UpdateDetails updateInfo(id, Version(version)); |
854 content::NotificationService::current()->Notify( | 871 content::NotificationService::current()->Notify( |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
890 identity_provider_->GetTokenService()->InvalidateToken( | 907 identity_provider_->GetTokenService()->InvalidateToken( |
891 identity_provider_->GetActiveAccountId(), | 908 identity_provider_->GetActiveAccountId(), |
892 webstore_scopes, | 909 webstore_scopes, |
893 access_token_); | 910 access_token_); |
894 access_token_.clear(); | 911 access_token_.clear(); |
895 return true; | 912 return true; |
896 } | 913 } |
897 // Either there is no Gaia identity available, the active identity | 914 // Either there is no Gaia identity available, the active identity |
898 // doesn't have access to this resource, or the server keeps returning | 915 // doesn't have access to this resource, or the server keeps returning |
899 // 401s and we've retried too many times. Fall back on cookies. | 916 // 401s and we've retried too many times. Fall back on cookies. |
900 if (access_token_.empty() || | 917 if (access_token_.empty() || response_code == net::HTTP_FORBIDDEN || |
901 response_code == net::HTTP_FORBIDDEN || | |
902 fetch->oauth2_attempt_count > kMaxOAuth2Attempts) { | 918 fetch->oauth2_attempt_count > kMaxOAuth2Attempts) { |
903 fetch->credentials = ExtensionFetch::CREDENTIALS_COOKIES; | 919 fetch->credentials = ExtensionFetch::CREDENTIALS_COOKIES; |
904 return true; | 920 return true; |
905 } | 921 } |
906 // Something else is wrong. Time to give up. | 922 // Something else is wrong. Time to give up. |
907 return false; | 923 return false; |
908 case ExtensionFetch::CREDENTIALS_COOKIES: | 924 case ExtensionFetch::CREDENTIALS_COOKIES: |
909 if (response_code == net::HTTP_FORBIDDEN) { | 925 if (response_code == net::HTTP_FORBIDDEN) { |
910 // Try the next session identity, up to some maximum. | 926 // Try the next session identity, up to some maximum. |
911 return IncrementAuthUserIndex(&fetch->url); | 927 return IncrementAuthUserIndex(&fetch->url); |
912 } | 928 } |
913 return false; | 929 return false; |
914 default: | 930 default: |
915 NOTREACHED(); | 931 NOTREACHED(); |
916 } | 932 } |
917 NOTREACHED(); | 933 NOTREACHED(); |
918 return false; | 934 return false; |
919 } | 935 } |
920 | 936 |
921 void ExtensionDownloader::OnGetTokenSuccess( | 937 void ExtensionDownloader::OnGetTokenSuccess( |
922 const OAuth2TokenService::Request* request, | 938 const OAuth2TokenService::Request* request, |
923 const std::string& access_token, | 939 const std::string& access_token, |
924 const base::Time& expiration_time) { | 940 const base::Time& expiration_time) { |
925 access_token_ = access_token; | 941 access_token_ = access_token; |
926 extension_fetcher_->AddExtraRequestHeader( | 942 extension_fetcher_->AddExtraRequestHeader( |
927 base::StringPrintf("%s: Bearer %s", | 943 base::StringPrintf("%s: Bearer %s", |
928 net::HttpRequestHeaders::kAuthorization, | 944 net::HttpRequestHeaders::kAuthorization, |
929 access_token_.c_str())); | 945 access_token_.c_str())); |
930 extension_fetcher_->Start(); | 946 extension_fetcher_->Start(); |
931 } | 947 } |
932 | 948 |
933 void ExtensionDownloader::OnGetTokenFailure( | 949 void ExtensionDownloader::OnGetTokenFailure( |
934 const OAuth2TokenService::Request* request, | 950 const OAuth2TokenService::Request* request, |
935 const GoogleServiceAuthError& error) { | 951 const GoogleServiceAuthError& error) { |
936 // If we fail to get an access token, kick the pending fetch and let it fall | 952 // If we fail to get an access token, kick the pending fetch and let it fall |
937 // back on cookies. | 953 // back on cookies. |
938 extension_fetcher_->Start(); | 954 extension_fetcher_->Start(); |
939 } | 955 } |
940 | 956 |
941 ManifestFetchData* ExtensionDownloader::CreateManifestFetchData( | 957 ManifestFetchData* ExtensionDownloader::CreateManifestFetchData( |
942 const GURL& update_url, | 958 const GURL& update_url, |
943 int request_id) { | 959 int request_id) { |
944 ManifestFetchData::PingMode ping_mode = ManifestFetchData::NO_PING; | 960 ManifestFetchData::PingMode ping_mode = ManifestFetchData::NO_PING; |
945 if (update_url.DomainIs(ping_enabled_domain_.c_str())) { | 961 if (update_url.DomainIs(ping_enabled_domain_.c_str())) { |
946 if (enable_extra_update_metrics_) { | 962 if (enable_extra_update_metrics_) { |
947 ping_mode = ManifestFetchData::PING_WITH_METRICS; | 963 ping_mode = ManifestFetchData::PING_WITH_METRICS; |
948 } else { | 964 } else { |
949 ping_mode = ManifestFetchData::PING; | 965 ping_mode = ManifestFetchData::PING; |
950 } | 966 } |
951 } | 967 } |
952 return new ManifestFetchData( | 968 return new ManifestFetchData( |
953 update_url, request_id, brand_code_, manifest_query_params_, ping_mode); | 969 update_url, request_id, brand_code_, manifest_query_params_, ping_mode); |
954 } | 970 } |
955 | 971 |
956 } // namespace extensions | 972 } // namespace extensions |
OLD | NEW |