Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / google_apis / gaia / oauth2_api_call_flow.cc
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.
4
5 #include "google_apis/gaia/oauth2_api_call_flow.h"
6
7 #include <string>
8 #include <vector>
9
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"
19
20 using net::ResponseCookies;
21 using net::URLFetcher;
22 using net::URLFetcherDelegate;
23 using net::URLRequestContextGetter;
24 using net::URLRequestStatus;
25
26 namespace {
27 static const char kAuthorizationHeaderFormat[] =
28     "Authorization: Bearer %s";
29
30 static std::string MakeAuthorizationHeader(const std::string& auth_token) {
31   return base::StringPrintf(kAuthorizationHeaderFormat, auth_token.c_str());
32 }
33 }  // namespace
34
35 OAuth2ApiCallFlow::OAuth2ApiCallFlow() : state_(INITIAL) {
36 }
37
38 OAuth2ApiCallFlow::~OAuth2ApiCallFlow() {}
39
40 void OAuth2ApiCallFlow::Start(net::URLRequestContextGetter* context,
41                               const std::string& access_token) {
42   CHECK(state_ == INITIAL);
43   state_ = API_CALL_STARTED;
44
45   url_fetcher_.reset(CreateURLFetcher(context, access_token));
46   url_fetcher_->Start();  // OnURLFetchComplete will be called.
47 }
48
49 void OAuth2ApiCallFlow::EndApiCall(const net::URLFetcher* source) {
50   CHECK_EQ(API_CALL_STARTED, state_);
51
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)) {
56     state_ = ERROR_STATE;
57     ProcessApiCallFailure(source);
58   } else {
59     state_ = API_CALL_DONE;
60     ProcessApiCallSuccess(source);
61   }
62 }
63
64 std::string OAuth2ApiCallFlow::CreateApiCallBodyContentType() {
65   return "application/x-www-form-urlencoded";
66 }
67
68 void OAuth2ApiCallFlow::OnURLFetchComplete(const net::URLFetcher* source) {
69   CHECK(source);
70   CHECK_EQ(API_CALL_STARTED, state_);
71   EndApiCall(source);
72 }
73
74 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   URLFetcher* result = net::URLFetcher::Create(
80       0,
81       CreateApiCallUrl(),
82       empty_body ? URLFetcher::GET : URLFetcher::POST,
83       this);
84
85   result->SetRequestContext(context);
86   result->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES |
87                        net::LOAD_DO_NOT_SAVE_COOKIES);
88   result->AddExtraRequestHeader(MakeAuthorizationHeader(access_token));
89   // Fetchers are sometimes cancelled because a network change was detected,
90   // especially at startup and after sign-in on ChromeOS. Retrying once should
91   // be enough in those cases; let the fetcher retry up to 3 times just in case.
92   // http://crbug.com/163710
93   result->SetAutomaticallyRetryOnNetworkChanges(3);
94
95   if (!empty_body)
96     result->SetUploadData(CreateApiCallBodyContentType(), body);
97
98   return result;
99 }