http_proxy_client_socket_pool.cc revision 7b9ca917061470268bf3395c8925d4b9cc52d8e1
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
114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint HttpProxyConnectJob::ConnectInternal() {
1153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (params_->tcp_params())
1163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    next_state_ = STATE_TCP_CONNECT;
1173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  else
1183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    next_state_ = STATE_SSL_CONNECT;
119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return DoLoop(OK);
120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid HttpProxyConnectJob::OnIOComplete(int result) {
123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int rv = DoLoop(result);
124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (rv != ERR_IO_PENDING)
125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NotifyDelegateOfCompletion(rv);  // Deletes |this|
126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
128c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint HttpProxyConnectJob::DoLoop(int result) {
1293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  DCHECK_NE(next_state_, STATE_NONE);
130c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int rv = result;
132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  do {
133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    State state = next_state_;
1343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    next_state_ = STATE_NONE;
135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    switch (state) {
1363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      case STATE_TCP_CONNECT:
137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        DCHECK_EQ(OK, rv);
138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        rv = DoTCPConnect();
139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        break;
1403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      case STATE_TCP_CONNECT_COMPLETE:
141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        rv = DoTCPConnectComplete(rv);
142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        break;
1433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      case STATE_SSL_CONNECT:
1443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        DCHECK_EQ(OK, rv);
1453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        rv = DoSSLConnect();
1463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        break;
1473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      case STATE_SSL_CONNECT_COMPLETE:
1483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        rv = DoSSLConnectComplete(rv);
1493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        break;
1503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      case STATE_HTTP_PROXY_CONNECT:
151c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        DCHECK_EQ(OK, rv);
152c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        rv = DoHttpProxyConnect();
153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        break;
1543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      case STATE_HTTP_PROXY_CONNECT_COMPLETE:
155c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        rv = DoHttpProxyConnectComplete(rv);
156c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        break;
157731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      case STATE_SPDY_PROXY_CREATE_STREAM:
158731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        DCHECK_EQ(OK, rv);
159731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        rv = DoSpdyProxyCreateStream();
160731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        break;
161731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      case STATE_SPDY_PROXY_CREATE_STREAM_COMPLETE:
162731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        rv = DoSpdyProxyCreateStreamComplete(rv);
163731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        break;
164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      default:
165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        NOTREACHED() << "bad state";
166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        rv = ERR_FAILED;
167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        break;
168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
1693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE);
170c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
171c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return rv;
172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint HttpProxyConnectJob::DoTCPConnect() {
1753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  next_state_ = STATE_TCP_CONNECT_COMPLETE;
1763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  transport_socket_handle_.reset(new ClientSocketHandle());
1773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  return transport_socket_handle_->Init(
178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      group_name(), params_->tcp_params(),
179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      params_->tcp_params()->destination().priority(), &callback_, tcp_pool_,
180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      net_log());
181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint HttpProxyConnectJob::DoTCPConnectComplete(int result) {
184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (result != OK)
1853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    return ERR_PROXY_CONNECTION_FAILED;
186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Reset the timer to just the length of time allowed for HttpProxy handshake
188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // so that a fast TCP connection plus a slow HttpProxy failure doesn't take
189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // longer to timeout than it should.
190c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ResetTimer(base::TimeDelta::FromSeconds(
191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      kHttpProxyConnectJobTimeoutInSeconds));
192731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
1933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  next_state_ = STATE_HTTP_PROXY_CONNECT;
1943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  return result;
1953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
1963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickint HttpProxyConnectJob::DoSSLConnect() {
198731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (params_->tunnel()) {
199731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    HostPortProxyPair pair(params_->destination().host_port_pair(),
200731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                           ProxyServer::Direct());
201731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    if (params_->spdy_session_pool()->HasSession(pair)) {
202731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      using_spdy_ = true;
203731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      next_state_ = STATE_SPDY_PROXY_CREATE_STREAM;
204731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      return OK;
205731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    }
206731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
2073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  next_state_ = STATE_SSL_CONNECT_COMPLETE;
2083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  transport_socket_handle_.reset(new ClientSocketHandle());
2093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  return transport_socket_handle_->Init(
2103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      group_name(), params_->ssl_params(),
2113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      params_->ssl_params()->tcp_params()->destination().priority(),
2123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      &callback_, ssl_pool_, net_log());
2133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
2143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
2153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickint HttpProxyConnectJob::DoSSLConnectComplete(int result) {
2164a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) {
2174a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    error_response_info_ = transport_socket_handle_->ssl_error_response_info();
2184a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    DCHECK(error_response_info_.cert_request_info.get());
2194a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    return result;
2204a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  }
221731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (IsCertificateError(result)) {
222731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    if (params_->ssl_params()->load_flags() & LOAD_IGNORE_ALL_CERT_ERRORS)
223731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      result = OK;
224731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    else
225731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      // TODO(rch): allow the user to deal with proxy cert errors in the
226731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      // same way as server cert errors.
227731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      return ERR_PROXY_CERTIFICATE_INVALID;
228731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
2293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (result < 0) {
2303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    if (transport_socket_handle_->socket())
2313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      transport_socket_handle_->socket()->Disconnect();
232731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    return ERR_PROXY_CONNECTION_FAILED;
2333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
2343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
2353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  SSLClientSocket* ssl =
2363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      static_cast<SSLClientSocket*>(transport_socket_handle_->socket());
2373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  using_spdy_ = ssl->was_spdy_negotiated();
2383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
2393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Reset the timer to just the length of time allowed for HttpProxy handshake
2403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // so that a fast SSL connection plus a slow HttpProxy failure doesn't take
2413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // longer to timeout than it should.
2423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ResetTimer(base::TimeDelta::FromSeconds(
2433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      kHttpProxyConnectJobTimeoutInSeconds));
244731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // TODO(rch): If we ever decide to implement a "trusted" SPDY proxy
245731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // (one that we speak SPDY over SSL to, but to which we send HTTPS
246731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // request directly instead of through CONNECT tunnels, then we
247731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // need to add a predicate to this if statement so we fall through
248731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // to the else case. (HttpProxyClientSocket currently acts as
249731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // a "trusted" SPDY proxy).
250731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (using_spdy_ && params_->tunnel())
251731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    next_state_ = STATE_SPDY_PROXY_CREATE_STREAM;
252731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  else
253731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    next_state_ = STATE_HTTP_PROXY_CONNECT;
254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return result;
255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2574a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdochvoid HttpProxyConnectJob::GetAdditionalErrorState(ClientSocketHandle * handle) {
2584a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  if (error_response_info_.cert_request_info) {
2594a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    handle->set_ssl_error_response_info(error_response_info_);
2604a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    handle->set_is_ssl_error(true);
2614a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  }
2624a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch}
2634a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
264731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickint HttpProxyConnectJob::DoSpdyProxyCreateStream() {
265731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  DCHECK(using_spdy_);
266731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  DCHECK(params_->tunnel());
267731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
268731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  HostPortProxyPair pair(params_->destination().host_port_pair(),
269731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                         ProxyServer::Direct());
270731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  SpdySessionPool* spdy_pool = params_->spdy_session_pool();
271731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_refptr<SpdySession> spdy_session;
272731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // It's possible that a session to the proxy has recently been created
273731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (spdy_pool->HasSession(pair)) {
2744a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    if (transport_socket_handle_.get()) {
2754a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch      if (transport_socket_handle_->socket())
2764a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch        transport_socket_handle_->socket()->Disconnect();
2774a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch      transport_socket_handle_->Reset();
2784a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    }
279731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    spdy_session = spdy_pool->Get(pair, params_->spdy_settings(), net_log());
280731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  } else {
281731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    // Create a session direct to the proxy itself
282731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    int rv = spdy_pool->GetSpdySessionFromSocket(
283731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        pair, params_->spdy_settings(), transport_socket_handle_.release(),
284731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        net_log(), OK, &spdy_session, /*using_ssl_*/ true);
2854a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    if (rv < 0)
286731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      return rv;
287731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
288731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
289731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  next_state_ = STATE_SPDY_PROXY_CREATE_STREAM_COMPLETE;
290731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  return spdy_session->CreateStream(params_->request_url(),
291731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                    params_->destination().priority(),
292201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                                    &spdy_stream_, spdy_session->net_log(),
293201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                                    &callback_);
294731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
295731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
2967b9ca917061470268bf3395c8925d4b9cc52d8e1Kristian Monsen#ifdef ANDROID
2977b9ca917061470268bf3395c8925d4b9cc52d8e1Kristian Monsen// TODO(kristianm): Find out if Connect should block
2987b9ca917061470268bf3395c8925d4b9cc52d8e1Kristian Monsen#endif
299731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickint HttpProxyConnectJob::DoSpdyProxyCreateStreamComplete(int result) {
300731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (result < 0)
301731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    return result;
302731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
303731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  next_state_ = STATE_HTTP_PROXY_CONNECT_COMPLETE;
304731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  transport_socket_.reset(
305731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      new SpdyProxyClientSocket(spdy_stream_,
306731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                params_->user_agent(),
307731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                params_->endpoint(),
308731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                params_->request_url(),
309731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                params_->destination().host_port_pair(),
310731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                params_->http_auth_cache(),
311731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                params_->http_auth_handler_factory()));
3127b9ca917061470268bf3395c8925d4b9cc52d8e1Kristian Monsen  return transport_socket_->Connect(&callback_
3137b9ca917061470268bf3395c8925d4b9cc52d8e1Kristian Monsen#ifdef ANDROID
3147b9ca917061470268bf3395c8925d4b9cc52d8e1Kristian Monsen                                    , false
3157b9ca917061470268bf3395c8925d4b9cc52d8e1Kristian Monsen#endif
3167b9ca917061470268bf3395c8925d4b9cc52d8e1Kristian Monsen                                   );
317731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
318731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
3197b9ca917061470268bf3395c8925d4b9cc52d8e1Kristian Monsen#ifdef ANDROID
3207b9ca917061470268bf3395c8925d4b9cc52d8e1Kristian Monsen// TODO(kristianm): Find out if Connect should block
3217b9ca917061470268bf3395c8925d4b9cc52d8e1Kristian Monsen#endif
322c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint HttpProxyConnectJob::DoHttpProxyConnect() {
3233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  next_state_ = STATE_HTTP_PROXY_CONNECT_COMPLETE;
3243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  const HostResolver::RequestInfo& tcp_destination = params_->destination();
3253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  const HostPortPair& proxy_server = tcp_destination.host_port_pair();
326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
327c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Add a HttpProxy connection on top of the tcp socket.
3283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  transport_socket_.reset(
3293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      new HttpProxyClientSocket(transport_socket_handle_.release(),
3303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                params_->request_url(),
3313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                params_->user_agent(),
3323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                params_->endpoint(),
3333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                proxy_server,
3343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                params_->http_auth_cache(),
3353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                params_->http_auth_handler_factory(),
3363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                params_->tunnel(),
3373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                using_spdy_));
3387b9ca917061470268bf3395c8925d4b9cc52d8e1Kristian Monsen  return transport_socket_->Connect(&callback_
3397b9ca917061470268bf3395c8925d4b9cc52d8e1Kristian Monsen#ifdef ANDROID
3407b9ca917061470268bf3395c8925d4b9cc52d8e1Kristian Monsen                                    , false
3417b9ca917061470268bf3395c8925d4b9cc52d8e1Kristian Monsen#endif
3427b9ca917061470268bf3395c8925d4b9cc52d8e1Kristian Monsen                                   );
343c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
344c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
345c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint HttpProxyConnectJob::DoHttpProxyConnectComplete(int result) {
346c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (result == OK || result == ERR_PROXY_AUTH_REQUESTED)
3473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      set_socket(transport_socket_.release());
348c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
349c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return result;
350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
351c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3523345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickHttpProxyClientSocketPool::
3533345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickHttpProxyConnectJobFactory::HttpProxyConnectJobFactory(
3543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    TCPClientSocketPool* tcp_pool,
3553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    SSLClientSocketPool* ssl_pool,
3563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    HostResolver* host_resolver,
3573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    NetLog* net_log)
3583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    : tcp_pool_(tcp_pool),
3593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      ssl_pool_(ssl_pool),
3603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      host_resolver_(host_resolver),
3613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      net_log_(net_log) {
3623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  base::TimeDelta max_pool_timeout = base::TimeDelta();
3633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (tcp_pool_)
3643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    max_pool_timeout = tcp_pool_->ConnectionTimeout();
3653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (ssl_pool_)
3663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    max_pool_timeout = std::max(max_pool_timeout,
3673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                ssl_pool_->ConnectionTimeout());
3683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  timeout_ = max_pool_timeout +
3693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    base::TimeDelta::FromSeconds(kHttpProxyConnectJobTimeoutInSeconds);
3703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
3713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
3723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
373c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochConnectJob*
374c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochHttpProxyClientSocketPool::HttpProxyConnectJobFactory::NewConnectJob(
375c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const std::string& group_name,
376c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const PoolBase::Request& request,
377c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ConnectJob::Delegate* delegate) const {
378c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return new HttpProxyConnectJob(group_name, request.params(),
3793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                 ConnectionTimeout(), tcp_pool_, ssl_pool_,
3803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                 host_resolver_, delegate, net_log_);
381c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
382c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
383c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochHttpProxyClientSocketPool::HttpProxyClientSocketPool(
384c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int max_sockets,
385c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int max_sockets_per_group,
3863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    ClientSocketPoolHistograms* histograms,
387731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    HostResolver* host_resolver,
3883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    TCPClientSocketPool* tcp_pool,
3893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    SSLClientSocketPool* ssl_pool,
390c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NetLog* net_log)
3913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    : tcp_pool_(tcp_pool),
3923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      ssl_pool_(ssl_pool),
3933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      base_(max_sockets, max_sockets_per_group, histograms,
394c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            base::TimeDelta::FromSeconds(
395c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                ClientSocketPool::unused_idle_socket_timeout()),
396c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            base::TimeDelta::FromSeconds(kUsedIdleSocketTimeout),
3973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            new HttpProxyConnectJobFactory(tcp_pool, ssl_pool, host_resolver,
3983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                           net_log)) {}
399c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
400c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochHttpProxyClientSocketPool::~HttpProxyClientSocketPool() {}
401c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
402c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint HttpProxyClientSocketPool::RequestSocket(const std::string& group_name,
403c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                             const void* socket_params,
404c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                             RequestPriority priority,
405c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                             ClientSocketHandle* handle,
406c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                             CompletionCallback* callback,
407c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                             const BoundNetLog& net_log) {
408c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const scoped_refptr<HttpProxySocketParams>* casted_socket_params =
409c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      static_cast<const scoped_refptr<HttpProxySocketParams>*>(socket_params);
410c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
411c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return base_.RequestSocket(group_name, *casted_socket_params, priority,
412c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                             handle, callback, net_log);
413c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
414c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
415731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid HttpProxyClientSocketPool::RequestSockets(
416731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    const std::string& group_name,
417731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    const void* params,
418731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    int num_sockets,
419731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    const BoundNetLog& net_log) {
420731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  const scoped_refptr<HttpProxySocketParams>* casted_params =
421731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      static_cast<const scoped_refptr<HttpProxySocketParams>*>(params);
422731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
423731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  base_.RequestSockets(group_name, *casted_params, num_sockets, net_log);
424731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
425731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
426c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid HttpProxyClientSocketPool::CancelRequest(
427c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const std::string& group_name,
428c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ClientSocketHandle* handle) {
429c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  base_.CancelRequest(group_name, handle);
430c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
431c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
432c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid HttpProxyClientSocketPool::ReleaseSocket(const std::string& group_name,
433c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                              ClientSocket* socket, int id) {
434c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  base_.ReleaseSocket(group_name, socket, id);
435c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
436c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
437c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid HttpProxyClientSocketPool::Flush() {
438c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  base_.Flush();
439c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
440c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
441c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid HttpProxyClientSocketPool::CloseIdleSockets() {
442c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  base_.CloseIdleSockets();
443c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
444c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
445c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint HttpProxyClientSocketPool::IdleSocketCountInGroup(
446c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const std::string& group_name) const {
447c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return base_.IdleSocketCountInGroup(group_name);
448c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
449c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
450c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochLoadState HttpProxyClientSocketPool::GetLoadState(
451c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const std::string& group_name, const ClientSocketHandle* handle) const {
452c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return base_.GetLoadState(group_name, handle);
453c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
454c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4553345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickDictionaryValue* HttpProxyClientSocketPool::GetInfoAsValue(
4563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    const std::string& name,
4573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    const std::string& type,
4583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    bool include_nested_pools) const {
4593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  DictionaryValue* dict = base_.GetInfoAsValue(name, type);
4603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (include_nested_pools) {
4613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    ListValue* list = new ListValue();
4623345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    if (tcp_pool_) {
4633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      list->Append(tcp_pool_->GetInfoAsValue("tcp_socket_pool",
4643345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                             "tcp_socket_pool",
4653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                             true));
4663345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    }
4673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    if (ssl_pool_) {
4683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      list->Append(ssl_pool_->GetInfoAsValue("ssl_socket_pool",
4693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                             "ssl_socket_pool",
4703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                             true));
4713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    }
4723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    dict->Set("nested_pools", list);
4733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
4743345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  return dict;
4753345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
4763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
477c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}  // namespace net
478