• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2019 The Chromium Authors
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_CONNECT_JOB_H_
6 #define NET_HTTP_HTTP_PROXY_CONNECT_JOB_H_
7 
8 #include <memory>
9 #include <string>
10 
11 #include "base/functional/callback_forward.h"
12 #include "base/memory/ref_counted.h"
13 #include "base/time/time.h"
14 #include "net/base/host_port_pair.h"
15 #include "net/base/net_export.h"
16 #include "net/base/network_anonymization_key.h"
17 #include "net/base/request_priority.h"
18 #include "net/dns/public/resolve_error_info.h"
19 #include "net/http/http_auth.h"
20 #include "net/quic/quic_chromium_client_session.h"
21 #include "net/socket/connect_job.h"
22 #include "net/socket/ssl_client_socket.h"
23 #include "net/spdy/spdy_session_key.h"
24 #include "net/ssl/ssl_cert_request_info.h"
25 #include "net/traffic_annotation/network_traffic_annotation.h"
26 
27 namespace net {
28 
29 class HttpAuthController;
30 class HttpResponseInfo;
31 class NetworkQualityEstimator;
32 class SocketTag;
33 class ProxyClientSocket;
34 class SpdyStreamRequest;
35 class SSLSocketParams;
36 class TransportSocketParams;
37 class QuicStreamRequest;
38 
39 // HttpProxySocketParams only needs the socket params for one of the proxy
40 // types.  The other param must be NULL.  When using an HTTP proxy,
41 // |transport_params| must be set.  When using an HTTPS proxy or QUIC proxy,
42 // |ssl_params| must be set.
43 class NET_EXPORT_PRIVATE HttpProxySocketParams
44     : public base::RefCounted<HttpProxySocketParams> {
45  public:
46   HttpProxySocketParams(
47       scoped_refptr<TransportSocketParams> transport_params,
48       scoped_refptr<SSLSocketParams> ssl_params,
49       bool is_quic,
50       const HostPortPair& endpoint,
51       bool tunnel,
52       const NetworkTrafficAnnotationTag traffic_annotation,
53       const NetworkAnonymizationKey& network_anonymization_key);
54 
55   HttpProxySocketParams(const HttpProxySocketParams&) = delete;
56   HttpProxySocketParams& operator=(const HttpProxySocketParams&) = delete;
57 
transport_params()58   const scoped_refptr<TransportSocketParams>& transport_params() const {
59     return transport_params_;
60   }
ssl_params()61   const scoped_refptr<SSLSocketParams>& ssl_params() const {
62     return ssl_params_;
63   }
is_quic()64   bool is_quic() const { return is_quic_; }
endpoint()65   const HostPortPair& endpoint() const { return endpoint_; }
tunnel()66   bool tunnel() const { return tunnel_; }
network_anonymization_key()67   const NetworkAnonymizationKey& network_anonymization_key() const {
68     return network_anonymization_key_;
69   }
traffic_annotation()70   const NetworkTrafficAnnotationTag traffic_annotation() const {
71     return traffic_annotation_;
72   }
73 
74  private:
75   friend class base::RefCounted<HttpProxySocketParams>;
76   ~HttpProxySocketParams();
77 
78   const scoped_refptr<TransportSocketParams> transport_params_;
79   const scoped_refptr<SSLSocketParams> ssl_params_;
80   bool is_quic_;
81   const HostPortPair endpoint_;
82   const bool tunnel_;
83   const NetworkAnonymizationKey network_anonymization_key_;
84   const NetworkTrafficAnnotationTag traffic_annotation_;
85 };
86 
87 // HttpProxyConnectJob optionally establishes a tunnel through the proxy
88 // server after connecting the underlying transport socket.
89 class NET_EXPORT_PRIVATE HttpProxyConnectJob : public ConnectJob,
90                                                public ConnectJob::Delegate {
91  public:
92   class NET_EXPORT_PRIVATE Factory {
93    public:
94     Factory() = default;
95     virtual ~Factory() = default;
96 
97     virtual std::unique_ptr<HttpProxyConnectJob> Create(
98         RequestPriority priority,
99         const SocketTag& socket_tag,
100         const CommonConnectJobParams* common_connect_job_params,
101         scoped_refptr<HttpProxySocketParams> params,
102         ConnectJob::Delegate* delegate,
103         const NetLogWithSource* net_log);
104   };
105 
106   HttpProxyConnectJob(RequestPriority priority,
107                       const SocketTag& socket_tag,
108                       const CommonConnectJobParams* common_connect_job_params,
109                       scoped_refptr<HttpProxySocketParams> params,
110                       ConnectJob::Delegate* delegate,
111                       const NetLogWithSource* net_log);
112 
113   HttpProxyConnectJob(const HttpProxyConnectJob&) = delete;
114   HttpProxyConnectJob& operator=(const HttpProxyConnectJob&) = delete;
115 
116   ~HttpProxyConnectJob() override;
117 
118   // A single priority is used for tunnels over H2 and QUIC, which can be shared
119   // by multiple requests of different priorities either in series (tunnels for
120   // HTTP/1.x requests) or simultaneously (tunnels for H2 requests). Changing
121   // the priority of the tunnel based on the current request also potentially
122   // leaks private data to the proxy.
123   static const RequestPriority kH2QuicTunnelPriority;
124 
125   // ConnectJob methods.
126   LoadState GetLoadState() const override;
127   bool HasEstablishedConnection() const override;
128   ResolveErrorInfo GetResolveErrorInfo() const override;
129   bool IsSSLError() const override;
130   scoped_refptr<SSLCertRequestInfo> GetCertRequestInfo() override;
131 
132   // ConnectJob::Delegate implementation.
133   void OnConnectJobComplete(int result, ConnectJob* job) override;
134   void OnNeedsProxyAuth(const HttpResponseInfo& response,
135                         HttpAuthController* auth_controller,
136                         base::OnceClosure restart_with_auth_callback,
137                         ConnectJob* job) override;
138 
139   // In some cases, a timeout that's stricter than the TCP (+SSL, if applicable)
140   // is used for HTTP proxies during connection establishment and SSL
141   // negotiation for the connection to the proxy itself. In those cases, returns
142   // the connection timeout that will be used by a HttpProxyConnectJob created
143   // with the specified parameters, given current network conditions. Otherwise,
144   // returns base::TimeDelta().
145   static base::TimeDelta AlternateNestedConnectionTimeout(
146       const HttpProxySocketParams& params,
147       const NetworkQualityEstimator* network_quality_estimator);
148 
149   // Returns the timeout for establishing a tunnel after a connection has been
150   // established.
151   static base::TimeDelta TunnelTimeoutForTesting();
152 
153   // Updates the field trial parameters used in calculating timeouts.
154   static void UpdateFieldTrialParametersForTesting();
155 
156  private:
157   enum State {
158     STATE_BEGIN_CONNECT,
159     STATE_TRANSPORT_CONNECT,
160     STATE_TRANSPORT_CONNECT_COMPLETE,
161     STATE_HTTP_PROXY_CONNECT,
162     STATE_HTTP_PROXY_CONNECT_COMPLETE,
163     STATE_SPDY_PROXY_CREATE_STREAM,
164     STATE_SPDY_PROXY_CREATE_STREAM_COMPLETE,
165     STATE_QUIC_PROXY_CREATE_SESSION,
166     STATE_QUIC_PROXY_CREATE_STREAM,
167     STATE_QUIC_PROXY_CREATE_STREAM_COMPLETE,
168     STATE_RESTART_WITH_AUTH,
169     STATE_RESTART_WITH_AUTH_COMPLETE,
170     STATE_NONE,
171   };
172 
173   // Begins the tcp connection and the optional Http proxy tunnel.  If the
174   // request is not immediately serviceable (likely), the request will return
175   // ERR_IO_PENDING. An OK return from this function or the callback means
176   // that the connection is established; ERR_PROXY_AUTH_REQUESTED means
177   // that the tunnel needs authentication credentials, the socket will be
178   // returned in this case, and must be released back to the pool; or
179   // a standard net error code will be returned.
180   int ConnectInternal() override;
181 
182   ProxyServer::Scheme GetProxyServerScheme() const;
183 
184   void OnIOComplete(int result);
185 
186   void RestartWithAuthCredentials();
187 
188   // Runs the state transition loop.
189   int DoLoop(int result);
190 
191   // Determine if need to go through TCP or SSL path.
192   int DoBeginConnect();
193   // Connecting to HTTP or HTTPS Proxy
194   int DoTransportConnect();
195   int DoTransportConnectComplete(int result);
196 
197   int DoHttpProxyConnect();
198   int DoHttpProxyConnectComplete(int result);
199 
200   int DoSpdyProxyCreateStream();
201   int DoSpdyProxyCreateStreamComplete(int result);
202 
203   int DoQuicProxyCreateSession();
204   int DoQuicProxyCreateStream(int result);
205   int DoQuicProxyCreateStreamComplete(int result);
206 
207   int DoRestartWithAuth();
208   int DoRestartWithAuthComplete(int result);
209 
210   // ConnectJob implementation.
211   void ChangePriorityInternal(RequestPriority priority) override;
212   void OnTimedOutInternal() override;
213 
214   void OnAuthChallenge();
215 
216   const HostPortPair& GetDestination() const;
217 
218   std::string GetUserAgent() const;
219 
220   SpdySessionKey CreateSpdySessionKey() const;
221 
222   scoped_refptr<HttpProxySocketParams> params_;
223 
224   scoped_refptr<SSLCertRequestInfo> ssl_cert_request_info_;
225 
226   State next_state_ = STATE_NONE;
227 
228   bool has_restarted_ = false;
229 
230   // Set to true once a connection has been successfully established. Remains
231   // true even if a new socket is being connected to retry with auth.
232   bool has_established_connection_ = false;
233 
234   ResolveErrorInfo resolve_error_info_;
235 
236   std::unique_ptr<ConnectJob> nested_connect_job_;
237   std::unique_ptr<ProxyClientSocket> transport_socket_;
238 
239   std::unique_ptr<SpdyStreamRequest> spdy_stream_request_;
240 
241   std::unique_ptr<QuicStreamRequest> quic_stream_request_;
242   std::unique_ptr<QuicChromiumClientSession::Handle> quic_session_;
243 
244   scoped_refptr<HttpAuthController> http_auth_controller_;
245 
246   NetErrorDetails quic_net_error_details_;
247 
248   // Time when the connection to the proxy was started.
249   base::TimeTicks connect_start_time_;
250 
251   base::WeakPtrFactory<HttpProxyConnectJob> weak_ptr_factory_{this};
252 };
253 
254 }  // namespace net
255 
256 #endif  // NET_HTTP_HTTP_PROXY_CONNECT_JOB_H_
257