Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(814)

Side by Side Diff: chrome/browser/extensions/updater/extension_downloader.cc

Issue 129873019: Support extension update dwnloads which require auth (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: new tests, nits Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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 "chrome/browser/extensions/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 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
71 -1, 71 -1,
72 72
73 // Don't use initial delay unless the last request was an error. 73 // Don't use initial delay unless the last request was an error.
74 false, 74 false,
75 }; 75 };
76 76
77 const char kNotFromWebstoreInstallSource[] = "notfromwebstore"; 77 const char kNotFromWebstoreInstallSource[] = "notfromwebstore";
78 const char kDefaultInstallSource[] = ""; 78 const char kDefaultInstallSource[] = "";
79 79
80 #define RETRY_HISTOGRAM(name, retry_count, url) \ 80 #define RETRY_HISTOGRAM(name, retry_count, url) \
81 if ((url).DomainIs("google.com")) \ 81 if ((url).DomainIs("google.com")) { \
82 UMA_HISTOGRAM_CUSTOM_COUNTS( \ 82 UMA_HISTOGRAM_CUSTOM_COUNTS( \
83 "Extensions." name "RetryCountGoogleUrl", retry_count, 1, \ 83 "Extensions." name "RetryCountGoogleUrl", retry_count, 1, \
84 kMaxRetries, kMaxRetries+1); \ 84 kMaxRetries, kMaxRetries+1); \
85 else \ 85 } else { \
86 UMA_HISTOGRAM_CUSTOM_COUNTS( \ 86 UMA_HISTOGRAM_CUSTOM_COUNTS( \
87 "Extensions." name "RetryCountOtherUrl", retry_count, 1, \ 87 "Extensions." name "RetryCountOtherUrl", retry_count, 1, \
88 kMaxRetries, kMaxRetries+1) 88 kMaxRetries, kMaxRetries+1); \
89 }
89 90
90 bool ShouldRetryRequest(const net::URLRequestStatus& status, 91 bool ShouldRetryRequest(const net::URLRequestStatus& status,
91 int response_code) { 92 int response_code) {
92 // Retry if the response code is a server error, or the request failed because 93 // Retry if the response code is a server error, or the request failed because
93 // of network errors as opposed to file errors. 94 // of network errors as opposed to file errors.
94 return (response_code >= 500 && status.is_success()) || 95 return (response_code >= 500 && status.is_success()) ||
95 status.status() == net::URLRequestStatus::FAILED; 96 status.status() == net::URLRequestStatus::FAILED;
96 } 97 }
97 98
98 } // namespace 99 } // namespace
99 100
100 UpdateDetails::UpdateDetails(const std::string& id, const Version& version) 101 UpdateDetails::UpdateDetails(const std::string& id, const Version& version)
101 : id(id), version(version) {} 102 : id(id), version(version) {}
102 103
103 UpdateDetails::~UpdateDetails() {} 104 UpdateDetails::~UpdateDetails() {}
104 105
105 ExtensionDownloader::ExtensionFetch::ExtensionFetch() : url() {} 106 ExtensionDownloader::ExtensionFetch::ExtensionFetch()
107 : url(), is_protected(false) {}
106 108
107 ExtensionDownloader::ExtensionFetch::ExtensionFetch( 109 ExtensionDownloader::ExtensionFetch::ExtensionFetch(
108 const std::string& id, 110 const std::string& id,
109 const GURL& url, 111 const GURL& url,
110 const std::string& package_hash, 112 const std::string& package_hash,
111 const std::string& version, 113 const std::string& version,
112 const std::set<int>& request_ids) 114 const std::set<int>& request_ids)
113 : id(id), url(url), package_hash(package_hash), version(version), 115 : id(id), url(url), package_hash(package_hash), version(version),
114 request_ids(request_ids) {} 116 request_ids(request_ids), is_protected(false) {}
115 117
116 ExtensionDownloader::ExtensionFetch::~ExtensionFetch() {} 118 ExtensionDownloader::ExtensionFetch::~ExtensionFetch() {}
117 119
118 ExtensionDownloader::ExtensionDownloader( 120 ExtensionDownloader::ExtensionDownloader(
119 ExtensionDownloaderDelegate* delegate, 121 ExtensionDownloaderDelegate* delegate,
120 net::URLRequestContextGetter* request_context) 122 net::URLRequestContextGetter* request_context)
121 : delegate_(delegate), 123 : delegate_(delegate),
122 request_context_(request_context), 124 request_context_(request_context),
123 weak_ptr_factory_(this), 125 weak_ptr_factory_(this),
124 manifests_queue_(&kDefaultBackoffPolicy, 126 manifests_queue_(&kDefaultBackoffPolicy,
(...skipping 525 matching lines...) Expand 10 before | Expand all | Expand 10 after
650 scoped_ptr<ExtensionFetch> fetch_data, 652 scoped_ptr<ExtensionFetch> fetch_data,
651 const base::FilePath& crx_path, 653 const base::FilePath& crx_path,
652 bool file_ownership_passed) { 654 bool file_ownership_passed) {
653 delegate_->OnExtensionDownloadFinished(fetch_data->id, crx_path, 655 delegate_->OnExtensionDownloadFinished(fetch_data->id, crx_path,
654 file_ownership_passed, fetch_data->url, fetch_data->version, 656 file_ownership_passed, fetch_data->url, fetch_data->version,
655 ping_results_[fetch_data->id], fetch_data->request_ids); 657 ping_results_[fetch_data->id], fetch_data->request_ids);
656 ping_results_.erase(fetch_data->id); 658 ping_results_.erase(fetch_data->id);
657 } 659 }
658 660
659 void ExtensionDownloader::CreateExtensionFetcher() { 661 void ExtensionDownloader::CreateExtensionFetcher() {
662 const ExtensionFetch* fetch = extensions_queue_.active_request();
663 int load_flags = net::LOAD_DISABLE_CACHE;
664 if (!fetch->is_protected || !fetch->url.SchemeIs("https")) {
665 load_flags |= net::LOAD_DO_NOT_SEND_COOKIES |
666 net::LOAD_DO_NOT_SAVE_COOKIES;
667 }
660 extension_fetcher_.reset(net::URLFetcher::Create( 668 extension_fetcher_.reset(net::URLFetcher::Create(
661 kExtensionFetcherId, extensions_queue_.active_request()->url, 669 kExtensionFetcherId, fetch->url, net::URLFetcher::GET, this));
662 net::URLFetcher::GET, this));
663 extension_fetcher_->SetRequestContext(request_context_); 670 extension_fetcher_->SetRequestContext(request_context_);
664 extension_fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES | 671 extension_fetcher_->SetLoadFlags(load_flags);
665 net::LOAD_DO_NOT_SAVE_COOKIES |
666 net::LOAD_DISABLE_CACHE);
667 extension_fetcher_->SetAutomaticallyRetryOnNetworkChanges(3); 672 extension_fetcher_->SetAutomaticallyRetryOnNetworkChanges(3);
668 // Download CRX files to a temp file. The blacklist is small and will be 673 // Download CRX files to a temp file. The blacklist is small and will be
669 // processed in memory, so it is fetched into a string. 674 // processed in memory, so it is fetched into a string.
670 if (extensions_queue_.active_request()->id != kBlacklistAppID) { 675 if (fetch->id != kBlacklistAppID) {
671 extension_fetcher_->SaveResponseToTemporaryFile( 676 extension_fetcher_->SaveResponseToTemporaryFile(
672 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE)); 677 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE));
673 } 678 }
674 679
675 VLOG(2) << "Starting fetch of " << extensions_queue_.active_request()->url 680 VLOG(2) << "Starting fetch of " << fetch->url << " for " << fetch->id;
676 << " for " << extensions_queue_.active_request()->id;
677 681
678 extension_fetcher_->Start(); 682 extension_fetcher_->Start();
679 } 683 }
680 684
681 void ExtensionDownloader::OnCRXFetchComplete( 685 void ExtensionDownloader::OnCRXFetchComplete(
682 const net::URLFetcher* source, 686 const net::URLFetcher* source,
683 const GURL& url, 687 const GURL& url,
684 const net::URLRequestStatus& status, 688 const net::URLRequestStatus& status,
685 int response_code, 689 int response_code,
686 const base::TimeDelta& backoff_delay) { 690 const base::TimeDelta& backoff_delay) {
687 const std::string& id = extensions_queue_.active_request()->id; 691 const std::string& id = extensions_queue_.active_request()->id;
688 if (status.status() == net::URLRequestStatus::SUCCESS && 692 if (status.status() == net::URLRequestStatus::SUCCESS &&
689 (response_code == 200 || url.SchemeIsFile())) { 693 (response_code == 200 || url.SchemeIsFile())) {
690 RETRY_HISTOGRAM("CrxFetchSuccess", 694 RETRY_HISTOGRAM("CrxFetchSuccess",
691 extensions_queue_.active_request_failure_count(), url); 695 extensions_queue_.active_request_failure_count(), url);
692 base::FilePath crx_path; 696 base::FilePath crx_path;
693 // Take ownership of the file at |crx_path|. 697 // Take ownership of the file at |crx_path|.
694 CHECK(source->GetResponseAsFilePath(true, &crx_path)); 698 CHECK(source->GetResponseAsFilePath(true, &crx_path));
695 scoped_ptr<ExtensionFetch> fetch_data = 699 scoped_ptr<ExtensionFetch> fetch_data =
696 extensions_queue_.reset_active_request(); 700 extensions_queue_.reset_active_request();
697 if (extension_cache_) { 701 if (extension_cache_) {
698 const std::string& version = fetch_data->version; 702 const std::string& version = fetch_data->version;
699 extension_cache_->PutExtension(id, crx_path, version, 703 extension_cache_->PutExtension(id, crx_path, version,
700 base::Bind(&ExtensionDownloader::NotifyDelegateDownloadFinished, 704 base::Bind(&ExtensionDownloader::NotifyDelegateDownloadFinished,
701 weak_ptr_factory_.GetWeakPtr(), 705 weak_ptr_factory_.GetWeakPtr(),
702 base::Passed(&fetch_data))); 706 base::Passed(&fetch_data)));
703 } else { 707 } else {
704 NotifyDelegateDownloadFinished(fetch_data.Pass(), crx_path, true); 708 NotifyDelegateDownloadFinished(fetch_data.Pass(), crx_path, true);
705 } 709 }
710 } else if (status.status() == net::URLRequestStatus::SUCCESS &&
711 (response_code == 401 || response_code == 403) &&
712 !extensions_queue_.active_request()->is_protected) {
713 // On 401 or 403, requeue this fetch with cookies enabled.
714 extensions_queue_.active_request()->is_protected = true;
715 extensions_queue_.RetryRequest(backoff_delay);
706 } else { 716 } else {
707 const std::set<int>& request_ids = 717 const std::set<int>& request_ids =
708 extensions_queue_.active_request()->request_ids; 718 extensions_queue_.active_request()->request_ids;
709 const ExtensionDownloaderDelegate::PingResult& ping = ping_results_[id]; 719 const ExtensionDownloaderDelegate::PingResult& ping = ping_results_[id];
710 720
711 VLOG(1) << "Failed to fetch extension '" << url.possibly_invalid_spec() 721 VLOG(1) << "Failed to fetch extension '" << url.possibly_invalid_spec()
712 << "' response code:" << response_code; 722 << "' response code:" << response_code;
713 if (ShouldRetryRequest(status, response_code) && 723 if (ShouldRetryRequest(status, response_code) &&
714 extensions_queue_.active_request_failure_count() < kMaxRetries) { 724 extensions_queue_.active_request_failure_count() < kMaxRetries) {
715 extensions_queue_.RetryRequest(backoff_delay); 725 extensions_queue_.RetryRequest(backoff_delay);
(...skipping 30 matching lines...) Expand all
746 void ExtensionDownloader::NotifyUpdateFound(const std::string& id, 756 void ExtensionDownloader::NotifyUpdateFound(const std::string& id,
747 const std::string& version) { 757 const std::string& version) {
748 UpdateDetails updateInfo(id, Version(version)); 758 UpdateDetails updateInfo(id, Version(version));
749 content::NotificationService::current()->Notify( 759 content::NotificationService::current()->Notify(
750 chrome::NOTIFICATION_EXTENSION_UPDATE_FOUND, 760 chrome::NOTIFICATION_EXTENSION_UPDATE_FOUND,
751 content::NotificationService::AllBrowserContextsAndSources(), 761 content::NotificationService::AllBrowserContextsAndSources(),
752 content::Details<UpdateDetails>(&updateInfo)); 762 content::Details<UpdateDetails>(&updateInfo));
753 } 763 }
754 764
755 } // namespace extensions 765 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698