| 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 "extensions/browser/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" |
| (...skipping 510 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 521 // We want to try parsing the manifest, and if it indicates updates are | 521 // We want to try parsing the manifest, and if it indicates updates are |
| 522 // available, we want to fire off requests to fetch those updates. | 522 // available, we want to fire off requests to fetch those updates. |
| 523 if (status.status() == net::URLRequestStatus::SUCCESS && | 523 if (status.status() == net::URLRequestStatus::SUCCESS && |
| 524 (response_code == 200 || (url.SchemeIsFile() && data.length() > 0))) { | 524 (response_code == 200 || (url.SchemeIsFile() && data.length() > 0))) { |
| 525 RETRY_HISTOGRAM("ManifestFetchSuccess", | 525 RETRY_HISTOGRAM("ManifestFetchSuccess", |
| 526 manifests_queue_.active_request_failure_count(), | 526 manifests_queue_.active_request_failure_count(), |
| 527 url); | 527 url); |
| 528 VLOG(2) << "beginning manifest parse for " << url; | 528 VLOG(2) << "beginning manifest parse for " << url; |
| 529 scoped_refptr<SafeManifestParser> safe_parser(new SafeManifestParser( | 529 scoped_refptr<SafeManifestParser> safe_parser(new SafeManifestParser( |
| 530 data, | 530 data, |
| 531 manifests_queue_.reset_active_request().release(), | 531 base::Bind( |
| 532 base::Bind(&ExtensionDownloader::HandleManifestResults, | 532 &ExtensionDownloader::HandleManifestResults, |
| 533 weak_ptr_factory_.GetWeakPtr()))); | 533 weak_ptr_factory_.GetWeakPtr(), |
| 534 base::Owned(manifests_queue_.reset_active_request().release())))); |
| 534 safe_parser->Start(); | 535 safe_parser->Start(); |
| 535 } else { | 536 } else { |
| 536 VLOG(1) << "Failed to fetch manifest '" << url.possibly_invalid_spec() | 537 VLOG(1) << "Failed to fetch manifest '" << url.possibly_invalid_spec() |
| 537 << "' response code:" << response_code; | 538 << "' response code:" << response_code; |
| 538 if (ShouldRetryRequest(status, response_code) && | 539 if (ShouldRetryRequest(status, response_code) && |
| 539 manifests_queue_.active_request_failure_count() < kMaxRetries) { | 540 manifests_queue_.active_request_failure_count() < kMaxRetries) { |
| 540 manifests_queue_.RetryRequest(backoff_delay); | 541 manifests_queue_.RetryRequest(backoff_delay); |
| 541 } else { | 542 } else { |
| 542 RETRY_HISTOGRAM("ManifestFetchFailure", | 543 RETRY_HISTOGRAM("ManifestFetchFailure", |
| 543 manifests_queue_.active_request_failure_count(), | 544 manifests_queue_.active_request_failure_count(), |
| 544 url); | 545 url); |
| 545 NotifyExtensionsDownloadFailed( | 546 NotifyExtensionsDownloadFailed( |
| 546 manifests_queue_.active_request()->extension_ids(), | 547 manifests_queue_.active_request()->extension_ids(), |
| 547 manifests_queue_.active_request()->request_ids(), | 548 manifests_queue_.active_request()->request_ids(), |
| 548 ExtensionDownloaderDelegate::MANIFEST_FETCH_FAILED); | 549 ExtensionDownloaderDelegate::MANIFEST_FETCH_FAILED); |
| 549 } | 550 } |
| 550 } | 551 } |
| 551 manifest_fetcher_.reset(); | 552 manifest_fetcher_.reset(); |
| 552 manifests_queue_.reset_active_request(); | 553 manifests_queue_.reset_active_request(); |
| 553 | 554 |
| 554 // If we have any pending manifest requests, fire off the next one. | 555 // If we have any pending manifest requests, fire off the next one. |
| 555 manifests_queue_.StartNextRequest(); | 556 manifests_queue_.StartNextRequest(); |
| 556 } | 557 } |
| 557 | 558 |
| 558 void ExtensionDownloader::HandleManifestResults( | 559 void ExtensionDownloader::HandleManifestResults( |
| 559 const ManifestFetchData& fetch_data, | 560 const ManifestFetchData* fetch_data, |
| 560 const UpdateManifest::Results* results) { | 561 const UpdateManifest::Results* results) { |
| 561 // Keep a list of extensions that will not be updated, so that the |delegate_| | 562 // Keep a list of extensions that will not be updated, so that the |delegate_| |
| 562 // can be notified once we're done here. | 563 // can be notified once we're done here. |
| 563 std::set<std::string> not_updated(fetch_data.extension_ids()); | 564 std::set<std::string> not_updated(fetch_data->extension_ids()); |
| 564 | 565 |
| 565 if (!results) { | 566 if (!results) { |
| 567 VLOG(2) << "parsing manifest failed (" << fetch_data->full_url() << ")"; |
| 566 NotifyExtensionsDownloadFailed( | 568 NotifyExtensionsDownloadFailed( |
| 567 not_updated, | 569 not_updated, fetch_data->request_ids(), |
| 568 fetch_data.request_ids(), | |
| 569 ExtensionDownloaderDelegate::MANIFEST_INVALID); | 570 ExtensionDownloaderDelegate::MANIFEST_INVALID); |
| 570 return; | 571 return; |
| 572 } else { |
| 573 VLOG(2) << "parsing manifest succeeded (" << fetch_data->full_url() << ")"; |
| 571 } | 574 } |
| 572 | 575 |
| 573 // Examine the parsed manifest and kick off fetches of any new crx files. | 576 // Examine the parsed manifest and kick off fetches of any new crx files. |
| 574 std::vector<int> updates; | 577 std::vector<int> updates; |
| 575 DetermineUpdates(fetch_data, *results, &updates); | 578 DetermineUpdates(*fetch_data, *results, &updates); |
| 576 for (size_t i = 0; i < updates.size(); i++) { | 579 for (size_t i = 0; i < updates.size(); i++) { |
| 577 const UpdateManifest::Result* update = &(results->list.at(updates[i])); | 580 const UpdateManifest::Result* update = &(results->list.at(updates[i])); |
| 578 const std::string& id = update->extension_id; | 581 const std::string& id = update->extension_id; |
| 579 not_updated.erase(id); | 582 not_updated.erase(id); |
| 580 | 583 |
| 581 GURL crx_url = update->crx_url; | 584 GURL crx_url = update->crx_url; |
| 582 if (id != kBlacklistAppID) { | 585 if (id != kBlacklistAppID) { |
| 583 NotifyUpdateFound(update->extension_id, update->version); | 586 NotifyUpdateFound(update->extension_id, update->version); |
| 584 } else { | 587 } else { |
| 585 // The URL of the blacklist file is returned by the server and we need to | 588 // The URL of the blacklist file is returned by the server and we need to |
| 586 // be sure that we continue to be able to reliably detect whether a URL | 589 // be sure that we continue to be able to reliably detect whether a URL |
| 587 // references a blacklist file. | 590 // references a blacklist file. |
| 588 DCHECK(extension_urls::IsBlacklistUpdateUrl(crx_url)) << crx_url; | 591 DCHECK(extension_urls::IsBlacklistUpdateUrl(crx_url)) << crx_url; |
| 589 | 592 |
| 590 // Force https (crbug.com/129587). | 593 // Force https (crbug.com/129587). |
| 591 if (!crx_url.SchemeIsSecure()) { | 594 if (!crx_url.SchemeIsSecure()) { |
| 592 url::Replacements<char> replacements; | 595 url::Replacements<char> replacements; |
| 593 std::string scheme("https"); | 596 std::string scheme("https"); |
| 594 replacements.SetScheme(scheme.c_str(), | 597 replacements.SetScheme(scheme.c_str(), |
| 595 url::Component(0, scheme.size())); | 598 url::Component(0, scheme.size())); |
| 596 crx_url = crx_url.ReplaceComponents(replacements); | 599 crx_url = crx_url.ReplaceComponents(replacements); |
| 597 } | 600 } |
| 598 } | 601 } |
| 599 scoped_ptr<ExtensionFetch> fetch( | 602 scoped_ptr<ExtensionFetch> fetch( |
| 600 new ExtensionFetch(update->extension_id, | 603 new ExtensionFetch(update->extension_id, crx_url, update->package_hash, |
| 601 crx_url, | 604 update->version, fetch_data->request_ids())); |
| 602 update->package_hash, | |
| 603 update->version, | |
| 604 fetch_data.request_ids())); | |
| 605 FetchUpdatedExtension(fetch.Pass()); | 605 FetchUpdatedExtension(fetch.Pass()); |
| 606 } | 606 } |
| 607 | 607 |
| 608 // If the manifest response included a <daystart> element, we want to save | 608 // If the manifest response included a <daystart> element, we want to save |
| 609 // that value for any extensions which had sent a ping in the request. | 609 // that value for any extensions which had sent a ping in the request. |
| 610 if (fetch_data.base_url().DomainIs(kGoogleDotCom) && | 610 if (fetch_data->base_url().DomainIs(kGoogleDotCom) && |
| 611 results->daystart_elapsed_seconds >= 0) { | 611 results->daystart_elapsed_seconds >= 0) { |
| 612 Time day_start = | 612 Time day_start = |
| 613 Time::Now() - TimeDelta::FromSeconds(results->daystart_elapsed_seconds); | 613 Time::Now() - TimeDelta::FromSeconds(results->daystart_elapsed_seconds); |
| 614 | 614 |
| 615 const std::set<std::string>& extension_ids = fetch_data.extension_ids(); | 615 const std::set<std::string>& extension_ids = fetch_data->extension_ids(); |
| 616 std::set<std::string>::const_iterator i; | 616 std::set<std::string>::const_iterator i; |
| 617 for (i = extension_ids.begin(); i != extension_ids.end(); i++) { | 617 for (i = extension_ids.begin(); i != extension_ids.end(); i++) { |
| 618 const std::string& id = *i; | 618 const std::string& id = *i; |
| 619 ExtensionDownloaderDelegate::PingResult& result = ping_results_[id]; | 619 ExtensionDownloaderDelegate::PingResult& result = ping_results_[id]; |
| 620 result.did_ping = fetch_data.DidPing(id, ManifestFetchData::ROLLCALL); | 620 result.did_ping = fetch_data->DidPing(id, ManifestFetchData::ROLLCALL); |
| 621 result.day_start = day_start; | 621 result.day_start = day_start; |
| 622 } | 622 } |
| 623 } | 623 } |
| 624 | 624 |
| 625 NotifyExtensionsDownloadFailed( | 625 NotifyExtensionsDownloadFailed( |
| 626 not_updated, | 626 not_updated, fetch_data->request_ids(), |
| 627 fetch_data.request_ids(), | |
| 628 ExtensionDownloaderDelegate::NO_UPDATE_AVAILABLE); | 627 ExtensionDownloaderDelegate::NO_UPDATE_AVAILABLE); |
| 629 } | 628 } |
| 630 | 629 |
| 631 void ExtensionDownloader::DetermineUpdates( | 630 void ExtensionDownloader::DetermineUpdates( |
| 632 const ManifestFetchData& fetch_data, | 631 const ManifestFetchData& fetch_data, |
| 633 const UpdateManifest::Results& possible_updates, | 632 const UpdateManifest::Results& possible_updates, |
| 634 std::vector<int>* result) { | 633 std::vector<int>* result) { |
| 635 for (size_t i = 0; i < possible_updates.list.size(); i++) { | 634 for (size_t i = 0; i < possible_updates.list.size(); i++) { |
| 636 const UpdateManifest::Result* update = &possible_updates.list[i]; | 635 const UpdateManifest::Result* update = &possible_updates.list[i]; |
| 637 const std::string& id = update->extension_id; | 636 const std::string& id = update->extension_id; |
| (...skipping 311 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 949 const GURL& update_url, | 948 const GURL& update_url, |
| 950 int request_id) { | 949 int request_id) { |
| 951 ManifestFetchData::PingMode ping_mode = ManifestFetchData::NO_PING; | 950 ManifestFetchData::PingMode ping_mode = ManifestFetchData::NO_PING; |
| 952 if (update_url.DomainIs(ping_enabled_domain_.c_str())) | 951 if (update_url.DomainIs(ping_enabled_domain_.c_str())) |
| 953 ping_mode = ManifestFetchData::PING_WITH_ENABLED_STATE; | 952 ping_mode = ManifestFetchData::PING_WITH_ENABLED_STATE; |
| 954 return new ManifestFetchData( | 953 return new ManifestFetchData( |
| 955 update_url, request_id, brand_code_, manifest_query_params_, ping_mode); | 954 update_url, request_id, brand_code_, manifest_query_params_, ping_mode); |
| 956 } | 955 } |
| 957 | 956 |
| 958 } // namespace extensions | 957 } // namespace extensions |
| OLD | NEW |