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