http_proxy_client_socket_pool.cc revision 4a5e2dc747d50c653511c68ccb2cfbfb740bd5a7
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));
533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickconst HostResolver::RequestInfo& HttpProxySocketParams::destination() const {
563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (tcp_params_ == NULL)
573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    return ssl_params_->tcp_params()->destination();
583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  else
593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    return tcp_params_->destination();
60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
62c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochHttpProxySocketParams::~HttpProxySocketParams() {}
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// HttpProxyConnectJobs will time out after this many seconds.  Note this is on
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// top of the timeout for the transport socket.
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const int kHttpProxyConnectJobTimeoutInSeconds = 30;
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
68c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochHttpProxyConnectJob::HttpProxyConnectJob(
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const std::string& group_name,
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const scoped_refptr<HttpProxySocketParams>& params,
71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const base::TimeDelta& timeout_duration,
723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    TCPClientSocketPool* tcp_pool,
733345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    SSLClientSocketPool* ssl_pool,
74731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    HostResolver* host_resolver,
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    Delegate* delegate,
76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NetLog* net_log)
77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    : ConnectJob(group_name, timeout_duration, delegate,
78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                 BoundNetLog::Make(net_log, NetLog::SOURCE_CONNECT_JOB)),
79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      params_(params),
80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      tcp_pool_(tcp_pool),
813345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      ssl_pool_(ssl_pool),
82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      resolver_(host_resolver),
83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ALLOW_THIS_IN_INITIALIZER_LIST(
843345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick          callback_(this, &HttpProxyConnectJob::OnIOComplete)),
853345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      using_spdy_(false) {
86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
88c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochHttpProxyConnectJob::~HttpProxyConnectJob() {}
89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
90c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochLoadState HttpProxyConnectJob::GetLoadState() const {
91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  switch (next_state_) {
923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    case STATE_TCP_CONNECT:
933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    case STATE_TCP_CONNECT_COMPLETE:
943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    case STATE_SSL_CONNECT:
953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    case STATE_SSL_CONNECT_COMPLETE:
963345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      return transport_socket_handle_->GetLoadState();
973345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    case STATE_HTTP_PROXY_CONNECT:
983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    case STATE_HTTP_PROXY_CONNECT_COMPLETE:
99731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    case STATE_SPDY_PROXY_CREATE_STREAM:
100731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    case STATE_SPDY_PROXY_CREATE_STREAM_COMPLETE:
101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return LOAD_STATE_ESTABLISHING_PROXY_TUNNEL;
102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    default:
103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NOTREACHED();
104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return LOAD_STATE_IDLE;
105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint HttpProxyConnectJob::ConnectInternal() {
1093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (params_->tcp_params())
1103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    next_state_ = STATE_TCP_CONNECT;
1113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  else
1123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    next_state_ = STATE_SSL_CONNECT;
113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return DoLoop(OK);
114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid HttpProxyConnectJob::OnIOComplete(int result) {
117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int rv = DoLoop(result);
118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (rv != ERR_IO_PENDING)
119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NotifyDelegateOfCompletion(rv);  // Deletes |this|
120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint HttpProxyConnectJob::DoLoop(int result) {
1233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  DCHECK_NE(next_state_, STATE_NONE);
124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int rv = result;
126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  do {
127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    State state = next_state_;
1283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    next_state_ = STATE_NONE;
129c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    switch (state) {
1303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      case STATE_TCP_CONNECT:
131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        DCHECK_EQ(OK, rv);
132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        rv = DoTCPConnect();
133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        break;
1343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      case STATE_TCP_CONNECT_COMPLETE:
135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        rv = DoTCPConnectComplete(rv);
136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        break;
1373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      case STATE_SSL_CONNECT:
1383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        DCHECK_EQ(OK, rv);
1393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        rv = DoSSLConnect();
1403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        break;
1413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      case STATE_SSL_CONNECT_COMPLETE:
1423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        rv = DoSSLConnectComplete(rv);
1433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        break;
1443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      case STATE_HTTP_PROXY_CONNECT:
145c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        DCHECK_EQ(OK, rv);
146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        rv = DoHttpProxyConnect();
147c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        break;
1483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      case STATE_HTTP_PROXY_CONNECT_COMPLETE:
149c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        rv = DoHttpProxyConnectComplete(rv);
150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        break;
151731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      case STATE_SPDY_PROXY_CREATE_STREAM:
152731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        DCHECK_EQ(OK, rv);
153731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        rv = DoSpdyProxyCreateStream();
154731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        break;
155731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      case STATE_SPDY_PROXY_CREATE_STREAM_COMPLETE:
156731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        rv = DoSpdyProxyCreateStreamComplete(rv);
157731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        break;
158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      default:
159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        NOTREACHED() << "bad state";
160c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        rv = ERR_FAILED;
161c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        break;
162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
1633345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE);
164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
165c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return rv;
166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
168c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint HttpProxyConnectJob::DoTCPConnect() {
1693345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  next_state_ = STATE_TCP_CONNECT_COMPLETE;
1703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  transport_socket_handle_.reset(new ClientSocketHandle());
1713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  return transport_socket_handle_->Init(
172c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      group_name(), params_->tcp_params(),
173c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      params_->tcp_params()->destination().priority(), &callback_, tcp_pool_,
174c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      net_log());
175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint HttpProxyConnectJob::DoTCPConnectComplete(int result) {
178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (result != OK)
1793345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    return ERR_PROXY_CONNECTION_FAILED;
180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Reset the timer to just the length of time allowed for HttpProxy handshake
182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // so that a fast TCP connection plus a slow HttpProxy failure doesn't take
183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // longer to timeout than it should.
184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ResetTimer(base::TimeDelta::FromSeconds(
185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      kHttpProxyConnectJobTimeoutInSeconds));
186731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
1873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  next_state_ = STATE_HTTP_PROXY_CONNECT;
1883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  return result;
1893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
1903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
1913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickint HttpProxyConnectJob::DoSSLConnect() {
192731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (params_->tunnel()) {
193731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    HostPortProxyPair pair(params_->destination().host_port_pair(),
194731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                           ProxyServer::Direct());
195731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    if (params_->spdy_session_pool()->HasSession(pair)) {
196731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      using_spdy_ = true;
197731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      next_state_ = STATE_SPDY_PROXY_CREATE_STREAM;
198731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      return OK;
199731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    }
200731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
2013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  next_state_ = STATE_SSL_CONNECT_COMPLETE;
2023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  transport_socket_handle_.reset(new ClientSocketHandle());
2033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  return transport_socket_handle_->Init(
2043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      group_name(), params_->ssl_params(),
2053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      params_->ssl_params()->tcp_params()->destination().priority(),
2063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      &callback_, ssl_pool_, net_log());
2073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
2083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
2093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickint HttpProxyConnectJob::DoSSLConnectComplete(int result) {
2104a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) {
2114a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    error_response_info_ = transport_socket_handle_->ssl_error_response_info();
2124a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    DCHECK(error_response_info_.cert_request_info.get());
2134a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    return result;
2144a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  }
215731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (IsCertificateError(result)) {
216731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    if (params_->ssl_params()->load_flags() & LOAD_IGNORE_ALL_CERT_ERRORS)
217731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      result = OK;
218731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    else
219731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      // TODO(rch): allow the user to deal with proxy cert errors in the
220731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      // same way as server cert errors.
221731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      return ERR_PROXY_CERTIFICATE_INVALID;
222731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
2233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (result < 0) {
2243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    if (transport_socket_handle_->socket())
2253345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      transport_socket_handle_->socket()->Disconnect();
226731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    return ERR_PROXY_CONNECTION_FAILED;
2273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
2283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
2293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  SSLClientSocket* ssl =
2303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      static_cast<SSLClientSocket*>(transport_socket_handle_->socket());
2313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  using_spdy_ = ssl->was_spdy_negotiated();
2323345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
2333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Reset the timer to just the length of time allowed for HttpProxy handshake
2343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // so that a fast SSL connection plus a slow HttpProxy failure doesn't take
2353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // longer to timeout than it should.
2363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ResetTimer(base::TimeDelta::FromSeconds(
2373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      kHttpProxyConnectJobTimeoutInSeconds));
238731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // TODO(rch): If we ever decide to implement a "trusted" SPDY proxy
239731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // (one that we speak SPDY over SSL to, but to which we send HTTPS
240731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // request directly instead of through CONNECT tunnels, then we
241731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // need to add a predicate to this if statement so we fall through
242731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // to the else case. (HttpProxyClientSocket currently acts as
243731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // a "trusted" SPDY proxy).
244731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (using_spdy_ && params_->tunnel())
245731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    next_state_ = STATE_SPDY_PROXY_CREATE_STREAM;
246731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  else
247731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    next_state_ = STATE_HTTP_PROXY_CONNECT;
248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return result;
249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2514a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdochvoid HttpProxyConnectJob::GetAdditionalErrorState(ClientSocketHandle * handle) {
2524a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  if (error_response_info_.cert_request_info) {
2534a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    handle->set_ssl_error_response_info(error_response_info_);
2544a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    handle->set_is_ssl_error(true);
2554a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  }
2564a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch}
2574a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
258731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickint HttpProxyConnectJob::DoSpdyProxyCreateStream() {
259731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  DCHECK(using_spdy_);
260731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  DCHECK(params_->tunnel());
261731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
262731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  HostPortProxyPair pair(params_->destination().host_port_pair(),
263731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                         ProxyServer::Direct());
264731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  SpdySessionPool* spdy_pool = params_->spdy_session_pool();
265731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_refptr<SpdySession> spdy_session;
266731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // It's possible that a session to the proxy has recently been created
267731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (spdy_pool->HasSession(pair)) {
2684a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    if (transport_socket_handle_.get()) {
2694a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch      if (transport_socket_handle_->socket())
2704a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch        transport_socket_handle_->socket()->Disconnect();
2714a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch      transport_socket_handle_->Reset();
2724a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    }
273731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    spdy_session = spdy_pool->Get(pair, params_->spdy_settings(), net_log());
274731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  } else {
275731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    // Create a session direct to the proxy itself
276731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    int rv = spdy_pool->GetSpdySessionFromSocket(
277731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        pair, params_->spdy_settings(), transport_socket_handle_.release(),
278731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        net_log(), OK, &spdy_session, /*using_ssl_*/ true);
2794a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    if (rv < 0)
280731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      return rv;
281731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
282731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
283731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  next_state_ = STATE_SPDY_PROXY_CREATE_STREAM_COMPLETE;
284731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  return spdy_session->CreateStream(params_->request_url(),
285731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                    params_->destination().priority(),
286731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                    &spdy_stream_, net_log(), &callback_);
287731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
288731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
289731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickint HttpProxyConnectJob::DoSpdyProxyCreateStreamComplete(int result) {
290731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (result < 0)
291731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    return result;
292731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
293731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  next_state_ = STATE_HTTP_PROXY_CONNECT_COMPLETE;
294731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  transport_socket_.reset(
295731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      new SpdyProxyClientSocket(spdy_stream_,
296731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                params_->user_agent(),
297731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                params_->endpoint(),
298731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                params_->request_url(),
299731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                params_->destination().host_port_pair(),
300731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                params_->http_auth_cache(),
301731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                params_->http_auth_handler_factory()));
302731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  return transport_socket_->Connect(&callback_);
303731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
304731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
305c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint HttpProxyConnectJob::DoHttpProxyConnect() {
3063345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  next_state_ = STATE_HTTP_PROXY_CONNECT_COMPLETE;
3073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  const HostResolver::RequestInfo& tcp_destination = params_->destination();
3083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  const HostPortPair& proxy_server = tcp_destination.host_port_pair();
309c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
310c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Add a HttpProxy connection on top of the tcp socket.
3113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  transport_socket_.reset(
3123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      new HttpProxyClientSocket(transport_socket_handle_.release(),
3133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                params_->request_url(),
3143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                params_->user_agent(),
3153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                params_->endpoint(),
3163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                proxy_server,
3173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                params_->http_auth_cache(),
3183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                params_->http_auth_handler_factory(),
3193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                params_->tunnel(),
3203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                using_spdy_));
321731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  return transport_socket_->Connect(&callback_);
322c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
323c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint HttpProxyConnectJob::DoHttpProxyConnectComplete(int result) {
325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (result == OK || result == ERR_PROXY_AUTH_REQUESTED)
3263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      set_socket(transport_socket_.release());
327c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
328c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return result;
329c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
330c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3313345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickHttpProxyClientSocketPool::
3323345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickHttpProxyConnectJobFactory::HttpProxyConnectJobFactory(
3333345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    TCPClientSocketPool* tcp_pool,
3343345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    SSLClientSocketPool* ssl_pool,
3353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    HostResolver* host_resolver,
3363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    NetLog* net_log)
3373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    : tcp_pool_(tcp_pool),
3383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      ssl_pool_(ssl_pool),
3393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      host_resolver_(host_resolver),
3403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      net_log_(net_log) {
3413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  base::TimeDelta max_pool_timeout = base::TimeDelta();
3423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (tcp_pool_)
3433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    max_pool_timeout = tcp_pool_->ConnectionTimeout();
3443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (ssl_pool_)
3453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    max_pool_timeout = std::max(max_pool_timeout,
3463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                ssl_pool_->ConnectionTimeout());
3473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  timeout_ = max_pool_timeout +
3483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    base::TimeDelta::FromSeconds(kHttpProxyConnectJobTimeoutInSeconds);
3493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
3503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
3513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
352c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochConnectJob*
353c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochHttpProxyClientSocketPool::HttpProxyConnectJobFactory::NewConnectJob(
354c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const std::string& group_name,
355c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const PoolBase::Request& request,
356c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ConnectJob::Delegate* delegate) const {
357c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return new HttpProxyConnectJob(group_name, request.params(),
3583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                 ConnectionTimeout(), tcp_pool_, ssl_pool_,
3593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                 host_resolver_, delegate, net_log_);
360c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
361c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
362c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochHttpProxyClientSocketPool::HttpProxyClientSocketPool(
363c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int max_sockets,
364c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int max_sockets_per_group,
3653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    ClientSocketPoolHistograms* histograms,
366731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    HostResolver* host_resolver,
3673345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    TCPClientSocketPool* tcp_pool,
3683345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    SSLClientSocketPool* ssl_pool,
369c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NetLog* net_log)
3703345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    : tcp_pool_(tcp_pool),
3713345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      ssl_pool_(ssl_pool),
3723345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      base_(max_sockets, max_sockets_per_group, histograms,
373c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            base::TimeDelta::FromSeconds(
374c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                ClientSocketPool::unused_idle_socket_timeout()),
375c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            base::TimeDelta::FromSeconds(kUsedIdleSocketTimeout),
3763345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick            new HttpProxyConnectJobFactory(tcp_pool, ssl_pool, host_resolver,
3773345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                           net_log)) {}
378c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
379c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochHttpProxyClientSocketPool::~HttpProxyClientSocketPool() {}
380c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
381c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint HttpProxyClientSocketPool::RequestSocket(const std::string& group_name,
382c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                             const void* socket_params,
383c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                             RequestPriority priority,
384c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                             ClientSocketHandle* handle,
385c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                             CompletionCallback* callback,
386c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                             const BoundNetLog& net_log) {
387c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const scoped_refptr<HttpProxySocketParams>* casted_socket_params =
388c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      static_cast<const scoped_refptr<HttpProxySocketParams>*>(socket_params);
389c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
390c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return base_.RequestSocket(group_name, *casted_socket_params, priority,
391c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                             handle, callback, net_log);
392c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
393c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
394731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid HttpProxyClientSocketPool::RequestSockets(
395731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    const std::string& group_name,
396731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    const void* params,
397731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    int num_sockets,
398731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    const BoundNetLog& net_log) {
399731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  const scoped_refptr<HttpProxySocketParams>* casted_params =
400731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      static_cast<const scoped_refptr<HttpProxySocketParams>*>(params);
401731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
402731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  base_.RequestSockets(group_name, *casted_params, num_sockets, net_log);
403731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
404731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
405c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid HttpProxyClientSocketPool::CancelRequest(
406c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const std::string& group_name,
407c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ClientSocketHandle* handle) {
408c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  base_.CancelRequest(group_name, handle);
409c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
410c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
411c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid HttpProxyClientSocketPool::ReleaseSocket(const std::string& group_name,
412c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                              ClientSocket* socket, int id) {
413c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  base_.ReleaseSocket(group_name, socket, id);
414c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
415c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
416c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid HttpProxyClientSocketPool::Flush() {
417c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  base_.Flush();
418c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
419c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
420c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid HttpProxyClientSocketPool::CloseIdleSockets() {
421c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  base_.CloseIdleSockets();
422c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
423c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
424c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint HttpProxyClientSocketPool::IdleSocketCountInGroup(
425c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const std::string& group_name) const {
426c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return base_.IdleSocketCountInGroup(group_name);
427c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
428c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
429c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochLoadState HttpProxyClientSocketPool::GetLoadState(
430c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const std::string& group_name, const ClientSocketHandle* handle) const {
431c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return base_.GetLoadState(group_name, handle);
432c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
433c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4343345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickDictionaryValue* HttpProxyClientSocketPool::GetInfoAsValue(
4353345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    const std::string& name,
4363345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    const std::string& type,
4373345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    bool include_nested_pools) const {
4383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  DictionaryValue* dict = base_.GetInfoAsValue(name, type);
4393345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (include_nested_pools) {
4403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    ListValue* list = new ListValue();
4413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    if (tcp_pool_) {
4423345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      list->Append(tcp_pool_->GetInfoAsValue("tcp_socket_pool",
4433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                             "tcp_socket_pool",
4443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                             true));
4453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    }
4463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    if (ssl_pool_) {
4473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      list->Append(ssl_pool_->GetInfoAsValue("ssl_socket_pool",
4483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                             "ssl_socket_pool",
4493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                             true));
4503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    }
4513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    dict->Set("nested_pools", list);
4523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
4533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  return dict;
4543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
4553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
456c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}  // namespace net
457