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

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 != OK) {
324 if (result == ERR_NO_KEEP_ALIVE_ON_AUTH_RESTART) {
325 next_state_ = params_->transport_params() ?
vandebo (ex-Chrome) 2012/01/20 21:58:20 You really love that tristate, huh?
326 STATE_TCP_CONNECT : STATE_SSL_CONNECT;
327 return OK;
328 }
329 if (result == ERR_PROXY_AUTH_REQUESTED ||
330 result == ERR_HTTPS_PROXY_TUNNEL_RESPONSE) {
331 set_socket(transport_socket_.release());
332 }
333 return result;
334 }
335
336 next_state_ = STATE_HTTP_PROXY_CONNECT_COMPLETE;
337 return OK;
338 }
339
278 int HttpProxyConnectJob::DoHttpProxyConnectComplete(int result) { 340 int HttpProxyConnectJob::DoHttpProxyConnectComplete(int result) {
279 if (result == OK || result == ERR_PROXY_AUTH_REQUESTED || 341 // Handle a proxy auth challenge by asynchronously invoking the callback.
342 // We do this asynchronously so that the caller is notified of job
343 // completion only via NotifyDelegateOfCompletion.
344 if (result == ERR_PROXY_AUTH_REQUESTED) {
345 MessageLoop::current()->PostTask(
346 FROM_HERE,
347 base::Bind(&HttpProxyConnectJob::HandleProxyAuthChallenge,
348 ptr_factory_.GetWeakPtr()));
349 return ERR_IO_PENDING;
350 }
351 if (result == OK ||
280 result == ERR_HTTPS_PROXY_TUNNEL_RESPONSE) { 352 result == ERR_HTTPS_PROXY_TUNNEL_RESPONSE) {
281 set_socket(transport_socket_.release()); 353 set_socket(transport_socket_.release());
282 } 354 }
283 355
284 return result; 356 return result;
285 } 357 }
286 358
287 int HttpProxyConnectJob::DoSpdyProxyCreateStream() { 359 int HttpProxyConnectJob::DoSpdyProxyCreateStream() {
288 DCHECK(using_spdy_); 360 DCHECK(using_spdy_);
289 DCHECK(params_->tunnel()); 361 DCHECK(params_->tunnel());
(...skipping 29 matching lines...) Expand all
319 if (result < 0) 391 if (result < 0)
320 return result; 392 return result;
321 393
322 next_state_ = STATE_HTTP_PROXY_CONNECT_COMPLETE; 394 next_state_ = STATE_HTTP_PROXY_CONNECT_COMPLETE;
323 transport_socket_.reset( 395 transport_socket_.reset(
324 new SpdyProxyClientSocket(spdy_stream_, 396 new SpdyProxyClientSocket(spdy_stream_,
325 params_->user_agent(), 397 params_->user_agent(),
326 params_->endpoint(), 398 params_->endpoint(),
327 params_->request_url(), 399 params_->request_url(),
328 params_->destination().host_port_pair(), 400 params_->destination().host_port_pair(),
329 params_->http_auth_cache(), 401 auth_));
330 params_->http_auth_handler_factory()));
331 return transport_socket_->Connect(callback_); 402 return transport_socket_->Connect(callback_);
332 } 403 }
333 404
334 int HttpProxyConnectJob::ConnectInternal() { 405 int HttpProxyConnectJob::ConnectInternal() {
335 if (params_->transport_params()) 406 if (params_->transport_params())
336 next_state_ = STATE_TCP_CONNECT; 407 next_state_ = STATE_TCP_CONNECT;
337 else 408 else
338 next_state_ = STATE_SSL_CONNECT; 409 next_state_ = STATE_SSL_CONNECT;
339 return DoLoop(OK); 410 return DoLoop(OK);
340 } 411 }
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after
506 return base_.histograms(); 577 return base_.histograms();
507 } 578 }
508 579
509 bool HttpProxyClientSocketPool::CloseOneIdleConnection() { 580 bool HttpProxyClientSocketPool::CloseOneIdleConnection() {
510 if (base_.CloseOneIdleSocket()) 581 if (base_.CloseOneIdleSocket())
511 return true; 582 return true;
512 return base_.CloseOneIdleConnectionInLayeredPool(); 583 return base_.CloseOneIdleConnectionInLayeredPool();
513 } 584 }
514 585
515 } // namespace net 586 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698