OLD | NEW |
---|---|
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 Loading... | |
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) { | |
cbentzel
2012/01/20 02:09:46
NOTE TO SELF: Make sure this is ok.
Ryan Hamilton
2012/01/20 04:20:04
The self there is you, not me, right? (I think it
cbentzel
2012/01/20 11:15:46
Yeah, it was a note to me while doing the review.
| |
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 Loading... | |
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 Loading... | |
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 Loading... | |
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_->auth_controller(), | |
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_->auth_controller()->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) { | |
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |