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

Side by Side Diff: net/http/http_proxy_client_socket_pool.cc

Issue 9148011: Allow chrome to handle 407 auth challenges to CONNECT requests (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: '' Created 8 years, 11 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 | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/http/http_proxy_client_socket_pool.h" 5 #include "net/http/http_proxy_client_socket_pool.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/time.h" 9 #include "base/time.h"
10 #include "base/values.h" 10 #include "base/values.h"
(...skipping 10 matching lines...) Expand all
21 #include "net/socket/ssl_client_socket_pool.h" 21 #include "net/socket/ssl_client_socket_pool.h"
22 #include "net/socket/transport_client_socket_pool.h" 22 #include "net/socket/transport_client_socket_pool.h"
23 #include "net/spdy/spdy_proxy_client_socket.h" 23 #include "net/spdy/spdy_proxy_client_socket.h"
24 #include "net/spdy/spdy_session.h" 24 #include "net/spdy/spdy_session.h"
25 #include "net/spdy/spdy_session_pool.h" 25 #include "net/spdy/spdy_session_pool.h"
26 #include "net/spdy/spdy_settings_storage.h" 26 #include "net/spdy/spdy_settings_storage.h"
27 #include "net/spdy/spdy_stream.h" 27 #include "net/spdy/spdy_stream.h"
28 28
29 namespace net { 29 namespace net {
30 30
31 namespace {
32
33 std::string GetProxyUrl(const scoped_refptr<HttpProxySocketParams>& params) {
34 return (params->ssl_params() != NULL ? "https://" : "http://")
35 + params->destination().host_port_pair().ToString();
36 }
37
38 } // namespace
39
31 HttpProxySocketParams::HttpProxySocketParams( 40 HttpProxySocketParams::HttpProxySocketParams(
32 const scoped_refptr<TransportSocketParams>& transport_params, 41 const scoped_refptr<TransportSocketParams>& transport_params,
33 const scoped_refptr<SSLSocketParams>& ssl_params, 42 const scoped_refptr<SSLSocketParams>& ssl_params,
34 const GURL& request_url, 43 const GURL& request_url,
35 const std::string& user_agent, 44 const std::string& user_agent,
36 HostPortPair endpoint, 45 HostPortPair endpoint,
37 HttpAuthCache* http_auth_cache, 46 HttpAuthCache* http_auth_cache,
38 HttpAuthHandlerFactory* http_auth_handler_factory, 47 HttpAuthHandlerFactory* http_auth_handler_factory,
39 SpdySessionPool* spdy_session_pool, 48 SpdySessionPool* spdy_session_pool,
40 bool tunnel) 49 bool tunnel,
50 TunnelAuthCallback auth_needed_callback)
41 : transport_params_(transport_params), 51 : transport_params_(transport_params),
42 ssl_params_(ssl_params), 52 ssl_params_(ssl_params),
43 spdy_session_pool_(spdy_session_pool), 53 spdy_session_pool_(spdy_session_pool),
44 request_url_(request_url), 54 request_url_(request_url),
45 user_agent_(user_agent), 55 user_agent_(user_agent),
46 endpoint_(endpoint), 56 endpoint_(endpoint),
47 http_auth_cache_(tunnel ? http_auth_cache : NULL), 57 http_auth_cache_(tunnel ? http_auth_cache : NULL),
48 http_auth_handler_factory_(tunnel ? http_auth_handler_factory : NULL), 58 http_auth_handler_factory_(tunnel ? http_auth_handler_factory : NULL),
49 tunnel_(tunnel) { 59 tunnel_(tunnel),
60 auth_needed_callback_(auth_needed_callback) {
50 DCHECK((transport_params == NULL && ssl_params != NULL) || 61 DCHECK((transport_params == NULL && ssl_params != NULL) ||
51 (transport_params != NULL && ssl_params == NULL)); 62 (transport_params != NULL && ssl_params == NULL));
52 if (transport_params_) 63 if (transport_params_)
53 ignore_limits_ = transport_params->ignore_limits(); 64 ignore_limits_ = transport_params->ignore_limits();
54 else 65 else
55 ignore_limits_ = ssl_params->ignore_limits(); 66 ignore_limits_ = ssl_params->ignore_limits();
56 } 67 }
57 68
58 const HostResolver::RequestInfo& HttpProxySocketParams::destination() const { 69 const HostResolver::RequestInfo& HttpProxySocketParams::destination() const {
59 if (transport_params_ == NULL) 70 if (transport_params_ == NULL)
(...skipping 20 matching lines...) Expand all
80 : ConnectJob(group_name, timeout_duration, delegate, 91 : ConnectJob(group_name, timeout_duration, delegate,
81 BoundNetLog::Make(net_log, NetLog::SOURCE_CONNECT_JOB)), 92 BoundNetLog::Make(net_log, NetLog::SOURCE_CONNECT_JOB)),
82 params_(params), 93 params_(params),
83 transport_pool_(transport_pool), 94 transport_pool_(transport_pool),
84 ssl_pool_(ssl_pool), 95 ssl_pool_(ssl_pool),
85 resolver_(host_resolver), 96 resolver_(host_resolver),
86 ALLOW_THIS_IN_INITIALIZER_LIST( 97 ALLOW_THIS_IN_INITIALIZER_LIST(
87 callback_(base::Bind(&HttpProxyConnectJob::OnIOComplete, 98 callback_(base::Bind(&HttpProxyConnectJob::OnIOComplete,
88 base::Unretained(this)))), 99 base::Unretained(this)))),
89 using_spdy_(false), 100 using_spdy_(false),
90 protocol_negotiated_(SSLClientSocket::kProtoUnknown) { 101 protocol_negotiated_(SSLClientSocket::kProtoUnknown),
102 auth_(params->tunnel() ?
103 new HttpAuthController(HttpAuth::AUTH_PROXY,
104 GURL(GetProxyUrl(params_)),
105 params->http_auth_cache(),
106 params->http_auth_handler_factory())
107 : NULL),
108 ALLOW_THIS_IN_INITIALIZER_LIST(ptr_factory_(this)) {
91 } 109 }
92 110
93 HttpProxyConnectJob::~HttpProxyConnectJob() {} 111 HttpProxyConnectJob::~HttpProxyConnectJob() {}
94 112
95 LoadState HttpProxyConnectJob::GetLoadState() const { 113 LoadState HttpProxyConnectJob::GetLoadState() const {
96 switch (next_state_) { 114 switch (next_state_) {
97 case STATE_TCP_CONNECT: 115 case STATE_TCP_CONNECT:
98 case STATE_TCP_CONNECT_COMPLETE: 116 case STATE_TCP_CONNECT_COMPLETE:
99 case STATE_SSL_CONNECT: 117 case STATE_SSL_CONNECT:
100 case STATE_SSL_CONNECT_COMPLETE: 118 case STATE_SSL_CONNECT_COMPLETE:
101 return transport_socket_handle_->GetLoadState(); 119 return transport_socket_handle_->GetLoadState();
102 case STATE_HTTP_PROXY_CONNECT: 120 case STATE_HTTP_PROXY_CONNECT:
103 case STATE_HTTP_PROXY_CONNECT_COMPLETE: 121 case STATE_HTTP_PROXY_CONNECT_COMPLETE:
104 case STATE_SPDY_PROXY_CREATE_STREAM: 122 case STATE_SPDY_PROXY_CREATE_STREAM:
105 case STATE_SPDY_PROXY_CREATE_STREAM_COMPLETE: 123 case STATE_SPDY_PROXY_CREATE_STREAM_COMPLETE:
124 case STATE_RESTART_WITH_AUTH:
125 case STATE_RESTART_WITH_AUTH_COMPLETE:
106 return LOAD_STATE_ESTABLISHING_PROXY_TUNNEL; 126 return LOAD_STATE_ESTABLISHING_PROXY_TUNNEL;
107 default: 127 default:
108 NOTREACHED(); 128 NOTREACHED();
109 return LOAD_STATE_IDLE; 129 return LOAD_STATE_IDLE;
110 } 130 }
111 } 131 }
112 132
113 void HttpProxyConnectJob::GetAdditionalErrorState(ClientSocketHandle * handle) { 133 void HttpProxyConnectJob::GetAdditionalErrorState(ClientSocketHandle * handle) {
114 if (error_response_info_.cert_request_info) { 134 if (error_response_info_.cert_request_info) {
115 handle->set_ssl_error_response_info(error_response_info_); 135 handle->set_ssl_error_response_info(error_response_info_);
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
152 case STATE_HTTP_PROXY_CONNECT_COMPLETE: 172 case STATE_HTTP_PROXY_CONNECT_COMPLETE:
153 rv = DoHttpProxyConnectComplete(rv); 173 rv = DoHttpProxyConnectComplete(rv);
154 break; 174 break;
155 case STATE_SPDY_PROXY_CREATE_STREAM: 175 case STATE_SPDY_PROXY_CREATE_STREAM:
156 DCHECK_EQ(OK, rv); 176 DCHECK_EQ(OK, rv);
157 rv = DoSpdyProxyCreateStream(); 177 rv = DoSpdyProxyCreateStream();
158 break; 178 break;
159 case STATE_SPDY_PROXY_CREATE_STREAM_COMPLETE: 179 case STATE_SPDY_PROXY_CREATE_STREAM_COMPLETE:
160 rv = DoSpdyProxyCreateStreamComplete(rv); 180 rv = DoSpdyProxyCreateStreamComplete(rv);
161 break; 181 break;
182 case STATE_RESTART_WITH_AUTH:
183 DCHECK_EQ(OK, rv);
184 rv = DoRestartWithAuth();
185 break;
186 case STATE_RESTART_WITH_AUTH_COMPLETE:
187 rv = DoRestartWithAuthComplete(rv);
188 break;
162 default: 189 default:
163 NOTREACHED() << "bad state"; 190 NOTREACHED() << "bad state";
164 rv = ERR_FAILED; 191 rv = ERR_FAILED;
165 break; 192 break;
166 } 193 }
167 } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE); 194 } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE);
168 195
169 return rv; 196 return rv;
170 } 197 }
171 198
(...skipping 87 matching lines...) Expand 10 before | Expand all | Expand 10 after
259 const HostResolver::RequestInfo& tcp_destination = params_->destination(); 286 const HostResolver::RequestInfo& tcp_destination = params_->destination();
260 const HostPortPair& proxy_server = tcp_destination.host_port_pair(); 287 const HostPortPair& proxy_server = tcp_destination.host_port_pair();
261 288
262 // Add a HttpProxy connection on top of the tcp socket. 289 // Add a HttpProxy connection on top of the tcp socket.
263 transport_socket_.reset( 290 transport_socket_.reset(
264 new HttpProxyClientSocket(transport_socket_handle_.release(), 291 new HttpProxyClientSocket(transport_socket_handle_.release(),
265 params_->request_url(), 292 params_->request_url(),
266 params_->user_agent(), 293 params_->user_agent(),
267 params_->endpoint(), 294 params_->endpoint(),
268 proxy_server, 295 proxy_server,
269 params_->http_auth_cache(), 296 auth_,
270 params_->http_auth_handler_factory(),
271 params_->tunnel(), 297 params_->tunnel(),
272 using_spdy_, 298 using_spdy_,
273 protocol_negotiated_, 299 protocol_negotiated_,
274 params_->ssl_params() != NULL)); 300 params_->ssl_params() != NULL));
275 return transport_socket_->Connect(callback_); 301 return transport_socket_->Connect(callback_);
276 } 302 }
277 303
304 void HttpProxyConnectJob::HandleProxyAuthChallenge() {
305 next_state_ = STATE_RESTART_WITH_AUTH;
306 params_->auth_needed_callback().Run(
307 *transport_socket_->GetConnectResponseInfo(),
308 transport_socket_->GetAuthController(),
309 callback_);
310 }
311
312 int HttpProxyConnectJob::DoRestartWithAuth() {
313 // If no auth was added to the controller, then we should abort.
314 next_state_ = STATE_RESTART_WITH_AUTH_COMPLETE;
315 if (!transport_socket_->GetAuthController()->HaveAuth()) {
316 return ERR_PROXY_AUTH_REQUESTED;
317 }
318
319 return transport_socket_->RestartWithAuth(callback_);
320 }
321
322 int HttpProxyConnectJob::DoRestartWithAuthComplete(int result) {
323 if (result == ERR_NO_KEEP_ALIVE_ON_AUTH_RESTART) {
vandebo (ex-Chrome) 2012/01/20 20:49:29 nit: put this inside the result != OK block?
Ryan Hamilton 2012/01/20 21:51:35 Done.
324 if (params_->transport_params())
325 next_state_ = STATE_TCP_CONNECT;
326 else
327 next_state_ = STATE_SSL_CONNECT;
328 return OK;
329 }
330
331 if (result != OK) {
332 if (result == ERR_PROXY_AUTH_REQUESTED ||
333 result == ERR_HTTPS_PROXY_TUNNEL_RESPONSE) {
334 set_socket(transport_socket_.release());
335 }
336 return result;
337 }
338
339 next_state_ = STATE_HTTP_PROXY_CONNECT_COMPLETE;
340 return OK;
341 }
342
278 int HttpProxyConnectJob::DoHttpProxyConnectComplete(int result) { 343 int HttpProxyConnectJob::DoHttpProxyConnectComplete(int result) {
279 if (result == OK || result == ERR_PROXY_AUTH_REQUESTED || 344 // Handle a proxy auth challenge by asynchronously invoking the callback.
345 // We do this asynchronously so that the caller is notified of job
346 // completion only via NotifyDelegateOfCompletion.
347 if (result == ERR_PROXY_AUTH_REQUESTED) {
348 MessageLoop::current()->PostTask(
349 FROM_HERE,
350 base::Bind(&HttpProxyConnectJob::HandleProxyAuthChallenge,
351 ptr_factory_.GetWeakPtr()));
352 return ERR_IO_PENDING;
353 }
354 if (result == OK ||
280 result == ERR_HTTPS_PROXY_TUNNEL_RESPONSE) { 355 result == ERR_HTTPS_PROXY_TUNNEL_RESPONSE) {
281 set_socket(transport_socket_.release()); 356 set_socket(transport_socket_.release());
282 } 357 }
283 358
284 return result; 359 return result;
285 } 360 }
286 361
287 int HttpProxyConnectJob::DoSpdyProxyCreateStream() { 362 int HttpProxyConnectJob::DoSpdyProxyCreateStream() {
288 DCHECK(using_spdy_); 363 DCHECK(using_spdy_);
289 DCHECK(params_->tunnel()); 364 DCHECK(params_->tunnel());
(...skipping 29 matching lines...) Expand all
319 if (result < 0) 394 if (result < 0)
320 return result; 395 return result;
321 396
322 next_state_ = STATE_HTTP_PROXY_CONNECT_COMPLETE; 397 next_state_ = STATE_HTTP_PROXY_CONNECT_COMPLETE;
323 transport_socket_.reset( 398 transport_socket_.reset(
324 new SpdyProxyClientSocket(spdy_stream_, 399 new SpdyProxyClientSocket(spdy_stream_,
325 params_->user_agent(), 400 params_->user_agent(),
326 params_->endpoint(), 401 params_->endpoint(),
327 params_->request_url(), 402 params_->request_url(),
328 params_->destination().host_port_pair(), 403 params_->destination().host_port_pair(),
329 params_->http_auth_cache(), 404 auth_));
330 params_->http_auth_handler_factory()));
331 return transport_socket_->Connect(callback_); 405 return transport_socket_->Connect(callback_);
332 } 406 }
333 407
334 int HttpProxyConnectJob::ConnectInternal() { 408 int HttpProxyConnectJob::ConnectInternal() {
335 if (params_->transport_params()) 409 if (params_->transport_params())
336 next_state_ = STATE_TCP_CONNECT; 410 next_state_ = STATE_TCP_CONNECT;
337 else 411 else
338 next_state_ = STATE_SSL_CONNECT; 412 next_state_ = STATE_SSL_CONNECT;
339 return DoLoop(OK); 413 return DoLoop(OK);
340 } 414 }
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
506 return base_.histograms(); 580 return base_.histograms();
507 } 581 }
508 582
509 bool HttpProxyClientSocketPool::CloseOneIdleConnection() { 583 bool HttpProxyClientSocketPool::CloseOneIdleConnection() {
510 if (base_.CloseOneIdleSocket()) 584 if (base_.CloseOneIdleSocket())
511 return true; 585 return true;
512 return base_.CloseOneIdleConnectionInLayeredPool(); 586 return base_.CloseOneIdleConnectionInLayeredPool();
513 } 587 }
514 588
515 } // namespace net 589 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698