1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 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"
21ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "net/socket/transport_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(
31ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    const scoped_refptr<TransportSocketParams>& transport_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,
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    bool tunnel)
40ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    : transport_params_(transport_params),
413345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      ssl_params_(ssl_params),
42731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      spdy_session_pool_(spdy_session_pool),
43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      request_url_(request_url),
443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      user_agent_(user_agent),
45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      endpoint_(endpoint),
463345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      http_auth_cache_(tunnel ? http_auth_cache : NULL),
473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      http_auth_handler_factory_(tunnel ? http_auth_handler_factory : NULL),
48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      tunnel_(tunnel) {
49ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  DCHECK((transport_params == NULL && ssl_params != NULL) ||
50ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen         (transport_params != NULL && ssl_params == NULL));
51ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (transport_params_)
52ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ignore_limits_ = transport_params->ignore_limits();
53ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  else
54ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ignore_limits_ = ssl_params->ignore_limits();
553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickconst HostResolver::RequestInfo& HttpProxySocketParams::destination() const {
58ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (transport_params_ == NULL)
59ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return ssl_params_->transport_params()->destination();
603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  else
61ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    return transport_params_->destination();
62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochHttpProxySocketParams::~HttpProxySocketParams() {}
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
66e14dcc5a172cad1c4716af7ab94121a73c0c698eAshish Sharma#ifdef ANDROID
67e14dcc5a172cad1c4716af7ab94121a73c0c698eAshish Sharmabool HttpProxySocketParams::getUID(uid_t *uid) const {
68e14dcc5a172cad1c4716af7ab94121a73c0c698eAshish Sharma  if (transport_params_ == NULL)
69e14dcc5a172cad1c4716af7ab94121a73c0c698eAshish Sharma    return ssl_params_->transport_params()->getUID(uid);
70e14dcc5a172cad1c4716af7ab94121a73c0c698eAshish Sharma  else
71e14dcc5a172cad1c4716af7ab94121a73c0c698eAshish Sharma    return transport_params_->getUID(uid);
72e14dcc5a172cad1c4716af7ab94121a73c0c698eAshish Sharma}
73e14dcc5a172cad1c4716af7ab94121a73c0c698eAshish Sharma
74e14dcc5a172cad1c4716af7ab94121a73c0c698eAshish Sharmavoid HttpProxySocketParams::setUID(uid_t uid) {
75e14dcc5a172cad1c4716af7ab94121a73c0c698eAshish Sharma  if (transport_params_ == NULL)
76e14dcc5a172cad1c4716af7ab94121a73c0c698eAshish Sharma    ssl_params_->transport_params()->setUID(uid);
77e14dcc5a172cad1c4716af7ab94121a73c0c698eAshish Sharma  else
78e14dcc5a172cad1c4716af7ab94121a73c0c698eAshish Sharma    transport_params_->setUID(uid);
79e14dcc5a172cad1c4716af7ab94121a73c0c698eAshish Sharma}
80e14dcc5a172cad1c4716af7ab94121a73c0c698eAshish Sharma#endif
81e14dcc5a172cad1c4716af7ab94121a73c0c698eAshish Sharma
82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// HttpProxyConnectJobs will time out after this many seconds.  Note this is on
83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// top of the timeout for the transport socket.
84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochstatic const int kHttpProxyConnectJobTimeoutInSeconds = 30;
85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
86c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochHttpProxyConnectJob::HttpProxyConnectJob(
87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const std::string& group_name,
88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const scoped_refptr<HttpProxySocketParams>& params,
89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const base::TimeDelta& timeout_duration,
90ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    TransportClientSocketPool* transport_pool,
913345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    SSLClientSocketPool* ssl_pool,
92731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    HostResolver* host_resolver,
93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    Delegate* delegate,
94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NetLog* net_log)
95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    : ConnectJob(group_name, timeout_duration, delegate,
96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                 BoundNetLog::Make(net_log, NetLog::SOURCE_CONNECT_JOB)),
97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      params_(params),
98ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      transport_pool_(transport_pool),
993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      ssl_pool_(ssl_pool),
100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      resolver_(host_resolver),
101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      ALLOW_THIS_IN_INITIALIZER_LIST(
1023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick          callback_(this, &HttpProxyConnectJob::OnIOComplete)),
1033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      using_spdy_(false) {
104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
106c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochHttpProxyConnectJob::~HttpProxyConnectJob() {}
107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
108c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochLoadState HttpProxyConnectJob::GetLoadState() const {
109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  switch (next_state_) {
1103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    case STATE_TCP_CONNECT:
1113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    case STATE_TCP_CONNECT_COMPLETE:
1123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    case STATE_SSL_CONNECT:
1133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    case STATE_SSL_CONNECT_COMPLETE:
1143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      return transport_socket_handle_->GetLoadState();
1153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    case STATE_HTTP_PROXY_CONNECT:
1163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    case STATE_HTTP_PROXY_CONNECT_COMPLETE:
117731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    case STATE_SPDY_PROXY_CREATE_STREAM:
118731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    case STATE_SPDY_PROXY_CREATE_STREAM_COMPLETE:
119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return LOAD_STATE_ESTABLISHING_PROXY_TUNNEL;
120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    default:
121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      NOTREACHED();
122c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      return LOAD_STATE_IDLE;
123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
124c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
125c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
12672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenvoid HttpProxyConnectJob::GetAdditionalErrorState(ClientSocketHandle * handle) {
12772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (error_response_info_.cert_request_info) {
12872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    handle->set_ssl_error_response_info(error_response_info_);
12972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    handle->set_is_ssl_error(true);
13072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
132c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid HttpProxyConnectJob::OnIOComplete(int result) {
134c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int rv = DoLoop(result);
135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (rv != ERR_IO_PENDING)
136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NotifyDelegateOfCompletion(rv);  // Deletes |this|
137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
138c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
139c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint HttpProxyConnectJob::DoLoop(int result) {
1403345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  DCHECK_NE(next_state_, STATE_NONE);
141c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
142c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int rv = result;
143c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  do {
144c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    State state = next_state_;
1453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    next_state_ = STATE_NONE;
146c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    switch (state) {
1473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      case STATE_TCP_CONNECT:
148c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        DCHECK_EQ(OK, rv);
149ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        rv = DoTransportConnect();
150c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        break;
1513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      case STATE_TCP_CONNECT_COMPLETE:
152ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        rv = DoTransportConnectComplete(rv);
153c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        break;
1543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      case STATE_SSL_CONNECT:
1553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        DCHECK_EQ(OK, rv);
1563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        rv = DoSSLConnect();
1573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        break;
1583345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      case STATE_SSL_CONNECT_COMPLETE:
1593345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        rv = DoSSLConnectComplete(rv);
1603345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick        break;
1613345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      case STATE_HTTP_PROXY_CONNECT:
162c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        DCHECK_EQ(OK, rv);
163c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        rv = DoHttpProxyConnect();
164c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        break;
1653345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      case STATE_HTTP_PROXY_CONNECT_COMPLETE:
166c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        rv = DoHttpProxyConnectComplete(rv);
167c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        break;
168731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      case STATE_SPDY_PROXY_CREATE_STREAM:
169731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        DCHECK_EQ(OK, rv);
170731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        rv = DoSpdyProxyCreateStream();
171731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        break;
172731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      case STATE_SPDY_PROXY_CREATE_STREAM_COMPLETE:
173731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        rv = DoSpdyProxyCreateStreamComplete(rv);
174731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        break;
175c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      default:
176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        NOTREACHED() << "bad state";
177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        rv = ERR_FAILED;
178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        break;
179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
1803345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  } while (rv != ERR_IO_PENDING && next_state_ != STATE_NONE);
181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return rv;
183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
185ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenint HttpProxyConnectJob::DoTransportConnect() {
1863345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  next_state_ = STATE_TCP_CONNECT_COMPLETE;
1873345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  transport_socket_handle_.reset(new ClientSocketHandle());
1883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  return transport_socket_handle_->Init(
189ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      group_name(),
190ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      params_->transport_params(),
191ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      params_->transport_params()->destination().priority(),
192ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      &callback_,
193ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      transport_pool_,
194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      net_log());
195c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
196c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
197ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsenint HttpProxyConnectJob::DoTransportConnectComplete(int result) {
198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  if (result != OK)
1993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    return ERR_PROXY_CONNECTION_FAILED;
200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Reset the timer to just the length of time allowed for HttpProxy handshake
202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // so that a fast TCP connection plus a slow HttpProxy failure doesn't take
203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // longer to timeout than it should.
204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ResetTimer(base::TimeDelta::FromSeconds(
205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      kHttpProxyConnectJobTimeoutInSeconds));
206731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
2073345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  next_state_ = STATE_HTTP_PROXY_CONNECT;
2083345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  return result;
2093345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
2103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
2113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickint HttpProxyConnectJob::DoSSLConnect() {
212731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (params_->tunnel()) {
213731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    HostPortProxyPair pair(params_->destination().host_port_pair(),
214731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                           ProxyServer::Direct());
215731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    if (params_->spdy_session_pool()->HasSession(pair)) {
216731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      using_spdy_ = true;
217731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      next_state_ = STATE_SPDY_PROXY_CREATE_STREAM;
218731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      return OK;
219731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    }
220731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
2213345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  next_state_ = STATE_SSL_CONNECT_COMPLETE;
2223345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  transport_socket_handle_.reset(new ClientSocketHandle());
2233345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  return transport_socket_handle_->Init(
2243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      group_name(), params_->ssl_params(),
225ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      params_->ssl_params()->transport_params()->destination().priority(),
2263345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      &callback_, ssl_pool_, net_log());
2273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
2283345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
2293345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrickint HttpProxyConnectJob::DoSSLConnectComplete(int result) {
2304a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) {
2314a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    error_response_info_ = transport_socket_handle_->ssl_error_response_info();
2324a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    DCHECK(error_response_info_.cert_request_info.get());
2334a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    return result;
2344a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  }
235731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (IsCertificateError(result)) {
236731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    if (params_->ssl_params()->load_flags() & LOAD_IGNORE_ALL_CERT_ERRORS)
237731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      result = OK;
238731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    else
239731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      // TODO(rch): allow the user to deal with proxy cert errors in the
240731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      // same way as server cert errors.
241731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      return ERR_PROXY_CERTIFICATE_INVALID;
242731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
2433345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (result < 0) {
2443345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    if (transport_socket_handle_->socket())
2453345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      transport_socket_handle_->socket()->Disconnect();
246731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    return ERR_PROXY_CONNECTION_FAILED;
2473345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
2483345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
2493345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  SSLClientSocket* ssl =
2503345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      static_cast<SSLClientSocket*>(transport_socket_handle_->socket());
2513345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  using_spdy_ = ssl->was_spdy_negotiated();
2523345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
2533345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // Reset the timer to just the length of time allowed for HttpProxy handshake
2543345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // so that a fast SSL connection plus a slow HttpProxy failure doesn't take
2553345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  // longer to timeout than it should.
2563345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  ResetTimer(base::TimeDelta::FromSeconds(
2573345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      kHttpProxyConnectJobTimeoutInSeconds));
258731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // TODO(rch): If we ever decide to implement a "trusted" SPDY proxy
259731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // (one that we speak SPDY over SSL to, but to which we send HTTPS
260731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // request directly instead of through CONNECT tunnels, then we
261731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // need to add a predicate to this if statement so we fall through
262731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // to the else case. (HttpProxyClientSocket currently acts as
263731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // a "trusted" SPDY proxy).
264731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (using_spdy_ && params_->tunnel())
265731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    next_state_ = STATE_SPDY_PROXY_CREATE_STREAM;
266731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  else
267731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    next_state_ = STATE_HTTP_PROXY_CONNECT;
268c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return result;
269c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
270c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
2715852652987a195e279633156fd0f937f6e12a918Kristian Monsen#ifdef ANDROID
2725852652987a195e279633156fd0f937f6e12a918Kristian Monsen// TODO(kristianm): Find out if Connect should block
2735852652987a195e279633156fd0f937f6e12a918Kristian Monsen#endif
27472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenint HttpProxyConnectJob::DoHttpProxyConnect() {
27572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  next_state_ = STATE_HTTP_PROXY_CONNECT_COMPLETE;
27672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  const HostResolver::RequestInfo& tcp_destination = params_->destination();
27772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  const HostPortPair& proxy_server = tcp_destination.host_port_pair();
27872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
27972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Add a HttpProxy connection on top of the tcp socket.
28072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  transport_socket_.reset(
28172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      new HttpProxyClientSocket(transport_socket_handle_.release(),
28272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                params_->request_url(),
28372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                params_->user_agent(),
28472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                params_->endpoint(),
28572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                proxy_server,
28672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                params_->http_auth_cache(),
28772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                params_->http_auth_handler_factory(),
28872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                params_->tunnel(),
28972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                using_spdy_,
29072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                                params_->ssl_params() != NULL));
291e14dcc5a172cad1c4716af7ab94121a73c0c698eAshish Sharma
292e14dcc5a172cad1c4716af7ab94121a73c0c698eAshish Sharma#ifdef ANDROID
293e14dcc5a172cad1c4716af7ab94121a73c0c698eAshish Sharma  uid_t calling_uid = 0;
294e14dcc5a172cad1c4716af7ab94121a73c0c698eAshish Sharma  bool valid_uid = params_->transport_params()->getUID(&calling_uid);
295e14dcc5a172cad1c4716af7ab94121a73c0c698eAshish Sharma#endif
296e14dcc5a172cad1c4716af7ab94121a73c0c698eAshish Sharma
2975852652987a195e279633156fd0f937f6e12a918Kristian Monsen  return transport_socket_->Connect(&callback_
2985852652987a195e279633156fd0f937f6e12a918Kristian Monsen#ifdef ANDROID
2995852652987a195e279633156fd0f937f6e12a918Kristian Monsen                                    , false
300e14dcc5a172cad1c4716af7ab94121a73c0c698eAshish Sharma                                    , valid_uid
301e14dcc5a172cad1c4716af7ab94121a73c0c698eAshish Sharma                                    , calling_uid
3025852652987a195e279633156fd0f937f6e12a918Kristian Monsen#endif
3035852652987a195e279633156fd0f937f6e12a918Kristian Monsen                                   );
30472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
30572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
30672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenint HttpProxyConnectJob::DoHttpProxyConnectComplete(int result) {
30772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  if (result == OK || result == ERR_PROXY_AUTH_REQUESTED ||
30872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      result == ERR_HTTPS_PROXY_TUNNEL_RESPONSE) {
30972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      set_socket(transport_socket_.release());
3104a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch  }
31172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
31272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  return result;
3134a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch}
3144a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch
315731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickint HttpProxyConnectJob::DoSpdyProxyCreateStream() {
316731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  DCHECK(using_spdy_);
317731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  DCHECK(params_->tunnel());
318731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
319731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  HostPortProxyPair pair(params_->destination().host_port_pair(),
320731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                         ProxyServer::Direct());
321731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  SpdySessionPool* spdy_pool = params_->spdy_session_pool();
322731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_refptr<SpdySession> spdy_session;
323731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  // It's possible that a session to the proxy has recently been created
324731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (spdy_pool->HasSession(pair)) {
3254a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    if (transport_socket_handle_.get()) {
3264a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch      if (transport_socket_handle_->socket())
3274a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch        transport_socket_handle_->socket()->Disconnect();
3284a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch      transport_socket_handle_->Reset();
3294a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    }
330dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen    spdy_session = spdy_pool->Get(pair, net_log());
331731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  } else {
332731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    // Create a session direct to the proxy itself
333731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    int rv = spdy_pool->GetSpdySessionFromSocket(
334dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen        pair, transport_socket_handle_.release(),
335731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        net_log(), OK, &spdy_session, /*using_ssl_*/ true);
3364a5e2dc747d50c653511c68ccb2cfbfb740bd5a7Ben Murdoch    if (rv < 0)
337731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      return rv;
338731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
339731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
340731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  next_state_ = STATE_SPDY_PROXY_CREATE_STREAM_COMPLETE;
341731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  return spdy_session->CreateStream(params_->request_url(),
342731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                    params_->destination().priority(),
343201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                                    &spdy_stream_, spdy_session->net_log(),
344201ade2fbba22bfb27ae029f4d23fca6ded109a0Ben Murdoch                                    &callback_);
345731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
346731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
3477b9ca917061470268bf3395c8925d4b9cc52d8e1Kristian Monsen#ifdef ANDROID
3487b9ca917061470268bf3395c8925d4b9cc52d8e1Kristian Monsen// TODO(kristianm): Find out if Connect should block
3497b9ca917061470268bf3395c8925d4b9cc52d8e1Kristian Monsen#endif
350731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickint HttpProxyConnectJob::DoSpdyProxyCreateStreamComplete(int result) {
351731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  if (result < 0)
352731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    return result;
353731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
354e14dcc5a172cad1c4716af7ab94121a73c0c698eAshish Sharma#ifdef ANDROID
355e14dcc5a172cad1c4716af7ab94121a73c0c698eAshish Sharma  uid_t calling_uid = 0;
356e14dcc5a172cad1c4716af7ab94121a73c0c698eAshish Sharma  bool valid_uid = params_->transport_params()->getUID(&calling_uid);
357e14dcc5a172cad1c4716af7ab94121a73c0c698eAshish Sharma#endif
358e14dcc5a172cad1c4716af7ab94121a73c0c698eAshish Sharma
359731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  next_state_ = STATE_HTTP_PROXY_CONNECT_COMPLETE;
360731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  transport_socket_.reset(
361731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      new SpdyProxyClientSocket(spdy_stream_,
362731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                params_->user_agent(),
363731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                params_->endpoint(),
364731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                params_->request_url(),
365731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                params_->destination().host_port_pair(),
366731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                params_->http_auth_cache(),
367731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                                params_->http_auth_handler_factory()));
3687b9ca917061470268bf3395c8925d4b9cc52d8e1Kristian Monsen  return transport_socket_->Connect(&callback_
3697b9ca917061470268bf3395c8925d4b9cc52d8e1Kristian Monsen#ifdef ANDROID
3707b9ca917061470268bf3395c8925d4b9cc52d8e1Kristian Monsen                                    , false
371e14dcc5a172cad1c4716af7ab94121a73c0c698eAshish Sharma                                    , valid_uid
372e14dcc5a172cad1c4716af7ab94121a73c0c698eAshish Sharma                                    , calling_uid
3737b9ca917061470268bf3395c8925d4b9cc52d8e1Kristian Monsen#endif
3747b9ca917061470268bf3395c8925d4b9cc52d8e1Kristian Monsen                                   );
375731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
376731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
37772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsenint HttpProxyConnectJob::ConnectInternal() {
378ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (params_->transport_params())
37972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    next_state_ = STATE_TCP_CONNECT;
38072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  else
38172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    next_state_ = STATE_SSL_CONNECT;
38272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  return DoLoop(OK);
383c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
384c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
3853345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickHttpProxyClientSocketPool::
3863345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickHttpProxyConnectJobFactory::HttpProxyConnectJobFactory(
387ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    TransportClientSocketPool* transport_pool,
3883345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    SSLClientSocketPool* ssl_pool,
3893345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    HostResolver* host_resolver,
3903345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    NetLog* net_log)
391ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    : transport_pool_(transport_pool),
3923345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      ssl_pool_(ssl_pool),
3933345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      host_resolver_(host_resolver),
3943345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      net_log_(net_log) {
3953345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  base::TimeDelta max_pool_timeout = base::TimeDelta();
396ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  if (transport_pool_)
397ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    max_pool_timeout = transport_pool_->ConnectionTimeout();
3983345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (ssl_pool_)
3993345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    max_pool_timeout = std::max(max_pool_timeout,
4003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                ssl_pool_->ConnectionTimeout());
4013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  timeout_ = max_pool_timeout +
4023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    base::TimeDelta::FromSeconds(kHttpProxyConnectJobTimeoutInSeconds);
4033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
4043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
4053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
406c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochConnectJob*
407c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochHttpProxyClientSocketPool::HttpProxyConnectJobFactory::NewConnectJob(
408c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const std::string& group_name,
409c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const PoolBase::Request& request,
410c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ConnectJob::Delegate* delegate) const {
411ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  return new HttpProxyConnectJob(group_name,
412ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                 request.params(),
413ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                 ConnectionTimeout(),
414ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                 transport_pool_,
415ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                 ssl_pool_,
416ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                 host_resolver_,
417ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                 delegate,
418ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                 net_log_);
419c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
420c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
421c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochHttpProxyClientSocketPool::HttpProxyClientSocketPool(
422c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int max_sockets,
423c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    int max_sockets_per_group,
4243345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    ClientSocketPoolHistograms* histograms,
425731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    HostResolver* host_resolver,
426ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    TransportClientSocketPool* transport_pool,
4273345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    SSLClientSocketPool* ssl_pool,
428c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    NetLog* net_log)
429ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    : transport_pool_(transport_pool),
4303345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      ssl_pool_(ssl_pool),
4313345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      base_(max_sockets, max_sockets_per_group, histograms,
432c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            base::TimeDelta::FromSeconds(
433c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                ClientSocketPool::unused_idle_socket_timeout()),
434c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch            base::TimeDelta::FromSeconds(kUsedIdleSocketTimeout),
435ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen            new HttpProxyConnectJobFactory(transport_pool,
436ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                           ssl_pool,
437ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                           host_resolver,
4383345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                           net_log)) {}
439c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
440c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochHttpProxyClientSocketPool::~HttpProxyClientSocketPool() {}
441c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
442c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint HttpProxyClientSocketPool::RequestSocket(const std::string& group_name,
443c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                             const void* socket_params,
444c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                             RequestPriority priority,
445c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                             ClientSocketHandle* handle,
446c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                             CompletionCallback* callback,
447c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                             const BoundNetLog& net_log) {
448c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  const scoped_refptr<HttpProxySocketParams>* casted_socket_params =
449c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      static_cast<const scoped_refptr<HttpProxySocketParams>*>(socket_params);
450c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
451c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return base_.RequestSocket(group_name, *casted_socket_params, priority,
452c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                             handle, callback, net_log);
453c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
454c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
455731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickvoid HttpProxyClientSocketPool::RequestSockets(
456731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    const std::string& group_name,
457731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    const void* params,
458731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    int num_sockets,
459731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    const BoundNetLog& net_log) {
460731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  const scoped_refptr<HttpProxySocketParams>* casted_params =
461731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      static_cast<const scoped_refptr<HttpProxySocketParams>*>(params);
462731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
463731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  base_.RequestSockets(group_name, *casted_params, num_sockets, net_log);
464731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
465731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
466c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid HttpProxyClientSocketPool::CancelRequest(
467c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const std::string& group_name,
468c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    ClientSocketHandle* handle) {
469c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  base_.CancelRequest(group_name, handle);
470c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
471c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
472c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid HttpProxyClientSocketPool::ReleaseSocket(const std::string& group_name,
473c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                              ClientSocket* socket, int id) {
474c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  base_.ReleaseSocket(group_name, socket, id);
475c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
476c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
477c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid HttpProxyClientSocketPool::Flush() {
478c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  base_.Flush();
479c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
480c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
481c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochvoid HttpProxyClientSocketPool::CloseIdleSockets() {
482c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  base_.CloseIdleSockets();
483c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
484c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
48521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenint HttpProxyClientSocketPool::IdleSocketCount() const {
48621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  return base_.idle_socket_count();
48721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
48821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
489c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochint HttpProxyClientSocketPool::IdleSocketCountInGroup(
490c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const std::string& group_name) const {
491c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return base_.IdleSocketCountInGroup(group_name);
492c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
493c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
494c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochLoadState HttpProxyClientSocketPool::GetLoadState(
495c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    const std::string& group_name, const ClientSocketHandle* handle) const {
496c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  return base_.GetLoadState(group_name, handle);
497c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
498c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4993345a6884c488ff3a535c2c9acdd33d74b37e311Iain MerrickDictionaryValue* HttpProxyClientSocketPool::GetInfoAsValue(
5003345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    const std::string& name,
5013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    const std::string& type,
5023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    bool include_nested_pools) const {
5033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  DictionaryValue* dict = base_.GetInfoAsValue(name, type);
5043345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  if (include_nested_pools) {
5053345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    ListValue* list = new ListValue();
506ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (transport_pool_) {
507ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      list->Append(transport_pool_->GetInfoAsValue("transport_socket_pool",
508ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                                   "transport_socket_pool",
509ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                                   true));
5103345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    }
5113345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    if (ssl_pool_) {
5123345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick      list->Append(ssl_pool_->GetInfoAsValue("ssl_socket_pool",
5133345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                             "ssl_socket_pool",
5143345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick                                             true));
5153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    }
5163345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick    dict->Set("nested_pools", list);
5173345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  }
5183345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick  return dict;
5193345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick}
5203345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick
52121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenbase::TimeDelta HttpProxyClientSocketPool::ConnectionTimeout() const {
52221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  return base_.ConnectionTimeout();
52321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
52421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
52521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenClientSocketPoolHistograms* HttpProxyClientSocketPool::histograms() const {
52621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  return base_.histograms();
52721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
52821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
529c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}  // namespace net
530