// Copyright (c) 2012 The Chromium Authors. All rights reserved. // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. #ifndef NET_HTTP_HTTP_PROXY_CLIENT_SOCKET_POOL_H_ #define NET_HTTP_HTTP_PROXY_CLIENT_SOCKET_POOL_H_ #include #include #include #include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" #include "base/time/time.h" #include "net/base/host_port_pair.h" #include "net/base/net_export.h" #include "net/http/http_auth.h" #include "net/http/http_response_info.h" #include "net/http/proxy_client_socket.h" #include "net/socket/client_socket_pool.h" #include "net/socket/client_socket_pool_base.h" #include "net/socket/ssl_client_socket.h" #include "net/spdy/spdy_session.h" #include "net/traffic_annotation/network_traffic_annotation.h" namespace net { class HttpAuthCache; class HttpAuthHandlerFactory; class HttpProxyClientSocketWrapper; class NetLog; class NetworkQualityProvider; class QuicStreamFactory; class SSLClientSocketPool; class SSLSocketParams; class SpdySessionPool; class TransportClientSocketPool; class TransportSocketParams; // HttpProxySocketParams only needs the socket params for one of the proxy // types. The other param must be NULL. When using an HTTP proxy, // |transport_params| must be set. When using an HTTPS proxy or QUIC proxy, // |ssl_params| must be set. Also, if using a QUIC proxy, |quic_version| must // not be QUIC_VERSION_UNSUPPORTED. class NET_EXPORT_PRIVATE HttpProxySocketParams : public base::RefCounted { public: HttpProxySocketParams( const scoped_refptr& transport_params, const scoped_refptr& ssl_params, QuicTransportVersion quic_version, const std::string& user_agent, const HostPortPair& endpoint, HttpAuthCache* http_auth_cache, HttpAuthHandlerFactory* http_auth_handler_factory, SpdySessionPool* spdy_session_pool, QuicStreamFactory* quic_stream_factory, bool is_trusted_proxy, bool tunnel, const NetworkTrafficAnnotationTag traffic_annotation); const scoped_refptr& transport_params() const { return transport_params_; } const scoped_refptr& ssl_params() const { return ssl_params_; } QuicTransportVersion quic_version() const { return quic_version_; } const std::string& user_agent() const { return user_agent_; } const HostPortPair& endpoint() const { return endpoint_; } HttpAuthCache* http_auth_cache() const { return http_auth_cache_; } HttpAuthHandlerFactory* http_auth_handler_factory() const { return http_auth_handler_factory_; } SpdySessionPool* spdy_session_pool() { return spdy_session_pool_; } QuicStreamFactory* quic_stream_factory() const { return quic_stream_factory_; } const HostResolver::RequestInfo& destination() const; bool is_trusted_proxy() const { return is_trusted_proxy_; } bool tunnel() const { return tunnel_; } const NetworkTrafficAnnotationTag traffic_annotation() const { return traffic_annotation_; } private: friend class base::RefCounted; ~HttpProxySocketParams(); const scoped_refptr transport_params_; const scoped_refptr ssl_params_; QuicTransportVersion quic_version_; SpdySessionPool* spdy_session_pool_; QuicStreamFactory* quic_stream_factory_; const std::string user_agent_; const HostPortPair endpoint_; HttpAuthCache* const http_auth_cache_; HttpAuthHandlerFactory* const http_auth_handler_factory_; const bool is_trusted_proxy_; const bool tunnel_; const NetworkTrafficAnnotationTag traffic_annotation_; DISALLOW_COPY_AND_ASSIGN(HttpProxySocketParams); }; // HttpProxyConnectJob optionally establishes a tunnel through the proxy // server after connecting the underlying transport socket. class HttpProxyConnectJob : public ConnectJob { public: HttpProxyConnectJob(const std::string& group_name, RequestPriority priority, const SocketTag& socket_tag, ClientSocketPool::RespectLimits respect_limits, const scoped_refptr& params, const base::TimeDelta& timeout_duration, TransportClientSocketPool* transport_pool, SSLClientSocketPool* ssl_pool, Delegate* delegate, NetLog* net_log); ~HttpProxyConnectJob() override; // ConnectJob methods. LoadState GetLoadState() const override; void GetAdditionalErrorState(ClientSocketHandle* handle) override; private: // Begins the tcp connection and the optional Http proxy tunnel. If the // request is not immediately servicable (likely), the request will return // ERR_IO_PENDING. An OK return from this function or the callback means // that the connection is established; ERR_PROXY_AUTH_REQUESTED means // that the tunnel needs authentication credentials, the socket will be // returned in this case, and must be release back to the pool; or // a standard net error code will be returned. int ConnectInternal() override; void OnConnectComplete(int result); int HandleConnectResult(int result); std::unique_ptr client_socket_; std::unique_ptr error_response_info_; DISALLOW_COPY_AND_ASSIGN(HttpProxyConnectJob); }; class NET_EXPORT_PRIVATE HttpProxyClientSocketPool : public ClientSocketPool, public HigherLayeredPool { public: typedef HttpProxySocketParams SocketParams; HttpProxyClientSocketPool(int max_sockets, int max_sockets_per_group, TransportClientSocketPool* transport_pool, SSLClientSocketPool* ssl_pool, NetworkQualityProvider* network_quality_provider, NetLog* net_log); ~HttpProxyClientSocketPool() override; // ClientSocketPool implementation. int RequestSocket(const std::string& group_name, const void* connect_params, RequestPriority priority, const SocketTag& socket_tag, RespectLimits respect_limits, ClientSocketHandle* handle, const CompletionCallback& callback, const NetLogWithSource& net_log) override; void RequestSockets(const std::string& group_name, const void* params, int num_sockets, const NetLogWithSource& net_log) override; void SetPriority(const std::string& group_name, ClientSocketHandle* handle, RequestPriority priority) override; void CancelRequest(const std::string& group_name, ClientSocketHandle* handle) override; void ReleaseSocket(const std::string& group_name, std::unique_ptr socket, int id) override; void FlushWithError(int error) override; void CloseIdleSockets() override; void CloseIdleSocketsInGroup(const std::string& group_name) override; int IdleSocketCount() const override; int IdleSocketCountInGroup(const std::string& group_name) const override; LoadState GetLoadState(const std::string& group_name, const ClientSocketHandle* handle) const override; std::unique_ptr GetInfoAsValue( const std::string& name, const std::string& type, bool include_nested_pools) const override; base::TimeDelta ConnectionTimeout() const override; // LowerLayeredPool implementation. bool IsStalled() const override; void AddHigherLayeredPool(HigherLayeredPool* higher_pool) override; void RemoveHigherLayeredPool(HigherLayeredPool* higher_pool) override; // HigherLayeredPool implementation. bool CloseOneIdleConnection() override; private: FRIEND_TEST_ALL_PREFIXES(HttpProxyClientSocketPoolTest, ProxyPoolTimeoutWithConnectionProperty); typedef ClientSocketPoolBase PoolBase; class NET_EXPORT_PRIVATE HttpProxyConnectJobFactory : public PoolBase::ConnectJobFactory { public: HttpProxyConnectJobFactory(TransportClientSocketPool* transport_pool, SSLClientSocketPool* ssl_pool, NetworkQualityProvider* network_quality_provider, NetLog* net_log); // ClientSocketPoolBase::ConnectJobFactory methods. std::unique_ptr NewConnectJob( const std::string& group_name, const PoolBase::Request& request, ConnectJob::Delegate* delegate) const override; base::TimeDelta ConnectionTimeout() const override; private: FRIEND_TEST_ALL_PREFIXES(HttpProxyClientSocketPoolTest, ProxyPoolTimeoutWithConnectionProperty); // Returns proxy connection timeout for secure proxies if // |is_secure_connection| is true. Otherwise, returns timeout for insecure // proxies. base::TimeDelta ConnectionTimeoutWithConnectionProperty( bool is_secure_connection) const; TransportClientSocketPool* const transport_pool_; SSLClientSocketPool* const ssl_pool_; NetworkQualityProvider* const network_quality_provider_; // For secure proxies, the connection timeout is set to // |ssl_http_rtt_multiplier_| times the HTTP RTT estimate. For insecure // proxies, the connection timeout is set to |non_ssl_http_rtt_multiplier_| // times the HTTP RTT estimate. In either case, the connection timeout // is clamped to be between |min_proxy_connection_timeout_| and // |max_proxy_connection_timeout_|. const int32_t ssl_http_rtt_multiplier_; const int32_t non_ssl_http_rtt_multiplier_; const base::TimeDelta min_proxy_connection_timeout_; const base::TimeDelta max_proxy_connection_timeout_; NetLog* net_log_; DISALLOW_COPY_AND_ASSIGN(HttpProxyConnectJobFactory); }; TransportClientSocketPool* const transport_pool_; SSLClientSocketPool* const ssl_pool_; PoolBase base_; DISALLOW_COPY_AND_ASSIGN(HttpProxyClientSocketPool); }; } // namespace net #endif // NET_HTTP_HTTP_PROXY_CLIENT_SOCKET_POOL_H_