1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#ifndef NET_HTTP_HTTP_PROXY_CLIENT_SOCKET_POOL_H_
6#define NET_HTTP_HTTP_PROXY_CLIENT_SOCKET_POOL_H_
7
8#include <string>
9
10#include "base/basictypes.h"
11#include "base/memory/ref_counted.h"
12#include "base/memory/scoped_ptr.h"
13#include "base/memory/weak_ptr.h"
14#include "base/time/time.h"
15#include "net/base/host_port_pair.h"
16#include "net/base/net_export.h"
17#include "net/http/http_auth.h"
18#include "net/http/http_response_info.h"
19#include "net/http/proxy_client_socket.h"
20#include "net/socket/client_socket_pool.h"
21#include "net/socket/client_socket_pool_base.h"
22#include "net/socket/client_socket_pool_histograms.h"
23#include "net/socket/ssl_client_socket.h"
24#include "net/spdy/spdy_session.h"
25
26namespace net {
27
28class HostResolver;
29class HttpAuthCache;
30class HttpAuthHandlerFactory;
31class SSLClientSocketPool;
32class SSLSocketParams;
33class SpdySessionPool;
34class SpdyStream;
35class TransportClientSocketPool;
36class TransportSocketParams;
37
38// HttpProxySocketParams only needs the socket params for one of the proxy
39// types.  The other param must be NULL.  When using an HTTP Proxy,
40// |transport_params| must be set.  When using an HTTPS Proxy, |ssl_params|
41// must be set.
42class NET_EXPORT_PRIVATE HttpProxySocketParams
43    : public base::RefCounted<HttpProxySocketParams> {
44 public:
45  HttpProxySocketParams(
46      const scoped_refptr<TransportSocketParams>& transport_params,
47      const scoped_refptr<SSLSocketParams>& ssl_params,
48      const GURL& request_url,
49      const std::string& user_agent,
50      const HostPortPair& endpoint,
51      HttpAuthCache* http_auth_cache,
52      HttpAuthHandlerFactory* http_auth_handler_factory,
53      SpdySessionPool* spdy_session_pool,
54      bool tunnel);
55
56  const scoped_refptr<TransportSocketParams>& transport_params() const {
57    return transport_params_;
58  }
59  const scoped_refptr<SSLSocketParams>& ssl_params() const {
60    return ssl_params_;
61  }
62  const GURL& request_url() const { return request_url_; }
63  const std::string& user_agent() const { return user_agent_; }
64  const HostPortPair& endpoint() const { return endpoint_; }
65  HttpAuthCache* http_auth_cache() const { return http_auth_cache_; }
66  HttpAuthHandlerFactory* http_auth_handler_factory() const {
67    return http_auth_handler_factory_;
68  }
69  SpdySessionPool* spdy_session_pool() {
70    return spdy_session_pool_;
71  }
72  const HostResolver::RequestInfo& destination() const;
73  bool tunnel() const { return tunnel_; }
74  bool ignore_limits() const { return ignore_limits_; }
75
76 private:
77  friend class base::RefCounted<HttpProxySocketParams>;
78  ~HttpProxySocketParams();
79
80  const scoped_refptr<TransportSocketParams> transport_params_;
81  const scoped_refptr<SSLSocketParams> ssl_params_;
82  SpdySessionPool* spdy_session_pool_;
83  const GURL request_url_;
84  const std::string user_agent_;
85  const HostPortPair endpoint_;
86  HttpAuthCache* const http_auth_cache_;
87  HttpAuthHandlerFactory* const http_auth_handler_factory_;
88  const bool tunnel_;
89  bool ignore_limits_;
90
91  DISALLOW_COPY_AND_ASSIGN(HttpProxySocketParams);
92};
93
94// HttpProxyConnectJob optionally establishes a tunnel through the proxy
95// server after connecting the underlying transport socket.
96class HttpProxyConnectJob : public ConnectJob {
97 public:
98  HttpProxyConnectJob(const std::string& group_name,
99                      RequestPriority priority,
100                      const scoped_refptr<HttpProxySocketParams>& params,
101                      const base::TimeDelta& timeout_duration,
102                      TransportClientSocketPool* transport_pool,
103                      SSLClientSocketPool* ssl_pool,
104                      HostResolver* host_resolver,
105                      Delegate* delegate,
106                      NetLog* net_log);
107  virtual ~HttpProxyConnectJob();
108
109  // ConnectJob methods.
110  virtual LoadState GetLoadState() const OVERRIDE;
111
112  virtual void GetAdditionalErrorState(ClientSocketHandle* handle) OVERRIDE;
113
114 private:
115  enum State {
116    STATE_TCP_CONNECT,
117    STATE_TCP_CONNECT_COMPLETE,
118    STATE_SSL_CONNECT,
119    STATE_SSL_CONNECT_COMPLETE,
120    STATE_HTTP_PROXY_CONNECT,
121    STATE_HTTP_PROXY_CONNECT_COMPLETE,
122    STATE_SPDY_PROXY_CREATE_STREAM,
123    STATE_SPDY_PROXY_CREATE_STREAM_COMPLETE,
124    STATE_SPDY_PROXY_CONNECT_COMPLETE,
125    STATE_NONE,
126  };
127
128  void OnIOComplete(int result);
129
130  // Runs the state transition loop.
131  int DoLoop(int result);
132
133  // Connecting to HTTP Proxy
134  int DoTransportConnect();
135  int DoTransportConnectComplete(int result);
136  // Connecting to HTTPS Proxy
137  int DoSSLConnect();
138  int DoSSLConnectComplete(int result);
139
140  int DoHttpProxyConnect();
141  int DoHttpProxyConnectComplete(int result);
142
143  int DoSpdyProxyCreateStream();
144  int DoSpdyProxyCreateStreamComplete(int result);
145
146  // Begins the tcp connection and the optional Http proxy tunnel.  If the
147  // request is not immediately servicable (likely), the request will return
148  // ERR_IO_PENDING. An OK return from this function or the callback means
149  // that the connection is established; ERR_PROXY_AUTH_REQUESTED means
150  // that the tunnel needs authentication credentials, the socket will be
151  // returned in this case, and must be release back to the pool; or
152  // a standard net error code will be returned.
153  virtual int ConnectInternal() OVERRIDE;
154
155  base::WeakPtrFactory<HttpProxyConnectJob> weak_ptr_factory_;
156  scoped_refptr<HttpProxySocketParams> params_;
157  TransportClientSocketPool* const transport_pool_;
158  SSLClientSocketPool* const ssl_pool_;
159  HostResolver* const resolver_;
160
161  State next_state_;
162  CompletionCallback callback_;
163  scoped_ptr<ClientSocketHandle> transport_socket_handle_;
164  scoped_ptr<ProxyClientSocket> transport_socket_;
165  bool using_spdy_;
166  // Protocol negotiated with the server.
167  NextProto protocol_negotiated_;
168
169  HttpResponseInfo error_response_info_;
170
171  SpdyStreamRequest spdy_stream_request_;
172
173  DISALLOW_COPY_AND_ASSIGN(HttpProxyConnectJob);
174};
175
176class NET_EXPORT_PRIVATE HttpProxyClientSocketPool
177    : public ClientSocketPool,
178      public HigherLayeredPool {
179 public:
180  typedef HttpProxySocketParams SocketParams;
181
182  HttpProxyClientSocketPool(
183      int max_sockets,
184      int max_sockets_per_group,
185      ClientSocketPoolHistograms* histograms,
186      HostResolver* host_resolver,
187      TransportClientSocketPool* transport_pool,
188      SSLClientSocketPool* ssl_pool,
189      NetLog* net_log);
190
191  virtual ~HttpProxyClientSocketPool();
192
193  // ClientSocketPool implementation.
194  virtual int RequestSocket(const std::string& group_name,
195                            const void* connect_params,
196                            RequestPriority priority,
197                            ClientSocketHandle* handle,
198                            const CompletionCallback& callback,
199                            const BoundNetLog& net_log) OVERRIDE;
200
201  virtual void RequestSockets(const std::string& group_name,
202                              const void* params,
203                              int num_sockets,
204                              const BoundNetLog& net_log) OVERRIDE;
205
206  virtual void CancelRequest(const std::string& group_name,
207                             ClientSocketHandle* handle) OVERRIDE;
208
209  virtual void ReleaseSocket(const std::string& group_name,
210                             scoped_ptr<StreamSocket> socket,
211                             int id) OVERRIDE;
212
213  virtual void FlushWithError(int error) OVERRIDE;
214
215  virtual void CloseIdleSockets() OVERRIDE;
216
217  virtual int IdleSocketCount() const OVERRIDE;
218
219  virtual int IdleSocketCountInGroup(
220      const std::string& group_name) const OVERRIDE;
221
222  virtual LoadState GetLoadState(
223      const std::string& group_name,
224      const ClientSocketHandle* handle) const OVERRIDE;
225
226  virtual base::DictionaryValue* GetInfoAsValue(
227      const std::string& name,
228      const std::string& type,
229      bool include_nested_pools) const OVERRIDE;
230
231  virtual base::TimeDelta ConnectionTimeout() const OVERRIDE;
232
233  virtual ClientSocketPoolHistograms* histograms() const OVERRIDE;
234
235  // LowerLayeredPool implementation.
236  virtual bool IsStalled() const OVERRIDE;
237
238  virtual void AddHigherLayeredPool(HigherLayeredPool* higher_pool) OVERRIDE;
239
240  virtual void RemoveHigherLayeredPool(HigherLayeredPool* higher_pool) OVERRIDE;
241
242  // HigherLayeredPool implementation.
243  virtual bool CloseOneIdleConnection() OVERRIDE;
244
245 private:
246  typedef ClientSocketPoolBase<HttpProxySocketParams> PoolBase;
247
248  class HttpProxyConnectJobFactory : public PoolBase::ConnectJobFactory {
249   public:
250    HttpProxyConnectJobFactory(
251        TransportClientSocketPool* transport_pool,
252        SSLClientSocketPool* ssl_pool,
253        HostResolver* host_resolver,
254        NetLog* net_log);
255
256    // ClientSocketPoolBase::ConnectJobFactory methods.
257    virtual scoped_ptr<ConnectJob> NewConnectJob(
258        const std::string& group_name,
259        const PoolBase::Request& request,
260        ConnectJob::Delegate* delegate) const OVERRIDE;
261
262    virtual base::TimeDelta ConnectionTimeout() const OVERRIDE;
263
264   private:
265    TransportClientSocketPool* const transport_pool_;
266    SSLClientSocketPool* const ssl_pool_;
267    HostResolver* const host_resolver_;
268    NetLog* net_log_;
269    base::TimeDelta timeout_;
270
271    DISALLOW_COPY_AND_ASSIGN(HttpProxyConnectJobFactory);
272  };
273
274  TransportClientSocketPool* const transport_pool_;
275  SSLClientSocketPool* const ssl_pool_;
276  PoolBase base_;
277
278  DISALLOW_COPY_AND_ASSIGN(HttpProxyClientSocketPool);
279};
280
281}  // namespace net
282
283#endif  // NET_HTTP_HTTP_PROXY_CLIENT_SOCKET_POOL_H_
284