diff options
author | bcwhite <bcwhite@chromium.org> | 2015-04-03 00:47:01 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-04-03 07:47:56 +0000 |
commit | b7f9590aecaf544ca435559c98c4bb9b61d06405 (patch) | |
tree | 2fc3a131c1dfd96f481098936fc8be770645e13f /google_apis | |
parent | 43af203adea6535c2b89d2ba4a06c2dcd888dc3c (diff) | |
download | chromium_src-b7f9590aecaf544ca435559c98c4bb9b61d06405.zip chromium_src-b7f9590aecaf544ca435559c98c4bb9b61d06405.tar.gz chromium_src-b7f9590aecaf544ca435559c98c4bb9b61d06405.tar.bz2 |
If an OAuth error is permanent, remember it instead of retrying.
BUG=466799
Review URL: https://codereview.chromium.org/1004623011
Cr-Commit-Position: refs/heads/master@{#323663}
Diffstat (limited to 'google_apis')
-rw-r--r-- | google_apis/BUILD.gn | 2 | ||||
-rw-r--r-- | google_apis/gaia/google_service_auth_error.cc | 20 | ||||
-rw-r--r-- | google_apis/gaia/google_service_auth_error.h | 6 | ||||
-rw-r--r-- | google_apis/gaia/oauth2_access_token_fetcher_permanent_error.cc | 72 | ||||
-rw-r--r-- | google_apis/gaia/oauth2_access_token_fetcher_permanent_error.h | 64 | ||||
-rw-r--r-- | google_apis/google_apis.gyp | 2 |
6 files changed, 166 insertions, 0 deletions
diff --git a/google_apis/BUILD.gn b/google_apis/BUILD.gn index bee149a..e6e22ab 100644 --- a/google_apis/BUILD.gn +++ b/google_apis/BUILD.gn @@ -104,6 +104,8 @@ source_set("google_apis") { "gaia/oauth2_access_token_fetcher.h", "gaia/oauth2_access_token_fetcher_impl.cc", "gaia/oauth2_access_token_fetcher_impl.h", + "gaia/oauth2_access_token_fetcher_permanent_error.cc", + "gaia/oauth2_access_token_fetcher_permanent_error.h", "gaia/oauth2_api_call_flow.cc", "gaia/oauth2_api_call_flow.h", "gaia/oauth2_mint_token_flow.cc", diff --git a/google_apis/gaia/google_service_auth_error.cc b/google_apis/gaia/google_service_auth_error.cc index 7796fae..5fab6dd 100644 --- a/google_apis/gaia/google_service_auth_error.cc +++ b/google_apis/gaia/google_service_auth_error.cc @@ -64,6 +64,11 @@ bool GoogleServiceAuthError::operator==( second_factor_ == b.second_factor_); } +bool GoogleServiceAuthError::operator!=( + const GoogleServiceAuthError& b) const { + return !(*this == b); +} + GoogleServiceAuthError::GoogleServiceAuthError(State s) : state_(s), network_error_(0) { @@ -240,6 +245,21 @@ std::string GoogleServiceAuthError::ToString() const { } } +bool GoogleServiceAuthError::IsPersistentError() const { + if (state_ == GoogleServiceAuthError::NONE) return false; + return !IsTransientError(); +} + +bool GoogleServiceAuthError::IsTransientError() const { + switch (state_) { + case GoogleServiceAuthError::CONNECTION_FAILED: + case GoogleServiceAuthError::SERVICE_UNAVAILABLE: + return true; + default: + return false; + } +} + GoogleServiceAuthError::GoogleServiceAuthError(State s, int error) : state_(s), network_error_(error) { diff --git a/google_apis/gaia/google_service_auth_error.h b/google_apis/gaia/google_service_auth_error.h index fd643bd..15db61c 100644 --- a/google_apis/gaia/google_service_auth_error.h +++ b/google_apis/gaia/google_service_auth_error.h @@ -139,6 +139,7 @@ class GoogleServiceAuthError { // For test only. bool operator==(const GoogleServiceAuthError &b) const; + bool operator!=(const GoogleServiceAuthError &b) const; // Construct a GoogleServiceAuthError from a State with no additional data. explicit GoogleServiceAuthError(State s); @@ -186,6 +187,11 @@ class GoogleServiceAuthError { // Returns a message describing the error. std::string ToString() const; + // Check if this is error may go away simply by trying again. Except for the + // NONE case, these are mutually exclusive. + bool IsPersistentError() const; + bool IsTransientError() const; + private: GoogleServiceAuthError(State s, int error); diff --git a/google_apis/gaia/oauth2_access_token_fetcher_permanent_error.cc b/google_apis/gaia/oauth2_access_token_fetcher_permanent_error.cc new file mode 100644 index 0000000..0f24e3d --- /dev/null +++ b/google_apis/gaia/oauth2_access_token_fetcher_permanent_error.cc @@ -0,0 +1,72 @@ +// Copyright 2014 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "google_apis/gaia/oauth2_access_token_fetcher_permanent_error.h" + +#include "base/bind.h" +#include "base/message_loop/message_loop.h" +#include "google_apis/gaia/google_service_auth_error.h" + + +OAuth2AccessTokenFetcherPermanentError::FailCaller::FailCaller( + OAuth2AccessTokenFetcherPermanentError* fetcher) + : fetcher_(fetcher) { + base::MessageLoop* looper = base::MessageLoop::current(); + DCHECK(looper); + looper->PostTask( + FROM_HERE, + base::Bind(&OAuth2AccessTokenFetcherPermanentError::FailCaller::run, + this)); +} + +OAuth2AccessTokenFetcherPermanentError::FailCaller::~FailCaller() { +} + +void OAuth2AccessTokenFetcherPermanentError::FailCaller::run() { + if (fetcher_) { + fetcher_->Fail(); + fetcher_ = NULL; + } +} + +void OAuth2AccessTokenFetcherPermanentError::FailCaller::detach() { + fetcher_ = NULL; +} + + +OAuth2AccessTokenFetcherPermanentError::OAuth2AccessTokenFetcherPermanentError( + OAuth2AccessTokenConsumer* consumer, + const GoogleServiceAuthError& error) + : OAuth2AccessTokenFetcher(consumer), + permanent_error_(error) { + DCHECK(!permanent_error_.IsTransientError()); +} + +OAuth2AccessTokenFetcherPermanentError:: + ~OAuth2AccessTokenFetcherPermanentError() { + CancelRequest(); +} + +void OAuth2AccessTokenFetcherPermanentError::CancelRequest() { + if (failer_) { + failer_->detach(); + failer_ = NULL; + } +} + +void OAuth2AccessTokenFetcherPermanentError::Start( + const std::string& client_id, + const std::string& client_secret, + const std::vector<std::string>& scopes) { + failer_ = new FailCaller(this); +} + +void OAuth2AccessTokenFetcherPermanentError::Fail() { + // The call below will likely destruct this object. We have to make a copy + // of the error into a local variable because the class member thus will + // be destroyed after which the copy-passed-by-reference will cause a + // memory violation when accessed. + GoogleServiceAuthError error_copy = permanent_error_; + FireOnGetTokenFailure(error_copy); +} diff --git a/google_apis/gaia/oauth2_access_token_fetcher_permanent_error.h b/google_apis/gaia/oauth2_access_token_fetcher_permanent_error.h new file mode 100644 index 0000000..e7053ce --- /dev/null +++ b/google_apis/gaia/oauth2_access_token_fetcher_permanent_error.h @@ -0,0 +1,64 @@ +// Copyright 2015 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef GOOGLE_APIS_GAIA_OAUTH2_ACCESS_TOKEN_FETCHER_PERMANENT_ERROR_H_ +#define GOOGLE_APIS_GAIA_OAUTH2_ACCESS_TOKEN_FETCHER_PERMANENT_ERROR_H_ + +#include "base/memory/ref_counted.h" +#include "google_apis/gaia/google_service_auth_error.h" +#include "google_apis/gaia/oauth2_access_token_consumer.h" +#include "google_apis/gaia/oauth2_access_token_fetcher.h" + +// This is an implementation of the OAuth2 fetcher that immediately returns +// an error. This is useful as a replacement to a real fetcher when a +// permanent error has previously been seen. +// +// This class should be used on a single thread, but it can be whichever thread +// that you like. +// Also, do not reuse the same instance. Once Start() is called, the instance +// should not be reused. +// +// Usage: +// * Create an instance with a consumer. +// * Call Start() +// * The consumer passed in the constructor will be called on the same +// thread Start was called with the results. +// +// This class can handle one request at a time. To parallelize requests, +// create multiple instances. +class OAuth2AccessTokenFetcherPermanentError : public OAuth2AccessTokenFetcher { + public: + OAuth2AccessTokenFetcherPermanentError(OAuth2AccessTokenConsumer* consumer, + const GoogleServiceAuthError& error); + ~OAuth2AccessTokenFetcherPermanentError() override; + + void Start(const std::string& client_id, + const std::string& client_secret, + const std::vector<std::string>& scopes) override; + + void CancelRequest() override; + + private: + class FailCaller : public base::RefCounted<FailCaller> { + public: + FailCaller(OAuth2AccessTokenFetcherPermanentError* fetcher); + + void run(); + void detach(); + + private: + friend class base::RefCounted<FailCaller>; + ~FailCaller(); + + OAuth2AccessTokenFetcherPermanentError* fetcher_; + }; + + void Fail(); + + scoped_refptr<FailCaller> failer_; + GoogleServiceAuthError permanent_error_; + DISALLOW_COPY_AND_ASSIGN(OAuth2AccessTokenFetcherPermanentError); +}; + +#endif // GOOGLE_APIS_GAIA_OAUTH2_ACCESS_TOKEN_FETCHER_PERMANENT_ERROR_H_ diff --git a/google_apis/google_apis.gyp b/google_apis/google_apis.gyp index 20c3269..0969651 100644 --- a/google_apis/google_apis.gyp +++ b/google_apis/google_apis.gyp @@ -95,6 +95,8 @@ 'gaia/oauth2_access_token_fetcher.h', 'gaia/oauth2_access_token_fetcher_impl.cc', 'gaia/oauth2_access_token_fetcher_impl.h', + 'gaia/oauth2_access_token_fetcher_permanent_error.cc', + 'gaia/oauth2_access_token_fetcher_permanent_error.h', 'gaia/oauth2_api_call_flow.cc', 'gaia/oauth2_api_call_flow.h', 'gaia/oauth2_mint_token_flow.cc', |