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
3 // found in the LICENSE file.
5 #include "google_apis/gaia/oauth2_api_call_flow.h"
10 #include "base/basictypes.h"
11 #include "base/profiler/scoped_tracker.h"
12 #include "base/strings/stringprintf.h"
13 #include "google_apis/gaia/gaia_urls.h"
14 #include "net/base/escape.h"
15 #include "net/base/load_flags.h"
16 #include "net/http/http_status_code.h"
17 #include "net/url_request/url_fetcher.h"
18 #include "net/url_request/url_request_context_getter.h"
19 #include "net/url_request/url_request_status.h"
21 using net::ResponseCookies
;
22 using net::URLFetcher
;
23 using net::URLFetcherDelegate
;
24 using net::URLRequestContextGetter
;
25 using net::URLRequestStatus
;
28 static const char kAuthorizationHeaderFormat
[] =
29 "Authorization: Bearer %s";
31 static std::string
MakeAuthorizationHeader(const std::string
& auth_token
) {
32 return base::StringPrintf(kAuthorizationHeaderFormat
, auth_token
.c_str());
36 OAuth2ApiCallFlow::OAuth2ApiCallFlow() : state_(INITIAL
) {
39 OAuth2ApiCallFlow::~OAuth2ApiCallFlow() {}
41 void OAuth2ApiCallFlow::Start(net::URLRequestContextGetter
* context
,
42 const std::string
& access_token
) {
43 CHECK(state_
== INITIAL
);
44 state_
= API_CALL_STARTED
;
46 url_fetcher_
.reset(CreateURLFetcher(context
, access_token
));
47 url_fetcher_
->Start(); // OnURLFetchComplete will be called.
50 void OAuth2ApiCallFlow::EndApiCall(const net::URLFetcher
* source
) {
51 CHECK_EQ(API_CALL_STARTED
, state_
);
53 URLRequestStatus status
= source
->GetStatus();
54 int status_code
= source
->GetResponseCode();
55 if (!status
.is_success() ||
56 (status_code
!= net::HTTP_OK
&& status_code
!= net::HTTP_NO_CONTENT
)) {
58 ProcessApiCallFailure(source
);
60 state_
= API_CALL_DONE
;
61 ProcessApiCallSuccess(source
);
65 std::string
OAuth2ApiCallFlow::CreateApiCallBodyContentType() {
66 return "application/x-www-form-urlencoded";
69 void OAuth2ApiCallFlow::OnURLFetchComplete(const net::URLFetcher
* source
) {
70 // TODO(vadimt): Remove ScopedTracker below once crbug.com/422577 is fixed.
71 tracked_objects::ScopedTracker
tracking_profile(
72 FROM_HERE_WITH_EXPLICIT_FUNCTION(
73 "422577 OAuth2ApiCallFlow::OnURLFetchComplete"));
76 CHECK_EQ(API_CALL_STARTED
, state_
);
80 URLFetcher
* OAuth2ApiCallFlow::CreateURLFetcher(
81 net::URLRequestContextGetter
* context
,
82 const std::string
& access_token
) {
83 std::string body
= CreateApiCallBody();
84 bool empty_body
= body
.empty();
85 URLFetcher
* result
= net::URLFetcher::Create(
88 empty_body
? URLFetcher::GET
: URLFetcher::POST
,
91 result
->SetRequestContext(context
);
92 result
->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES
|
93 net::LOAD_DO_NOT_SAVE_COOKIES
);
94 result
->AddExtraRequestHeader(MakeAuthorizationHeader(access_token
));
95 // Fetchers are sometimes cancelled because a network change was detected,
96 // especially at startup and after sign-in on ChromeOS. Retrying once should
97 // be enough in those cases; let the fetcher retry up to 3 times just in case.
98 // http://crbug.com/163710
99 result
->SetAutomaticallyRetryOnNetworkChanges(3);
102 result
->SetUploadData(CreateApiCallBodyContentType(), body
);