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

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

Issue 434493002: OAuth2 support for Webstore downloads. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 4 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 13 matching lines...) Expand all
24 #include "chrome/browser/extensions/updater/request_queue_impl.h" 24 #include "chrome/browser/extensions/updater/request_queue_impl.h"
25 #include "chrome/browser/extensions/updater/safe_manifest_parser.h" 25 #include "chrome/browser/extensions/updater/safe_manifest_parser.h"
26 #include "chrome/browser/metrics/chrome_metrics_service_accessor.h" 26 #include "chrome/browser/metrics/chrome_metrics_service_accessor.h"
27 #include "chrome/common/chrome_switches.h" 27 #include "chrome/common/chrome_switches.h"
28 #include "chrome/common/chrome_version_info.h" 28 #include "chrome/common/chrome_version_info.h"
29 #include "chrome/common/extensions/extension_constants.h" 29 #include "chrome/common/extensions/extension_constants.h"
30 #include "chrome/common/extensions/manifest_url_handler.h" 30 #include "chrome/common/extensions/manifest_url_handler.h"
31 #include "content/public/browser/browser_thread.h" 31 #include "content/public/browser/browser_thread.h"
32 #include "content/public/browser/notification_details.h" 32 #include "content/public/browser/notification_details.h"
33 #include "content/public/browser/notification_service.h" 33 #include "content/public/browser/notification_service.h"
34 #include "extensions/browser/webstore_oauth2_token_provider.h"
34 #include "net/base/backoff_entry.h" 35 #include "net/base/backoff_entry.h"
35 #include "net/base/load_flags.h" 36 #include "net/base/load_flags.h"
36 #include "net/base/net_errors.h" 37 #include "net/base/net_errors.h"
38 #include "net/http/http_request_headers.h"
37 #include "net/url_request/url_fetcher.h" 39 #include "net/url_request/url_fetcher.h"
38 #include "net/url_request/url_request_context_getter.h" 40 #include "net/url_request/url_request_context_getter.h"
39 #include "net/url_request/url_request_status.h" 41 #include "net/url_request/url_request_status.h"
40 42
41 using base::Time; 43 using base::Time;
42 using base::TimeDelta; 44 using base::TimeDelta;
43 using content::BrowserThread; 45 using content::BrowserThread;
44 46
45 namespace extensions { 47 namespace extensions {
46 48
(...skipping 27 matching lines...) Expand all
74 false, 76 false,
75 }; 77 };
76 78
77 const char kAuthUserQueryKey[] = "authuser"; 79 const char kAuthUserQueryKey[] = "authuser";
78 80
79 const int kMaxAuthUserValue = 10; 81 const int kMaxAuthUserValue = 10;
80 82
81 const char kNotFromWebstoreInstallSource[] = "notfromwebstore"; 83 const char kNotFromWebstoreInstallSource[] = "notfromwebstore";
82 const char kDefaultInstallSource[] = ""; 84 const char kDefaultInstallSource[] = "";
83 85
84 #define RETRY_HISTOGRAM(name, retry_count, url) \ 86 const char kGoogleDotCom[] = "google.com";
85 if ((url).DomainIs("google.com")) { \ 87
86 UMA_HISTOGRAM_CUSTOM_COUNTS( \ 88 #define RETRY_HISTOGRAM(name, retry_count, url) \
87 "Extensions." name "RetryCountGoogleUrl", retry_count, 1, \ 89 if ((url).DomainIs(kGoogleDotCom)) { \
88 kMaxRetries, kMaxRetries+1); \ 90 UMA_HISTOGRAM_CUSTOM_COUNTS("Extensions." name "RetryCountGoogleUrl", \
89 } else { \ 91 retry_count, \
90 UMA_HISTOGRAM_CUSTOM_COUNTS( \ 92 1, \
91 "Extensions." name "RetryCountOtherUrl", retry_count, 1, \ 93 kMaxRetries, \
92 kMaxRetries, kMaxRetries+1); \ 94 kMaxRetries + 1); \
93 } 95 } else { \
96 UMA_HISTOGRAM_CUSTOM_COUNTS("Extensions." name "RetryCountOtherUrl", \
97 retry_count, \
98 1, \
99 kMaxRetries, \
100 kMaxRetries + 1); \
101 }
94 102
95 bool ShouldRetryRequest(const net::URLRequestStatus& status, 103 bool ShouldRetryRequest(const net::URLRequestStatus& status,
96 int response_code) { 104 int response_code) {
97 // Retry if the response code is a server error, or the request failed because 105 // Retry if the response code is a server error, or the request failed because
98 // of network errors as opposed to file errors. 106 // of network errors as opposed to file errors.
99 return ((response_code >= 500 && status.is_success()) || 107 return ((response_code >= 500 && status.is_success()) ||
100 status.status() == net::URLRequestStatus::FAILED); 108 status.status() == net::URLRequestStatus::FAILED);
101 } 109 }
102 110
103 bool ShouldRetryRequestWithCookies(const net::URLRequestStatus& status,
104 int response_code,
105 bool included_cookies) {
106 if (included_cookies)
107 return false;
108
109 if (status.status() == net::URLRequestStatus::CANCELED)
110 return true;
111
112 // Retry if a 401 or 403 is received.
113 return (status.status() == net::URLRequestStatus::SUCCESS &&
114 (response_code == 401 || response_code == 403));
115 }
116
117 bool ShouldRetryRequestWithNextUser(const net::URLRequestStatus& status,
118 int response_code,
119 bool included_cookies) {
120 // Retry if a 403 is received in response to a request including cookies.
121 // Note that receiving a 401 in response to a request which included cookies
122 // should indicate that the |authuser| index was out of bounds for the profile
123 // and therefore Chrome should NOT retry with another index.
124 return (status.status() == net::URLRequestStatus::SUCCESS &&
125 response_code == 403 && included_cookies);
126 }
127
128 // This parses and updates a URL query such that the value of the |authuser| 111 // This parses and updates a URL query such that the value of the |authuser|
129 // query parameter is incremented by 1. If parameter was not present in the URL, 112 // query parameter is incremented by 1. If parameter was not present in the URL,
130 // it will be added with a value of 1. All other query keys and values are 113 // it will be added with a value of 1. All other query keys and values are
131 // preserved as-is. Returns |false| if the user index exceeds a hard-coded 114 // preserved as-is. Returns |false| if the user index exceeds a hard-coded
132 // maximum. 115 // maximum.
133 bool IncrementAuthUserIndex(GURL* url) { 116 bool IncrementAuthUserIndex(GURL* url) {
134 int user_index = 0; 117 int user_index = 0;
135 std::string old_query = url->query(); 118 std::string old_query = url->query();
136 std::vector<std::string> new_query_parts; 119 std::vector<std::string> new_query_parts;
137 url::Component query(0, old_query.length()); 120 url::Component query(0, old_query.length());
(...skipping 21 matching lines...) Expand all
159 } 142 }
160 143
161 } // namespace 144 } // namespace
162 145
163 UpdateDetails::UpdateDetails(const std::string& id, const Version& version) 146 UpdateDetails::UpdateDetails(const std::string& id, const Version& version)
164 : id(id), version(version) {} 147 : id(id), version(version) {}
165 148
166 UpdateDetails::~UpdateDetails() {} 149 UpdateDetails::~UpdateDetails() {}
167 150
168 ExtensionDownloader::ExtensionFetch::ExtensionFetch() 151 ExtensionDownloader::ExtensionFetch::ExtensionFetch()
169 : url(), is_protected(false) {} 152 : url(), credentials(CREDENTIALS_NONE) {
153 }
170 154
171 ExtensionDownloader::ExtensionFetch::ExtensionFetch( 155 ExtensionDownloader::ExtensionFetch::ExtensionFetch(
172 const std::string& id, 156 const std::string& id,
173 const GURL& url, 157 const GURL& url,
174 const std::string& package_hash, 158 const std::string& package_hash,
175 const std::string& version, 159 const std::string& version,
176 const std::set<int>& request_ids) 160 const std::set<int>& request_ids)
177 : id(id), url(url), package_hash(package_hash), version(version), 161 : id(id),
178 request_ids(request_ids), is_protected(false) {} 162 url(url),
163 package_hash(package_hash),
164 version(version),
165 request_ids(request_ids),
166 credentials(CREDENTIALS_NONE) {
167 }
179 168
180 ExtensionDownloader::ExtensionFetch::~ExtensionFetch() {} 169 ExtensionDownloader::ExtensionFetch::~ExtensionFetch() {}
181 170
171 bool ExtensionDownloader::ExtensionFetch::IterateCredentialsAfterFailure(
172 const net::URLRequestStatus& status,
173 int response_code,
174 bool support_oauth2) {
175 bool auth_failure = status.status() == net::URLRequestStatus::CANCELED ||
176 (status.status() == net::URLRequestStatus::SUCCESS &&
177 (response_code == 401 || response_code == 403));
178 if (!auth_failure) {
179 return false;
180 }
181 switch (credentials) {
182 case CREDENTIALS_NONE:
183 if (url.DomainIs(kGoogleDotCom) && support_oauth2) {
184 credentials = CREDENTIALS_OAUTH2_TOKEN;
185 } else {
186 credentials = CREDENTIALS_COOKIES;
187 }
188 break;
189 case CREDENTIALS_OAUTH2_TOKEN:
190 credentials = CREDENTIALS_COOKIES;
191 break;
192 case CREDENTIALS_COOKIES:
193 if (response_code == 403) {
194 return IncrementAuthUserIndex(&url);
195 }
196 return false;
197 default:
198 NOTREACHED();
199 }
200 return true;
201 }
asargent_no_longer_on_chrome 2014/08/06 00:26:29 I think this function pushes ExtensionFetch over t
Ken Rockot(use gerrit already) 2014/08/06 16:49:55 Actually, I feel like the requirement for this spe
202
182 ExtensionDownloader::ExtensionDownloader( 203 ExtensionDownloader::ExtensionDownloader(
183 ExtensionDownloaderDelegate* delegate, 204 ExtensionDownloaderDelegate* delegate,
184 net::URLRequestContextGetter* request_context) 205 net::URLRequestContextGetter* request_context,
206 IdentityProvider* webstore_identity_provider)
185 : delegate_(delegate), 207 : delegate_(delegate),
186 request_context_(request_context), 208 request_context_(request_context),
187 weak_ptr_factory_(this), 209 weak_ptr_factory_(this),
188 manifests_queue_(&kDefaultBackoffPolicy, 210 manifests_queue_(&kDefaultBackoffPolicy,
189 base::Bind(&ExtensionDownloader::CreateManifestFetcher, 211 base::Bind(&ExtensionDownloader::CreateManifestFetcher,
190 base::Unretained(this))), 212 base::Unretained(this))),
191 extensions_queue_(&kDefaultBackoffPolicy, 213 extensions_queue_(&kDefaultBackoffPolicy,
192 base::Bind(&ExtensionDownloader::CreateExtensionFetcher, 214 base::Bind(&ExtensionDownloader::CreateExtensionFetcher,
193 base::Unretained(this))), 215 base::Unretained(this))),
194 extension_cache_(NULL) { 216 extension_cache_(NULL) {
217 if (webstore_identity_provider) {
218 webstore_token_provider_.reset(
219 new WebstoreOAuth2TokenProvider(webstore_identity_provider));
220 }
195 DCHECK(delegate_); 221 DCHECK(delegate_);
196 DCHECK(request_context_); 222 DCHECK(request_context_);
197 } 223 }
198 224
199 ExtensionDownloader::~ExtensionDownloader() {} 225 ExtensionDownloader::~ExtensionDownloader() {}
200 226
201 bool ExtensionDownloader::AddExtension(const Extension& extension, 227 bool ExtensionDownloader::AddExtension(const Extension& extension,
202 int request_id) { 228 int request_id) {
203 // Skip extensions with empty update URLs converted from user 229 // Skip extensions with empty update URLs converted from user
204 // scripts. 230 // scripts.
(...skipping 94 matching lines...) Expand 10 before | Expand all | Expand 10 after
299 if (extension_urls::IsWebstoreUpdateUrl(update_url) && 325 if (extension_urls::IsWebstoreUpdateUrl(update_url) &&
300 !update_url.SchemeIsSecure()) 326 !update_url.SchemeIsSecure())
301 update_url = extension_urls::GetWebstoreUpdateUrl(); 327 update_url = extension_urls::GetWebstoreUpdateUrl();
302 328
303 // Skip extensions with empty IDs. 329 // Skip extensions with empty IDs.
304 if (id.empty()) { 330 if (id.empty()) {
305 LOG(WARNING) << "Found extension with empty ID"; 331 LOG(WARNING) << "Found extension with empty ID";
306 return false; 332 return false;
307 } 333 }
308 334
309 if (update_url.DomainIs("google.com")) { 335 if (update_url.DomainIs(kGoogleDotCom)) {
310 url_stats_.google_url_count++; 336 url_stats_.google_url_count++;
311 } else if (update_url.is_empty()) { 337 } else if (update_url.is_empty()) {
312 url_stats_.no_url_count++; 338 url_stats_.no_url_count++;
313 // Fill in default update URL. 339 // Fill in default update URL.
314 update_url = extension_urls::GetWebstoreUpdateUrl(); 340 update_url = extension_urls::GetWebstoreUpdateUrl();
315 } else { 341 } else {
316 url_stats_.other_url_count++; 342 url_stats_.other_url_count++;
317 } 343 }
318 344
319 switch (extension_type) { 345 switch (extension_type) {
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after
573 } 599 }
574 } 600 }
575 scoped_ptr<ExtensionFetch> fetch(new ExtensionFetch( 601 scoped_ptr<ExtensionFetch> fetch(new ExtensionFetch(
576 update->extension_id, crx_url, update->package_hash, 602 update->extension_id, crx_url, update->package_hash,
577 update->version, fetch_data.request_ids())); 603 update->version, fetch_data.request_ids()));
578 FetchUpdatedExtension(fetch.Pass()); 604 FetchUpdatedExtension(fetch.Pass());
579 } 605 }
580 606
581 // If the manifest response included a <daystart> element, we want to save 607 // If the manifest response included a <daystart> element, we want to save
582 // that value for any extensions which had sent a ping in the request. 608 // that value for any extensions which had sent a ping in the request.
583 if (fetch_data.base_url().DomainIs("google.com") && 609 if (fetch_data.base_url().DomainIs(kGoogleDotCom) &&
584 results->daystart_elapsed_seconds >= 0) { 610 results->daystart_elapsed_seconds >= 0) {
585 Time day_start = 611 Time day_start =
586 Time::Now() - TimeDelta::FromSeconds(results->daystart_elapsed_seconds); 612 Time::Now() - TimeDelta::FromSeconds(results->daystart_elapsed_seconds);
587 613
588 const std::set<std::string>& extension_ids = fetch_data.extension_ids(); 614 const std::set<std::string>& extension_ids = fetch_data.extension_ids();
589 std::set<std::string>::const_iterator i; 615 std::set<std::string>::const_iterator i;
590 for (i = extension_ids.begin(); i != extension_ids.end(); i++) { 616 for (i = extension_ids.begin(); i != extension_ids.end(); i++) {
591 const std::string& id = *i; 617 const std::string& id = *i;
592 ExtensionDownloaderDelegate::PingResult& result = ping_results_[id]; 618 ExtensionDownloaderDelegate::PingResult& result = ping_results_[id];
593 result.did_ping = fetch_data.DidPing(id, ManifestFetchData::ROLLCALL); 619 result.did_ping = fetch_data.DidPing(id, ManifestFetchData::ROLLCALL);
(...skipping 121 matching lines...) Expand 10 before | Expand all | Expand 10 after
715 const base::FilePath& crx_path, 741 const base::FilePath& crx_path,
716 bool file_ownership_passed) { 742 bool file_ownership_passed) {
717 delegate_->OnExtensionDownloadFinished(fetch_data->id, crx_path, 743 delegate_->OnExtensionDownloadFinished(fetch_data->id, crx_path,
718 file_ownership_passed, fetch_data->url, fetch_data->version, 744 file_ownership_passed, fetch_data->url, fetch_data->version,
719 ping_results_[fetch_data->id], fetch_data->request_ids); 745 ping_results_[fetch_data->id], fetch_data->request_ids);
720 ping_results_.erase(fetch_data->id); 746 ping_results_.erase(fetch_data->id);
721 } 747 }
722 748
723 void ExtensionDownloader::CreateExtensionFetcher() { 749 void ExtensionDownloader::CreateExtensionFetcher() {
724 const ExtensionFetch* fetch = extensions_queue_.active_request(); 750 const ExtensionFetch* fetch = extensions_queue_.active_request();
751 extension_fetcher_.reset(net::URLFetcher::Create(
752 kExtensionFetcherId, fetch->url, net::URLFetcher::GET, this));
753 extension_fetcher_->SetRequestContext(request_context_);
754 extension_fetcher_->SetAutomaticallyRetryOnNetworkChanges(3);
755
725 int load_flags = net::LOAD_DISABLE_CACHE; 756 int load_flags = net::LOAD_DISABLE_CACHE;
726 if (!fetch->is_protected || !fetch->url.SchemeIs("https")) { 757 bool is_https = fetch->url.SchemeIs("https");
asargent_no_longer_on_chrome 2014/08/06 00:26:29 can you switch this to url::kHttpsScheme while you
Ken Rockot(use gerrit already) 2014/08/06 16:49:55 Done.
758 if (fetch->credentials != ExtensionFetch::CREDENTIALS_COOKIES || !is_https) {
727 load_flags |= net::LOAD_DO_NOT_SEND_COOKIES | 759 load_flags |= net::LOAD_DO_NOT_SEND_COOKIES |
728 net::LOAD_DO_NOT_SAVE_COOKIES; 760 net::LOAD_DO_NOT_SAVE_COOKIES;
729 } 761 }
730 extension_fetcher_.reset(net::URLFetcher::Create(
731 kExtensionFetcherId, fetch->url, net::URLFetcher::GET, this));
732 extension_fetcher_->SetRequestContext(request_context_);
733 extension_fetcher_->SetLoadFlags(load_flags); 762 extension_fetcher_->SetLoadFlags(load_flags);
734 extension_fetcher_->SetAutomaticallyRetryOnNetworkChanges(3); 763
735 // 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
736 // processed in memory, so it is fetched into a string. 765 // processed in memory, so it is fetched into a string.
737 if (fetch->id != kBlacklistAppID) { 766 if (fetch->id != kBlacklistAppID) {
738 extension_fetcher_->SaveResponseToTemporaryFile( 767 extension_fetcher_->SaveResponseToTemporaryFile(
739 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE)); 768 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE));
740 } 769 }
741 770
742 VLOG(2) << "Starting fetch of " << fetch->url << " for " << fetch->id; 771 // If we should use OAuth2, fetch a token first.
743 772 if (fetch->credentials == ExtensionFetch::CREDENTIALS_OAUTH2_TOKEN &&
744 extension_fetcher_->Start(); 773 is_https && webstore_token_provider_) {
774 webstore_token_provider_->FetchToken(
775 base::Bind(&ExtensionDownloader::OnWebstoreOAuth2TokenReceived,
776 weak_ptr_factory_.GetWeakPtr()));
777 } else {
778 VLOG(2) << "Starting fetch of " << fetch->url << " for " << fetch->id;
779 extension_fetcher_->Start();
780 }
745 } 781 }
746 782
747 void ExtensionDownloader::OnCRXFetchComplete( 783 void ExtensionDownloader::OnCRXFetchComplete(
748 const net::URLFetcher* source, 784 const net::URLFetcher* source,
749 const GURL& url, 785 const GURL& url,
750 const net::URLRequestStatus& status, 786 const net::URLRequestStatus& status,
751 int response_code, 787 int response_code,
752 const base::TimeDelta& backoff_delay) { 788 const base::TimeDelta& backoff_delay) {
753 const std::string& id = extensions_queue_.active_request()->id; 789 ExtensionFetch& active_request = *extensions_queue_.active_request();
790 const std::string& id = active_request.id;
754 if (status.status() == net::URLRequestStatus::SUCCESS && 791 if (status.status() == net::URLRequestStatus::SUCCESS &&
755 (response_code == 200 || url.SchemeIsFile())) { 792 (response_code == 200 || url.SchemeIsFile())) {
756 RETRY_HISTOGRAM("CrxFetchSuccess", 793 RETRY_HISTOGRAM("CrxFetchSuccess",
757 extensions_queue_.active_request_failure_count(), url); 794 extensions_queue_.active_request_failure_count(), url);
758 base::FilePath crx_path; 795 base::FilePath crx_path;
759 // Take ownership of the file at |crx_path|. 796 // Take ownership of the file at |crx_path|.
760 CHECK(source->GetResponseAsFilePath(true, &crx_path)); 797 CHECK(source->GetResponseAsFilePath(true, &crx_path));
761 scoped_ptr<ExtensionFetch> fetch_data = 798 scoped_ptr<ExtensionFetch> fetch_data =
762 extensions_queue_.reset_active_request(); 799 extensions_queue_.reset_active_request();
763 if (extension_cache_) { 800 if (extension_cache_) {
764 const std::string& version = fetch_data->version; 801 const std::string& version = fetch_data->version;
765 extension_cache_->PutExtension(id, crx_path, version, 802 extension_cache_->PutExtension(id, crx_path, version,
766 base::Bind(&ExtensionDownloader::NotifyDelegateDownloadFinished, 803 base::Bind(&ExtensionDownloader::NotifyDelegateDownloadFinished,
767 weak_ptr_factory_.GetWeakPtr(), 804 weak_ptr_factory_.GetWeakPtr(),
768 base::Passed(&fetch_data))); 805 base::Passed(&fetch_data)));
769 } else { 806 } else {
770 NotifyDelegateDownloadFinished(fetch_data.Pass(), crx_path, true); 807 NotifyDelegateDownloadFinished(fetch_data.Pass(), crx_path, true);
771 } 808 }
772 } else if (ShouldRetryRequestWithCookies( 809 } else if (active_request.IterateCredentialsAfterFailure(
773 status, 810 status,
774 response_code, 811 response_code,
775 extensions_queue_.active_request()->is_protected)) { 812 webstore_token_provider_ != NULL)) {
776 // Requeue the fetch with |is_protected| set, enabling cookies.
777 extensions_queue_.active_request()->is_protected = true;
778 extensions_queue_.RetryRequest(backoff_delay);
779 } else if (ShouldRetryRequestWithNextUser(
780 status,
781 response_code,
782 extensions_queue_.active_request()->is_protected) &&
783 IncrementAuthUserIndex(&extensions_queue_.active_request()->url)) {
784 extensions_queue_.RetryRequest(backoff_delay); 813 extensions_queue_.RetryRequest(backoff_delay);
785 } else { 814 } else {
786 const std::set<int>& request_ids = 815 const std::set<int>& request_ids = active_request.request_ids;
787 extensions_queue_.active_request()->request_ids;
788 const ExtensionDownloaderDelegate::PingResult& ping = ping_results_[id]; 816 const ExtensionDownloaderDelegate::PingResult& ping = ping_results_[id];
789 VLOG(1) << "Failed to fetch extension '" << url.possibly_invalid_spec() 817 VLOG(1) << "Failed to fetch extension '" << url.possibly_invalid_spec()
790 << "' response code:" << response_code; 818 << "' response code:" << response_code;
791 if (ShouldRetryRequest(status, response_code) && 819 if (ShouldRetryRequest(status, response_code) &&
792 extensions_queue_.active_request_failure_count() < kMaxRetries) { 820 extensions_queue_.active_request_failure_count() < kMaxRetries) {
793 extensions_queue_.RetryRequest(backoff_delay); 821 extensions_queue_.RetryRequest(backoff_delay);
794 } else { 822 } else {
795 RETRY_HISTOGRAM("CrxFetchFailure", 823 RETRY_HISTOGRAM("CrxFetchFailure",
796 extensions_queue_.active_request_failure_count(), url); 824 extensions_queue_.active_request_failure_count(), url);
797 // status.error() is 0 (net::OK) or negative. (See net/base/net_errors.h) 825 // status.error() is 0 (net::OK) or negative. (See net/base/net_errors.h)
(...skipping 25 matching lines...) Expand all
823 851
824 void ExtensionDownloader::NotifyUpdateFound(const std::string& id, 852 void ExtensionDownloader::NotifyUpdateFound(const std::string& id,
825 const std::string& version) { 853 const std::string& version) {
826 UpdateDetails updateInfo(id, Version(version)); 854 UpdateDetails updateInfo(id, Version(version));
827 content::NotificationService::current()->Notify( 855 content::NotificationService::current()->Notify(
828 extensions::NOTIFICATION_EXTENSION_UPDATE_FOUND, 856 extensions::NOTIFICATION_EXTENSION_UPDATE_FOUND,
829 content::NotificationService::AllBrowserContextsAndSources(), 857 content::NotificationService::AllBrowserContextsAndSources(),
830 content::Details<UpdateDetails>(&updateInfo)); 858 content::Details<UpdateDetails>(&updateInfo));
831 } 859 }
832 860
861 void ExtensionDownloader::OnWebstoreOAuth2TokenReceived(
862 bool success,
863 const std::string& token) {
864 // If for whatever reason the token fetch fails, the fetch will still be
865 // retried with no Authorization header; in such cases the download is
866 // probably going to fail again, but the fetcher will then fall back onto
867 // cookie-based authentication.
868 if (success) {
869 extension_fetcher_->AddExtraRequestHeader(
870 base::StringPrintf("%s:Bearer %s",
871 net::HttpRequestHeaders::kAuthorization,
872 token.c_str()));
873 }
874 extension_fetcher_->Start();
875 }
876
833 } // namespace extensions 877 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698