15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved. 25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be 35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file. 45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_proxy_client_socket_pool.h" 65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include <algorithm> 85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 92a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/compiler_specific.h" 10eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "base/time/time.h" 115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h" 125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/load_flags.h" 135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/base/net_errors.h" 145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_network_session.h" 155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/http/http_proxy_client_socket.h" 165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/socket/client_socket_factory.h" 175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/socket/client_socket_handle.h" 185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/socket/client_socket_pool_base.h" 195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/socket/ssl_client_socket.h" 205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/socket/ssl_client_socket_pool.h" 215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/socket/transport_client_socket_pool.h" 225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/spdy/spdy_proxy_client_socket.h" 235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/spdy/spdy_session.h" 245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/spdy/spdy_session_pool.h" 255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/spdy/spdy_stream.h" 262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/ssl/ssl_cert_request_info.h" 277dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "url/gurl.h" 285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)namespace net { 305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HttpProxySocketParams::HttpProxySocketParams( 325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const scoped_refptr<TransportSocketParams>& transport_params, 335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const scoped_refptr<SSLSocketParams>& ssl_params, 345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const GURL& request_url, 355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& user_agent, 365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const HostPortPair& endpoint, 375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpAuthCache* http_auth_cache, 385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HttpAuthHandlerFactory* http_auth_handler_factory, 395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SpdySessionPool* spdy_session_pool, 401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci bool tunnel, 411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ProxyDelegate* proxy_delegate) 425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : transport_params_(transport_params), 435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ssl_params_(ssl_params), 445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) spdy_session_pool_(spdy_session_pool), 455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) request_url_(request_url), 465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) user_agent_(user_agent), 475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) endpoint_(endpoint), 485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) http_auth_cache_(tunnel ? http_auth_cache : NULL), 495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) http_auth_handler_factory_(tunnel ? http_auth_handler_factory : NULL), 501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci tunnel_(tunnel), 511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci proxy_delegate_(proxy_delegate) { 52868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK((transport_params.get() == NULL && ssl_params.get() != NULL) || 53868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) (transport_params.get() != NULL && ssl_params.get() == NULL)); 54868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (transport_params_.get()) { 555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ignore_limits_ = transport_params->ignore_limits(); 565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ignore_limits_ = ssl_params->ignore_limits(); 585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)const HostResolver::RequestInfo& HttpProxySocketParams::destination() const { 62868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (transport_params_.get() == NULL) { 633551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return ssl_params_->GetDirectConnectionParams()->destination(); 645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return transport_params_->destination(); 665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HttpProxySocketParams::~HttpProxySocketParams() {} 705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// HttpProxyConnectJobs will time out after this many seconds. Note this is on 725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// top of the timeout for the transport socket. 731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// TODO(kundaji): Proxy connect timeout should be independent of platform and be 741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// based on proxy. Bug http://crbug.com/407446. 751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#if defined(OS_ANDROID) || defined(OS_IOS) 762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)static const int kHttpProxyConnectJobTimeoutInSeconds = 10; 772a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#else 785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)static const int kHttpProxyConnectJobTimeoutInSeconds = 30; 792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 802a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HttpProxyConnectJob::HttpProxyConnectJob( 825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& group_name, 833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) RequestPriority priority, 845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const scoped_refptr<HttpProxySocketParams>& params, 855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const base::TimeDelta& timeout_duration, 865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TransportClientSocketPool* transport_pool, 875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSLClientSocketPool* ssl_pool, 885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HostResolver* host_resolver, 895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) Delegate* delegate, 905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NetLog* net_log) 913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) : ConnectJob(group_name, timeout_duration, priority, delegate, 925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) BoundNetLog::Make(net_log, NetLog::SOURCE_CONNECT_JOB)), 935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params_(params), 945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) transport_pool_(transport_pool), 955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ssl_pool_(ssl_pool), 965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) resolver_(host_resolver), 975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) using_spdy_(false), 981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci protocol_negotiated_(kProtoUnknown), 991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci weak_ptr_factory_(this) { 1001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci callback_= base::Bind(&HttpProxyConnectJob::OnIOComplete, 1011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci weak_ptr_factory_.GetWeakPtr()); 1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HttpProxyConnectJob::~HttpProxyConnectJob() {} 1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LoadState HttpProxyConnectJob::GetLoadState() const { 1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (next_state_) { 1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_TCP_CONNECT: 1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_TCP_CONNECT_COMPLETE: 1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_SSL_CONNECT: 1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_SSL_CONNECT_COMPLETE: 1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return transport_socket_handle_->GetLoadState(); 1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_HTTP_PROXY_CONNECT: 1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_HTTP_PROXY_CONNECT_COMPLETE: 1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_SPDY_PROXY_CREATE_STREAM: 1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_SPDY_PROXY_CREATE_STREAM_COMPLETE: 1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return LOAD_STATE_ESTABLISHING_PROXY_TUNNEL; 1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED(); 1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return LOAD_STATE_IDLE; 1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpProxyConnectJob::GetAdditionalErrorState(ClientSocketHandle * handle) { 125868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (error_response_info_.cert_request_info.get()) { 1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) handle->set_ssl_error_response_info(error_response_info_); 1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) handle->set_is_ssl_error(true); 1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpProxyConnectJob::OnIOComplete(int result) { 1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rv = DoLoop(result); 1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (rv != ERR_IO_PENDING) 1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NotifyDelegateOfCompletion(rv); // Deletes |this| 1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int HttpProxyConnectJob::DoLoop(int result) { 1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_NE(next_state_, STATE_NONE); 1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int rv = result; 1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) do { 1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) State state = next_state_; 1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next_state_ = STATE_NONE; 1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) switch (state) { 1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_TCP_CONNECT: 1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(OK, rv); 1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = DoTransportConnect(); 1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_TCP_CONNECT_COMPLETE: 1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = DoTransportConnectComplete(rv); 1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_SSL_CONNECT: 1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(OK, rv); 1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = DoSSLConnect(); 1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_SSL_CONNECT_COMPLETE: 1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = DoSSLConnectComplete(rv); 1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_HTTP_PROXY_CONNECT: 1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(OK, rv); 1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = DoHttpProxyConnect(); 1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_HTTP_PROXY_CONNECT_COMPLETE: 1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = DoHttpProxyConnectComplete(rv); 1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_SPDY_PROXY_CREATE_STREAM: 1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK_EQ(OK, rv); 1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = DoSpdyProxyCreateStream(); 1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) case STATE_SPDY_PROXY_CREATE_STREAM_COMPLETE: 1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = DoSpdyProxyCreateStreamComplete(rv); 1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) default: 1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NOTREACHED() << "bad state"; 1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) rv = ERR_FAILED; 1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) break; 1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE); 1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return rv; 1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int HttpProxyConnectJob::DoTransportConnect() { 1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next_state_ = STATE_TCP_CONNECT_COMPLETE; 1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) transport_socket_handle_.reset(new ClientSocketHandle()); 1863551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return transport_socket_handle_->Init(group_name(), 1873551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params_->transport_params(), 1883551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) priority(), 1893551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) callback_, 1903551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) transport_pool_, 1913551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) net_log()); 1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int HttpProxyConnectJob::DoTransportConnectComplete(int result) { 1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result != OK) 1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ERR_PROXY_CONNECTION_FAILED; 1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Reset the timer to just the length of time allowed for HttpProxy handshake 1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // so that a fast TCP connection plus a slow HttpProxy failure doesn't take 2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // longer to timeout than it should. 2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResetTimer(base::TimeDelta::FromSeconds( 2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kHttpProxyConnectJobTimeoutInSeconds)); 2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next_state_ = STATE_HTTP_PROXY_CONNECT; 2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int HttpProxyConnectJob::DoSSLConnect() { 2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (params_->tunnel()) { 21090dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SpdySessionKey key(params_->destination().host_port_pair(), 21190dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ProxyServer::Direct(), 212e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch PRIVACY_MODE_DISABLED); 2137dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (params_->spdy_session_pool()->FindAvailableSession(key, net_log())) { 2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) using_spdy_ = true; 2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next_state_ = STATE_SPDY_PROXY_CREATE_STREAM; 2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return OK; 2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next_state_ = STATE_SSL_CONNECT_COMPLETE; 2205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) transport_socket_handle_.reset(new ClientSocketHandle()); 2215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return transport_socket_handle_->Init( 2223551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) group_name(), params_->ssl_params(), priority(), callback_, 2233551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ssl_pool_, net_log()); 2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int HttpProxyConnectJob::DoSSLConnectComplete(int result) { 2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) { 2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_response_info_ = transport_socket_handle_->ssl_error_response_info(); 2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(error_response_info_.cert_request_info.get()); 2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) error_response_info_.cert_request_info->is_proxy = true; 2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (IsCertificateError(result)) { 2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (params_->ssl_params()->load_flags() & LOAD_IGNORE_ALL_CERT_ERRORS) { 2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result = OK; 2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(rch): allow the user to deal with proxy cert errors in the 2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // same way as server cert errors. 2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) transport_socket_handle_->socket()->Disconnect(); 2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ERR_PROXY_CERTIFICATE_INVALID; 2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2436d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) // A SPDY session to the proxy completed prior to resolving the proxy 2446d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) // hostname. Surface this error, and allow the delegate to retry. 2456d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) // See crbug.com/334413. 2466d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) if (result == ERR_SPDY_SESSION_ALREADY_EXISTS) { 2476d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) DCHECK(!transport_socket_handle_->socket()); 2486d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) return ERR_SPDY_SESSION_ALREADY_EXISTS; 2496d86b77056ed63eb6871182f42a9fd5f07550f90Torne (Richard Coles) } 2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result < 0) { 2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (transport_socket_handle_->socket()) 2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) transport_socket_handle_->socket()->Disconnect(); 2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return ERR_PROXY_CONNECTION_FAILED; 2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSLClientSocket* ssl = 2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<SSLClientSocket*>(transport_socket_handle_->socket()); 2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) using_spdy_ = ssl->was_spdy_negotiated(); 2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protocol_negotiated_ = ssl->GetNegotiatedProtocol(); 2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Reset the timer to just the length of time allowed for HttpProxy handshake 2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // so that a fast SSL connection plus a slow HttpProxy failure doesn't take 2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // longer to timeout than it should. 2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ResetTimer(base::TimeDelta::FromSeconds( 2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) kHttpProxyConnectJobTimeoutInSeconds)); 2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // TODO(rch): If we ever decide to implement a "trusted" SPDY proxy 2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // (one that we speak SPDY over SSL to, but to which we send HTTPS 2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // request directly instead of through CONNECT tunnels, then we 2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // need to add a predicate to this if statement so we fall through 2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // to the else case. (HttpProxyClientSocket currently acts as 2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // a "trusted" SPDY proxy). 2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (using_spdy_ && params_->tunnel()) { 2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next_state_ = STATE_SPDY_PROXY_CREATE_STREAM; 2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next_state_ = STATE_HTTP_PROXY_CONNECT; 2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int HttpProxyConnectJob::DoHttpProxyConnect() { 2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next_state_ = STATE_HTTP_PROXY_CONNECT_COMPLETE; 2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const HostResolver::RequestInfo& tcp_destination = params_->destination(); 2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const HostPortPair& proxy_server = tcp_destination.host_port_pair(); 2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Add a HttpProxy connection on top of the tcp socket. 2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) transport_socket_.reset( 2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new HttpProxyClientSocket(transport_socket_handle_.release(), 2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params_->request_url(), 2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params_->user_agent(), 2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params_->endpoint(), 2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) proxy_server, 2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params_->http_auth_cache(), 2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params_->http_auth_handler_factory(), 2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params_->tunnel(), 2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) using_spdy_, 2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protocol_negotiated_, 2971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci params_->proxy_delegate(), 298868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) params_->ssl_params().get() != NULL)); 2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return transport_socket_->Connect(callback_); 3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int HttpProxyConnectJob::DoHttpProxyConnectComplete(int result) { 3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result == OK || result == ERR_PROXY_AUTH_REQUESTED || 3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) result == ERR_HTTPS_PROXY_TUNNEL_RESPONSE) { 3053551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) SetSocket(transport_socket_.PassAs<StreamSocket>()); 3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int HttpProxyConnectJob::DoSpdyProxyCreateStream() { 3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(using_spdy_); 3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) DCHECK(params_->tunnel()); 31490dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) SpdySessionKey key(params_->destination().host_port_pair(), 31590dce4d38c5ff5333bea97d859d4e484e27edf0cTorne (Richard Coles) ProxyServer::Direct(), 316e5d81f57cb97b3b6b7fccc9c5610d21eb81db09dBen Murdoch PRIVACY_MODE_DISABLED); 3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SpdySessionPool* spdy_pool = params_->spdy_session_pool(); 318ca12bfac764ba476d6cd062bf1dde12cc64c3f40Ben Murdoch base::WeakPtr<SpdySession> spdy_session = 3197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch spdy_pool->FindAvailableSession(key, net_log()); 3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // It's possible that a session to the proxy has recently been created 3217dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch if (spdy_session) { 3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (transport_socket_handle_.get()) { 3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (transport_socket_handle_->socket()) 3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) transport_socket_handle_->socket()->Disconnect(); 3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) transport_socket_handle_->Reset(); 3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // Create a session direct to the proxy itself 329effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch spdy_session = 330effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch spdy_pool->CreateAvailableSessionFromSocket( 331effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch key, transport_socket_handle_.Pass(), 332effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch net_log(), OK, /*using_ssl_*/ true); 333effb81e5f8246d0db0270817048dc992db66e9fbBen Murdoch DCHECK(spdy_session); 3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next_state_ = STATE_SPDY_PROXY_CREATE_STREAM_COMPLETE; 3373551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return spdy_stream_request_.StartRequest(SPDY_BIDIRECTIONAL_STREAM, 3383551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) spdy_session, 3393551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) params_->request_url(), 3403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) priority(), 3413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) spdy_session->net_log(), 3423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) callback_); 3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int HttpProxyConnectJob::DoSpdyProxyCreateStreamComplete(int result) { 3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (result < 0) 3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return result; 3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next_state_ = STATE_HTTP_PROXY_CONNECT_COMPLETE; 350a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles) base::WeakPtr<SpdyStream> stream = spdy_stream_request_.ReleaseStream(); 351868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) DCHECK(stream.get()); 3522a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) // |transport_socket_| will set itself as |stream|'s delegate. 3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) transport_socket_.reset( 3542a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) new SpdyProxyClientSocket(stream, 3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params_->user_agent(), 3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params_->endpoint(), 3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params_->request_url(), 3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params_->destination().host_port_pair(), 3592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) net_log(), 3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params_->http_auth_cache(), 3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) params_->http_auth_handler_factory())); 3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return transport_socket_->Connect(callback_); 3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int HttpProxyConnectJob::ConnectInternal() { 366868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles) if (params_->transport_params().get()) { 3675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next_state_ = STATE_TCP_CONNECT; 3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } else { 3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) next_state_ = STATE_SSL_CONNECT; 3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return DoLoop(OK); 3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HttpProxyClientSocketPool:: 3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HttpProxyConnectJobFactory::HttpProxyConnectJobFactory( 3765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TransportClientSocketPool* transport_pool, 3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSLClientSocketPool* ssl_pool, 3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HostResolver* host_resolver, 3791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const ProxyDelegate* proxy_delegate, 3805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NetLog* net_log) 3815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : transport_pool_(transport_pool), 3825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ssl_pool_(ssl_pool), 3835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) host_resolver_(host_resolver), 3841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci proxy_delegate_(proxy_delegate), 3855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_log_(net_log) { 3865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta max_pool_timeout = base::TimeDelta(); 3872a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) 3881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// TODO(kundaji): Proxy connect timeout should be independent of platform and be 3891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// based on proxy. Bug http://crbug.com/407446. 3901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#if (defined(OS_ANDROID) || defined(OS_IOS)) 391b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#else 3925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (transport_pool_) 3935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max_pool_timeout = transport_pool_->ConnectionTimeout(); 3945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ssl_pool_) 3955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) max_pool_timeout = std::max(max_pool_timeout, 3965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ssl_pool_->ConnectionTimeout()); 3972a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#endif 3985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) timeout_ = max_pool_timeout + 3995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base::TimeDelta::FromSeconds(kHttpProxyConnectJobTimeoutInSeconds); 4005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4033551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)scoped_ptr<ConnectJob> 4045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HttpProxyClientSocketPool::HttpProxyConnectJobFactory::NewConnectJob( 4055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& group_name, 4065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const PoolBase::Request& request, 4075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ConnectJob::Delegate* delegate) const { 4083551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return scoped_ptr<ConnectJob>(new HttpProxyConnectJob(group_name, 4093551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) request.priority(), 4103551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) request.params(), 4113551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ConnectionTimeout(), 4123551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) transport_pool_, 4133551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) ssl_pool_, 4143551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) host_resolver_, 4153551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) delegate, 4163551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) net_log_)); 4175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::TimeDelta 4205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HttpProxyClientSocketPool::HttpProxyConnectJobFactory::ConnectionTimeout( 4215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ) const { 4225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return timeout_; 4235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HttpProxyClientSocketPool::HttpProxyClientSocketPool( 4265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int max_sockets, 4275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int max_sockets_per_group, 4285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ClientSocketPoolHistograms* histograms, 4295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) HostResolver* host_resolver, 4305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) TransportClientSocketPool* transport_pool, 4315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) SSLClientSocketPool* ssl_pool, 4321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci const ProxyDelegate* proxy_delegate, 4335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) NetLog* net_log) 4345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) : transport_pool_(transport_pool), 4355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ssl_pool_(ssl_pool), 4363551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base_(this, max_sockets, max_sockets_per_group, histograms, 4375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ClientSocketPool::unused_idle_socket_timeout(), 4385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ClientSocketPool::used_idle_socket_timeout(), 4395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) new HttpProxyConnectJobFactory(transport_pool, 4405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ssl_pool, 4415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) host_resolver, 4421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci proxy_delegate, 4435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) net_log)) { 4445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) // We should always have a |transport_pool_| except in unit tests. 4455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (transport_pool_) 4463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base_.AddLowerLayeredPool(transport_pool_); 4475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ssl_pool_) 4483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base_.AddLowerLayeredPool(ssl_pool_); 4495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)HttpProxyClientSocketPool::~HttpProxyClientSocketPool() { 4525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int HttpProxyClientSocketPool::RequestSocket( 4555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& group_name, const void* socket_params, 4565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) RequestPriority priority, ClientSocketHandle* handle, 4575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const CompletionCallback& callback, const BoundNetLog& net_log) { 4585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const scoped_refptr<HttpProxySocketParams>* casted_socket_params = 4595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<const scoped_refptr<HttpProxySocketParams>*>(socket_params); 4605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return base_.RequestSocket(group_name, *casted_socket_params, priority, 4625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) handle, callback, net_log); 4635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpProxyClientSocketPool::RequestSockets( 4665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& group_name, 4675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const void* params, 4685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) int num_sockets, 4695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const BoundNetLog& net_log) { 4705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const scoped_refptr<HttpProxySocketParams>* casted_params = 4715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) static_cast<const scoped_refptr<HttpProxySocketParams>*>(params); 4725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base_.RequestSockets(group_name, *casted_params, num_sockets, net_log); 4745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpProxyClientSocketPool::CancelRequest( 4775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& group_name, 4785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) ClientSocketHandle* handle) { 4795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base_.CancelRequest(group_name, handle); 4805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpProxyClientSocketPool::ReleaseSocket(const std::string& group_name, 4833551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) scoped_ptr<StreamSocket> socket, 4843551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) int id) { 4853551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base_.ReleaseSocket(group_name, socket.Pass(), id); 4865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4882a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)void HttpProxyClientSocketPool::FlushWithError(int error) { 4892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles) base_.FlushWithError(error); 4905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void HttpProxyClientSocketPool::CloseIdleSockets() { 4935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) base_.CloseIdleSockets(); 4945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 4965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int HttpProxyClientSocketPool::IdleSocketCount() const { 4975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return base_.idle_socket_count(); 4985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 4995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int HttpProxyClientSocketPool::IdleSocketCountInGroup( 5015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& group_name) const { 5025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return base_.IdleSocketCountInGroup(group_name); 5035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)LoadState HttpProxyClientSocketPool::GetLoadState( 5065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& group_name, const ClientSocketHandle* handle) const { 5075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return base_.GetLoadState(group_name, handle); 5085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)base::DictionaryValue* HttpProxyClientSocketPool::GetInfoAsValue( 5115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& name, 5125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) const std::string& type, 5135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) bool include_nested_pools) const { 5147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::DictionaryValue* dict = base_.GetInfoAsValue(name, type); 5155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (include_nested_pools) { 5167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) base::ListValue* list = new base::ListValue(); 5175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (transport_pool_) { 5185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) list->Append(transport_pool_->GetInfoAsValue("transport_socket_pool", 5195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "transport_socket_pool", 5205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) true)); 5215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (ssl_pool_) { 5235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) list->Append(ssl_pool_->GetInfoAsValue("ssl_socket_pool", 5245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) "ssl_socket_pool", 5255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) true)); 5265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) dict->Set("nested_pools", list); 5285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) } 5295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return dict; 5305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)base::TimeDelta HttpProxyClientSocketPool::ConnectionTimeout() const { 5335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return base_.ConnectionTimeout(); 5345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)ClientSocketPoolHistograms* HttpProxyClientSocketPool::histograms() const { 5375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return base_.histograms(); 5385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5403551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)bool HttpProxyClientSocketPool::IsStalled() const { 5413551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return base_.IsStalled(); 5423551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 5433551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 5443551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void HttpProxyClientSocketPool::AddHigherLayeredPool( 5453551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) HigherLayeredPool* higher_pool) { 5463551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base_.AddHigherLayeredPool(higher_pool); 5473551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 5483551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 5493551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)void HttpProxyClientSocketPool::RemoveHigherLayeredPool( 5503551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) HigherLayeredPool* higher_pool) { 5513551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) base_.RemoveHigherLayeredPool(higher_pool); 5523551c9c881056c480085172ff9840cab31610854Torne (Richard Coles)} 5533551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) 5545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)bool HttpProxyClientSocketPool::CloseOneIdleConnection() { 5555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) if (base_.CloseOneIdleSocket()) 5565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) return true; 5573551c9c881056c480085172ff9840cab31610854Torne (Richard Coles) return base_.CloseOneIdleConnectionInHigherLayeredPool(); 5585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} 5595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) 5605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)} // namespace net 561