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

Unified Diff: chrome/browser/extensions/updater/extension_downloader.cc

Issue 279453002: Support multiple sign-in for extension updates. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: nits, formatting, Resolve->ReplaceComponents Created 6 years, 7 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | chrome/browser/extensions/updater/extension_updater_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: chrome/browser/extensions/updater/extension_downloader.cc
diff --git a/chrome/browser/extensions/updater/extension_downloader.cc b/chrome/browser/extensions/updater/extension_downloader.cc
index 8a2177be92bdb7feed14220066931ad2879bddfa..7cad3ea278301d8fbf2d3c610eaeb3d153e18212 100644
--- a/chrome/browser/extensions/updater/extension_downloader.cc
+++ b/chrome/browser/extensions/updater/extension_downloader.cc
@@ -16,7 +16,9 @@
#include "base/metrics/sparse_histogram.h"
#include "base/platform_file.h"
#include "base/stl_util.h"
+#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
+#include "base/strings/stringprintf.h"
#include "base/time/time.h"
#include "base/version.h"
#include "chrome/browser/chrome_notification_types.h"
@@ -74,6 +76,10 @@ const net::BackoffEntry::Policy kDefaultBackoffPolicy = {
false,
};
+const char kAuthUserQueryKey[] = "authuser";
+
+const int kMaxAuthUserValue = 10;
+
const char kNotFromWebstoreInstallSource[] = "notfromwebstore";
const char kDefaultInstallSource[] = "";
@@ -92,8 +98,66 @@ bool ShouldRetryRequest(const net::URLRequestStatus& status,
int response_code) {
// Retry if the response code is a server error, or the request failed because
// of network errors as opposed to file errors.
- return (response_code >= 500 && status.is_success()) ||
- status.status() == net::URLRequestStatus::FAILED;
+ return ((response_code >= 500 && status.is_success()) ||
+ status.status() == net::URLRequestStatus::FAILED);
+}
+
+bool ShouldRetryRequestWithCookies(const net::URLRequestStatus& status,
+ int response_code,
+ bool included_cookies) {
+ if (included_cookies)
+ return false;
+
+ if (status.status() == net::URLRequestStatus::CANCELED)
+ return true;
+
+ // Retry if a 401 or 403 is received.
+ return (status.status() == net::URLRequestStatus::SUCCESS &&
+ (response_code == 401 || response_code == 403));
+}
+
+bool ShouldRetryRequestWithNextUser(const net::URLRequestStatus& status,
+ int response_code,
+ bool included_cookies) {
+ // Retry if a 403 is received in response to a request including cookies.
+ // Note that receiving a 401 in response to a request which included cookies
+ // should indicate that the |authuser| index was out of bounds for the profile
+ // and therefore Chrome should NOT retry with another index.
+ return (status.status() == net::URLRequestStatus::SUCCESS &&
+ response_code == 403 && included_cookies);
+}
+
+// This parses and updates a URL query such that the value of the |authuser|
+// query parameter is incremented by 1. If parameter was not present in the URL,
+// it will be added with a value of 1. All other query keys and values are
+// preserved as-is. Returns |false| if the user index exceeds a hard-coded
+// maximum.
+bool IncrementAuthUserIndex(GURL* url) {
+ int user_index = 0;
+ std::string old_query = url->query();
+ std::vector<std::string> new_query_parts;
+ url::Component query(0, old_query.length());
+ url::Component key, value;
+ while (url::ExtractQueryKeyValue(old_query.c_str(), &query, &key, &value)) {
+ std::string key_string = old_query.substr(key.begin, key.len);
+ std::string value_string = old_query.substr(value.begin, value.len);
+ if (key_string == kAuthUserQueryKey) {
+ base::StringToInt(value_string, &user_index);
+ } else {
+ new_query_parts.push_back(base::StringPrintf(
+ "%s=%s", key_string.c_str(), value_string.c_str()));
+ }
+ }
+ if (user_index >= kMaxAuthUserValue)
+ return false;
+ new_query_parts.push_back(
+ base::StringPrintf("%s=%d", kAuthUserQueryKey, user_index + 1));
+ std::string new_query_string = JoinString(new_query_parts, '&');
+ url::Component new_query(0, new_query_string.size());
+ url::Replacements<char> replacements;
+ replacements.SetQuery(new_query_string.c_str(), new_query);
+ *url = url->ReplaceComponents(replacements);
+ return true;
}
} // namespace
@@ -707,17 +771,23 @@ void ExtensionDownloader::OnCRXFetchComplete(
} else {
NotifyDelegateDownloadFinished(fetch_data.Pass(), crx_path, true);
}
- } else if (status.status() == net::URLRequestStatus::SUCCESS &&
- (response_code == 401 || response_code == 403) &&
- !extensions_queue_.active_request()->is_protected) {
- // On 401 or 403, requeue this fetch with cookies enabled.
+ } else if (ShouldRetryRequestWithCookies(
+ status,
+ response_code,
+ extensions_queue_.active_request()->is_protected)) {
+ // Requeue the fetch with |is_protected| set, enabling cookies.
extensions_queue_.active_request()->is_protected = true;
extensions_queue_.RetryRequest(backoff_delay);
+ } else if (ShouldRetryRequestWithNextUser(
+ status,
+ response_code,
+ extensions_queue_.active_request()->is_protected) &&
+ IncrementAuthUserIndex(&extensions_queue_.active_request()->url)) {
+ extensions_queue_.RetryRequest(backoff_delay);
} else {
const std::set<int>& request_ids =
extensions_queue_.active_request()->request_ids;
const ExtensionDownloaderDelegate::PingResult& ping = ping_results_[id];
-
VLOG(1) << "Failed to fetch extension '" << url.possibly_invalid_spec()
<< "' response code:" << response_code;
if (ShouldRetryRequest(status, response_code) &&
« no previous file with comments | « no previous file | chrome/browser/extensions/updater/extension_updater_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698