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