1// Copyright (c) 2011 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#pragma once
8
9#include <string>
10
11#include "base/basictypes.h"
12#include "base/memory/ref_counted.h"
13#include "base/memory/scoped_ptr.h"
14#include "base/time.h"
15#include "net/base/host_port_pair.h"
16#include "net/http/http_auth.h"
17#include "net/http/http_response_info.h"
18#include "net/http/proxy_client_socket.h"
19#include "net/socket/client_socket_pool_base.h"
20#include "net/socket/client_socket_pool_histograms.h"
21#include "net/socket/client_socket_pool.h"
22
23namespace net {
24
25class HostResolver;
26class HttpAuthCache;
27class HttpAuthHandlerFactory;
28class SSLClientSocketPool;
29class SSLSocketParams;
30class SpdySessionPool;
31class SpdyStream;
32class TransportClientSocketPool;
33class TransportSocketParams;
34
35// HttpProxySocketParams only needs the socket params for one of the proxy
36// types.  The other param must be NULL.  When using an HTTP Proxy,
37// |transport_params| must be set.  When using an HTTPS Proxy, |ssl_params|
38// must be set.
39class HttpProxySocketParams : public base::RefCounted<HttpProxySocketParams> {
40 public:
41  HttpProxySocketParams(
42      const scoped_refptr<TransportSocketParams>& transport_params,
43      const scoped_refptr<SSLSocketParams>& ssl_params,
44      const GURL& request_url,
45      const std::string& user_agent,
46      HostPortPair endpoint,
47      HttpAuthCache* http_auth_cache,
48      HttpAuthHandlerFactory* http_auth_handler_factory,
49      SpdySessionPool* spdy_session_pool,
50      bool tunnel);
51
52  const scoped_refptr<TransportSocketParams>& transport_params() const {
53    return transport_params_;
54  }
55  const scoped_refptr<SSLSocketParams>& ssl_params() const {
56    return ssl_params_;
57  }
58  const GURL& request_url() const { return request_url_; }
59  const std::string& user_agent() const { return user_agent_; }
60  const HostPortPair& endpoint() const { return endpoint_; }
61  HttpAuthCache* http_auth_cache() const { return http_auth_cache_; }
62  HttpAuthHandlerFactory* http_auth_handler_factory() const {
63    return http_auth_handler_factory_;
64  }
65  SpdySessionPool* spdy_session_pool() {
66    return spdy_session_pool_;
67  }
68  const HostResolver::RequestInfo& destination() const;
69  bool tunnel() const { return tunnel_; }
70  bool ignore_limits() const { return ignore_limits_; }
71#ifdef ANDROID
72  // Gets the UID of the calling process
73  bool getUID(uid_t *uid) const;
74  void setUID(uid_t uid);
75#endif
76
77 private:
78  friend class base::RefCounted<HttpProxySocketParams>;
79  ~HttpProxySocketParams();
80
81  const scoped_refptr<TransportSocketParams> transport_params_;
82  const scoped_refptr<SSLSocketParams> ssl_params_;
83  SpdySessionPool* spdy_session_pool_;
84  const GURL request_url_;
85  const std::string user_agent_;
86  const HostPortPair endpoint_;
87  HttpAuthCache* const http_auth_cache_;
88  HttpAuthHandlerFactory* const http_auth_handler_factory_;
89  const bool tunnel_;
90  bool ignore_limits_;
91
92  DISALLOW_COPY_AND_ASSIGN(HttpProxySocketParams);
93};
94
95// HttpProxyConnectJob optionally establishes a tunnel through the proxy
96// server after connecting the underlying transport socket.
97class HttpProxyConnectJob : public ConnectJob {
98 public:
99  HttpProxyConnectJob(const std::string& group_name,
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;
111
112  virtual void GetAdditionalErrorState(ClientSocketHandle* handle);
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();
154
155  scoped_refptr<HttpProxySocketParams> params_;
156  TransportClientSocketPool* const transport_pool_;
157  SSLClientSocketPool* const ssl_pool_;
158  HostResolver* const resolver_;
159
160  State next_state_;
161  CompletionCallbackImpl<HttpProxyConnectJob> callback_;
162  scoped_ptr<ClientSocketHandle> transport_socket_handle_;
163  scoped_ptr<ProxyClientSocket> transport_socket_;
164  bool using_spdy_;
165
166  HttpResponseInfo error_response_info_;
167
168  scoped_refptr<SpdyStream> spdy_stream_;
169
170  DISALLOW_COPY_AND_ASSIGN(HttpProxyConnectJob);
171};
172
173class HttpProxyClientSocketPool : public ClientSocketPool {
174 public:
175  HttpProxyClientSocketPool(
176      int max_sockets,
177      int max_sockets_per_group,
178      ClientSocketPoolHistograms* histograms,
179      HostResolver* host_resolver,
180      TransportClientSocketPool* transport_pool,
181      SSLClientSocketPool* ssl_pool,
182      NetLog* net_log);
183
184  virtual ~HttpProxyClientSocketPool();
185
186  // ClientSocketPool methods:
187  virtual int RequestSocket(const std::string& group_name,
188                            const void* connect_params,
189                            RequestPriority priority,
190                            ClientSocketHandle* handle,
191                            CompletionCallback* callback,
192                            const BoundNetLog& net_log);
193
194  virtual void RequestSockets(const std::string& group_name,
195                              const void* params,
196                              int num_sockets,
197                              const BoundNetLog& net_log);
198
199  virtual void CancelRequest(const std::string& group_name,
200                             ClientSocketHandle* handle);
201
202  virtual void ReleaseSocket(const std::string& group_name,
203                             ClientSocket* socket,
204                             int id);
205
206  virtual void Flush();
207
208  virtual void CloseIdleSockets();
209
210  virtual int IdleSocketCount() const;
211
212  virtual int IdleSocketCountInGroup(const std::string& group_name) const;
213
214  virtual LoadState GetLoadState(const std::string& group_name,
215                                 const ClientSocketHandle* handle) const;
216
217  virtual DictionaryValue* GetInfoAsValue(const std::string& name,
218                                          const std::string& type,
219                                          bool include_nested_pools) const;
220
221  virtual base::TimeDelta ConnectionTimeout() const;
222
223  virtual ClientSocketPoolHistograms* histograms() const;
224
225 private:
226  typedef ClientSocketPoolBase<HttpProxySocketParams> PoolBase;
227
228  class HttpProxyConnectJobFactory : public PoolBase::ConnectJobFactory {
229   public:
230    HttpProxyConnectJobFactory(
231        TransportClientSocketPool* transport_pool,
232        SSLClientSocketPool* ssl_pool,
233        HostResolver* host_resolver,
234        NetLog* net_log);
235
236    // ClientSocketPoolBase::ConnectJobFactory methods.
237    virtual ConnectJob* NewConnectJob(const std::string& group_name,
238                                      const PoolBase::Request& request,
239                                      ConnectJob::Delegate* delegate) const;
240
241    virtual base::TimeDelta ConnectionTimeout() const { return timeout_; }
242
243   private:
244    TransportClientSocketPool* const transport_pool_;
245    SSLClientSocketPool* const ssl_pool_;
246    HostResolver* const host_resolver_;
247    NetLog* net_log_;
248    base::TimeDelta timeout_;
249
250    DISALLOW_COPY_AND_ASSIGN(HttpProxyConnectJobFactory);
251  };
252
253  TransportClientSocketPool* const transport_pool_;
254  SSLClientSocketPool* const ssl_pool_;
255  PoolBase base_;
256
257  DISALLOW_COPY_AND_ASSIGN(HttpProxyClientSocketPool);
258};
259
260REGISTER_SOCKET_PARAMS_FOR_POOL(HttpProxyClientSocketPool,
261                                HttpProxySocketParams);
262
263}  // namespace net
264
265#endif  // NET_HTTP_HTTP_PROXY_CLIENT_SOCKET_POOL_H_
266