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

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: Add unit test 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() : url() {}
asargent_no_longer_on_chrome 2014/01/31 18:22:26 nit: make sure to initialize is_protected in this
Ken Rockot(use gerrit already) 2014/01/31 22:12:58 Done.
106 107
107 ExtensionDownloader::ExtensionFetch::ExtensionFetch( 108 ExtensionDownloader::ExtensionFetch::ExtensionFetch(
108 const std::string& id, 109 const std::string& id,
109 const GURL& url, 110 const GURL& url,
110 const std::string& package_hash, 111 const std::string& package_hash,
111 const std::string& version, 112 const std::string& version,
112 const std::set<int>& request_ids) 113 const std::set<int>& request_ids)
113 : id(id), url(url), package_hash(package_hash), version(version), 114 : id(id), url(url), package_hash(package_hash), version(version),
114 request_ids(request_ids) {} 115 request_ids(request_ids), is_protected(false) {}
115 116
116 ExtensionDownloader::ExtensionFetch::~ExtensionFetch() {} 117 ExtensionDownloader::ExtensionFetch::~ExtensionFetch() {}
117 118
118 ExtensionDownloader::ExtensionDownloader( 119 ExtensionDownloader::ExtensionDownloader(
119 ExtensionDownloaderDelegate* delegate, 120 ExtensionDownloaderDelegate* delegate,
120 net::URLRequestContextGetter* request_context) 121 net::URLRequestContextGetter* request_context)
121 : delegate_(delegate), 122 : delegate_(delegate),
122 request_context_(request_context), 123 request_context_(request_context),
123 weak_ptr_factory_(this), 124 weak_ptr_factory_(this),
124 manifests_queue_(&kDefaultBackoffPolicy, 125 manifests_queue_(&kDefaultBackoffPolicy,
(...skipping 525 matching lines...) Expand 10 before | Expand all | Expand 10 after
650 scoped_ptr<ExtensionFetch> fetch_data, 651 scoped_ptr<ExtensionFetch> fetch_data,
651 const base::FilePath& crx_path, 652 const base::FilePath& crx_path,
652 bool file_ownership_passed) { 653 bool file_ownership_passed) {
653 delegate_->OnExtensionDownloadFinished(fetch_data->id, crx_path, 654 delegate_->OnExtensionDownloadFinished(fetch_data->id, crx_path,
654 file_ownership_passed, fetch_data->url, fetch_data->version, 655 file_ownership_passed, fetch_data->url, fetch_data->version,
655 ping_results_[fetch_data->id], fetch_data->request_ids); 656 ping_results_[fetch_data->id], fetch_data->request_ids);
656 ping_results_.erase(fetch_data->id); 657 ping_results_.erase(fetch_data->id);
657 } 658 }
658 659
659 void ExtensionDownloader::CreateExtensionFetcher() { 660 void ExtensionDownloader::CreateExtensionFetcher() {
661 const ExtensionFetch* fetch = extensions_queue_.active_request();
662 int load_flags = net::LOAD_DISABLE_CACHE;
663 if (!fetch->is_protected) {
664 load_flags |= net::LOAD_DO_NOT_SEND_COOKIES |
665 net::LOAD_DO_NOT_SAVE_COOKIES;
666 }
asargent_no_longer_on_chrome 2014/01/31 18:22:26 Perhaps we should also only send cookies on https
Ken Rockot(use gerrit already) 2014/01/31 22:12:58 Good catch. Done.
660 extension_fetcher_.reset(net::URLFetcher::Create( 667 extension_fetcher_.reset(net::URLFetcher::Create(
661 kExtensionFetcherId, extensions_queue_.active_request()->url, 668 kExtensionFetcherId, fetch->url, net::URLFetcher::GET, this));
662 net::URLFetcher::GET, this));
663 extension_fetcher_->SetRequestContext(request_context_); 669 extension_fetcher_->SetRequestContext(request_context_);
664 extension_fetcher_->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES | 670 extension_fetcher_->SetLoadFlags(load_flags);
665 net::LOAD_DO_NOT_SAVE_COOKIES |
666 net::LOAD_DISABLE_CACHE);
667 extension_fetcher_->SetAutomaticallyRetryOnNetworkChanges(3); 671 extension_fetcher_->SetAutomaticallyRetryOnNetworkChanges(3);
668 // Download CRX files to a temp file. The blacklist is small and will be 672 // 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. 673 // processed in memory, so it is fetched into a string.
670 if (extensions_queue_.active_request()->id != kBlacklistAppID) { 674 if (fetch->id != kBlacklistAppID) {
671 extension_fetcher_->SaveResponseToTemporaryFile( 675 extension_fetcher_->SaveResponseToTemporaryFile(
672 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE)); 676 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::FILE));
673 } 677 }
674 678
675 VLOG(2) << "Starting fetch of " << extensions_queue_.active_request()->url 679 VLOG(2) << "Starting fetch of " << fetch->url << " for " << fetch->id;
676 << " for " << extensions_queue_.active_request()->id;
677 680
678 extension_fetcher_->Start(); 681 extension_fetcher_->Start();
679 } 682 }
680 683
681 void ExtensionDownloader::OnCRXFetchComplete( 684 void ExtensionDownloader::OnCRXFetchComplete(
682 const net::URLFetcher* source, 685 const net::URLFetcher* source,
683 const GURL& url, 686 const GURL& url,
684 const net::URLRequestStatus& status, 687 const net::URLRequestStatus& status,
685 int response_code, 688 int response_code,
686 const base::TimeDelta& backoff_delay) { 689 const base::TimeDelta& backoff_delay) {
687 const std::string& id = extensions_queue_.active_request()->id; 690 const std::string& id = extensions_queue_.active_request()->id;
688 if (status.status() == net::URLRequestStatus::SUCCESS && 691 if (status.status() == net::URLRequestStatus::SUCCESS &&
689 (response_code == 200 || url.SchemeIsFile())) { 692 (response_code == 200 || url.SchemeIsFile())) {
690 RETRY_HISTOGRAM("CrxFetchSuccess", 693 RETRY_HISTOGRAM("CrxFetchSuccess",
691 extensions_queue_.active_request_failure_count(), url); 694 extensions_queue_.active_request_failure_count(), url);
692 base::FilePath crx_path; 695 base::FilePath crx_path;
693 // Take ownership of the file at |crx_path|. 696 // Take ownership of the file at |crx_path|.
694 CHECK(source->GetResponseAsFilePath(true, &crx_path)); 697 CHECK(source->GetResponseAsFilePath(true, &crx_path));
695 scoped_ptr<ExtensionFetch> fetch_data = 698 scoped_ptr<ExtensionFetch> fetch_data =
696 extensions_queue_.reset_active_request(); 699 extensions_queue_.reset_active_request();
697 if (extension_cache_) { 700 if (extension_cache_) {
698 const std::string& version = fetch_data->version; 701 const std::string& version = fetch_data->version;
699 extension_cache_->PutExtension(id, crx_path, version, 702 extension_cache_->PutExtension(id, crx_path, version,
700 base::Bind(&ExtensionDownloader::NotifyDelegateDownloadFinished, 703 base::Bind(&ExtensionDownloader::NotifyDelegateDownloadFinished,
701 weak_ptr_factory_.GetWeakPtr(), 704 weak_ptr_factory_.GetWeakPtr(),
702 base::Passed(&fetch_data))); 705 base::Passed(&fetch_data)));
703 } else { 706 } else {
704 NotifyDelegateDownloadFinished(fetch_data.Pass(), crx_path, true); 707 NotifyDelegateDownloadFinished(fetch_data.Pass(), crx_path, true);
705 } 708 }
709 } else if (status.status() == net::URLRequestStatus::SUCCESS &&
710 (response_code == 401 || response_code == 403) &&
711 !extensions_queue_.active_request()->is_protected) {
712 // On 401 or 403, requeue this fetch with cookies enabled.
713 extensions_queue_.active_request()->is_protected = true;
714 extensions_queue_.RetryRequest(backoff_delay);
706 } else { 715 } else {
707 const std::set<int>& request_ids = 716 const std::set<int>& request_ids =
708 extensions_queue_.active_request()->request_ids; 717 extensions_queue_.active_request()->request_ids;
709 const ExtensionDownloaderDelegate::PingResult& ping = ping_results_[id]; 718 const ExtensionDownloaderDelegate::PingResult& ping = ping_results_[id];
710 719
711 VLOG(1) << "Failed to fetch extension '" << url.possibly_invalid_spec() 720 VLOG(1) << "Failed to fetch extension '" << url.possibly_invalid_spec()
712 << "' response code:" << response_code; 721 << "' response code:" << response_code;
713 if (ShouldRetryRequest(status, response_code) && 722 if (ShouldRetryRequest(status, response_code) &&
714 extensions_queue_.active_request_failure_count() < kMaxRetries) { 723 extensions_queue_.active_request_failure_count() < kMaxRetries) {
715 extensions_queue_.RetryRequest(backoff_delay); 724 extensions_queue_.RetryRequest(backoff_delay);
(...skipping 30 matching lines...) Expand all
746 void ExtensionDownloader::NotifyUpdateFound(const std::string& id, 755 void ExtensionDownloader::NotifyUpdateFound(const std::string& id,
747 const std::string& version) { 756 const std::string& version) {
748 UpdateDetails updateInfo(id, Version(version)); 757 UpdateDetails updateInfo(id, Version(version));
749 content::NotificationService::current()->Notify( 758 content::NotificationService::current()->Notify(
750 chrome::NOTIFICATION_EXTENSION_UPDATE_FOUND, 759 chrome::NOTIFICATION_EXTENSION_UPDATE_FOUND,
751 content::NotificationService::AllBrowserContextsAndSources(), 760 content::NotificationService::AllBrowserContextsAndSources(),
752 content::Details<UpdateDetails>(&updateInfo)); 761 content::Details<UpdateDetails>(&updateInfo));
753 } 762 }
754 763
755 } // namespace extensions 764 } // namespace extensions
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698