http_proxy_client_socket_pool.cc revision 5852652987a195e279633156fd0f937f6e12a918
1c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Copyright (c) 2010 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/http/http_proxy_client_socket_pool.h"
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
73345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include <algorithm>
83345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "base/time.h"
103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "base/values.h"
11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "googleurl/src/gurl.h"
123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "net/base/load_flags.h"
13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/net_errors.h"
143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "net/http/http_network_session.h"
15c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/http/http_proxy_client_socket.h"
16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/socket/client_socket_factory.h"
17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/socket/client_socket_handle.h"
18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/socket/client_socket_pool_base.h"
193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "net/socket/ssl_client_socket.h"
203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "net/socket/ssl_client_socket_pool.h"
213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#include "net/socket/tcp_client_socket_pool.h"
22731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "net/spdy/spdy_proxy_client_socket.h"
23731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "net/spdy/spdy_session.h"
24731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "net/spdy/spdy_session_pool.h"
25731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "net/spdy/spdy_settings_storage.h"
26731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick#include "net/spdy/spdy_stream.h"
27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace net {
29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
30c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochHttpProxySocketParams::HttpProxySocketParams(
313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    const scoped_refptr<TCPSocketParams>& tcp_params,
323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    const scoped_refptr<SSLSocketParams>& ssl_params,
33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const GURL& request_url,
343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    const std::string& user_agent,
35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    HostPortPair endpoint,
363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    HttpAuthCache* http_auth_cache,
373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    HttpAuthHandlerFactory* http_auth_handler_factory,
38731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    SpdySessionPool* spdy_session_pool,
39731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    SpdySettingsStorage* spdy_settings,
40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    bool tunnel)
413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    : tcp_params_(tcp_params),
423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      ssl_params_(ssl_params),
43731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      spdy_session_pool_(spdy_session_pool),
44731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      spdy_settings_(spdy_settings),
45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      request_url_(request_url),
463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      user_agent_(user_agent),
47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      endpoint_(endpoint),
483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      http_auth_cache_(tunnel ? http_auth_cache : NULL),
493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      http_auth_handler_factory_(tunnel ? http_auth_handler_factory : NULL),
50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      tunnel_(tunnel) {
513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  DCHECK((tcp_params == NULL && ssl_params != NULL) ||
523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick         (tcp_params != NULL && ssl_params == NULL));
5321ae586050b3022a662bfe7743553d462ae4ced8Kristian Monsen#ifdef ANDROID
5421ae586050b3022a662bfe7743553d462ae4ced8Kristian Monsen  if (tcp_params_)
5521ae586050b3022a662bfe7743553d462ae4ced8Kristian Monsen    ignore_limits_ = tcp_params->ignore_limits();
5621ae586050b3022a662bfe7743553d462ae4ced8Kristian Monsen  else
5721ae586050b3022a662bfe7743553d462ae4ced8Kristian Monsen    ignore_limits_ = ssl_params->ignore_limits();
5821ae586050b3022a662bfe7743553d462ae4ced8Kristian Monsen#endif
593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickconst HostResolver::RequestInfo& HttpProxySocketParams::destination() const {
623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (tcp_params_ == NULL)
633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    return ssl_params_->tcp_params()->destination();
643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  else
653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    return tcp_params_->destination();
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochHttpProxySocketParams::~HttpProxySocketParams() {}
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// HttpProxyConnectJobs will time out after this many seconds.  Note this is on
71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// top of the timeout for the transport socket.
72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const int kHttpProxyConnectJobTimeoutInSeconds = 30;
73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochHttpProxyConnectJob::HttpProxyConnectJob(
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const std::string& group_name,
76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const scoped_refptr<HttpProxySocketParams>& params,
77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const base::TimeDelta& timeout_duration,
783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    TCPClientSocketPool* tcp_pool,
793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    SSLClientSocketPool* ssl_pool,
80731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    HostResolver* host_resolver,
81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    Delegate* delegate,
82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NetLog* net_log)
83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    : ConnectJob(group_name, timeout_duration, delegate,
84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                 BoundNetLog::Make(net_log, NetLog::SOURCE_CONNECT_JOB)),
85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      params_(params),
86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      tcp_pool_(tcp_pool),
873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      ssl_pool_(ssl_pool),
88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      resolver_(host_resolver),
89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ALLOW_THIS_IN_INITIALIZER_LIST(
903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick          callback_(this, &HttpProxyConnectJob::OnIOComplete)),
913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      using_spdy_(false) {
92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
94c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochHttpProxyConnectJob::~HttpProxyConnectJob() {}
95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
96c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochLoadState HttpProxyConnectJob::GetLoadState() const {
97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  switch (next_state_) {
983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    case STATE_TCP_CONNECT:
993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    case STATE_TCP_CONNECT_COMPLETE:
1003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    case STATE_SSL_CONNECT:
1013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    case STATE_SSL_CONNECT_COMPLETE:
1023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      return transport_socket_handle_->GetLoadState();
1033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    case STATE_HTTP_PROXY_CONNECT:
1043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    case STATE_HTTP_PROXY_CONNECT_COMPLETE:
105731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    case STATE_SPDY_PROXY_CREATE_STREAM:
106731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    case STATE_SPDY_PROXY_CREATE_STREAM_COMPLETE:
107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return LOAD_STATE_ESTABLISHING_PROXY_TUNNEL;
108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    default:
109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NOTREACHED();
110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return LOAD_STATE_IDLE;
111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
11472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid HttpProxyConnectJob::GetAdditionalErrorState(ClientSocketHandle * handle) {
11572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (error_response_info_.cert_request_info) {
11672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    handle->set_ssl_error_response_info(error_response_info_);
11772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    handle->set_is_ssl_error(true);
11872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid HttpProxyConnectJob::OnIOComplete(int result) {
122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int rv = DoLoop(result);
123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (rv != ERR_IO_PENDING)
124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NotifyDelegateOfCompletion(rv);  // Deletes |this|
125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint HttpProxyConnectJob::DoLoop(int result) {
1283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  DCHECK_NE(next_state_, STATE_NONE);
129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int rv = result;
131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  do {
132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    State state = next_state_;
1333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    next_state_ = STATE_NONE;
134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    switch (state) {
1353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      case STATE_TCP_CONNECT:
136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        DCHECK_EQ(OK, rv);
137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        rv = DoTCPConnect();
138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        break;
1393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      case STATE_TCP_CONNECT_COMPLETE:
140c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        rv = DoTCPConnectComplete(rv);
141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        break;
1423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      case STATE_SSL_CONNECT:
1433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        DCHECK_EQ(OK, rv);
1443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        rv = DoSSLConnect();
1453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        break;
1463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      case STATE_SSL_CONNECT_COMPLETE:
1473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        rv = DoSSLConnectComplete(rv);
1483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        break;
1493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      case STATE_HTTP_PROXY_CONNECT:
150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        DCHECK_EQ(OK, rv);
151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        rv = DoHttpProxyConnect();
152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        break;
1533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      case STATE_HTTP_PROXY_CONNECT_COMPLETE:
154c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        rv = DoHttpProxyConnectComplete(rv);
155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        break;
156731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      case STATE_SPDY_PROXY_CREATE_STREAM:
157731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        DCHECK_EQ(OK, rv);
158731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        rv = DoSpdyProxyCreateStream();
159731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        break;
160731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      case STATE_SPDY_PROXY_CREATE_STREAM_COMPLETE:
161731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        rv = DoSpdyProxyCreateStreamComplete(rv);
162731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        break;
163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      default:
164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        NOTREACHED() << "bad state";
165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        rv = ERR_FAILED;
166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        break;
167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
1683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE);
169c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return rv;
171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint HttpProxyConnectJob::DoTCPConnect() {
1743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  next_state_ = STATE_TCP_CONNECT_COMPLETE;
1753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  transport_socket_handle_.reset(new ClientSocketHandle());
1763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  return transport_socket_handle_->Init(
177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      group_name(), params_->tcp_params(),
178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      params_->tcp_params()->destination().priority(), &callback_, tcp_pool_,
179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      net_log());
180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint HttpProxyConnectJob::DoTCPConnectComplete(int result) {
183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (result != OK)
1843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    return ERR_PROXY_CONNECTION_FAILED;
185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Reset the timer to just the length of time allowed for HttpProxy handshake
187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // so that a fast TCP connection plus a slow HttpProxy failure doesn't take
188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // longer to timeout than it should.
189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ResetTimer(base::TimeDelta::FromSeconds(
190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      kHttpProxyConnectJobTimeoutInSeconds));
191731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
1923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  next_state_ = STATE_HTTP_PROXY_CONNECT;
1933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  return result;
1943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
1953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickint HttpProxyConnectJob::DoSSLConnect() {
197731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (params_->tunnel()) {
198731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    HostPortProxyPair pair(params_->destination().host_port_pair(),
199731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                           ProxyServer::Direct());
200731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    if (params_->spdy_session_pool()->HasSession(pair)) {
201731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      using_spdy_ = true;
202731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      next_state_ = STATE_SPDY_PROXY_CREATE_STREAM;
203731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      return OK;
204731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    }
205731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
2063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  next_state_ = STATE_SSL_CONNECT_COMPLETE;
2073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  transport_socket_handle_.reset(new ClientSocketHandle());
2083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  return transport_socket_handle_->Init(
2093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      group_name(), params_->ssl_params(),
2103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      params_->ssl_params()->tcp_params()->destination().priority(),
2113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      &callback_, ssl_pool_, net_log());
2123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
2133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
2143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickint HttpProxyConnectJob::DoSSLConnectComplete(int result) {
2154a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) {
2164a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    error_response_info_ = transport_socket_handle_->ssl_error_response_info();
2174a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    DCHECK(error_response_info_.cert_request_info.get());
2184a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    return result;
2194a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  }
220731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (IsCertificateError(result)) {
221731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    if (params_->ssl_params()->load_flags() & LOAD_IGNORE_ALL_CERT_ERRORS)
222731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      result = OK;
223731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    else
224731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      // TODO(rch): allow the user to deal with proxy cert errors in the
225731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      // same way as server cert errors.
226731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      return ERR_PROXY_CERTIFICATE_INVALID;
227731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
2283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (result < 0) {
2293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    if (transport_socket_handle_->socket())
2303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      transport_socket_handle_->socket()->Disconnect();
231731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    return ERR_PROXY_CONNECTION_FAILED;
2323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
2333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
2343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  SSLClientSocket* ssl =
2353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      static_cast<SSLClientSocket*>(transport_socket_handle_->socket());
2363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  using_spdy_ = ssl->was_spdy_negotiated();
2373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
2383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Reset the timer to just the length of time allowed for HttpProxy handshake
2393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // so that a fast SSL connection plus a slow HttpProxy failure doesn't take
2403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // longer to timeout than it should.
2413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ResetTimer(base::TimeDelta::FromSeconds(
2423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      kHttpProxyConnectJobTimeoutInSeconds));
243731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // TODO(rch): If we ever decide to implement a "trusted" SPDY proxy
244731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // (one that we speak SPDY over SSL to, but to which we send HTTPS
245731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // request directly instead of through CONNECT tunnels, then we
246731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // need to add a predicate to this if statement so we fall through
247731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // to the else case. (HttpProxyClientSocket currently acts as
248731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // a "trusted" SPDY proxy).
249731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (using_spdy_ && params_->tunnel())
250731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    next_state_ = STATE_SPDY_PROXY_CREATE_STREAM;
251731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  else
252731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    next_state_ = STATE_HTTP_PROXY_CONNECT;
253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return result;
254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2565852652987a195e279633156fd0f937f6e12a918Kristian Monsen#ifdef ANDROID
2575852652987a195e279633156fd0f937f6e12a918Kristian Monsen// TODO(kristianm): Find out if Connect should block
2585852652987a195e279633156fd0f937f6e12a918Kristian Monsen#endif
25972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenint HttpProxyConnectJob::DoHttpProxyConnect() {
26072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  next_state_ = STATE_HTTP_PROXY_CONNECT_COMPLETE;
26172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  const HostResolver::RequestInfo& tcp_destination = params_->destination();
26272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  const HostPortPair& proxy_server = tcp_destination.host_port_pair();
26372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
26472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Add a HttpProxy connection on top of the tcp socket.
26572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  transport_socket_.reset(
26672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      new HttpProxyClientSocket(transport_socket_handle_.release(),
26772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                params_->request_url(),
26872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                params_->user_agent(),
26972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                params_->endpoint(),
27072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                proxy_server,
27172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                params_->http_auth_cache(),
27272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                params_->http_auth_handler_factory(),
27372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                params_->tunnel(),
27472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                using_spdy_,
27572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                params_->ssl_params() != NULL));
2765852652987a195e279633156fd0f937f6e12a918Kristian Monsen  return transport_socket_->Connect(&callback_
2775852652987a195e279633156fd0f937f6e12a918Kristian Monsen#ifdef ANDROID
2785852652987a195e279633156fd0f937f6e12a918Kristian Monsen                                    , false
2795852652987a195e279633156fd0f937f6e12a918Kristian Monsen#endif
2805852652987a195e279633156fd0f937f6e12a918Kristian Monsen                                   );
28172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
28272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
28372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenint HttpProxyConnectJob::DoHttpProxyConnectComplete(int result) {
28472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (result == OK || result == ERR_PROXY_AUTH_REQUESTED ||
28572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      result == ERR_HTTPS_PROXY_TUNNEL_RESPONSE) {
28672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      set_socket(transport_socket_.release());
2874a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  }
28872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
28972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  return result;
2904a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch}
2914a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
292731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickint HttpProxyConnectJob::DoSpdyProxyCreateStream() {
293731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  DCHECK(using_spdy_);
294731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  DCHECK(params_->tunnel());
295731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
296731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  HostPortProxyPair pair(params_->destination().host_port_pair(),
297731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                         ProxyServer::Direct());
298731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  SpdySessionPool* spdy_pool = params_->spdy_session_pool();
299731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_refptr<SpdySession> spdy_session;
300731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // It's possible that a session to the proxy has recently been created
301731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (spdy_pool->HasSession(pair)) {
3024a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    if (transport_socket_handle_.get()) {
3034a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch      if (transport_socket_handle_->socket())
3044a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch        transport_socket_handle_->socket()->Disconnect();
3054a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch      transport_socket_handle_->Reset();
3064a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    }
307731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    spdy_session = spdy_pool->Get(pair, params_->spdy_settings(), net_log());
308731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  } else {
309731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    // Create a session direct to the proxy itself
310731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    int rv = spdy_pool->GetSpdySessionFromSocket(
311731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        pair, params_->spdy_settings(), transport_socket_handle_.release(),
312731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        net_log(), OK, &spdy_session, /*using_ssl_*/ true);
3134a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    if (rv < 0)
314731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      return rv;
315731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
316731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
317731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  next_state_ = STATE_SPDY_PROXY_CREATE_STREAM_COMPLETE;
318731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  return spdy_session->CreateStream(params_->request_url(),
319731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                    params_->destination().priority(),
320201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                                    &spdy_stream_, spdy_session->net_log(),
321201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                                    &callback_);
322731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
323731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
3247b9ca917061470268bf3395c8925d4b9cc52d8e1Kristian Monsen#ifdef ANDROID
3257b9ca917061470268bf3395c8925d4b9cc52d8e1Kristian Monsen// TODO(kristianm): Find out if Connect should block
3267b9ca917061470268bf3395c8925d4b9cc52d8e1Kristian Monsen#endif
327731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickint HttpProxyConnectJob::DoSpdyProxyCreateStreamComplete(int result) {
328731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (result < 0)
329731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    return result;
330731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
331731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  next_state_ = STATE_HTTP_PROXY_CONNECT_COMPLETE;
332731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  transport_socket_.reset(
333731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      new SpdyProxyClientSocket(spdy_stream_,
334731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                params_->user_agent(),
335731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                params_->endpoint(),
336731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                params_->request_url(),
337731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                params_->destination().host_port_pair(),
338731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                params_->http_auth_cache(),
339731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                params_->http_auth_handler_factory()));
3407b9ca917061470268bf3395c8925d4b9cc52d8e1Kristian Monsen  return transport_socket_->Connect(&callback_
3417b9ca917061470268bf3395c8925d4b9cc52d8e1Kristian Monsen#ifdef ANDROID
3427b9ca917061470268bf3395c8925d4b9cc52d8e1Kristian Monsen                                    , false
3437b9ca917061470268bf3395c8925d4b9cc52d8e1Kristian Monsen#endif
3447b9ca917061470268bf3395c8925d4b9cc52d8e1Kristian Monsen                                   );
345731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
346731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
34772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenint HttpProxyConnectJob::ConnectInternal() {
34872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (params_->tcp_params())
34972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    next_state_ = STATE_TCP_CONNECT;
35072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  else
35172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    next_state_ = STATE_SSL_CONNECT;
35272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  return DoLoop(OK);
353c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
354c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3553345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickHttpProxyClientSocketPool::
3563345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickHttpProxyConnectJobFactory::HttpProxyConnectJobFactory(
3573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    TCPClientSocketPool* tcp_pool,
3583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    SSLClientSocketPool* ssl_pool,
3593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    HostResolver* host_resolver,
3603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    NetLog* net_log)
3613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    : tcp_pool_(tcp_pool),
3623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      ssl_pool_(ssl_pool),
3633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      host_resolver_(host_resolver),
3643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      net_log_(net_log) {
3653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  base::TimeDelta max_pool_timeout = base::TimeDelta();
3663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (tcp_pool_)
3673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    max_pool_timeout = tcp_pool_->ConnectionTimeout();
3683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (ssl_pool_)
3693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    max_pool_timeout = std::max(max_pool_timeout,
3703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                ssl_pool_->ConnectionTimeout());
3713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  timeout_ = max_pool_timeout +
3723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    base::TimeDelta::FromSeconds(kHttpProxyConnectJobTimeoutInSeconds);
3733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
3743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
3753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
376c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochConnectJob*
377c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochHttpProxyClientSocketPool::HttpProxyConnectJobFactory::NewConnectJob(
378c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const std::string& group_name,
379c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const PoolBase::Request& request,
380c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ConnectJob::Delegate* delegate) const {
381c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return new HttpProxyConnectJob(group_name, request.params(),
3823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                 ConnectionTimeout(), tcp_pool_, ssl_pool_,
3833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                 host_resolver_, delegate, net_log_);
384c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
385c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
386c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochHttpProxyClientSocketPool::HttpProxyClientSocketPool(
387c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int max_sockets,
388c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int max_sockets_per_group,
3893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    ClientSocketPoolHistograms* histograms,
390731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    HostResolver* host_resolver,
3913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    TCPClientSocketPool* tcp_pool,
3923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    SSLClientSocketPool* ssl_pool,
393c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NetLog* net_log)
3943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    : tcp_pool_(tcp_pool),
3953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      ssl_pool_(ssl_pool),
3963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      base_(max_sockets, max_sockets_per_group, histograms,
397c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            base::TimeDelta::FromSeconds(
398c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                ClientSocketPool::unused_idle_socket_timeout()),
399c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            base::TimeDelta::FromSeconds(kUsedIdleSocketTimeout),
4003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            new HttpProxyConnectJobFactory(tcp_pool, ssl_pool, host_resolver,
4013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                           net_log)) {}
402c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
403c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochHttpProxyClientSocketPool::~HttpProxyClientSocketPool() {}
404c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
405c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint HttpProxyClientSocketPool::RequestSocket(const std::string& group_name,
406c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                             const void* socket_params,
407c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                             RequestPriority priority,
408c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                             ClientSocketHandle* handle,
409c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                             CompletionCallback* callback,
410c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                             const BoundNetLog& net_log) {
411c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const scoped_refptr<HttpProxySocketParams>* casted_socket_params =
412c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      static_cast<const scoped_refptr<HttpProxySocketParams>*>(socket_params);
413c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
414c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return base_.RequestSocket(group_name, *casted_socket_params, priority,
415c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                             handle, callback, net_log);
416c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
417c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
418731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid HttpProxyClientSocketPool::RequestSockets(
419731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    const std::string& group_name,
420731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    const void* params,
421731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    int num_sockets,
422731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    const BoundNetLog& net_log) {
423731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  const scoped_refptr<HttpProxySocketParams>* casted_params =
424731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      static_cast<const scoped_refptr<HttpProxySocketParams>*>(params);
425731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
426731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  base_.RequestSockets(group_name, *casted_params, num_sockets, net_log);
427731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
428731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
429c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid HttpProxyClientSocketPool::CancelRequest(
430c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const std::string& group_name,
431c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ClientSocketHandle* handle) {
432c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  base_.CancelRequest(group_name, handle);
433c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
434c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
435c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid HttpProxyClientSocketPool::ReleaseSocket(const std::string& group_name,
436c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                              ClientSocket* socket, int id) {
437c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  base_.ReleaseSocket(group_name, socket, id);
438c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
439c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
440c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid HttpProxyClientSocketPool::Flush() {
441c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  base_.Flush();
442c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
443c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
444c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid HttpProxyClientSocketPool::CloseIdleSockets() {
445c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  base_.CloseIdleSockets();
446c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
447c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
44821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenint HttpProxyClientSocketPool::IdleSocketCount() const {
44921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  return base_.idle_socket_count();
45021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
45121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
452c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint HttpProxyClientSocketPool::IdleSocketCountInGroup(
453c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const std::string& group_name) const {
454c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return base_.IdleSocketCountInGroup(group_name);
455c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
456c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
457c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochLoadState HttpProxyClientSocketPool::GetLoadState(
458c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const std::string& group_name, const ClientSocketHandle* handle) const {
459c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return base_.GetLoadState(group_name, handle);
460c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
461c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4623345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickDictionaryValue* HttpProxyClientSocketPool::GetInfoAsValue(
4633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    const std::string& name,
4643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    const std::string& type,
4653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    bool include_nested_pools) const {
4663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  DictionaryValue* dict = base_.GetInfoAsValue(name, type);
4673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (include_nested_pools) {
4683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    ListValue* list = new ListValue();
4693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    if (tcp_pool_) {
4703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      list->Append(tcp_pool_->GetInfoAsValue("tcp_socket_pool",
4713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                             "tcp_socket_pool",
4723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                             true));
4733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    }
4743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    if (ssl_pool_) {
4753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      list->Append(ssl_pool_->GetInfoAsValue("ssl_socket_pool",
4763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                             "ssl_socket_pool",
4773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                             true));
4783345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    }
4793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    dict->Set("nested_pools", list);
4803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
4813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  return dict;
4823345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
4833345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
48421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenbase::TimeDelta HttpProxyClientSocketPool::ConnectionTimeout() const {
48521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  return base_.ConnectionTimeout();
48621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
48721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
48821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenClientSocketPoolHistograms* HttpProxyClientSocketPool::histograms() const {
48921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  return base_.histograms();
49021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
49121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
492c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}  // namespace net
493