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

Side by Side Diff: components/signin/core/browser/gaia_cookie_manager_service.cc

Issue 1110743002: Handle transient LogOut errors with retry and backoff. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: rogerta's comments Created 5 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 unified diff | Download patch
OLDNEW
1 // Copyright 2014 The Chromium Authors. All rights reserved. 1 // Copyright 2014 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 "components/signin/core/browser/gaia_cookie_manager_service.h" 5 #include "components/signin/core/browser/gaia_cookie_manager_service.h"
6 6
7 #include <queue> 7 #include <queue>
8 #include <vector> 8 #include <vector>
9 9
10 #include "base/json/json_reader.h" 10 #include "base/json/json_reader.h"
11 #include "base/stl_util.h" 11 #include "base/stl_util.h"
12 #include "base/strings/string_util.h" 12 #include "base/strings/string_util.h"
13 #include "base/strings/stringprintf.h" 13 #include "base/strings/stringprintf.h"
14 #include "base/time/time.h" 14 #include "base/time/time.h"
15 #include "base/values.h" 15 #include "base/values.h"
16 #include "components/signin/core/browser/signin_metrics.h" 16 #include "components/signin/core/browser/signin_metrics.h"
17 #include "google_apis/gaia/gaia_auth_fetcher.h" 17 #include "google_apis/gaia/gaia_auth_fetcher.h"
18 #include "google_apis/gaia/gaia_auth_util.h" 18 #include "google_apis/gaia/gaia_auth_util.h"
19 #include "google_apis/gaia/gaia_constants.h" 19 #include "google_apis/gaia/gaia_constants.h"
20 #include "google_apis/gaia/gaia_urls.h" 20 #include "google_apis/gaia/gaia_urls.h"
21 #include "google_apis/gaia/oauth2_token_service.h" 21 #include "google_apis/gaia/oauth2_token_service.h"
22 #include "net/base/load_flags.h" 22 #include "net/base/load_flags.h"
23 #include "net/http/http_status_code.h" 23 #include "net/http/http_status_code.h"
24 #include "net/url_request/url_fetcher.h" 24 #include "net/url_request/url_fetcher.h"
25 #include "net/url_request/url_fetcher_delegate.h" 25 #include "net/url_request/url_fetcher_delegate.h"
26 26
27 namespace { 27 namespace {
28 28
29 // In case of an error while fetching using the GaiaAuthFetcher, retry with 29 // In case of an error while fetching using the GaiaAuthFetcher or URLFetcher,
30 // exponential backoff. Try up to 7 times within 15 minutes. 30 // retry with exponential backoff. Try up to 7 times within 15 minutes.
31 const net::BackoffEntry::Policy kBackoffPolicy = { 31 const net::BackoffEntry::Policy kBackoffPolicy = {
32 // Number of initial errors (in sequence) to ignore before applying 32 // Number of initial errors (in sequence) to ignore before applying
33 // exponential back-off rules. 33 // exponential back-off rules.
34 0, 34 0,
35 35
36 // Initial delay for exponential backoff in ms. 36 // Initial delay for exponential backoff in ms.
37 1000, 37 1000,
38 38
39 // Factor by which the waiting time will be multiplied. 39 // Factor by which the waiting time will be multiplied.
40 3, 40 3,
41 41
42 // Fuzzing percentage. ex: 10% will spread requests randomly 42 // Fuzzing percentage. ex: 10% will spread requests randomly
43 // between 90%-100% of the calculated time. 43 // between 90%-100% of the calculated time.
44 0.2, // 20% 44 0.2, // 20%
45 45
46 // Maximum amount of time we are willing to delay our request in ms. 46 // Maximum amount of time we are willing to delay our request in ms.
47 1000 * 60 * 60 * 4, // 15 minutes. 47 1000 * 60 * 60 * 4, // 15 minutes.
48 48
49 // Time to keep an entry from being discarded even when it 49 // Time to keep an entry from being discarded even when it
50 // has no significant state, -1 to never discard. 50 // has no significant state, -1 to never discard.
51 -1, 51 -1,
52 52
53 // Don't use initial delay unless the last request was an error. 53 // Don't use initial delay unless the last request was an error.
54 false, 54 false,
55 }; 55 };
56 56
57 const int kMaxGaiaAuthFetcherRetries = 8; 57 const int kMaxFetcherRetries = 8;
58 58
59 bool IsTransientError(const GoogleServiceAuthError& error) { 59 bool IsTransientError(const GoogleServiceAuthError& error) {
60 return error.state() == GoogleServiceAuthError::CONNECTION_FAILED || 60 return error.state() == GoogleServiceAuthError::CONNECTION_FAILED ||
61 error.state() == GoogleServiceAuthError::SERVICE_UNAVAILABLE || 61 error.state() == GoogleServiceAuthError::SERVICE_UNAVAILABLE ||
62 error.state() == GoogleServiceAuthError::REQUEST_CANCELED; 62 error.state() == GoogleServiceAuthError::REQUEST_CANCELED;
63 } 63 }
64 64
65 enum GaiaCookieRequestType { 65 enum GaiaCookieRequestType {
66 ADD_ACCOUNT, 66 ADD_ACCOUNT,
67 LOG_OUT_ALL_ACCOUNTS, 67 LOG_OUT_ALL_ACCOUNTS,
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
143 bool GaiaCookieManagerService::ExternalCcResultFetcher::IsRunning() { 143 bool GaiaCookieManagerService::ExternalCcResultFetcher::IsRunning() {
144 return helper_->gaia_auth_fetcher_ || fetchers_.size() > 0u; 144 return helper_->gaia_auth_fetcher_ || fetchers_.size() > 0u;
145 } 145 }
146 146
147 void GaiaCookieManagerService::ExternalCcResultFetcher::TimeoutForTests() { 147 void GaiaCookieManagerService::ExternalCcResultFetcher::TimeoutForTests() {
148 Timeout(); 148 Timeout();
149 } 149 }
150 150
151 void GaiaCookieManagerService::ExternalCcResultFetcher:: 151 void GaiaCookieManagerService::ExternalCcResultFetcher::
152 OnGetCheckConnectionInfoSuccess(const std::string& data) { 152 OnGetCheckConnectionInfoSuccess(const std::string& data) {
153 helper_->gaia_auth_fetcher_backoff_.InformOfRequest(true); 153 helper_->fetcher_backoff_.InformOfRequest(true);
154 gaia_auth_fetcher_timer_.Stop(); 154 gaia_auth_fetcher_timer_.Stop();
155 scoped_ptr<base::Value> value(base::JSONReader::Read(data)); 155 scoped_ptr<base::Value> value(base::JSONReader::Read(data));
156 const base::ListValue* list; 156 const base::ListValue* list;
157 if (!value || !value->GetAsList(&list)) { 157 if (!value || !value->GetAsList(&list)) {
158 CleanupTransientState(); 158 CleanupTransientState();
159 GetCheckConnectionInfoCompleted(false); 159 GetCheckConnectionInfoCompleted(false);
160 return; 160 return;
161 } 161 }
162 162
163 // If there is nothing to check, terminate immediately. 163 // If there is nothing to check, terminate immediately.
(...skipping 15 matching lines...) Expand all
179 net::URLFetcher* fetcher = CreateFetcher(GURL(url)); 179 net::URLFetcher* fetcher = CreateFetcher(GURL(url));
180 fetchers_[fetcher->GetOriginalURL()] = std::make_pair(token, fetcher); 180 fetchers_[fetcher->GetOriginalURL()] = std::make_pair(token, fetcher);
181 fetcher->Start(); 181 fetcher->Start();
182 } 182 }
183 } 183 }
184 } 184 }
185 } 185 }
186 186
187 void GaiaCookieManagerService::ExternalCcResultFetcher:: 187 void GaiaCookieManagerService::ExternalCcResultFetcher::
188 OnGetCheckConnectionInfoError(const GoogleServiceAuthError& error) { 188 OnGetCheckConnectionInfoError(const GoogleServiceAuthError& error) {
189 if (++helper_->gaia_auth_fetcher_retries_ < kMaxGaiaAuthFetcherRetries && 189 if (++helper_->fetcher_retries_ < kMaxFetcherRetries &&
190 IsTransientError(error)) { 190 IsTransientError(error)) {
191 helper_->gaia_auth_fetcher_backoff_.InformOfRequest(false); 191 helper_->fetcher_backoff_.InformOfRequest(false);
192 gaia_auth_fetcher_timer_.Start( 192 gaia_auth_fetcher_timer_.Start(
193 FROM_HERE, helper_->gaia_auth_fetcher_backoff_.GetTimeUntilRelease(), 193 FROM_HERE, helper_->fetcher_backoff_.GetTimeUntilRelease(),
194 this, &GaiaCookieManagerService::ExternalCcResultFetcher::Start); 194 this, &GaiaCookieManagerService::ExternalCcResultFetcher::Start);
195 return; 195 return;
196 } 196 }
197 197
198 CleanupTransientState(); 198 CleanupTransientState();
199 GetCheckConnectionInfoCompleted(false); 199 GetCheckConnectionInfoCompleted(false);
200 } 200 }
201 201
202 net::URLFetcher* 202 net::URLFetcher*
203 GaiaCookieManagerService::ExternalCcResultFetcher::CreateFetcher( 203 GaiaCookieManagerService::ExternalCcResultFetcher::CreateFetcher(
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
276 helper_->StartFetchingMergeSession(); 276 helper_->StartFetchingMergeSession();
277 } 277 }
278 278
279 GaiaCookieManagerService::GaiaCookieManagerService( 279 GaiaCookieManagerService::GaiaCookieManagerService(
280 OAuth2TokenService* token_service, 280 OAuth2TokenService* token_service,
281 const std::string& source, 281 const std::string& source,
282 SigninClient* signin_client) 282 SigninClient* signin_client)
283 : token_service_(token_service), 283 : token_service_(token_service),
284 signin_client_(signin_client), 284 signin_client_(signin_client),
285 external_cc_result_fetcher_(this), 285 external_cc_result_fetcher_(this),
286 gaia_auth_fetcher_backoff_(&kBackoffPolicy), 286 fetcher_backoff_(&kBackoffPolicy),
287 gaia_auth_fetcher_retries_(0), 287 fetcher_retries_(0),
288 source_(source), 288 source_(source),
289 external_cc_result_fetched_(false), 289 external_cc_result_fetched_(false),
290 list_accounts_fetched_once_(false) { 290 list_accounts_fetched_once_(false) {
291 } 291 }
292 292
293 GaiaCookieManagerService::~GaiaCookieManagerService() { 293 GaiaCookieManagerService::~GaiaCookieManagerService() {
294 CancelAll(); 294 CancelAll();
295 DCHECK(requests_.empty()); 295 DCHECK(requests_.empty());
296 } 296 }
297 297
(...skipping 29 matching lines...) Expand all
327 DCHECK(accounts); 327 DCHECK(accounts);
328 accounts->clear(); 328 accounts->clear();
329 329
330 // There is a fetch currently executing (the results being provided in the 330 // There is a fetch currently executing (the results being provided in the
331 // parameter don't align with the fetches that have been started), or the list 331 // parameter don't align with the fetches that have been started), or the list
332 // of accounts haven't been fetched even once. 332 // of accounts haven't been fetched even once.
333 if (!requests_.empty()) 333 if (!requests_.empty())
334 return false; 334 return false;
335 335
336 if (!list_accounts_fetched_once_) { 336 if (!list_accounts_fetched_once_) {
337 gaia_auth_fetcher_retries_ = 0; 337 fetcher_retries_ = 0;
338 requests_.push_back(GaiaCookieRequest::CreateListAccountsRequest()); 338 requests_.push_back(GaiaCookieRequest::CreateListAccountsRequest());
339 StartFetchingListAccounts(); 339 StartFetchingListAccounts();
340 return false; 340 return false;
341 } 341 }
342 342
343 accounts->assign(listed_accounts_.begin(), listed_accounts_.end()); 343 accounts->assign(listed_accounts_.begin(), listed_accounts_.end());
344 return true; 344 return true;
345 } 345 }
346 346
347 void GaiaCookieManagerService::LogOutAllAccounts() { 347 void GaiaCookieManagerService::LogOutAllAccounts() {
(...skipping 29 matching lines...) Expand all
377 // Remove all but the executing request. Re-add all requests being kept. 377 // Remove all but the executing request. Re-add all requests being kept.
378 if (requests_.size() > 1) { 378 if (requests_.size() > 1) {
379 requests_.erase(requests_.begin() + 1, requests_.end()); 379 requests_.erase(requests_.begin() + 1, requests_.end());
380 requests_.insert( 380 requests_.insert(
381 requests_.end(), requests_to_keep.begin(), requests_to_keep.end()); 381 requests_.end(), requests_to_keep.begin(), requests_to_keep.end());
382 } 382 }
383 } 383 }
384 384
385 if (!log_out_queued) { 385 if (!log_out_queued) {
386 requests_.push_back(GaiaCookieRequest::CreateLogOutRequest()); 386 requests_.push_back(GaiaCookieRequest::CreateLogOutRequest());
387 if (requests_.size() == 1) 387 if (requests_.size() == 1) {
388 fetcher_retries_ = 0;
388 StartLogOutUrlFetch(); 389 StartLogOutUrlFetch();
390 }
389 } 391 }
390 } 392 }
391 393
392 void GaiaCookieManagerService::AddObserver(Observer* observer) { 394 void GaiaCookieManagerService::AddObserver(Observer* observer) {
393 observer_list_.AddObserver(observer); 395 observer_list_.AddObserver(observer);
394 } 396 }
395 397
396 void GaiaCookieManagerService::RemoveObserver(Observer* observer) { 398 void GaiaCookieManagerService::RemoveObserver(Observer* observer) {
397 observer_list_.RemoveObserver(observer); 399 observer_list_.RemoveObserver(observer);
398 } 400 }
399 401
400 void GaiaCookieManagerService::CancelAll() { 402 void GaiaCookieManagerService::CancelAll() {
401 VLOG(1) << "GaiaCookieManagerService::CancelAll"; 403 VLOG(1) << "GaiaCookieManagerService::CancelAll";
402 gaia_auth_fetcher_.reset(); 404 gaia_auth_fetcher_.reset();
403 uber_token_fetcher_.reset(); 405 uber_token_fetcher_.reset();
404 requests_.clear(); 406 requests_.clear();
405 gaia_auth_fetcher_timer_.Stop(); 407 fetcher_timer_.Stop();
406 } 408 }
407 409
408 // It is unknown if the cookie was changed because of processing initiated by 410 // It is unknown if the cookie was changed because of processing initiated by
409 // this class or other (such as the user clearing all cookies or a cookie being 411 // this class or other (such as the user clearing all cookies or a cookie being
410 // evicted). 412 // evicted).
411 void GaiaCookieManagerService::OnCookieChanged( 413 void GaiaCookieManagerService::OnCookieChanged(
412 const net::CanonicalCookie& cookie, 414 const net::CanonicalCookie& cookie,
413 bool removed) { 415 bool removed) {
414 DCHECK_EQ("APISID", cookie.Name()); 416 DCHECK_EQ("APISID", cookie.Name());
415 DCHECK_EQ(GaiaUrls::GetInstance()->google_url().host(), cookie.Domain()); 417 DCHECK_EQ(GaiaUrls::GetInstance()->google_url().host(), cookie.Domain());
416 gaia_auth_fetcher_retries_ = 0;
417 if (requests_.empty()) { 418 if (requests_.empty()) {
418 requests_.push_back(GaiaCookieRequest::CreateListAccountsRequest()); 419 requests_.push_back(GaiaCookieRequest::CreateListAccountsRequest());
420 fetcher_retries_ = 0;
419 StartFetchingListAccounts(); 421 StartFetchingListAccounts();
420 } else { 422 } else {
421 // Remove all pending ListAccount calls; for efficiency, only call 423 // Remove all pending ListAccount calls; for efficiency, only call
422 // after all pending requests are processed. 424 // after all pending requests are processed.
423 // Track requests to keep; all other unstarted requests will be removed. 425 // Track requests to keep; all other unstarted requests will be removed.
424 std::vector<GaiaCookieRequest> requests_to_keep; 426 std::vector<GaiaCookieRequest> requests_to_keep;
425 427
426 // Check all pending, non-executing requests. 428 // Check all pending, non-executing requests.
427 for (auto it = requests_.begin() + 1; it != requests_.end(); ++it) { 429 for (auto it = requests_.begin() + 1; it != requests_.end(); ++it) {
428 // Keep all requests except for LIST_ACCOUNTS. 430 // Keep all requests except for LIST_ACCOUNTS.
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
460 fetcher->SetRequestContext(signin_client_->GetURLRequestContext()); 462 fetcher->SetRequestContext(signin_client_->GetURLRequestContext());
461 fetcher->Start(); 463 fetcher->Start();
462 } 464 }
463 465
464 void GaiaCookieManagerService::OnUbertokenSuccess( 466 void GaiaCookieManagerService::OnUbertokenSuccess(
465 const std::string& uber_token) { 467 const std::string& uber_token) {
466 DCHECK(requests_.front().request_type() == 468 DCHECK(requests_.front().request_type() ==
467 GaiaCookieRequestType::ADD_ACCOUNT); 469 GaiaCookieRequestType::ADD_ACCOUNT);
468 VLOG(1) << "GaiaCookieManagerService::OnUbertokenSuccess" 470 VLOG(1) << "GaiaCookieManagerService::OnUbertokenSuccess"
469 << " account=" << requests_.front().account_id(); 471 << " account=" << requests_.front().account_id();
470 gaia_auth_fetcher_retries_ = 0; 472 fetcher_retries_ = 0;
471 uber_token_ = uber_token; 473 uber_token_ = uber_token;
472 474
473 if (!external_cc_result_fetched_ && 475 if (!external_cc_result_fetched_ &&
474 !external_cc_result_fetcher_.IsRunning()) { 476 !external_cc_result_fetcher_.IsRunning()) {
475 external_cc_result_fetcher_.Start(); 477 external_cc_result_fetcher_.Start();
476 return; 478 return;
477 } 479 }
478 480
479 StartFetchingMergeSession(); 481 StartFetchingMergeSession();
480 } 482 }
481 483
482 void GaiaCookieManagerService::OnUbertokenFailure( 484 void GaiaCookieManagerService::OnUbertokenFailure(
483 const GoogleServiceAuthError& error) { 485 const GoogleServiceAuthError& error) {
486 // Note that the UberToken fetcher already retries transient errors.
484 VLOG(1) << "Failed to retrieve ubertoken" 487 VLOG(1) << "Failed to retrieve ubertoken"
485 << " account=" << requests_.front().account_id() 488 << " account=" << requests_.front().account_id()
486 << " error=" << error.ToString(); 489 << " error=" << error.ToString();
487 const std::string account_id = requests_.front().account_id(); 490 const std::string account_id = requests_.front().account_id();
488 HandleNextRequest(); 491 HandleNextRequest();
489 SignalComplete(account_id, error); 492 SignalComplete(account_id, error);
490 } 493 }
491 494
492 void GaiaCookieManagerService::OnMergeSessionSuccess(const std::string& data) { 495 void GaiaCookieManagerService::OnMergeSessionSuccess(const std::string& data) {
493 VLOG(1) << "MergeSession successful account=" 496 VLOG(1) << "MergeSession successful account="
494 << requests_.front().account_id(); 497 << requests_.front().account_id();
495 DCHECK(requests_.front().request_type() == 498 DCHECK(requests_.front().request_type() ==
496 GaiaCookieRequestType::ADD_ACCOUNT); 499 GaiaCookieRequestType::ADD_ACCOUNT);
497 const std::string account_id = requests_.front().account_id(); 500 const std::string account_id = requests_.front().account_id();
498 HandleNextRequest(); 501 HandleNextRequest();
499 SignalComplete(account_id, GoogleServiceAuthError::AuthErrorNone()); 502 SignalComplete(account_id, GoogleServiceAuthError::AuthErrorNone());
500 503
501 gaia_auth_fetcher_backoff_.InformOfRequest(true); 504 fetcher_backoff_.InformOfRequest(true);
502 uber_token_ = std::string(); 505 uber_token_ = std::string();
503 } 506 }
504 507
505 void GaiaCookieManagerService::OnMergeSessionFailure( 508 void GaiaCookieManagerService::OnMergeSessionFailure(
506 const GoogleServiceAuthError& error) { 509 const GoogleServiceAuthError& error) {
507 DCHECK(requests_.front().request_type() == 510 DCHECK(requests_.front().request_type() ==
508 GaiaCookieRequestType::ADD_ACCOUNT); 511 GaiaCookieRequestType::ADD_ACCOUNT);
509 VLOG(1) << "Failed MergeSession" 512 VLOG(1) << "Failed MergeSession"
510 << " account=" << requests_.front().account_id() 513 << " account=" << requests_.front().account_id()
511 << " error=" << error.ToString(); 514 << " error=" << error.ToString();
512 if (++gaia_auth_fetcher_retries_ < kMaxGaiaAuthFetcherRetries && 515 if (++fetcher_retries_ < kMaxFetcherRetries && IsTransientError(error)) {
513 IsTransientError(error)) { 516 fetcher_backoff_.InformOfRequest(false);
514 gaia_auth_fetcher_backoff_.InformOfRequest(false); 517 fetcher_timer_.Start(
515 gaia_auth_fetcher_timer_.Start( 518 FROM_HERE, fetcher_backoff_.GetTimeUntilRelease(), this,
516 FROM_HERE, gaia_auth_fetcher_backoff_.GetTimeUntilRelease(), this,
517 &GaiaCookieManagerService::StartFetchingMergeSession); 519 &GaiaCookieManagerService::StartFetchingMergeSession);
518 return; 520 return;
519 } 521 }
520 522
521 uber_token_ = std::string(); 523 uber_token_ = std::string();
522 const std::string account_id = requests_.front().account_id(); 524 const std::string account_id = requests_.front().account_id();
523 HandleNextRequest(); 525 HandleNextRequest();
524 SignalComplete(account_id, error); 526 SignalComplete(account_id, error);
525 } 527 }
526 528
527 void GaiaCookieManagerService::OnListAccountsSuccess(const std::string& data) { 529 void GaiaCookieManagerService::OnListAccountsSuccess(const std::string& data) {
528 VLOG(1) << "ListAccounts successful"; 530 VLOG(1) << "ListAccounts successful";
529 DCHECK(requests_.front().request_type() == 531 DCHECK(requests_.front().request_type() ==
530 GaiaCookieRequestType::LIST_ACCOUNTS); 532 GaiaCookieRequestType::LIST_ACCOUNTS);
531 gaia_auth_fetcher_backoff_.InformOfRequest(true); 533 fetcher_backoff_.InformOfRequest(true);
532 534
533 if (!gaia::ParseListAccountsData(data, &listed_accounts_)) { 535 if (!gaia::ParseListAccountsData(data, &listed_accounts_)) {
534 listed_accounts_.clear(); 536 listed_accounts_.clear();
535 OnListAccountsFailure(GoogleServiceAuthError( 537 OnListAccountsFailure(GoogleServiceAuthError(
536 GoogleServiceAuthError::UNEXPECTED_SERVICE_RESPONSE)); 538 GoogleServiceAuthError::UNEXPECTED_SERVICE_RESPONSE));
537 return; 539 return;
538 } 540 }
539 541
540 list_accounts_fetched_once_ = true; 542 list_accounts_fetched_once_ = true;
541 FOR_EACH_OBSERVER(Observer, observer_list_, 543 FOR_EACH_OBSERVER(Observer, observer_list_,
542 OnGaiaAccountsInCookieUpdated( 544 OnGaiaAccountsInCookieUpdated(
543 listed_accounts_, 545 listed_accounts_,
544 GoogleServiceAuthError(GoogleServiceAuthError::NONE))); 546 GoogleServiceAuthError(GoogleServiceAuthError::NONE)));
545 HandleNextRequest(); 547 HandleNextRequest();
546 } 548 }
547 549
548 void GaiaCookieManagerService::OnListAccountsFailure( 550 void GaiaCookieManagerService::OnListAccountsFailure(
549 const GoogleServiceAuthError& error) { 551 const GoogleServiceAuthError& error) {
550 VLOG(1) << "ListAccounts failed"; 552 VLOG(1) << "ListAccounts failed";
551 DCHECK(requests_.front().request_type() == 553 DCHECK(requests_.front().request_type() ==
552 GaiaCookieRequestType::LIST_ACCOUNTS); 554 GaiaCookieRequestType::LIST_ACCOUNTS);
553 if (++gaia_auth_fetcher_retries_ < kMaxGaiaAuthFetcherRetries && 555 if (++fetcher_retries_ < kMaxFetcherRetries && IsTransientError(error)) {
554 IsTransientError(error)) { 556 fetcher_backoff_.InformOfRequest(false);
555 gaia_auth_fetcher_backoff_.InformOfRequest(false); 557 fetcher_timer_.Start(
556 gaia_auth_fetcher_timer_.Start( 558 FROM_HERE, fetcher_backoff_.GetTimeUntilRelease(), this,
557 FROM_HERE, gaia_auth_fetcher_backoff_.GetTimeUntilRelease(), this,
558 &GaiaCookieManagerService::StartFetchingListAccounts); 559 &GaiaCookieManagerService::StartFetchingListAccounts);
559 return; 560 return;
560 } 561 }
561 562
562 FOR_EACH_OBSERVER(Observer, observer_list_, 563 FOR_EACH_OBSERVER(Observer, observer_list_,
563 OnGaiaAccountsInCookieUpdated(listed_accounts_, error)); 564 OnGaiaAccountsInCookieUpdated(listed_accounts_, error));
564 HandleNextRequest(); 565 HandleNextRequest();
565 } 566 }
566 567
567 void GaiaCookieManagerService::StartFetchingUbertoken() { 568 void GaiaCookieManagerService::StartFetchingUbertoken() {
(...skipping 20 matching lines...) Expand all
588 gaia_auth_fetcher_.reset( 589 gaia_auth_fetcher_.reset(
589 new GaiaAuthFetcher(this, source_, 590 new GaiaAuthFetcher(this, source_,
590 signin_client_->GetURLRequestContext())); 591 signin_client_->GetURLRequestContext()));
591 gaia_auth_fetcher_->StartListAccounts(); 592 gaia_auth_fetcher_->StartListAccounts();
592 } 593 }
593 594
594 void GaiaCookieManagerService::OnURLFetchComplete( 595 void GaiaCookieManagerService::OnURLFetchComplete(
595 const net::URLFetcher* source) { 596 const net::URLFetcher* source) {
596 DCHECK(requests_.front().request_type() == GaiaCookieRequestType::LOG_OUT); 597 DCHECK(requests_.front().request_type() == GaiaCookieRequestType::LOG_OUT);
597 VLOG(1) << "GaiaCookieManagerService::OnURLFetchComplete"; 598 VLOG(1) << "GaiaCookieManagerService::OnURLFetchComplete";
599
600 if ((!source->GetStatus().is_success() ||
601 source->GetResponseCode() != net::HTTP_OK) &&
602 ++fetcher_retries_ < kMaxFetcherRetries) {
603 fetcher_backoff_.InformOfRequest(false);
604 fetcher_timer_.Start(
605 FROM_HERE, fetcher_backoff_.GetTimeUntilRelease(), this,
606 &GaiaCookieManagerService::StartLogOutUrlFetch);
607 return;
608 }
609
610 fetcher_backoff_.InformOfRequest(true);
598 HandleNextRequest(); 611 HandleNextRequest();
599 } 612 }
600 613
601 void GaiaCookieManagerService::HandleNextRequest() { 614 void GaiaCookieManagerService::HandleNextRequest() {
602 VLOG(1) << "GaiaCookieManagerService::HandleNextRequest"; 615 VLOG(1) << "GaiaCookieManagerService::HandleNextRequest";
603 if (requests_.front().request_type() == 616 if (requests_.front().request_type() ==
604 GaiaCookieRequestType::LIST_ACCOUNTS) { 617 GaiaCookieRequestType::LIST_ACCOUNTS) {
605 // This and any directly subsequent list accounts would return the same. 618 // This and any directly subsequent list accounts would return the same.
606 while (!requests_.empty() && requests_.front().request_type() == 619 while (!requests_.empty() && requests_.front().request_type() ==
607 GaiaCookieRequestType::LIST_ACCOUNTS) { 620 GaiaCookieRequestType::LIST_ACCOUNTS) {
608 requests_.pop_front(); 621 requests_.pop_front();
609 } 622 }
610 } else { 623 } else {
611 // Pop the completed request. 624 // Pop the completed request.
612 requests_.pop_front(); 625 requests_.pop_front();
613 } 626 }
614 627
615 gaia_auth_fetcher_.reset(); 628 gaia_auth_fetcher_.reset();
616 gaia_auth_fetcher_retries_ = 0; 629 fetcher_retries_ = 0;
617 if (requests_.empty()) { 630 if (requests_.empty()) {
618 VLOG(1) << "GaiaCookieManagerService::HandleNextRequest: no more"; 631 VLOG(1) << "GaiaCookieManagerService::HandleNextRequest: no more";
619 uber_token_fetcher_.reset(); 632 uber_token_fetcher_.reset();
620 } else { 633 } else {
621 switch (requests_.front().request_type()) { 634 switch (requests_.front().request_type()) {
622 case GaiaCookieRequestType::ADD_ACCOUNT: 635 case GaiaCookieRequestType::ADD_ACCOUNT:
623 StartFetchingUbertoken(); 636 StartFetchingUbertoken();
624 break; 637 break;
625 case GaiaCookieRequestType::LOG_OUT: 638 case GaiaCookieRequestType::LOG_OUT:
626 StartLogOutUrlFetch(); 639 StartLogOutUrlFetch();
627 break; 640 break;
628 case GaiaCookieRequestType::LIST_ACCOUNTS: 641 case GaiaCookieRequestType::LIST_ACCOUNTS:
629 uber_token_fetcher_.reset(); 642 uber_token_fetcher_.reset();
630 StartFetchingListAccounts(); 643 StartFetchingListAccounts();
631 break; 644 break;
632 }; 645 };
633 } 646 }
634 } 647 }
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698