Extract SIGPIPE ignoring code to a common place.
[chromium-blink-merge.git] / google_apis / gaia / oauth2_revocation_fetcher.cc
blob2a4bae54a7cdb081d7a0f0322cdab694484c2511
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_revocation_fetcher.h"
7 #include <algorithm>
8 #include <string>
9 #include <vector>
11 #include "base/json/json_reader.h"
12 #include "base/string_util.h"
13 #include "base/stringprintf.h"
14 #include "base/values.h"
15 #include "google_apis/gaia/gaia_urls.h"
16 #include "google_apis/gaia/google_service_auth_error.h"
17 #include "net/base/escape.h"
18 #include "net/base/load_flags.h"
19 #include "net/http/http_status_code.h"
20 #include "net/url_request/url_fetcher.h"
21 #include "net/url_request/url_request_context_getter.h"
22 #include "net/url_request/url_request_status.h"
24 using net::ResponseCookies;
25 using net::URLFetcher;
26 using net::URLFetcherDelegate;
27 using net::URLRequestContextGetter;
28 using net::URLRequestStatus;
30 namespace {
31 static const char kOAuth2RevokeTokenURL[] =
32 "https://www.googleapis.com/oauth2/v2/RevokeToken";
34 static const char kAuthorizationHeaderFormat[] =
35 "Authorization: Bearer %s";
37 static const char kRevocationBodyFormat[] =
38 "client_id=%s&origin=%s";
40 static GoogleServiceAuthError CreateAuthError(URLRequestStatus status) {
41 CHECK(!status.is_success());
42 if (status.status() == URLRequestStatus::CANCELED) {
43 return GoogleServiceAuthError(GoogleServiceAuthError::REQUEST_CANCELED);
44 } else {
45 DLOG(WARNING) << "Could not reach Google Accounts servers: errno "
46 << status.error();
47 return GoogleServiceAuthError::FromConnectionError(status.error());
51 static URLFetcher* CreateFetcher(URLRequestContextGetter* getter,
52 const GURL& url,
53 const std::string& header,
54 const std::string& body,
55 URLFetcherDelegate* delegate) {
56 bool empty_body = body.empty();
57 URLFetcher* result = net::URLFetcher::Create(
58 0, url,
59 empty_body ? URLFetcher::GET : URLFetcher::POST,
60 delegate);
62 result->SetRequestContext(getter);
63 result->SetLoadFlags(net::LOAD_DO_NOT_SEND_COOKIES |
64 net::LOAD_DO_NOT_SAVE_COOKIES);
65 if (!header.empty())
66 result->SetExtraRequestHeaders(header);
68 if (!empty_body)
69 result->SetUploadData("application/x-www-form-urlencoded", body);
71 return result;
73 } // namespace
75 OAuth2RevocationFetcher::OAuth2RevocationFetcher(
76 OAuth2RevocationConsumer* consumer,
77 URLRequestContextGetter* getter)
78 : consumer_(consumer),
79 getter_(getter),
80 state_(INITIAL) { }
82 OAuth2RevocationFetcher::~OAuth2RevocationFetcher() { }
84 void OAuth2RevocationFetcher::CancelRequest() {
85 fetcher_.reset();
88 void OAuth2RevocationFetcher::Start(const std::string& access_token,
89 const std::string& client_id,
90 const std::string& origin) {
91 access_token_ = access_token;
92 client_id_ = client_id;
93 origin_ = origin;
94 StartRevocation();
97 void OAuth2RevocationFetcher::StartRevocation() {
98 CHECK_EQ(INITIAL, state_);
99 state_ = REVOCATION_STARTED;
100 fetcher_.reset(CreateFetcher(
101 getter_,
102 MakeRevocationUrl(),
103 MakeRevocationHeader(access_token_),
104 MakeRevocationBody(client_id_, origin_),
105 this));
106 fetcher_->Start(); // OnURLFetchComplete will be called.
109 void OAuth2RevocationFetcher::EndRevocation(const net::URLFetcher* source) {
110 CHECK_EQ(REVOCATION_STARTED, state_);
111 state_ = REVOCATION_DONE;
113 URLRequestStatus status = source->GetStatus();
114 if (!status.is_success()) {
115 OnRevocationFailure(CreateAuthError(status));
116 return;
119 if (source->GetResponseCode() != net::HTTP_NO_CONTENT) {
120 OnRevocationFailure(GoogleServiceAuthError(
121 GoogleServiceAuthError::INVALID_GAIA_CREDENTIALS));
122 return;
125 OnRevocationSuccess();
128 void OAuth2RevocationFetcher::OnRevocationSuccess() {
129 consumer_->OnRevocationSuccess();
132 void OAuth2RevocationFetcher::OnRevocationFailure(
133 const GoogleServiceAuthError& error) {
134 state_ = ERROR_STATE;
135 consumer_->OnRevocationFailure(error);
138 void OAuth2RevocationFetcher::OnURLFetchComplete(
139 const net::URLFetcher* source) {
140 CHECK(source);
141 EndRevocation(source);
144 // static
145 GURL OAuth2RevocationFetcher::MakeRevocationUrl() {
146 return GURL(kOAuth2RevokeTokenURL);
149 // static
150 std::string OAuth2RevocationFetcher::MakeRevocationHeader(
151 const std::string& access_token) {
152 return StringPrintf(kAuthorizationHeaderFormat, access_token.c_str());
155 // static
156 std::string OAuth2RevocationFetcher::MakeRevocationBody(
157 const std::string& client_id,
158 const std::string& origin) {
159 std::string enc_client_id = net::EscapeUrlEncodedData(client_id, true);
160 std::string enc_origin = net::EscapeUrlEncodedData(origin, true);
161 return StringPrintf(
162 kRevocationBodyFormat,
163 enc_client_id.c_str(),
164 enc_origin.c_str());