Chromium Code Reviews| Index: net/http/http_proxy_client_socket_pool.cc |
| =================================================================== |
| --- net/http/http_proxy_client_socket_pool.cc (revision 117986) |
| +++ net/http/http_proxy_client_socket_pool.cc (working copy) |
| @@ -28,6 +28,15 @@ |
| namespace net { |
| +namespace { |
| + |
| +std::string GetProxyUrl(const scoped_refptr<HttpProxySocketParams>& params) { |
| + return (params->ssl_params() != NULL ? "https://" : "http://") |
| + + params->destination().host_port_pair().ToString(); |
| +} |
| + |
| +} // namespace |
| + |
| HttpProxySocketParams::HttpProxySocketParams( |
| const scoped_refptr<TransportSocketParams>& transport_params, |
| const scoped_refptr<SSLSocketParams>& ssl_params, |
| @@ -37,7 +46,8 @@ |
| HttpAuthCache* http_auth_cache, |
| HttpAuthHandlerFactory* http_auth_handler_factory, |
| SpdySessionPool* spdy_session_pool, |
| - bool tunnel) |
| + bool tunnel, |
| + TunnelAuthCallback auth_needed_callback) |
| : transport_params_(transport_params), |
| ssl_params_(ssl_params), |
| spdy_session_pool_(spdy_session_pool), |
| @@ -46,7 +56,8 @@ |
| endpoint_(endpoint), |
| http_auth_cache_(tunnel ? http_auth_cache : NULL), |
| http_auth_handler_factory_(tunnel ? http_auth_handler_factory : NULL), |
| - tunnel_(tunnel) { |
| + tunnel_(tunnel), |
| + auth_needed_callback_(auth_needed_callback) { |
| DCHECK((transport_params == NULL && ssl_params != NULL) || |
| (transport_params != NULL && ssl_params == NULL)); |
| if (transport_params_) |
| @@ -87,7 +98,14 @@ |
| callback_(base::Bind(&HttpProxyConnectJob::OnIOComplete, |
| base::Unretained(this)))), |
| using_spdy_(false), |
| - protocol_negotiated_(SSLClientSocket::kProtoUnknown) { |
| + protocol_negotiated_(SSLClientSocket::kProtoUnknown), |
| + auth_(params->tunnel() ? |
| + new HttpAuthController(HttpAuth::AUTH_PROXY, |
| + GURL(GetProxyUrl(params_)), |
| + params->http_auth_cache(), |
| + params->http_auth_handler_factory()) |
| + : NULL), |
| + ALLOW_THIS_IN_INITIALIZER_LIST(ptr_factory_(this)) { |
| } |
| HttpProxyConnectJob::~HttpProxyConnectJob() {} |
| @@ -103,6 +121,8 @@ |
| case STATE_HTTP_PROXY_CONNECT_COMPLETE: |
| case STATE_SPDY_PROXY_CREATE_STREAM: |
| case STATE_SPDY_PROXY_CREATE_STREAM_COMPLETE: |
| + case STATE_RESTART_WITH_AUTH: |
| + case STATE_RESTART_WITH_AUTH_COMPLETE: |
| return LOAD_STATE_ESTABLISHING_PROXY_TUNNEL; |
| default: |
| NOTREACHED(); |
| @@ -159,6 +179,13 @@ |
| case STATE_SPDY_PROXY_CREATE_STREAM_COMPLETE: |
| rv = DoSpdyProxyCreateStreamComplete(rv); |
| break; |
| + case STATE_RESTART_WITH_AUTH: |
| + DCHECK_EQ(OK, rv); |
| + rv = DoRestartWithAuth(); |
| + break; |
| + case STATE_RESTART_WITH_AUTH_COMPLETE: |
| + rv = DoRestartWithAuthComplete(rv); |
| + break; |
| default: |
| NOTREACHED() << "bad state"; |
| rv = ERR_FAILED; |
| @@ -266,8 +293,7 @@ |
| params_->user_agent(), |
| params_->endpoint(), |
| proxy_server, |
| - params_->http_auth_cache(), |
| - params_->http_auth_handler_factory(), |
| + auth_, |
| params_->tunnel(), |
| using_spdy_, |
| protocol_negotiated_, |
| @@ -275,8 +301,57 @@ |
| return transport_socket_->Connect(callback_); |
| } |
| +void HttpProxyConnectJob::HandleProxyAuthChallenge() { |
| + next_state_ = STATE_RESTART_WITH_AUTH; |
| + params_->auth_needed_callback().Run( |
| + *transport_socket_->GetConnectResponseInfo(), |
| + transport_socket_->GetAuthController(), |
| + callback_); |
| +} |
| + |
| +int HttpProxyConnectJob::DoRestartWithAuth() { |
| + // If no auth was added to the controller, then we should abort. |
| + next_state_ = STATE_RESTART_WITH_AUTH_COMPLETE; |
| + if (!transport_socket_->GetAuthController()->HaveAuth()) { |
| + return ERR_PROXY_AUTH_REQUESTED; |
| + } |
| + |
| + return transport_socket_->RestartWithAuth(callback_); |
| +} |
| + |
| +int HttpProxyConnectJob::DoRestartWithAuthComplete(int result) { |
| + 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.
|
| + if (params_->transport_params()) |
| + next_state_ = STATE_TCP_CONNECT; |
| + else |
| + next_state_ = STATE_SSL_CONNECT; |
| + return OK; |
| + } |
| + |
| + if (result != OK) { |
| + if (result == ERR_PROXY_AUTH_REQUESTED || |
| + result == ERR_HTTPS_PROXY_TUNNEL_RESPONSE) { |
| + set_socket(transport_socket_.release()); |
| + } |
| + return result; |
| + } |
| + |
| + next_state_ = STATE_HTTP_PROXY_CONNECT_COMPLETE; |
| + return OK; |
| +} |
| + |
| int HttpProxyConnectJob::DoHttpProxyConnectComplete(int result) { |
| - if (result == OK || result == ERR_PROXY_AUTH_REQUESTED || |
| + // Handle a proxy auth challenge by asynchronously invoking the callback. |
| + // We do this asynchronously so that the caller is notified of job |
| + // completion only via NotifyDelegateOfCompletion. |
| + if (result == ERR_PROXY_AUTH_REQUESTED) { |
| + MessageLoop::current()->PostTask( |
| + FROM_HERE, |
| + base::Bind(&HttpProxyConnectJob::HandleProxyAuthChallenge, |
| + ptr_factory_.GetWeakPtr())); |
| + return ERR_IO_PENDING; |
| + } |
| + if (result == OK || |
| result == ERR_HTTPS_PROXY_TUNNEL_RESPONSE) { |
| set_socket(transport_socket_.release()); |
| } |
| @@ -326,8 +401,7 @@ |
| params_->endpoint(), |
| params_->request_url(), |
| params_->destination().host_port_pair(), |
| - params_->http_auth_cache(), |
| - params_->http_auth_handler_factory())); |
| + auth_)); |
| return transport_socket_->Connect(callback_); |
| } |