Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(913)

Side by Side Diff: services/authenticating_url_loader/authenticating_url_loader_impl.cc

Issue 1155283003: Change AuthenticatingURLLoader to be a URLLoaderInterceptor (Closed) Base URL: https://github.com/domokit/mojo.git@master
Patch Set: Address review Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2014 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 "services/authenticating_url_loader/authenticating_url_loader_impl.h"
6
7 #include "base/bind.h"
8 #include "base/logging.h"
9 #include "mojo/services/network/public/interfaces/network_service.mojom.h"
10
11 namespace mojo {
12
13 AuthenticatingURLLoaderImpl::AuthenticatingURLLoaderImpl(
14 InterfaceRequest<AuthenticatingURLLoader> request,
15 AuthenticatingURLLoaderFactoryImpl* factory)
16 : binding_(this, request.Pass()),
17 factory_(factory),
18 request_authorization_state_(REQUEST_INITIAL) {
19 binding_.set_error_handler(this);
20 }
21
22 AuthenticatingURLLoaderImpl::~AuthenticatingURLLoaderImpl() {
23 }
24
25 void AuthenticatingURLLoaderImpl::Start(
26 URLRequestPtr request,
27 const Callback<void(URLResponsePtr)>& callback) {
28 // TODO(blundell): If we need to handle requests with bodies, we'll need to
29 // do something here.
30 if (request->body) {
31 LOG(ERROR)
32 << "Cannot pass a request to AuthenticatingURLLoader that has a body";
33 callback.Run(nullptr);
34 return;
35 }
36 url_ = GURL(request->url);
37 auto_follow_redirects_ = request->auto_follow_redirects;
38 bypass_cache_ = request->bypass_cache;
39 headers_ = request->headers.Clone();
40 pending_request_callback_ = callback;
41 std::string token = factory_->GetCachedToken(url_);
42 if (token != "") {
43 auto auth_header = HttpHeader::New();
44 auth_header->name = "Authorization";
45 auth_header->value = "Bearer " + token;
46 request->headers.push_back(auth_header.Pass());
47 }
48 StartNetworkRequest(request.Pass());
49 }
50
51 void AuthenticatingURLLoaderImpl::FollowRedirect(
52 const Callback<void(URLResponsePtr)>& callback) {
53 mojo::String error;
54
55 if (!url_.is_valid() || !url_loader_) {
56 error = "No redirect to follow";
57 }
58
59 if (auto_follow_redirects_) {
60 error =
61 "FollowRedirect() should not be "
62 "called when auto_follow_redirects has been set";
63 }
64
65 if (request_authorization_state_ != REQUEST_INITIAL) {
66 error = "Not in the right state to follow a redirect";
67 }
68
69 if (!error.is_null()) {
70 LOG(ERROR) << "AuthenticatingURLLoader: " << error;
71 callback.Run(nullptr);
72 return;
73 }
74
75 pending_request_callback_ = callback;
76 FollowRedirectInternal();
77 }
78
79 void AuthenticatingURLLoaderImpl::StartNetworkRequest(URLRequestPtr request) {
80 factory_->network_service()->CreateURLLoader(mojo::GetProxy(&url_loader_));
81 url_loader_->Start(request.Pass(),
82 base::Bind(&AuthenticatingURLLoaderImpl::OnLoadComplete,
83 base::Unretained(this)));
84 }
85
86 void AuthenticatingURLLoaderImpl::OnConnectionError() {
87 factory_->OnURLLoaderError(this);
88 // The factory deleted this object.
89 }
90
91 void AuthenticatingURLLoaderImpl::OnLoadComplete(URLResponsePtr response) {
92 if (response->redirect_url) {
93 url_ = GURL(response->redirect_url);
94 request_authorization_state_ = REQUEST_INITIAL;
95
96 if (auto_follow_redirects_) {
97 FollowRedirectInternal();
98 } else {
99 // NOTE: We do not reset |url_loader_| here as it will be needed if the
100 // client calls |FollowRedirect()|.
101 pending_request_callback_.Run(response.Pass());
102 }
103 return;
104 }
105
106 url_loader_.reset();
107
108 if (response->status_code != 401 ||
109 request_authorization_state_ == REQUEST_USED_FRESH_AUTH_SERVICE_TOKEN) {
110 pending_request_callback_.Run(response.Pass());
111 return;
112 }
113
114 pending_response_ = response.Pass();
115
116 DCHECK(request_authorization_state_ == REQUEST_INITIAL ||
117 request_authorization_state_ ==
118 REQUEST_USED_CURRENT_AUTH_SERVICE_TOKEN);
119 if (request_authorization_state_ == REQUEST_INITIAL) {
120 request_authorization_state_ = REQUEST_USED_CURRENT_AUTH_SERVICE_TOKEN;
121 } else {
122 request_authorization_state_ = REQUEST_USED_FRESH_AUTH_SERVICE_TOKEN;
123 }
124 factory_->RetrieveToken(
125 url_, base::Bind(&AuthenticatingURLLoaderImpl::OnOAuth2TokenReceived,
126 base::Unretained(this)));
127 return;
128 }
129
130 void AuthenticatingURLLoaderImpl::FollowRedirectInternal() {
131 DCHECK(url_.is_valid());
132 DCHECK(url_loader_);
133 DCHECK(request_authorization_state_ == REQUEST_INITIAL);
134
135 url_loader_->FollowRedirect(base::Bind(
136 &AuthenticatingURLLoaderImpl::OnLoadComplete, base::Unretained(this)));
137 }
138
139 void AuthenticatingURLLoaderImpl::OnOAuth2TokenReceived(std::string token) {
140 if (token.empty()) {
141 LOG(ERROR) << "Error while getting token";
142 pending_request_callback_.Run(pending_response_.Pass());
143 return;
144 }
145
146 auto auth_header = HttpHeader::New();
147 auth_header->name = "Authorization";
148 auth_header->value = "Bearer " + token;
149 Array<HttpHeaderPtr> headers;
150 if (headers_)
151 headers = headers_.Clone();
152 headers.push_back(auth_header.Pass());
153
154 URLRequestPtr request(mojo::URLRequest::New());
155 request->url = url_.spec();
156 request->auto_follow_redirects = false;
157 request->bypass_cache = bypass_cache_;
158 request->headers = headers.Pass();
159
160 StartNetworkRequest(request.Pass());
161 }
162
163 } // namespace mojo
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698