diff options
author | rogerta@chromium.org <rogerta@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-08-15 21:34:43 +0000 |
---|---|---|
committer | rogerta@chromium.org <rogerta@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-08-15 21:34:43 +0000 |
commit | b4a0ef79e365c489131d615108e7c483c75a30c1 (patch) | |
tree | a29ea40741b4671c1a8b33df3ba44a4d7244bef6 | |
parent | 882ce0330dacf061792bf47ef1ae3d2e720da0e8 (diff) | |
download | chromium_src-b4a0ef79e365c489131d615108e7c483c75a30c1.zip chromium_src-b4a0ef79e365c489131d615108e7c483c75a30c1.tar.gz chromium_src-b4a0ef79e365c489131d615108e7c483c75a30c1.tar.bz2 |
Pre- and Auto-login should not log the user out of an already signed in
google account.
BUG=90510
TEST=See bug description. Also, use the switch account feature and make sure
auto-login does not log you out of any existing sessions.
Review URL: http://codereview.chromium.org/7600003
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@96840 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r-- | chrome/browser/sync/signin_manager.cc | 2 | ||||
-rw-r--r-- | chrome/browser/ui/autologin_infobar_delegate.cc | 12 | ||||
-rw-r--r-- | chrome/common/net/gaia/gaia_auth_consumer.h | 3 | ||||
-rw-r--r-- | chrome/common/net/gaia/gaia_auth_fetcher.cc | 73 | ||||
-rw-r--r-- | chrome/common/net/gaia/gaia_auth_fetcher.h | 20 | ||||
-rw-r--r-- | chrome/common/net/gaia/gaia_auth_fetcher_unittest.cc | 63 | ||||
-rw-r--r-- | chrome/common/net/gaia/gaia_urls.cc | 6 | ||||
-rw-r--r-- | chrome/common/net/gaia/gaia_urls.h | 2 | ||||
-rw-r--r-- | content/common/url_fetcher.cc | 4 | ||||
-rw-r--r-- | content/common/url_fetcher.h | 3 | ||||
-rw-r--r-- | content/test/test_url_fetcher_factory.cc | 4 | ||||
-rw-r--r-- | content/test/test_url_fetcher_factory.h | 23 |
12 files changed, 195 insertions, 20 deletions
diff --git a/chrome/browser/sync/signin_manager.cc b/chrome/browser/sync/signin_manager.cc index cdcad9f..66251d9 100644 --- a/chrome/browser/sync/signin_manager.cc +++ b/chrome/browser/sync/signin_manager.cc @@ -330,7 +330,7 @@ void SigninManager::Observe(int type, profile_->GetRequestContext())); } - client_login_->StartTokenAuth(tok_details->token()); + client_login_->StartMergeSession(tok_details->token()); // We only want to do this once per sign-in. CleanupNotificationRegistration(); diff --git a/chrome/browser/ui/autologin_infobar_delegate.cc b/chrome/browser/ui/autologin_infobar_delegate.cc index 1840897..b756933 100644 --- a/chrome/browser/ui/autologin_infobar_delegate.cc +++ b/chrome/browser/ui/autologin_infobar_delegate.cc @@ -52,9 +52,9 @@ class AutoLoginRedirector : public NotificationObserver { const NotificationSource& source, const NotificationDetails& details) OVERRIDE; - // Redirect tab to TokenAuth URL, logging the user in and navigating + // Redirect tab to MergeSession URL, logging the user in and navigating // to the desired page. - void RedirectToTokenAuth(const std::string& token); + void RedirectToMergeSession(const std::string& token); TabContentsWrapper* tab_contents_wrapper_; const std::string args_; @@ -95,7 +95,7 @@ void AutoLoginRedirector::Observe(int type, Details<TokenService::TokenAvailableDetails>(details).ptr(); if (tok_details->service() == GaiaConstants::kGaiaService) { - RedirectToTokenAuth(tok_details->token()); + RedirectToMergeSession(tok_details->token()); delete this; return; } @@ -111,7 +111,7 @@ void AutoLoginRedirector::Observe(int type, } } -void AutoLoginRedirector::RedirectToTokenAuth(const std::string& token) { +void AutoLoginRedirector::RedirectToMergeSession(const std::string& token) { // The args are URL encoded, so we need to decode them before use. url_canon::RawCanonOutputT<char16> output; url_util::DecodeURLEscapeSequences(args_.c_str(), args_.length(), &output); @@ -120,9 +120,9 @@ void AutoLoginRedirector::RedirectToTokenAuth(const std::string& token) { const char kUrlFormat[] = "%s?" "source=chrome&" - "auth=%s&" + "uberauth=%s&" "%s"; - const std::string url_string = GaiaUrls::GetInstance()->token_auth_url(); + const std::string url_string = GaiaUrls::GetInstance()->merge_session_url(); std::string url = base::StringPrintf(kUrlFormat, url_string.c_str(), token.c_str(), diff --git a/chrome/common/net/gaia/gaia_auth_consumer.h b/chrome/common/net/gaia/gaia_auth_consumer.h index 9878637..fdca0ab 100644 --- a/chrome/common/net/gaia/gaia_auth_consumer.h +++ b/chrome/common/net/gaia/gaia_auth_consumer.h @@ -49,6 +49,9 @@ class GaiaAuthConsumer { virtual void OnTokenAuthSuccess(const std::string& data) {} virtual void OnTokenAuthFailure(const GoogleServiceAuthError& error) {} + + virtual void OnMergeSessionSuccess(const std::string& data) {} + virtual void OnMergeSessionFailure(const GoogleServiceAuthError& error) {} }; #endif // CHROME_COMMON_NET_GAIA_GAIA_AUTH_CONSUMER_H_ diff --git a/chrome/common/net/gaia/gaia_auth_fetcher.cc b/chrome/common/net/gaia/gaia_auth_fetcher.cc index b2fffb3..65318ff 100644 --- a/chrome/common/net/gaia/gaia_auth_fetcher.cc +++ b/chrome/common/net/gaia/gaia_auth_fetcher.cc @@ -54,6 +54,11 @@ const char GaiaAuthFetcher::kTokenAuthFormat[] = "auth=%s&" "continue=%s&" "source=%s"; +// static +const char GaiaAuthFetcher::kMergeSessionFormat[] = + "uberauth=%s&" + "continue=%s&" + "source=%s"; // static const char GaiaAuthFetcher::kAccountDeletedError[] = "AccountDeleted"; @@ -104,6 +109,7 @@ GaiaAuthFetcher::GaiaAuthFetcher(GaiaAuthConsumer* consumer, issue_auth_token_gurl_(GaiaUrls::GetInstance()->issue_auth_token_url()), get_user_info_gurl_(GaiaUrls::GetInstance()->get_user_info_url()), token_auth_gurl_(GaiaUrls::GetInstance()->token_auth_url()), + merge_session_gurl_(GaiaUrls::GetInstance()->merge_session_url()), fetch_pending_(false) {} GaiaAuthFetcher::~GaiaAuthFetcher() {} @@ -122,6 +128,7 @@ URLFetcher* GaiaAuthFetcher::CreateGaiaFetcher( net::URLRequestContextGetter* getter, const std::string& body, const GURL& gaia_gurl, + bool send_cookies, URLFetcher::Delegate* delegate) { URLFetcher* to_return = @@ -130,8 +137,16 @@ URLFetcher* GaiaAuthFetcher::CreateGaiaFetcher( URLFetcher::POST, delegate); to_return->set_request_context(getter); - to_return->set_load_flags(net::LOAD_DO_NOT_SEND_COOKIES); to_return->set_upload_data("application/x-www-form-urlencoded", body); + + // The Gaia token exchange requests do not require any cookie-based + // identification as part of requests. We suppress sending any cookies to + // maintain a separation between the user's browsing and Chrome's internal + // services. Where such mixing is desired (MergeSession), it will be done + // explicitly. + if (!send_cookies) + to_return->set_load_flags(net::LOAD_DO_NOT_SEND_COOKIES); + return to_return; } @@ -213,6 +228,20 @@ std::string GaiaAuthFetcher::MakeTokenAuthBody(const std::string& auth_token, encoded_source.c_str()); } +// static +std::string GaiaAuthFetcher::MakeMergeSessionBody( + const std::string& auth_token, + const std::string& continue_url, + const std::string& source) { + std::string encoded_auth_token = EscapeUrlEncodedData(auth_token, true); + std::string encoded_continue_url = EscapeUrlEncodedData(continue_url, true); + std::string encoded_source = EscapeUrlEncodedData(source, true); + return base::StringPrintf(kMergeSessionFormat, + encoded_auth_token.c_str(), + encoded_continue_url.c_str(), + encoded_source.c_str()); +} + // Helper method that extracts tokens from a successful reply. // static void GaiaAuthFetcher::ParseClientLoginResponse(const std::string& data, @@ -288,6 +317,7 @@ void GaiaAuthFetcher::StartClientLogin( fetcher_.reset(CreateGaiaFetcher(getter_, request_body_, client_login_gurl_, + false, this)); fetch_pending_ = true; fetcher_->Start(); @@ -304,6 +334,7 @@ void GaiaAuthFetcher::StartIssueAuthToken(const std::string& sid, fetcher_.reset(CreateGaiaFetcher(getter_, request_body_, issue_auth_token_gurl_, + false, this)); fetch_pending_ = true; fetcher_->Start(); @@ -318,6 +349,7 @@ void GaiaAuthFetcher::StartGetUserInfo(const std::string& lsid, fetcher_.reset(CreateGaiaFetcher(getter_, request_body_, get_user_info_gurl_, + false, this)); fetch_pending_ = true; requested_info_key_ = info_key; @@ -337,6 +369,31 @@ void GaiaAuthFetcher::StartTokenAuth(const std::string& auth_token) { fetcher_.reset(CreateGaiaFetcher(getter_, request_body_, token_auth_gurl_, + false, + this)); + fetch_pending_ = true; + fetcher_->Start(); +} + +void GaiaAuthFetcher::StartMergeSession(const std::string& auth_token) { + DCHECK(!fetch_pending_) << "Tried to fetch two things at once!"; + + VLOG(1) << "Starting MergeSession with auth_token=" << auth_token; + + // The continue URL is a required parameter of the MergeSession API, but in + // this case we don't actually need or want to navigate to it. Setting it to + // an arbitrary Google URL. + // + // In order for the new session to be merged correctly, the server needs to + // know what sessions already exist in the browser. The fetcher needs to be + // created such that it sends the cookies with the request, which is + // different from all other requests the fetcher can make. + std::string continue_url("http://www.google.com"); + request_body_ = MakeMergeSessionBody(auth_token, continue_url, source_); + fetcher_.reset(CreateGaiaFetcher(getter_, + request_body_, + merge_session_gurl_, + true, this)); fetch_pending_ = true; fetcher_->Start(); @@ -512,6 +569,16 @@ void GaiaAuthFetcher::OnTokenAuthFetched(const std::string& data, } } +void GaiaAuthFetcher::OnMergeSessionFetched(const std::string& data, + const net::URLRequestStatus& status, + int response_code) { + if (status.is_success() && response_code == RC_REQUEST_OK) { + consumer_->OnMergeSessionSuccess(data); + } else { + consumer_->OnMergeSessionFailure(GenerateAuthError(data, status)); + } +} + void GaiaAuthFetcher::OnURLFetchComplete(const URLFetcher* source, const GURL& url, const net::URLRequestStatus& status, @@ -527,6 +594,10 @@ void GaiaAuthFetcher::OnURLFetchComplete(const URLFetcher* source, OnGetUserInfoFetched(data, status, response_code); } else if (url == token_auth_gurl_) { OnTokenAuthFetched(data, status, response_code); + } else if (url == merge_session_gurl_ || + (source && source->original_url() == merge_session_gurl_)) { + // MergeSession may redirect, so check the original URL of the fetcher. + OnMergeSessionFetched(data, status, response_code); } else { NOTREACHED(); } diff --git a/chrome/common/net/gaia/gaia_auth_fetcher.h b/chrome/common/net/gaia/gaia_auth_fetcher.h index 413b06a..1fb471a 100644 --- a/chrome/common/net/gaia/gaia_auth_fetcher.h +++ b/chrome/common/net/gaia/gaia_auth_fetcher.h @@ -71,6 +71,11 @@ class GaiaAuthFetcher : public URLFetcher::Delegate { // Start a TokenAuth request to pre-login the user with the given credentials. void StartTokenAuth(const std::string& auth_token); + // Start a MergeSession request to pre-login the user with the given + // credentials. Unlike TokenAuth above, MergeSession will not sign out any + // existing accounts. + void StartMergeSession(const std::string& auth_token); + // Implementation of URLFetcher::Delegate virtual void OnURLFetchComplete(const URLFetcher* source, const GURL& url, @@ -108,6 +113,8 @@ class GaiaAuthFetcher : public URLFetcher::Delegate { static const char kGetUserInfoFormat[]; // The format of the POST body for TokenAuth. static const char kTokenAuthFormat[]; + // The format of the POST body for MergeSession. + static const char kMergeSessionFormat[]; // Constants for parsing ClientLogin errors. static const char kAccountDeletedError[]; @@ -142,6 +149,10 @@ class GaiaAuthFetcher : public URLFetcher::Delegate { const net::URLRequestStatus& status, int response_code); + void OnMergeSessionFetched(const std::string& data, + const net::URLRequestStatus& status, + int response_code); + // Tokenize the results of a ClientLogin fetch. static void ParseClientLoginResponse(const std::string& data, std::string* sid, @@ -180,10 +191,16 @@ class GaiaAuthFetcher : public URLFetcher::Delegate { const std::string& continue_url, const std::string& source); + // Supply the authentication token returned from StartIssueAuthToken. + static std::string MakeMergeSessionBody(const std::string& auth_token, + const std::string& continue_url, + const std::string& source); + // Create a fetcher useable for making any Gaia request. static URLFetcher* CreateGaiaFetcher(net::URLRequestContextGetter* getter, const std::string& body, - const GURL& gaia_gurl_, + const GURL& gaia_gurl, + bool send_cookies, URLFetcher::Delegate* delegate); // From a URLFetcher result, generate an appropriate error. @@ -201,6 +218,7 @@ class GaiaAuthFetcher : public URLFetcher::Delegate { const GURL issue_auth_token_gurl_; const GURL get_user_info_gurl_; const GURL token_auth_gurl_; + const GURL merge_session_gurl_; // While a fetch is going on: scoped_ptr<URLFetcher> fetcher_; diff --git a/chrome/common/net/gaia/gaia_auth_fetcher_unittest.cc b/chrome/common/net/gaia/gaia_auth_fetcher_unittest.cc index 51a77a6..6f12911 100644 --- a/chrome/common/net/gaia/gaia_auth_fetcher_unittest.cc +++ b/chrome/common/net/gaia/gaia_auth_fetcher_unittest.cc @@ -21,6 +21,7 @@ #include "content/common/url_fetcher.h" #include "content/test/test_url_fetcher_factory.h" #include "googleurl/src/gurl.h" +#include "net/base/load_flags.h" #include "net/base/net_errors.h" #include "net/url_request/url_request_status.h" #include "testing/gmock/include/gmock/gmock.h" @@ -67,7 +68,8 @@ class GaiaAuthFetcherTest : public TestingBrowserProcessTest { : client_login_source_(GaiaUrls::GetInstance()->client_login_url()), issue_auth_token_source_( GaiaUrls::GetInstance()->issue_auth_token_url()), - token_auth_source_(GaiaUrls::GetInstance()->token_auth_url()) {} + token_auth_source_(GaiaUrls::GetInstance()->token_auth_url()), + merge_session_source_(GaiaUrls::GetInstance()->merge_session_url()) {} void RunParsingTest(const std::string& data, const std::string& sid, @@ -111,6 +113,7 @@ class GaiaAuthFetcherTest : public TestingBrowserProcessTest { GURL client_login_source_; GURL issue_auth_token_source_; GURL token_auth_source_; + GURL merge_session_source_; TestingProfile profile_; protected: MessageLoop message_loop_; @@ -125,11 +128,14 @@ class MockGaiaConsumer : public GaiaAuthConsumer { MOCK_METHOD2(OnIssueAuthTokenSuccess, void(const std::string& service, const std::string& token)); MOCK_METHOD1(OnTokenAuthSuccess, void(const std::string& data)); + MOCK_METHOD1(OnMergeSessionSuccess, void(const std::string& data)); MOCK_METHOD1(OnClientLoginFailure, void(const GoogleServiceAuthError& error)); MOCK_METHOD2(OnIssueAuthTokenFailure, void(const std::string& service, const GoogleServiceAuthError& error)); MOCK_METHOD1(OnTokenAuthFailure, void(const GoogleServiceAuthError& error)); + MOCK_METHOD1(OnMergeSessionFailure, void( + const GoogleServiceAuthError& error)); }; TEST_F(GaiaAuthFetcherTest, ErrorComparator) { @@ -592,3 +598,58 @@ TEST_F(GaiaAuthFetcherTest, TokenAuthNetFailure) { ""); EXPECT_FALSE(auth.HasPendingFetch()); } + +TEST_F(GaiaAuthFetcherTest, MergeSessionSuccess) { + MockGaiaConsumer consumer; + EXPECT_CALL(consumer, OnMergeSessionSuccess("<html></html>")) + .Times(1); + + TestingProfile profile; + TestURLFetcherFactory factory; + + GaiaAuthFetcher auth(&consumer, std::string(), + profile_.GetRequestContext()); + auth.StartMergeSession("myubertoken"); + + EXPECT_TRUE(auth.HasPendingFetch()); + auth.OnURLFetchComplete( + NULL, + merge_session_source_, + net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0), + RC_REQUEST_OK, + cookies_, + "<html></html>"); + EXPECT_FALSE(auth.HasPendingFetch()); +} + +TEST_F(GaiaAuthFetcherTest, MergeSessionSuccessRedirect) { + MockGaiaConsumer consumer; + EXPECT_CALL(consumer, OnMergeSessionSuccess("<html></html>")) + .Times(1); + + TestingProfile profile; + TestURLFetcherFactory factory; + + GaiaAuthFetcher auth(&consumer, std::string(), + profile_.GetRequestContext()); + auth.StartMergeSession("myubertoken"); + + // Make sure the fetcher created has the expected flags. Set its url() + // properties to reflect a redirect. + TestURLFetcher* test_fetcher = factory.GetFetcherByID(0); + EXPECT_TRUE(test_fetcher != NULL); + EXPECT_TRUE(test_fetcher->load_flags() == net::LOAD_NORMAL); + EXPECT_TRUE(auth.HasPendingFetch()); + + GURL final_url("http://www.google.com/CheckCookie"); + test_fetcher->set_url(final_url); + + auth.OnURLFetchComplete( + test_fetcher, + test_fetcher->url(), + net::URLRequestStatus(net::URLRequestStatus::SUCCESS, 0), + RC_REQUEST_OK, + cookies_, + "<html></html>"); + EXPECT_FALSE(auth.HasPendingFetch()); +} diff --git a/chrome/common/net/gaia/gaia_urls.cc b/chrome/common/net/gaia/gaia_urls.cc index cf64fb5..ca06741 100644 --- a/chrome/common/net/gaia/gaia_urls.cc +++ b/chrome/common/net/gaia/gaia_urls.cc @@ -15,6 +15,7 @@ const char kClientLoginUrlSuffix[] = "/accounts/ClientLogin"; const char kIssueAuthTokenUrlSuffix[] = "/accounts/IssueAuthToken"; const char kGetUserInfoUrlSuffix[] = "/accounts/GetUserInfo"; const char kTokenAuthUrlSuffix[] = "/accounts/TokenAuth"; +const char kMergeSessionUrlSuffix[] = "/accounts/MergeSession"; } // namespacce @@ -35,6 +36,7 @@ GaiaUrls::GaiaUrls() { issue_auth_token_url_ = "https://" + host_base_ + kIssueAuthTokenUrlSuffix; get_user_info_url_ = "https://" + host_base_ + kGetUserInfoUrlSuffix; token_auth_url_ = "https://" + host_base_ + kTokenAuthUrlSuffix; + merge_session_url_ = "https://" + host_base_ + kMergeSessionUrlSuffix; } GaiaUrls::~GaiaUrls() { @@ -59,3 +61,7 @@ const std::string& GaiaUrls::get_user_info_url() { const std::string& GaiaUrls::token_auth_url() { return token_auth_url_; } + +const std::string& GaiaUrls::merge_session_url() { + return merge_session_url_; +} diff --git a/chrome/common/net/gaia/gaia_urls.h b/chrome/common/net/gaia/gaia_urls.h index 327110d..c82823a 100644 --- a/chrome/common/net/gaia/gaia_urls.h +++ b/chrome/common/net/gaia/gaia_urls.h @@ -21,6 +21,7 @@ class GaiaUrls { const std::string& issue_auth_token_url(); const std::string& get_user_info_url(); const std::string& token_auth_url(); + const std::string& merge_session_url(); private: GaiaUrls(); @@ -34,6 +35,7 @@ class GaiaUrls { std::string issue_auth_token_url_; std::string get_user_info_url_; std::string token_auth_url_; + std::string merge_session_url_; DISALLOW_COPY_AND_ASSIGN(GaiaUrls); }; diff --git a/content/common/url_fetcher.cc b/content/common/url_fetcher.cc index 7f1f0c3..bb066a8 100644 --- a/content/common/url_fetcher.cc +++ b/content/common/url_fetcher.cc @@ -1029,6 +1029,10 @@ void URLFetcher::StartWithRequestContextGetter( core_->Start(); } +const GURL& URLFetcher::original_url() const { + return core_->original_url_; +} + const GURL& URLFetcher::url() const { return core_->url_; } diff --git a/content/common/url_fetcher.h b/content/common/url_fetcher.h index a888868..b3cee3b 100644 --- a/content/common/url_fetcher.h +++ b/content/common/url_fetcher.h @@ -220,6 +220,9 @@ class URLFetcher { void StartWithRequestContextGetter( net::URLRequestContextGetter* request_context_getter); + // Return the URL that we were asked to fetch. + virtual const GURL& original_url() const; + // Return the URL that this fetcher is processing. virtual const GURL& url() const; diff --git a/content/test/test_url_fetcher_factory.cc b/content/test/test_url_fetcher_factory.cc index ad6e512..d95fbf2 100644 --- a/content/test/test_url_fetcher_factory.cc +++ b/content/test/test_url_fetcher_factory.cc @@ -40,6 +40,10 @@ void TestURLFetcher::AppendChunkToUpload(const std::string& data, chunks_.push_back(data); } +const GURL& TestURLFetcher::original_url() const { + return original_url_; +} + void TestURLFetcher::set_status(const net::URLRequestStatus& status) { fake_status_ = status; } diff --git a/content/test/test_url_fetcher_factory.h b/content/test/test_url_fetcher_factory.h index f402875..8b60fd7 100644 --- a/content/test/test_url_fetcher_factory.h +++ b/content/test/test_url_fetcher_factory.h @@ -65,7 +65,8 @@ class TestURLFetcher : public URLFetcher { // Overriden to cache the chunks uploaded. Caller can read back the uploaded // chunks with the upload_data() accessor. - virtual void AppendChunkToUpload(const std::string& data, bool is_last_chunk); + virtual void AppendChunkToUpload(const std::string& data, bool is_last_chunk) + OVERRIDE; // Unique ID in our factory. int id() const { return id_; } @@ -73,7 +74,7 @@ class TestURLFetcher : public URLFetcher { // URL we were created with. Because of how we're using URLFetcher url() // always returns an empty URL. Chances are you'll want to use original_url() // in your tests. - const GURL& original_url() const { return original_url_; } + virtual const GURL& original_url() const OVERRIDE; // Returns the data uploaded on this URLFetcher. const std::string& upload_data() const { return URLFetcher::upload_data(); } @@ -85,15 +86,15 @@ class TestURLFetcher : public URLFetcher { Delegate* delegate() const { return URLFetcher::delegate(); } void set_url(const GURL& url) { fake_url_ = url; } - virtual const GURL& url() const; + virtual const GURL& url() const OVERRIDE; void set_status(const net::URLRequestStatus& status); - virtual const net::URLRequestStatus& status() const; + virtual const net::URLRequestStatus& status() const OVERRIDE; void set_response_code(int response_code) { fake_response_code_ = response_code; } - virtual int response_code() const; + virtual int response_code() const OVERRIDE; // Set string data. void SetResponseString(const std::string& response); @@ -102,9 +103,11 @@ class TestURLFetcher : public URLFetcher { void SetResponseFilePath(const FilePath& path); // Override response access functions to return fake data. - virtual bool GetResponseAsString(std::string* out_response_string) const; + virtual bool GetResponseAsString(std::string* out_response_string) const + OVERRIDE; virtual bool GetResponseAsFilePath(bool take_ownership, - FilePath* out_response_path) const; + FilePath* out_response_path) const + OVERRIDE; private: const int id_; @@ -136,7 +139,7 @@ class TestURLFetcherFactory : public URLFetcher::Factory, virtual URLFetcher* CreateURLFetcher(int id, const GURL& url, URLFetcher::RequestType request_type, - URLFetcher::Delegate* d); + URLFetcher::Delegate* d) OVERRIDE; TestURLFetcher* GetFetcherByID(int id) const; void RemoveFetcherFromMap(int id); @@ -197,7 +200,7 @@ class FakeURLFetcherFactory : public URLFetcher::Factory, virtual URLFetcher* CreateURLFetcher(int id, const GURL& url, URLFetcher::RequestType request_type, - URLFetcher::Delegate* d); + URLFetcher::Delegate* d) OVERRIDE; // Sets the fake response for a given URL. If success is true we will serve // an HTTP/200 and an HTTP/500 otherwise. The |response_data| may be empty. @@ -230,7 +233,7 @@ class URLFetcherFactory : public URLFetcher::Factory { virtual URLFetcher* CreateURLFetcher(int id, const GURL& url, URLFetcher::RequestType request_type, - URLFetcher::Delegate* d); + URLFetcher::Delegate* d) OVERRIDE; }; |