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/strings/stringprintf.h"
12 #include "google_apis/gaia/gaia_urls.h"
13 #include "net/base/escape.h"
14 #include "net/base/load_flags.h"
15 #include "net/http/http_status_code.h"
16 #include "net/url_request/url_fetcher.h"
17 #include "net/url_request/url_request_context_getter.h"
18 #include "net/url_request/url_request_status.h"
20 using net::ResponseCookies
;
21 using net::URLFetcher
;
22 using net::URLFetcherDelegate
;
23 using net::URLRequestContextGetter
;
24 using net::URLRequestStatus
;
27 static const char kAuthorizationHeaderFormat
[] =
28 "Authorization: Bearer %s";
30 static std::string
MakeAuthorizationHeader(const std::string
& auth_token
) {
31 return base::StringPrintf(kAuthorizationHeaderFormat
, auth_token
.c_str());
35 OAuth2ApiCallFlow::OAuth2ApiCallFlow() : state_(INITIAL
) {
38 OAuth2ApiCallFlow::~OAuth2ApiCallFlow() {}
40 void OAuth2ApiCallFlow::Start(net::URLRequestContextGetter
* context
,
41 const std::string
& access_token
) {
42 CHECK(state_
== INITIAL
);
43 state_
= API_CALL_STARTED
;
45 url_fetcher_
= CreateURLFetcher(context
, access_token
);
46 url_fetcher_
->Start(); // OnURLFetchComplete will be called.
49 void OAuth2ApiCallFlow::EndApiCall(const net::URLFetcher
* source
) {
50 CHECK_EQ(API_CALL_STARTED
, state_
);
52 URLRequestStatus status
= source
->GetStatus();
53 int status_code
= source
->GetResponseCode();
54 if (!status
.is_success() ||
55 (status_code
!= net::HTTP_OK
&& status_code
!= net::HTTP_NO_CONTENT
)) {
57 ProcessApiCallFailure(source
);
59 state_
= API_CALL_DONE
;
60 ProcessApiCallSuccess(source
);
64 std::string
OAuth2ApiCallFlow::CreateApiCallBodyContentType() {
65 return "application/x-www-form-urlencoded";
68 void OAuth2ApiCallFlow::OnURLFetchComplete(const net::URLFetcher
* source
) {
70 CHECK_EQ(API_CALL_STARTED
, state_
);
74 scoped_ptr
<URLFetcher
> OAuth2ApiCallFlow::CreateURLFetcher(
75 net::URLRequestContextGetter
* context
,
76 const std::string
& access_token
) {
77 std::string body
= CreateApiCallBody();
78 bool empty_body
= body
.empty();
79 scoped_ptr
<URLFetcher
> result
= net::URLFetcher::Create(
80 0, CreateApiCallUrl(), empty_body
? URLFetcher::GET
: URLFetcher::POST
,
83 result
->SetRequestContext(context
);
84 result
->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES
|
85 net::LOAD_DO_NOT_SAVE_COOKIES
);
86 result
->AddExtraRequestHeader(MakeAuthorizationHeader(access_token
));
87 // Fetchers are sometimes cancelled because a network change was detected,
88 // especially at startup and after sign-in on ChromeOS. Retrying once should
89 // be enough in those cases; let the fetcher retry up to 3 times just in case.
90 // http://crbug.com/163710
91 result
->SetAutomaticallyRetryOnNetworkChanges(3);
94 result
->SetUploadData(CreateApiCallBodyContentType(), body
);