diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2019-07-31 15:50:41 +0200 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2019-08-30 12:35:23 +0000 |
commit | 7b2ffa587235a47d4094787d72f38102089f402a (patch) | |
tree | 30e82af9cbab08a7fa028bb18f4f2987a3f74dfa /chromium/net/socket | |
parent | d94af01c90575348c4e81a418257f254b6f8d225 (diff) | |
download | qtwebengine-chromium-7b2ffa587235a47d4094787d72f38102089f402a.tar.gz |
BASELINE: Update Chromium to 76.0.3809.94
Change-Id: I321c3f5f929c105aec0f98c5091ef6108822e647
Reviewed-by: Michael BrĂ¼ning <michael.bruning@qt.io>
Diffstat (limited to 'chromium/net/socket')
47 files changed, 3064 insertions, 2123 deletions
diff --git a/chromium/net/socket/client_socket_factory.cc b/chromium/net/socket/client_socket_factory.cc index c43feccd4e0..313bc16b1f2 100644 --- a/chromium/net/socket/client_socket_factory.cc +++ b/chromium/net/socket/client_socket_factory.cc @@ -62,12 +62,11 @@ class DefaultClientSocketFactory : public ClientSocketFactory { bool using_spdy, NextProto negotiated_protocol, ProxyDelegate* proxy_delegate, - bool is_https_proxy, const NetworkTrafficAnnotationTag& traffic_annotation) override { return std::make_unique<HttpProxyClientSocket>( std::move(stream_socket), user_agent, endpoint, proxy_server, http_auth_controller, tunnel, using_spdy, negotiated_protocol, - proxy_delegate, is_https_proxy, traffic_annotation); + proxy_delegate, traffic_annotation); } }; diff --git a/chromium/net/socket/client_socket_factory.h b/chromium/net/socket/client_socket_factory.h index 169825265ee..db61cc42a65 100644 --- a/chromium/net/socket/client_socket_factory.h +++ b/chromium/net/socket/client_socket_factory.h @@ -67,7 +67,6 @@ class NET_EXPORT ClientSocketFactory { bool using_spdy, NextProto negotiated_protocol, ProxyDelegate* proxy_delegate, - bool is_https_proxy, const NetworkTrafficAnnotationTag& traffic_annotation) = 0; // Returns the default ClientSocketFactory. diff --git a/chromium/net/socket/client_socket_handle.cc b/chromium/net/socket/client_socket_handle.cc index 65edc74ec88..2e52f8ceb8e 100644 --- a/chromium/net/socket/client_socket_handle.cc +++ b/chromium/net/socket/client_socket_handle.cc @@ -34,6 +34,7 @@ ClientSocketHandle::~ClientSocketHandle() { int ClientSocketHandle::Init( const ClientSocketPool::GroupId& group_id, scoped_refptr<ClientSocketPool::SocketParams> socket_params, + const base::Optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag, RequestPriority priority, const SocketTag& socket_tag, ClientSocketPool::RespectLimits respect_limits, @@ -44,15 +45,16 @@ int ClientSocketHandle::Init( requesting_source_ = net_log.source(); CHECK(!group_id.destination().IsEmpty()); - ResetInternal(true); + ResetInternal(true /* cancel */, false /* cancel_connect_job */); ResetErrorState(); pool_ = pool; group_id_ = group_id; CompletionOnceCallback io_complete_callback = base::BindOnce(&ClientSocketHandle::OnIOComplete, base::Unretained(this)); int rv = pool_->RequestSocket( - group_id, std::move(socket_params), priority, socket_tag, respect_limits, - this, std::move(io_complete_callback), proxy_auth_callback, net_log); + group_id, std::move(socket_params), proxy_annotation_tag, priority, + socket_tag, respect_limits, this, std::move(io_complete_callback), + proxy_auth_callback, net_log); if (rv == ERR_IO_PENDING) { callback_ = std::move(callback); } else { @@ -73,55 +75,15 @@ void ClientSocketHandle::SetPriority(RequestPriority priority) { } void ClientSocketHandle::Reset() { - ResetInternal(true); + ResetInternal(true /* cancel */, false /* cancel_connect_job */); ResetErrorState(); } -void ClientSocketHandle::ResetInternal(bool cancel) { - // Was Init called? - if (!group_id_.destination().IsEmpty()) { - // If so, we must have a pool. - CHECK(pool_); - if (is_initialized()) { - if (socket_) { - socket_->NetLog().EndEvent(NetLogEventType::SOCKET_IN_USE); - // Release the socket back to the ClientSocketPool so it can be - // deleted or reused. - pool_->ReleaseSocket(group_id_, std::move(socket_), group_generation_); - } else { - // If the handle has been initialized, we should still have a - // socket. - NOTREACHED(); - } - } else if (cancel) { - // If we did not get initialized yet and we have a socket - // request pending, cancel it. - pool_->CancelRequest(group_id_, this); - } - } - is_initialized_ = false; - socket_.reset(); - group_id_ = ClientSocketPool::GroupId(); - reuse_type_ = ClientSocketHandle::UNUSED; - callback_.Reset(); - if (higher_pool_) - RemoveHigherLayeredPool(higher_pool_); - pool_ = nullptr; - idle_time_ = base::TimeDelta(); - // Connection timing is still needed for handling - // ERR_HTTPS_PROXY_TUNNEL_RESPONSE_REDIRECT errors. - // - // TODO(mmenke): Remove once ERR_HTTPS_PROXY_TUNNEL_RESPONSE_REDIRECT no - // longer results in following a redirect. - if (!pending_http_proxy_socket_) - connect_timing_ = LoadTimingInfo::ConnectTiming(); - group_generation_ = -1; -} - -void ClientSocketHandle::ResetErrorState() { - is_ssl_error_ = false; - ssl_cert_request_info_ = nullptr; - pending_http_proxy_socket_.reset(); +void ClientSocketHandle::ResetAndCloseSocket() { + if (is_initialized() && socket_) + socket_->Disconnect(); + ResetInternal(true /* cancel */, true /* cancel_connect_job */); + ResetErrorState(); } LoadState ClientSocketHandle::GetLoadState() const { @@ -172,12 +134,6 @@ bool ClientSocketHandle::GetLoadTimingInfo( LoadTimingInfo* load_timing_info) const { if (socket_) { load_timing_info->socket_log_id = socket_->NetLog().source().id; - } else if (pending_http_proxy_socket_) { - // TODO(mmenke): This case is only needed for timing for redirects in the - // case of ERR_HTTPS_PROXY_TUNNEL_RESPONSE_REDIRECT. Remove this code once - // we no longer follow those redirects. - load_timing_info->socket_log_id = - pending_http_proxy_socket_->NetLog().source().id; } else { // Only return load timing information when there's a socket. return false; @@ -207,20 +163,14 @@ void ClientSocketHandle::SetSocket(std::unique_ptr<StreamSocket> s) { void ClientSocketHandle::SetAdditionalErrorState(ConnectJob* connect_job) { connection_attempts_ = connect_job->GetConnectionAttempts(); - // TODO(mmenke): Once redirects are no longer followed on - // ERR_HTTPS_PROXY_TUNNEL_RESPONSE_REDIRECT, remove this code. - pending_http_proxy_socket_ = connect_job->PassProxySocketOnFailure(); - if (pending_http_proxy_socket_) { - // Connection timing is only set when a socket was actually established. In - // this particular case, there is a socket being returned, just not through - // the normal path, so need to set timing information here. - connect_timing_ = connect_job->connect_timing(); - } - is_ssl_error_ = connect_job->IsSSLError(); ssl_cert_request_info_ = connect_job->GetCertRequestInfo(); } +std::unique_ptr<StreamSocket> ClientSocketHandle::PassSocket() { + return std::move(socket_); +} + void ClientSocketHandle::OnIOComplete(int result) { TRACE_EVENT0(NetTracingCategory(), "ClientSocketHandle::OnIOComplete"); CompletionOnceCallback callback = std::move(callback_); @@ -229,15 +179,13 @@ void ClientSocketHandle::OnIOComplete(int result) { std::move(callback).Run(result); } -std::unique_ptr<StreamSocket> ClientSocketHandle::PassSocket() { - return std::move(socket_); -} - void ClientSocketHandle::HandleInitCompletion(int result) { CHECK_NE(ERR_IO_PENDING, result); if (result != OK) { if (!socket_.get()) - ResetInternal(false); // Nothing to cancel since the request failed. + ResetInternal(false /* cancel */, + false /* cancel_connect_job */); // Nothing to cancel since + // the request failed. else is_initialized_ = true; return; @@ -255,4 +203,46 @@ void ClientSocketHandle::HandleInitCompletion(int result) { requesting_source_.ToEventParametersCallback()); } +void ClientSocketHandle::ResetInternal(bool cancel, bool cancel_connect_job) { + DCHECK(cancel || !cancel_connect_job); + + // Was Init called? + if (!group_id_.destination().IsEmpty()) { + // If so, we must have a pool. + CHECK(pool_); + if (is_initialized()) { + if (socket_) { + socket_->NetLog().EndEvent(NetLogEventType::SOCKET_IN_USE); + // Release the socket back to the ClientSocketPool so it can be + // deleted or reused. + pool_->ReleaseSocket(group_id_, std::move(socket_), group_generation_); + } else { + // If the handle has been initialized, we should still have a + // socket. + NOTREACHED(); + } + } else if (cancel) { + // If we did not get initialized yet and we have a socket + // request pending, cancel it. + pool_->CancelRequest(group_id_, this, cancel_connect_job); + } + } + is_initialized_ = false; + socket_.reset(); + group_id_ = ClientSocketPool::GroupId(); + reuse_type_ = ClientSocketHandle::UNUSED; + callback_.Reset(); + if (higher_pool_) + RemoveHigherLayeredPool(higher_pool_); + pool_ = nullptr; + idle_time_ = base::TimeDelta(); + connect_timing_ = LoadTimingInfo::ConnectTiming(); + group_generation_ = -1; +} + +void ClientSocketHandle::ResetErrorState() { + is_ssl_error_ = false; + ssl_cert_request_info_ = nullptr; +} + } // namespace net diff --git a/chromium/net/socket/client_socket_handle.h b/chromium/net/socket/client_socket_handle.h index b20e4c75c3d..2ac9d88c195 100644 --- a/chromium/net/socket/client_socket_handle.h +++ b/chromium/net/socket/client_socket_handle.h @@ -13,6 +13,7 @@ #include "base/logging.h" #include "base/macros.h" #include "base/memory/ref_counted.h" +#include "base/optional.h" #include "base/time/time.h" #include "net/base/ip_endpoint.h" #include "net/base/load_states.h" @@ -30,6 +31,7 @@ namespace net { class ConnectJob; +struct NetworkTrafficAnnotationTag; class SocketTag; // A container for a StreamSocket. @@ -79,15 +81,17 @@ class NET_EXPORT ClientSocketHandle { // Init may be called multiple times. // // Profiling information for the request is saved to |net_log| if non-NULL. - int Init(const ClientSocketPool::GroupId& group_id, - scoped_refptr<ClientSocketPool::SocketParams> socket_params, - RequestPriority priority, - const SocketTag& socket_tag, - ClientSocketPool::RespectLimits respect_limits, - CompletionOnceCallback callback, - const ClientSocketPool::ProxyAuthCallback& proxy_auth_callback, - ClientSocketPool* pool, - const NetLogWithSource& net_log); + int Init( + const ClientSocketPool::GroupId& group_id, + scoped_refptr<ClientSocketPool::SocketParams> socket_params, + const base::Optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag, + RequestPriority priority, + const SocketTag& socket_tag, + ClientSocketPool::RespectLimits respect_limits, + CompletionOnceCallback callback, + const ClientSocketPool::ProxyAuthCallback& proxy_auth_callback, + ClientSocketPool* pool, + const NetLogWithSource& net_log); // Changes the priority of the ClientSocketHandle to the passed value. // This function is a no-op if |priority| is the same as the current @@ -105,6 +109,11 @@ class NET_EXPORT ClientSocketHandle { // StreamSocket. void Reset(); + // Like Reset(), but also closes the socket (if there is one) and cancels any + // pending attempt to establish a connection, if the connection attempt is + // still ongoing. + void ResetAndCloseSocket(); + // Used after Init() is called, but before the ClientSocketPool has // initialized the ClientSocketHandle. LoadState GetLoadState() const; @@ -160,9 +169,6 @@ class NET_EXPORT ClientSocketHandle { scoped_refptr<SSLCertRequestInfo> ssl_cert_request_info) { ssl_cert_request_info_ = std::move(ssl_cert_request_info); } - void set_pending_http_proxy_socket(std::unique_ptr<StreamSocket> socket) { - pending_http_proxy_socket_ = std::move(socket); - } void set_connection_attempts(const ConnectionAttempts& attempts) { connection_attempts_ = attempts; } @@ -179,10 +185,6 @@ class NET_EXPORT ClientSocketHandle { return ssl_cert_request_info_; } - std::unique_ptr<StreamSocket> release_pending_http_proxy_socket() { - return std::move(pending_http_proxy_socket_); - } - // If the connection failed, returns the connection attempts made. (If it // succeeded, they will be returned through the socket instead; see // |StreamSocket::GetConnectionAttempts|.) @@ -219,8 +221,11 @@ class NET_EXPORT ClientSocketHandle { // Resets the state of the ClientSocketHandle. |cancel| indicates whether or // not to try to cancel the request with the ClientSocketPool. Does not - // reset the supplemental error state. - void ResetInternal(bool cancel); + // reset the supplemental error state. |cancel_connect_job| indicates whether + // a pending ConnectJob, if there is one in the SocketPool, should be + // cancelled in addition to cancelling the request. It may only be true if + // |cancel| is also true. + void ResetInternal(bool cancel, bool cancel_connect_job); // Resets the supplemental error state. void ResetErrorState(); @@ -237,7 +242,6 @@ class NET_EXPORT ClientSocketHandle { int64_t group_generation_; bool is_ssl_error_; scoped_refptr<SSLCertRequestInfo> ssl_cert_request_info_; - std::unique_ptr<StreamSocket> pending_http_proxy_socket_; std::vector<ConnectionAttempt> connection_attempts_; NetLogSource requesting_source_; diff --git a/chromium/net/socket/client_socket_pool.cc b/chromium/net/socket/client_socket_pool.cc index 78b49709b55..62eb8f4bc76 100644 --- a/chromium/net/socket/client_socket_pool.cc +++ b/chromium/net/socket/client_socket_pool.cc @@ -7,15 +7,18 @@ #include <utility> #include "base/bind.h" +#include "base/feature_list.h" #include "base/logging.h" +#include "net/base/features.h" #include "net/http/http_proxy_connect_job.h" #include "net/log/net_log_event_type.h" #include "net/log/net_log_with_source.h" +#include "net/socket/connect_job.h" #include "net/socket/socks_connect_job.h" #include "net/socket/ssl_connect_job.h" #include "net/socket/stream_socket.h" -#include "net/socket/transport_connect_job.h" -#include "net/socket/websocket_transport_connect_job.h" +#include "net/spdy/spdy_session.h" +#include "net/spdy/spdy_session_pool.h" namespace net { @@ -24,102 +27,59 @@ namespace { // The maximum duration, in seconds, to keep used idle persistent sockets alive. int64_t g_used_idle_socket_timeout_s = 300; // 5 minutes -// TODO(mmenke): Once the socket pool arguments are no longer needed, remove -// this method and use TransportConnectJob::CreateTransportConnectJob() -// directly. -std::unique_ptr<ConnectJob> CreateTransportConnectJob( - scoped_refptr<TransportSocketParams> transport_socket_params, - RequestPriority priority, - const SocketTag& socket_tag, - const CommonConnectJobParams* common_connect_job_params, - ConnectJob::Delegate* delegate) { - return TransportConnectJob::CreateTransportConnectJob( - std::move(transport_socket_params), priority, socket_tag, - common_connect_job_params, delegate, nullptr /* net_log */); -} - -std::unique_ptr<ConnectJob> CreateSOCKSConnectJob( - scoped_refptr<SOCKSSocketParams> socks_socket_params, - RequestPriority priority, - const SocketTag& socket_tag, - const CommonConnectJobParams* common_connect_job_params, - ConnectJob::Delegate* delegate) { - return std::make_unique<SOCKSConnectJob>( - priority, socket_tag, common_connect_job_params, - std::move(socks_socket_params), delegate, nullptr /* net_log */); -} - -std::unique_ptr<ConnectJob> CreateSSLConnectJob( - scoped_refptr<SSLSocketParams> ssl_socket_params, - RequestPriority priority, - const SocketTag& socket_tag, - const CommonConnectJobParams* common_connect_job_params, - ConnectJob::Delegate* delegate) { - return std::make_unique<SSLConnectJob>( - priority, socket_tag, common_connect_job_params, - std::move(ssl_socket_params), delegate, nullptr /* net_log */); -} - -std::unique_ptr<ConnectJob> CreateHttpProxyConnectJob( - scoped_refptr<HttpProxySocketParams> http_proxy_socket_params, - RequestPriority priority, - const SocketTag& socket_tag, - const CommonConnectJobParams* common_connect_job_params, - ConnectJob::Delegate* delegate) { - return std::make_unique<HttpProxyConnectJob>( - priority, socket_tag, common_connect_job_params, - std::move(http_proxy_socket_params), delegate, nullptr /* net_log */); +// Invoked by the transport socket pool after host resolution is complete +// to allow the connection to be aborted, if a matching SPDY session can +// be found. Returns OnHostResolutionCallbackResult::kMayBeDeletedAsync if such +// a session is found, as it will post a task that may delete the calling +// ConnectJob. Also returns kMayBeDeletedAsync if there may already be such +// a task posted. +OnHostResolutionCallbackResult OnHostResolution( + SpdySessionPool* spdy_session_pool, + const SpdySessionKey& spdy_session_key, + bool is_for_websockets, + const HostPortPair& host_port_pair, + const AddressList& addresses) { + DCHECK(host_port_pair == spdy_session_key.host_port_pair()); + + // It is OK to dereference spdy_session_pool, because the + // ClientSocketPoolManager will be destroyed in the same callback that + // destroys the SpdySessionPool. + return spdy_session_pool->OnHostResolutionComplete( + spdy_session_key, is_for_websockets, addresses); } } // namespace ClientSocketPool::SocketParams::SocketParams( - const CreateConnectJobCallback& create_connect_job_callback) - : create_connect_job_callback_(create_connect_job_callback) {} - -scoped_refptr<ClientSocketPool::SocketParams> -ClientSocketPool::SocketParams::CreateFromTransportSocketParams( - scoped_refptr<TransportSocketParams> transport_client_params) { - CreateConnectJobCallback callback = base::BindRepeating( - &CreateTransportConnectJob, std::move(transport_client_params)); - return base::MakeRefCounted<SocketParams>(callback); -} - -scoped_refptr<ClientSocketPool::SocketParams> -ClientSocketPool::SocketParams::CreateFromSOCKSSocketParams( - scoped_refptr<SOCKSSocketParams> socks_socket_params) { - CreateConnectJobCallback callback = base::BindRepeating( - &CreateSOCKSConnectJob, std::move(socks_socket_params)); - return base::MakeRefCounted<SocketParams>(callback); -} + std::unique_ptr<SSLConfig> ssl_config_for_origin, + std::unique_ptr<SSLConfig> ssl_config_for_proxy) + : ssl_config_for_origin_(std::move(ssl_config_for_origin)), + ssl_config_for_proxy_(std::move(ssl_config_for_proxy)) {} -scoped_refptr<ClientSocketPool::SocketParams> -ClientSocketPool::SocketParams::CreateFromSSLSocketParams( - scoped_refptr<SSLSocketParams> ssl_socket_params) { - CreateConnectJobCallback callback = - base::BindRepeating(&CreateSSLConnectJob, std::move(ssl_socket_params)); - return base::MakeRefCounted<SocketParams>(callback); -} +ClientSocketPool::SocketParams::~SocketParams() = default; scoped_refptr<ClientSocketPool::SocketParams> -ClientSocketPool::SocketParams::CreateFromHttpProxySocketParams( - scoped_refptr<HttpProxySocketParams> http_proxy_socket_params) { - CreateConnectJobCallback callback = base::BindRepeating( - &CreateHttpProxyConnectJob, std::move(http_proxy_socket_params)); - return base::MakeRefCounted<SocketParams>(callback); +ClientSocketPool::SocketParams::CreateForHttpForTesting() { + return base::MakeRefCounted<SocketParams>(nullptr /* ssl_config_for_origin */, + nullptr /* ssl_config_for_proxy */); } -ClientSocketPool::SocketParams::~SocketParams() = default; - ClientSocketPool::GroupId::GroupId() - : socket_type_(SocketType::kHttp), privacy_mode_(false) {} + : socket_type_(SocketType::kHttp), + privacy_mode_(PrivacyMode::PRIVACY_MODE_DISABLED) {} ClientSocketPool::GroupId::GroupId(const HostPortPair& destination, SocketType socket_type, - bool privacy_mode) + PrivacyMode privacy_mode, + NetworkIsolationKey network_isolation_key) : destination_(destination), socket_type_(socket_type), - privacy_mode_(privacy_mode) {} + privacy_mode_(privacy_mode), + network_isolation_key_( + base::FeatureList::IsEnabled( + features::kPartitionConnectionsByNetworkIsolationKey) + ? network_isolation_key + : NetworkIsolationKey()) {} ClientSocketPool::GroupId::GroupId(const GroupId& group_id) = default; @@ -140,17 +100,17 @@ std::string ClientSocketPool::GroupId::ToString() const { case ClientSocketPool::SocketType::kSsl: result = "ssl/" + result; break; - - case ClientSocketPool::SocketType::kSslVersionInterferenceProbe: - result = "version-interference-probe/ssl/" + result; - break; - - case ClientSocketPool::SocketType::kFtp: - result = "ftp/" + result; - break; } if (privacy_mode_) result = "pm/" + result; + + if (base::FeatureList::IsEnabled( + features::kPartitionConnectionsByNetworkIsolationKey)) { + result += " <"; + result += network_isolation_key_.ToDebugString(); + result += ">"; + } + return result; } @@ -180,13 +140,54 @@ void ClientSocketPool::NetLogTcpClientSocketPoolRequestedSocket( } } -std::unique_ptr<base::Value> ClientSocketPool::NetLogGroupIdCallback( - const ClientSocketPool::GroupId* group_id, +base::Value ClientSocketPool::NetLogGroupIdCallback( + const GroupId* group_id, NetLogCaptureMode /* capture_mode */) { - std::unique_ptr<base::DictionaryValue> event_params( - new base::DictionaryValue()); - event_params->SetString("group_id", group_id->ToString()); - return event_params; + base::DictionaryValue event_params; + event_params.SetString("group_id", group_id->ToString()); + return std::move(event_params); +} + +std::unique_ptr<ConnectJob> ClientSocketPool::CreateConnectJob( + GroupId group_id, + scoped_refptr<SocketParams> socket_params, + const ProxyServer& proxy_server, + const base::Optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag, + bool is_for_websockets, + const CommonConnectJobParams* common_connect_job_params, + RequestPriority request_priority, + SocketTag socket_tag, + ConnectJob::Delegate* delegate) { + bool using_ssl = group_id.socket_type() == ClientSocketPool::SocketType::kSsl; + + // If applicable, set up a callback to handle checking for H2 IP pooling + // opportunities. + OnHostResolutionCallback resolution_callback; + if (using_ssl && proxy_server.is_direct()) { + resolution_callback = base::BindRepeating( + &OnHostResolution, common_connect_job_params->spdy_session_pool, + SpdySessionKey(group_id.destination(), proxy_server, + group_id.privacy_mode(), + SpdySessionKey::IsProxySession::kFalse, socket_tag, + group_id.network_isolation_key()), + is_for_websockets); + } else if (proxy_server.is_https()) { + resolution_callback = base::BindRepeating( + &OnHostResolution, common_connect_job_params->spdy_session_pool, + SpdySessionKey(proxy_server.host_port_pair(), ProxyServer::Direct(), + group_id.privacy_mode(), + SpdySessionKey::IsProxySession::kTrue, socket_tag, + group_id.network_isolation_key()), + is_for_websockets); + } + + return ConnectJob::CreateConnectJob( + using_ssl, group_id.destination(), proxy_server, proxy_annotation_tag, + socket_params->ssl_config_for_origin(), + socket_params->ssl_config_for_proxy(), is_for_websockets, + group_id.privacy_mode(), resolution_callback, request_priority, + socket_tag, group_id.network_isolation_key(), common_connect_job_params, + delegate); } } // namespace net diff --git a/chromium/net/socket/client_socket_pool.h b/chromium/net/socket/client_socket_pool.h index e9bf45b9a57..17a787eea3d 100644 --- a/chromium/net/socket/client_socket_pool.h +++ b/chromium/net/socket/client_socket_pool.h @@ -10,15 +10,19 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" +#include "base/optional.h" #include "base/time/time.h" #include "net/base/completion_once_callback.h" #include "net/base/load_states.h" #include "net/base/net_export.h" +#include "net/base/network_isolation_key.h" +#include "net/base/privacy_mode.h" #include "net/base/request_priority.h" #include "net/dns/host_resolver.h" #include "net/http/http_request_info.h" #include "net/log/net_log_capture_mode.h" #include "net/socket/connect_job.h" +#include "net/socket/socket_tag.h" namespace base { class DictionaryValue; @@ -33,13 +37,12 @@ namespace net { class ClientSocketHandle; struct CommonConnectJobParams; class HttpAuthController; -class HttpProxySocketParams; class HttpResponseInfo; class NetLogWithSource; -class SOCKSSocketParams; -class SSLSocketParams; +struct NetworkTrafficAnnotationTag; +class ProxyServer; +struct SSLConfig; class StreamSocket; -class TransportSocketParams; // ClientSocketPools are layered. This defines an interface for lower level // socket pools to communicate with higher layer pools. @@ -100,12 +103,6 @@ class NET_EXPORT ClientSocketPool : public LowerLayeredPool { // This is a connection that uses an SSL connection to the final // destination, though not necessarily to the proxy, if there is one. kSsl, - - // This is a connection for probing for SSL-breaking interference. - kSslVersionInterferenceProbe, - - // This is a connection through an HTTP proxy being used for FTP requests. - kFtp, }; // Group ID for a socket request. Requests with the same group ID are @@ -113,9 +110,12 @@ class NET_EXPORT ClientSocketPool : public LowerLayeredPool { class NET_EXPORT GroupId { public: GroupId(); + // TODO(mmenke): Remove default |network_isolation_key| value (only used by + // tests). GroupId(const HostPortPair& destination, SocketType socket_type, - bool privacy_mode); + PrivacyMode privacy_mode, + NetworkIsolationKey network_isolation_key = NetworkIsolationKey()); GroupId(const GroupId& group_id); ~GroupId(); @@ -127,21 +127,27 @@ class NET_EXPORT ClientSocketPool : public LowerLayeredPool { SocketType socket_type() const { return socket_type_; } - bool privacy_mode() const { return privacy_mode_; } + PrivacyMode privacy_mode() const { return privacy_mode_; } + + const NetworkIsolationKey& network_isolation_key() { + return network_isolation_key_; + } // Returns the group ID as a string, for logging. std::string ToString() const; bool operator==(const GroupId& other) const { - return std::tie(destination_, socket_type_, privacy_mode_) == + return std::tie(destination_, socket_type_, privacy_mode_, + network_isolation_key_) == std::tie(other.destination_, other.socket_type_, - other.privacy_mode_); + other.privacy_mode_, other.network_isolation_key_); } bool operator<(const GroupId& other) const { - return std::tie(destination_, socket_type_, privacy_mode_) < + return std::tie(destination_, socket_type_, privacy_mode_, + network_isolation_key_) < std::tie(other.destination_, other.socket_type_, - other.privacy_mode_); + other.privacy_mode_, other.network_isolation_key_); } private: @@ -150,51 +156,47 @@ class NET_EXPORT ClientSocketPool : public LowerLayeredPool { SocketType socket_type_; - // True if this request is for a privacy mode / uncredentials connection. - bool privacy_mode_; + // If this request is for a privacy mode / uncredentialed connection. + PrivacyMode privacy_mode_; + + // Used to separate requests made in different contexts. + NetworkIsolationKey network_isolation_key_; }; - // Callback to create a ConnectJob using the provided arguments. The lower - // level parameters used to construct the ConnectJob (like hostname, type of - // socket, proxy, etc) are all already bound to the callback. If - // |websocket_endpoint_lock_manager| is non-null, a ConnectJob for use by - // WebSockets should be created. - using CreateConnectJobCallback = - base::RepeatingCallback<std::unique_ptr<ConnectJob>( - RequestPriority priority, - const SocketTag& socket_tag, - const CommonConnectJobParams* common_connect_job_params, - ConnectJob::Delegate* delegate)>; - - // "Parameters" that own a single callback for creating a ConnectJob that can - // be of any type. + // Parameters that, in combination with GroupId, proxy, websocket information, + // and global state, are sufficient to create a ConnectJob. + // + // DO NOT ADD ANY FIELDS TO THIS CLASS. + // + // TODO(https://crbug.com/921369) In order to resolve longstanding issues + // related to pooling distinguishable sockets together, remove this class + // entirely. class NET_EXPORT_PRIVATE SocketParams : public base::RefCounted<SocketParams> { public: - explicit SocketParams( - const CreateConnectJobCallback& create_connect_job_callback); + // For non-SSL requests / non-HTTPS proxies, the corresponding SSLConfig + // argument may be nullptr. + SocketParams(std::unique_ptr<SSLConfig> ssl_config_for_origin, + std::unique_ptr<SSLConfig> ssl_config_for_proxy); - const CreateConnectJobCallback& create_connect_job_callback() { - return create_connect_job_callback_; - } - - static scoped_refptr<SocketParams> CreateFromTransportSocketParams( - scoped_refptr<TransportSocketParams> transport_client_params); - - static scoped_refptr<SocketParams> CreateFromSOCKSSocketParams( - scoped_refptr<SOCKSSocketParams> socks_socket_params); + // Creates a SocketParams object with none of the fields populated. This + // works for the HTTP case only. + static scoped_refptr<SocketParams> CreateForHttpForTesting(); - static scoped_refptr<SocketParams> CreateFromSSLSocketParams( - scoped_refptr<SSLSocketParams> ssl_socket_params); + const SSLConfig* ssl_config_for_origin() const { + return ssl_config_for_origin_.get(); + } - static scoped_refptr<SocketParams> CreateFromHttpProxySocketParams( - scoped_refptr<HttpProxySocketParams> http_proxy_socket_params); + const SSLConfig* ssl_config_for_proxy() const { + return ssl_config_for_proxy_.get(); + } private: friend class base::RefCounted<SocketParams>; ~SocketParams(); - const CreateConnectJobCallback create_connect_job_callback_; + std::unique_ptr<SSLConfig> ssl_config_for_origin_; + std::unique_ptr<SSLConfig> ssl_config_for_proxy_; DISALLOW_COPY_AND_ASSIGN(SocketParams); }; @@ -233,19 +235,23 @@ class NET_EXPORT ClientSocketPool : public LowerLayeredPool { // // If |respect_limits| is DISABLED, priority must be HIGHEST. // - // |on_proxy_auth_challenge_callback| will be invoked each time an auth - // challenge is seen while establishing a tunnel. It will never be invoked - // synchronously when RequestSocket is called, and will be invoked once for - // each challenge seen. - virtual int RequestSocket(const GroupId& group_id, - scoped_refptr<SocketParams> params, - RequestPriority priority, - const SocketTag& socket_tag, - RespectLimits respect_limits, - ClientSocketHandle* handle, - CompletionOnceCallback callback, - const ProxyAuthCallback& proxy_auth_challenge, - const NetLogWithSource& net_log) = 0; + // |proxy_annotation_tag| is the annotation used for proxy-related reads and + // writes, and may be nullopt if (and only if) no proxy is in use. + // + // |proxy_auth_callback| will be invoked each time an auth challenge is seen + // while establishing a tunnel. It will be invoked asynchronously, once for + // each auth challenge seen. + virtual int RequestSocket( + const GroupId& group_id, + scoped_refptr<SocketParams> params, + const base::Optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag, + RequestPriority priority, + const SocketTag& socket_tag, + RespectLimits respect_limits, + ClientSocketHandle* handle, + CompletionOnceCallback callback, + const ProxyAuthCallback& proxy_auth_callback, + const NetLogWithSource& net_log) = 0; // RequestSockets is used to request that |num_sockets| be connected in the // connection group for |group_id|. If the connection group already has @@ -257,10 +263,12 @@ class NET_EXPORT ClientSocketPool : public LowerLayeredPool { // This priority will probably be lower than all others, since this method // is intended to make sure ahead of time that |num_sockets| sockets are // available to talk to a host. - virtual void RequestSockets(const GroupId& group_id, - scoped_refptr<SocketParams> params, - int num_sockets, - const NetLogWithSource& net_log) = 0; + virtual void RequestSockets( + const GroupId& group_id, + scoped_refptr<SocketParams> params, + const base::Optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag, + int num_sockets, + const NetLogWithSource& net_log) = 0; // Called to change the priority of a RequestSocket call that returned // ERR_IO_PENDING and has not yet asynchronously completed. The same handle @@ -275,9 +283,13 @@ class NET_EXPORT ClientSocketPool : public LowerLayeredPool { // Called to cancel a RequestSocket call that returned ERR_IO_PENDING. The // same handle parameter must be passed to this method as was passed to the // RequestSocket call being cancelled. The associated callback is not run. - // However, for performance, we will let one ConnectJob complete and go idle. + // If |cancel_connect_job| is true, and there are more ConnectJobs than + // requests, a ConnectJob will be canceled. If it's false, excess ConnectJobs + // may be allowed to continue, just in case there are new requests to the same + // endpoint. virtual void CancelRequest(const GroupId& group_id, - ClientSocketHandle* handle) = 0; + ClientSocketHandle* handle, + bool cancel_connect_job) = 0; // Called to release a socket once the socket is no longer needed. If the // socket still has an established connection, then it will be added to the @@ -340,9 +352,19 @@ class NET_EXPORT ClientSocketPool : public LowerLayeredPool { const GroupId& group_id); // Utility method to log a GroupId with a NetLog event. - static std::unique_ptr<base::Value> NetLogGroupIdCallback( - const ClientSocketPool::GroupId* group_id, - NetLogCaptureMode capture_mode); + static base::Value NetLogGroupIdCallback(const GroupId* group_id, + NetLogCaptureMode capture_mode); + + static std::unique_ptr<ConnectJob> CreateConnectJob( + GroupId group_id, + scoped_refptr<SocketParams> socket_params, + const ProxyServer& proxy_server, + const base::Optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag, + bool is_for_websockets, + const CommonConnectJobParams* common_connect_job_params, + RequestPriority request_priority, + SocketTag socket_tag, + ConnectJob::Delegate* delegate); private: DISALLOW_COPY_AND_ASSIGN(ClientSocketPool); diff --git a/chromium/net/socket/client_socket_pool_base_unittest.cc b/chromium/net/socket/client_socket_pool_base_unittest.cc index 4876c9ccf7a..faa495115b4 100644 --- a/chromium/net/socket/client_socket_pool_base_unittest.cc +++ b/chromium/net/socket/client_socket_pool_base_unittest.cc @@ -16,17 +16,23 @@ #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" #include "base/message_loop/message_loop.h" +#include "base/optional.h" #include "base/run_loop.h" #include "base/single_thread_task_runner.h" #include "base/stl_util.h" #include "base/strings/string_number_conversions.h" #include "base/strings/stringprintf.h" +#include "base/test/scoped_feature_list.h" #include "base/threading/platform_thread.h" #include "base/threading/thread_task_runner_handle.h" #include "base/values.h" +#include "net/base/features.h" #include "net/base/load_timing_info.h" #include "net/base/load_timing_info_test_util.h" #include "net/base/net_errors.h" +#include "net/base/network_isolation_key.h" +#include "net/base/privacy_mode.h" +#include "net/base/proxy_server.h" #include "net/base/request_priority.h" #include "net/base/test_completion_callback.h" #include "net/http/http_response_headers.h" @@ -50,6 +56,7 @@ #include "net/ssl/ssl_cert_request_info.h" #include "net/test/gtest_util.h" #include "net/test/test_with_scoped_task_environment.h" +#include "net/traffic_annotation/network_traffic_annotation.h" #include "net/traffic_annotation/network_traffic_annotation_test_helper.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" @@ -69,21 +76,15 @@ const int kDefaultMaxSocketsPerGroup = 2; constexpr base::TimeDelta kUnusedIdleSocketTimeout = base::TimeDelta::FromSeconds(10); -ClientSocketPool::GroupId TestGroupId(const std::string& host, - int port = 80, - ClientSocketPool::SocketType socket_type = - ClientSocketPool::SocketType::kHttp, - bool privacy_mode = false) { +ClientSocketPool::GroupId TestGroupId( + const std::string& host, + int port = 80, + ClientSocketPool::SocketType socket_type = + ClientSocketPool::SocketType::kHttp, + PrivacyMode privacy_mode = PrivacyMode::PRIVACY_MODE_DISABLED, + NetworkIsolationKey network_isolation_key = NetworkIsolationKey()) { return ClientSocketPool::GroupId(HostPortPair(host, port), socket_type, - privacy_mode); -} - -// Returns a ClientSocketPool::SocketParams that will never be used to -// create a real TreansportConnectJob. -scoped_refptr<ClientSocketPool::SocketParams> CreateDummyParams() { - return ClientSocketPool::SocketParams::CreateFromTransportSocketParams( - base::MakeRefCounted<TransportSocketParams>(HostPortPair("ignored", 80), - OnHostResolutionCallback())); + privacy_mode, network_isolation_key); } // Make sure |handle| sets load times correctly when it has been assigned a @@ -263,7 +264,6 @@ class MockClientSocketFactory : public ClientSocketFactory { bool using_spdy, NextProto negotiated_protocol, ProxyDelegate* proxy_delegate, - bool is_https_proxy, const NetworkTrafficAnnotationTag& traffic_annotation) override { NOTIMPLEMENTED(); return nullptr; @@ -570,9 +570,11 @@ class TestConnectJobFactory // ConnectJobFactory implementation. std::unique_ptr<ConnectJob> NewConnectJob( + ClientSocketPool::GroupId group_id, + scoped_refptr<ClientSocketPool::SocketParams> socket_params, + const base::Optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag, RequestPriority request_priority, SocketTag socket_tag, - scoped_refptr<ClientSocketPool::SocketParams> socket_params, ConnectJob::Delegate* delegate) const override { EXPECT_TRUE(!job_types_ || !job_types_->empty()); TestConnectJob::JobType job_type = job_type_; @@ -628,7 +630,7 @@ class ClientSocketPoolBaseTest : public TestWithScopedTaskEnvironment { ClientSocketPoolBaseTest() : TestWithScopedTaskEnvironment( base::test::ScopedTaskEnvironment::MainThreadType::MOCK_TIME), - params_(CreateDummyParams()) { + params_(ClientSocketPool::SocketParams::CreateForHttpForTesting()) { connect_backup_jobs_enabled_ = TransportClientSocketPool::connect_backup_jobs_enabled(); TransportClientSocketPool::set_connect_backup_jobs_enabled(true); @@ -717,11 +719,11 @@ TEST_F(ClientSocketPoolBaseTest, BasicSynchronous) { BoundTestNetLog log; TestLoadTimingInfoNotConnected(handle); - EXPECT_EQ( - OK, handle.Init( - TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, callback.callback(), - ClientSocketPool::ProxyAuthCallback(), pool_.get(), log.bound())); + EXPECT_EQ(OK, handle.Init( + TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback.callback(), ClientSocketPool::ProxyAuthCallback(), + pool_.get(), log.bound())); EXPECT_TRUE(handle.is_initialized()); EXPECT_TRUE(handle.socket()); TestLoadTimingInfoConnectedNotReused(handle); @@ -759,10 +761,10 @@ TEST_F(ClientSocketPoolBaseTest, InitConnectionFailure) { handle.set_ssl_cert_request_info(base::MakeRefCounted<SSLCertRequestInfo>()); EXPECT_EQ( ERR_CONNECTION_FAILED, - handle.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, callback.callback(), - ClientSocketPool::ProxyAuthCallback(), pool_.get(), - log.bound())); + handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback.callback(), ClientSocketPool::ProxyAuthCallback(), + pool_.get(), log.bound())); EXPECT_FALSE(handle.socket()); EXPECT_FALSE(handle.is_ssl_error()); EXPECT_FALSE(handle.ssl_cert_request_info()); @@ -784,6 +786,10 @@ TEST_F(ClientSocketPoolBaseTest, InitConnectionFailure) { // Make sure different groups do not share sockets. TEST_F(ClientSocketPoolBaseTest, GroupSeparation) { + base::test::ScopedFeatureList feature_list; + feature_list.InitAndEnableFeature( + features::kPartitionConnectionsByNetworkIsolationKey); + CreatePool(1000 /* max_sockets */, 2 /* max_sockets_per_group */); const HostPortPair kHostPortPairs[] = { @@ -795,11 +801,15 @@ TEST_F(ClientSocketPoolBaseTest, GroupSeparation) { const ClientSocketPool::SocketType kSocketTypes[] = { ClientSocketPool::SocketType::kHttp, ClientSocketPool::SocketType::kSsl, - ClientSocketPool::SocketType::kSslVersionInterferenceProbe, - ClientSocketPool::SocketType::kFtp, }; - const bool kPrivacyModes[] = {false, true}; + const PrivacyMode kPrivacyModes[] = {PrivacyMode::PRIVACY_MODE_DISABLED, + PrivacyMode::PRIVACY_MODE_ENABLED}; + + const NetworkIsolationKey kNetworkIsolationKeys[] = { + NetworkIsolationKey(url::Origin::Create(GURL("http://a.test/"))), + NetworkIsolationKey(url::Origin::Create(GURL("http://b.test/"))), + }; int total_idle_sockets = 0; @@ -811,55 +821,58 @@ TEST_F(ClientSocketPoolBaseTest, GroupSeparation) { SCOPED_TRACE(static_cast<int>(socket_type)); for (const auto& privacy_mode : kPrivacyModes) { SCOPED_TRACE(privacy_mode); + for (const auto& network_isolation_key : kNetworkIsolationKeys) { + SCOPED_TRACE(network_isolation_key.ToString()); + + connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob); + + ClientSocketPool::GroupId group_id( + host_port_pair, socket_type, privacy_mode, network_isolation_key); + + EXPECT_FALSE(pool_->HasGroupForTesting(group_id)); + + TestCompletionCallback callback; + ClientSocketHandle handle; + + // Since the group is empty, requesting a socket should not complete + // synchronously. + EXPECT_THAT( + handle.Init(group_id, params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback.callback(), + ClientSocketPool::ProxyAuthCallback(), pool_.get(), + NetLogWithSource()), + IsError(ERR_IO_PENDING)); + EXPECT_TRUE(pool_->HasGroupForTesting(group_id)); + EXPECT_EQ(total_idle_sockets, pool_->IdleSocketCount()); + + EXPECT_THAT(callback.WaitForResult(), IsOk()); + EXPECT_TRUE(handle.socket()); + EXPECT_TRUE(pool_->HasGroupForTesting(group_id)); + EXPECT_EQ(total_idle_sockets, pool_->IdleSocketCount()); + + // Return socket to pool. + handle.Reset(); + EXPECT_EQ(total_idle_sockets + 1, pool_->IdleSocketCount()); + + // Requesting a socket again should return the same socket as before, + // so should complete synchronously. + EXPECT_THAT( + handle.Init(group_id, params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback.callback(), + ClientSocketPool::ProxyAuthCallback(), pool_.get(), + NetLogWithSource()), + IsOk()); + EXPECT_TRUE(handle.socket()); + EXPECT_EQ(total_idle_sockets, pool_->IdleSocketCount()); + + // Return socket to pool again. + handle.Reset(); + EXPECT_EQ(total_idle_sockets + 1, pool_->IdleSocketCount()); - connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob); - - ClientSocketPool::GroupId group_id(host_port_pair, socket_type, - privacy_mode); - - EXPECT_FALSE(pool_->HasGroupForTesting(group_id)); - - TestCompletionCallback callback; - ClientSocketHandle handle; - - // Since the group is empty, requesting a socket should not complete - // synchronously. - EXPECT_THAT( - handle.Init(group_id, params_, DEFAULT_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, - callback.callback(), - ClientSocketPool::ProxyAuthCallback(), pool_.get(), - NetLogWithSource()), - IsError(ERR_IO_PENDING)); - EXPECT_TRUE(pool_->HasGroupForTesting(group_id)); - EXPECT_EQ(total_idle_sockets, pool_->IdleSocketCount()); - - EXPECT_THAT(callback.WaitForResult(), IsOk()); - EXPECT_TRUE(handle.socket()); - EXPECT_TRUE(pool_->HasGroupForTesting(group_id)); - EXPECT_EQ(total_idle_sockets, pool_->IdleSocketCount()); - - // Return socket to pool. - handle.Reset(); - EXPECT_EQ(total_idle_sockets + 1, pool_->IdleSocketCount()); - - // Requesting a socket again should return the same socket as before, so - // should complete synchronously. - EXPECT_THAT( - handle.Init(group_id, params_, DEFAULT_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, - callback.callback(), - ClientSocketPool::ProxyAuthCallback(), pool_.get(), - NetLogWithSource()), - IsOk()); - EXPECT_TRUE(handle.socket()); - EXPECT_EQ(total_idle_sockets, pool_->IdleSocketCount()); - - // Return socket to pool again. - handle.Reset(); - EXPECT_EQ(total_idle_sockets + 1, pool_->IdleSocketCount()); - - ++total_idle_sockets; + ++total_idle_sockets; + } } } } @@ -1190,20 +1203,20 @@ TEST_F(ClientSocketPoolBaseTest, StallAndThenCancelAndTriggerAvailableSocket) { TestCompletionCallback callback; EXPECT_EQ( ERR_IO_PENDING, - handle.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, callback.callback(), - ClientSocketPool::ProxyAuthCallback(), pool_.get(), - NetLogWithSource())); + handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback.callback(), ClientSocketPool::ProxyAuthCallback(), + pool_.get(), NetLogWithSource())); ClientSocketHandle handles[4]; for (size_t i = 0; i < base::size(handles); ++i) { TestCompletionCallback callback; EXPECT_EQ(ERR_IO_PENDING, handles[i].Init( - TestGroupId("b"), params_, DEFAULT_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, callback.callback(), - ClientSocketPool::ProxyAuthCallback(), pool_.get(), - NetLogWithSource())); + TestGroupId("b"), params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback.callback(), ClientSocketPool::ProxyAuthCallback(), + pool_.get(), NetLogWithSource())); } // One will be stalled, cancel all the handles now. @@ -1221,12 +1234,13 @@ TEST_F(ClientSocketPoolBaseTest, CancelStalledSocketAtSocketLimit) { ClientSocketHandle handles[kDefaultMaxSockets]; TestCompletionCallback callbacks[kDefaultMaxSockets]; for (int i = 0; i < kDefaultMaxSockets; ++i) { - EXPECT_EQ(OK, handles[i].Init(TestGroupId(base::NumberToString(i)), - params_, DEFAULT_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, - callbacks[i].callback(), - ClientSocketPool::ProxyAuthCallback(), - pool_.get(), NetLogWithSource())); + EXPECT_EQ(OK, + handles[i].Init(TestGroupId(base::NumberToString(i)), params_, + base::nullopt, DEFAULT_PRIORITY, SocketTag(), + ClientSocketPool::RespectLimits::ENABLED, + callbacks[i].callback(), + ClientSocketPool::ProxyAuthCallback(), + pool_.get(), NetLogWithSource())); } // Force a stalled group. @@ -1234,10 +1248,10 @@ TEST_F(ClientSocketPoolBaseTest, CancelStalledSocketAtSocketLimit) { TestCompletionCallback callback; EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init( - TestGroupId("foo"), params_, DEFAULT_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, callback.callback(), - ClientSocketPool::ProxyAuthCallback(), pool_.get(), - NetLogWithSource())); + TestGroupId("foo"), params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback.callback(), ClientSocketPool::ProxyAuthCallback(), + pool_.get(), NetLogWithSource())); // Cancel the stalled request. stalled_handle.Reset(); @@ -1262,7 +1276,7 @@ TEST_F(ClientSocketPoolBaseTest, CancelPendingSocketAtSocketLimit) { TestCompletionCallback callback; EXPECT_EQ(ERR_IO_PENDING, handles[i].Init(TestGroupId(base::NumberToString(i)), params_, - DEFAULT_PRIORITY, SocketTag(), + base::nullopt, DEFAULT_PRIORITY, SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback.callback(), ClientSocketPool::ProxyAuthCallback(), @@ -1275,10 +1289,10 @@ TEST_F(ClientSocketPoolBaseTest, CancelPendingSocketAtSocketLimit) { TestCompletionCallback callback; EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init( - TestGroupId("foo"), params_, DEFAULT_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, callback.callback(), - ClientSocketPool::ProxyAuthCallback(), pool_.get(), - NetLogWithSource())); + TestGroupId("foo"), params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback.callback(), ClientSocketPool::ProxyAuthCallback(), + pool_.get(), NetLogWithSource())); // Since it is stalled, it should have no connect jobs. EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("foo"))); @@ -1327,12 +1341,12 @@ TEST_F(ClientSocketPoolBaseTest, WaitForStalledSocketAtSocketLimit) { for (int i = 0; i < kDefaultMaxSockets; ++i) { TestCompletionCallback callback; EXPECT_EQ( - OK, handles[i].Init(TestGroupId(base::StringPrintf("Take 2: %d", i)), - params_, DEFAULT_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, - callback.callback(), - ClientSocketPool::ProxyAuthCallback(), - pool_.get(), NetLogWithSource())); + OK, handles[i].Init( + TestGroupId(base::StringPrintf("Take 2: %d", i)), params_, + base::nullopt, DEFAULT_PRIORITY, SocketTag(), + ClientSocketPool::RespectLimits::ENABLED, callback.callback(), + ClientSocketPool::ProxyAuthCallback(), pool_.get(), + NetLogWithSource())); } EXPECT_EQ(kDefaultMaxSockets, client_socket_factory_.allocation_count()); @@ -1342,10 +1356,10 @@ TEST_F(ClientSocketPoolBaseTest, WaitForStalledSocketAtSocketLimit) { // Now we will hit the socket limit. EXPECT_EQ(ERR_IO_PENDING, stalled_handle.Init( - TestGroupId("foo"), params_, DEFAULT_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, callback.callback(), - ClientSocketPool::ProxyAuthCallback(), pool_.get(), - NetLogWithSource())); + TestGroupId("foo"), params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback.callback(), ClientSocketPool::ProxyAuthCallback(), + pool_.get(), NetLogWithSource())); EXPECT_TRUE(pool_->IsStalled()); // Dropping out of scope will close all handles and return them to idle. @@ -1369,7 +1383,7 @@ TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketAtSocketLimitDeleteGroup) { ClientSocketHandle handle; TestCompletionCallback callback; EXPECT_EQ(OK, handle.Init(TestGroupId(base::NumberToString(i)), params_, - DEFAULT_PRIORITY, SocketTag(), + base::nullopt, DEFAULT_PRIORITY, SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback.callback(), ClientSocketPool::ProxyAuthCallback(), @@ -1389,8 +1403,8 @@ TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketAtSocketLimitDeleteGroup) { // which is the one which we would close an idle socket for. We shouldn't // close an idle socket though, since we should reuse the idle socket. EXPECT_EQ(OK, handle.Init( - TestGroupId("0"), params_, DEFAULT_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, + TestGroupId("0"), params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource())); @@ -1451,10 +1465,7 @@ TEST_F(ClientSocketPoolBaseTest, PendingRequests_NoKeepAlive) { completion_count()); } -// This test will start up a RequestSocket() and then immediately Cancel() it. -// The pending connect job will be cancelled and should not call back into -// ClientSocketPoolBase. -TEST_F(ClientSocketPoolBaseTest, CancelRequestClearGroup) { +TEST_F(ClientSocketPoolBaseTest, ResetAndCloseSocket) { CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup); connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob); @@ -1462,11 +1473,144 @@ TEST_F(ClientSocketPoolBaseTest, CancelRequestClearGroup) { TestCompletionCallback callback; EXPECT_EQ( ERR_IO_PENDING, - handle.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, callback.callback(), - ClientSocketPool::ProxyAuthCallback(), pool_.get(), - NetLogWithSource())); + handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback.callback(), ClientSocketPool::ProxyAuthCallback(), + pool_.get(), NetLogWithSource())); + + EXPECT_THAT(callback.WaitForResult(), IsOk()); + ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a"))); + EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a"))); + EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a"))); + EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a"))); + + handle.ResetAndCloseSocket(); + EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a"))); +} + +// This test will start up a socket request and then call Reset() on the handle. +// The pending ConnectJob should not be destroyed. +TEST_F(ClientSocketPoolBaseTest, CancelRequestKeepsConnectJob) { + CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup); + + connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob); + ClientSocketHandle handle; + TestCompletionCallback callback; + EXPECT_EQ( + ERR_IO_PENDING, + handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback.callback(), ClientSocketPool::ProxyAuthCallback(), + pool_.get(), NetLogWithSource())); handle.Reset(); + ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a"))); + EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a"))); +} + +// This test will start up a socket request and then call ResetAndCloseSocket() +// on the handle. The pending ConnectJob or connected socket should be +// destroyed. +TEST_F(ClientSocketPoolBaseTest, CancelRequestAndCloseSocket) { + CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup); + + // When true, the socket connects before it's canceled. + for (bool cancel_when_callback_pending : {false, true}) { + if (cancel_when_callback_pending) { + connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob); + } else { + connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob); + } + ClientSocketHandle handle; + TestCompletionCallback callback; + EXPECT_EQ( + ERR_IO_PENDING, + handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback.callback(), ClientSocketPool::ProxyAuthCallback(), + pool_.get(), NetLogWithSource())); + ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a"))); + EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a"))); + + if (cancel_when_callback_pending) { + client_socket_factory_.SignalJobs(); + ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a"))); + EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a"))); + } + + handle.ResetAndCloseSocket(); + ASSERT_FALSE(pool_->HasGroupForTesting(TestGroupId("a"))); + } +} + +TEST_F(ClientSocketPoolBaseTest, + CancelRequestAndCloseSocketWhenMoreRequestsThanConnectJobs) { + CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup); + + // When true, the sockets connect before they're canceled. + for (bool cancel_when_callback_pending : {false, true}) { + if (cancel_when_callback_pending) { + connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob); + } else { + connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob); + } + + std::vector<std::unique_ptr<ClientSocketHandle>> handles; + TestCompletionCallback callback; + // Make |kDefaultMaxSockets + 1| socket requests. + for (int i = 0; i < kDefaultMaxSocketsPerGroup + 1; ++i) { + std::unique_ptr<ClientSocketHandle> handle = + std::make_unique<ClientSocketHandle>(); + EXPECT_EQ(ERR_IO_PENDING, + handle->Init( + TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback.callback(), ClientSocketPool::ProxyAuthCallback(), + pool_.get(), NetLogWithSource())); + handles.push_back(std::move(handle)); + ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a"))); + EXPECT_EQ( + static_cast<size_t>(std::min(i + 1, kDefaultMaxSocketsPerGroup)), + pool_->NumConnectJobsInGroupForTesting(TestGroupId("a"))); + } + + if (cancel_when_callback_pending) { + client_socket_factory_.SignalJobs(); + ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a"))); + EXPECT_EQ(kDefaultMaxSocketsPerGroup, + pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a"))); + } + + // Calling ResetAndCloseSocket() on a handle should not cancel a ConnectJob + // or close a socket, since there are more requests than ConnectJobs or + // sockets. + handles[kDefaultMaxSocketsPerGroup]->ResetAndCloseSocket(); + ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a"))); + if (cancel_when_callback_pending) { + EXPECT_EQ(kDefaultMaxSocketsPerGroup, + pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a"))); + } else { + EXPECT_EQ(static_cast<size_t>(kDefaultMaxSocketsPerGroup), + pool_->NumConnectJobsInGroupForTesting(TestGroupId("a"))); + } + + // Calling ResetAndCloseSocket() on other handles should cancel a ConnectJob + // or close a socket. + for (int i = kDefaultMaxSocketsPerGroup - 1; i >= 0; --i) { + handles[i]->ResetAndCloseSocket(); + if (i > 0) { + ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a"))); + if (cancel_when_callback_pending) { + EXPECT_EQ(i, + pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a"))); + } else { + EXPECT_EQ(static_cast<size_t>(i), + pool_->NumConnectJobsInGroupForTesting(TestGroupId("a"))); + } + } else { + EXPECT_FALSE(pool_->HasGroupForTesting(TestGroupId("a"))); + } + } + } } TEST_F(ClientSocketPoolBaseTest, ConnectCancelConnect) { @@ -1478,25 +1622,42 @@ TEST_F(ClientSocketPoolBaseTest, ConnectCancelConnect) { EXPECT_EQ( ERR_IO_PENDING, - handle.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, callback.callback(), - ClientSocketPool::ProxyAuthCallback(), pool_.get(), - NetLogWithSource())); + handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback.callback(), ClientSocketPool::ProxyAuthCallback(), + pool_.get(), NetLogWithSource())); handle.Reset(); + ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a"))); + EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a"))); + // This will create a second ConnectJob, since the other ConnectJob was + // previously assigned to a request. TestCompletionCallback callback2; EXPECT_EQ( ERR_IO_PENDING, - handle.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, + handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback2.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource())); + ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a"))); + EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a"))); + EXPECT_THAT(callback2.WaitForResult(), IsOk()); EXPECT_FALSE(callback.have_result()); + ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a"))); + // One ConnectJob completed, and its socket is now assigned to |handle|. + EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a"))); + // The other ConnectJob should have either completed, or still be connecting. + EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")) + + pool_->IdleSocketCountInGroup(TestGroupId("a"))); handle.Reset(); + ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a"))); + EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a")) + + pool_->IdleSocketCountInGroup(TestGroupId("a"))); + EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a"))); } TEST_F(ClientSocketPoolBaseTest, CancelRequest) { @@ -1557,9 +1718,11 @@ void RequestSocketOnComplete(ClientSocketHandle* handle, TestCompletionCallback callback; int rv = handle->Init( - TestGroupId("a"), CreateDummyParams(), LOWEST, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, nested_callback->callback(), - ClientSocketPool::ProxyAuthCallback(), pool, NetLogWithSource()); + TestGroupId("a"), + ClientSocketPool::SocketParams::CreateForHttpForTesting(), base::nullopt, + LOWEST, SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + nested_callback->callback(), ClientSocketPool::ProxyAuthCallback(), pool, + NetLogWithSource()); if (rv != ERR_IO_PENDING) { DCHECK_EQ(TestConnectJob::kMockJob, next_job_type); nested_callback->callback().Run(rv); @@ -1578,7 +1741,7 @@ TEST_F(ClientSocketPoolBaseTest, RequestPendingJobTwice) { ClientSocketHandle handle; TestCompletionCallback second_result_callback; int rv = handle.Init( - TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(), + TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, SocketTag(), ClientSocketPool::RespectLimits::ENABLED, base::BindOnce(&RequestSocketOnComplete, &handle, pool_.get(), connect_job_factory_, TestConnectJob::kMockPendingJob, @@ -1599,7 +1762,7 @@ TEST_F(ClientSocketPoolBaseTest, RequestPendingJobThenSynchronous) { ClientSocketHandle handle; TestCompletionCallback second_result_callback; int rv = handle.Init( - TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(), + TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, SocketTag(), ClientSocketPool::RespectLimits::ENABLED, base::BindOnce(&RequestSocketOnComplete, &handle, pool_.get(), connect_job_factory_, TestConnectJob::kMockPendingJob, @@ -1700,7 +1863,7 @@ TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestThenRequestSocket) { ClientSocketHandle handle; TestCompletionCallback callback; int rv = handle.Init( - TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(), + TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); @@ -1708,8 +1871,8 @@ TEST_F(ClientSocketPoolBaseTest, CancelActiveRequestThenRequestSocket) { // Cancel the active request. handle.Reset(); - rv = handle.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, + rv = handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); @@ -1726,7 +1889,7 @@ TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketsForced) { TestCompletionCallback callback; BoundTestNetLog log; int rv = handle.Init( - TestGroupId("a"), params_, LOWEST, SocketTag(), + TestGroupId("a"), params_, base::nullopt, LOWEST, SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), log.bound()); EXPECT_THAT(rv, IsOk()); @@ -1741,18 +1904,18 @@ TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketsInGroupForced) { BoundTestNetLog log; ClientSocketHandle handle1; int rv = handle1.Init( - TestGroupId("a"), params_, LOWEST, SocketTag(), + TestGroupId("a"), params_, base::nullopt, LOWEST, SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), log.bound()); EXPECT_THAT(rv, IsOk()); ClientSocketHandle handle2; - rv = handle2.Init(TestGroupId("a"), params_, LOWEST, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, + rv = handle2.Init(TestGroupId("a"), params_, base::nullopt, LOWEST, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), log.bound()); ClientSocketHandle handle3; - rv = handle3.Init(TestGroupId("b"), params_, LOWEST, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, + rv = handle3.Init(TestGroupId("b"), params_, base::nullopt, LOWEST, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), log.bound()); EXPECT_THAT(rv, IsOk()); @@ -1770,7 +1933,7 @@ TEST_F(ClientSocketPoolBaseTest, CleanUpUnusableIdleSockets) { TestCompletionCallback callback; BoundTestNetLog log; int rv = handle.Init( - TestGroupId("a"), params_, LOWEST, SocketTag(), + TestGroupId("a"), params_, base::nullopt, LOWEST, SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), log.bound()); EXPECT_THAT(rv, IsOk()); @@ -1781,8 +1944,8 @@ TEST_F(ClientSocketPoolBaseTest, CleanUpUnusableIdleSockets) { // Disconnect socket now to make the socket unusable. socket->Disconnect(); ClientSocketHandle handle2; - rv = handle2.Init(TestGroupId("a"), params_, LOWEST, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, + rv = handle2.Init(TestGroupId("a"), params_, base::nullopt, LOWEST, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), log.bound()); EXPECT_THAT(rv, IsOk()); @@ -1837,7 +2000,7 @@ TEST_F(ClientSocketPoolBaseTest, BasicAsynchronous) { TestCompletionCallback callback; BoundTestNetLog log; int rv = handle.Init( - TestGroupId("a"), params_, LOWEST, SocketTag(), + TestGroupId("a"), params_, base::nullopt, LOWEST, SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), log.bound()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); @@ -1883,10 +2046,10 @@ TEST_F(ClientSocketPoolBaseTest, handle.set_ssl_cert_request_info(base::MakeRefCounted<SSLCertRequestInfo>()); EXPECT_EQ( ERR_IO_PENDING, - handle.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, callback.callback(), - ClientSocketPool::ProxyAuthCallback(), pool_.get(), - log.bound())); + handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback.callback(), ClientSocketPool::ProxyAuthCallback(), + pool_.get(), log.bound())); EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState(TestGroupId("a"), &handle)); EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_FAILED)); @@ -1938,15 +2101,15 @@ TEST_F(ClientSocketPoolBaseTest, TwoRequestsCancelOne) { EXPECT_EQ( ERR_IO_PENDING, - handle.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, callback.callback(), - ClientSocketPool::ProxyAuthCallback(), pool_.get(), - NetLogWithSource())); + handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback.callback(), ClientSocketPool::ProxyAuthCallback(), + pool_.get(), NetLogWithSource())); BoundTestNetLog log2; EXPECT_EQ( ERR_IO_PENDING, - handle2.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, + handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback2.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource())); @@ -2004,7 +2167,7 @@ TEST_F(ClientSocketPoolBaseTest, ReleaseSockets) { size_t completion_count; // unused TestSocketRequest req1(&request_order, &completion_count); int rv = req1.handle()->Init( - TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(), + TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, SocketTag(), ClientSocketPool::RespectLimits::ENABLED, req1.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); @@ -2016,13 +2179,13 @@ TEST_F(ClientSocketPoolBaseTest, ReleaseSockets) { TestSocketRequest req2(&request_order, &completion_count); rv = req2.handle()->Init( - TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(), + TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, SocketTag(), ClientSocketPool::RespectLimits::ENABLED, req2.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); TestSocketRequest req3(&request_order, &completion_count); rv = req3.handle()->Init( - TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(), + TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, SocketTag(), ClientSocketPool::RespectLimits::ENABLED, req3.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); @@ -2059,14 +2222,14 @@ TEST_F(ClientSocketPoolBaseTest, PendingJobCompletionOrder) { size_t completion_count; // unused TestSocketRequest req1(&request_order, &completion_count); int rv = req1.handle()->Init( - TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(), + TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, SocketTag(), ClientSocketPool::RespectLimits::ENABLED, req1.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); TestSocketRequest req2(&request_order, &completion_count); rv = req2.handle()->Init( - TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(), + TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, SocketTag(), ClientSocketPool::RespectLimits::ENABLED, req2.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); @@ -2076,7 +2239,7 @@ TEST_F(ClientSocketPoolBaseTest, PendingJobCompletionOrder) { TestSocketRequest req3(&request_order, &completion_count); rv = req3.handle()->Init( - TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(), + TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, SocketTag(), ClientSocketPool::RespectLimits::ENABLED, req3.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); @@ -2099,7 +2262,7 @@ TEST_F(ClientSocketPoolBaseTest, LoadStateOneRequest) { ClientSocketHandle handle; TestCompletionCallback callback; int rv = handle.Init( - TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(), + TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); @@ -2120,7 +2283,7 @@ TEST_F(ClientSocketPoolBaseTest, LoadStateTwoRequests) { ClientSocketHandle handle; TestCompletionCallback callback; int rv = handle.Init( - TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(), + TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); @@ -2128,8 +2291,8 @@ TEST_F(ClientSocketPoolBaseTest, LoadStateTwoRequests) { ClientSocketHandle handle2; TestCompletionCallback callback2; - rv = handle2.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, + rv = handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback2.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); @@ -2168,7 +2331,7 @@ TEST_F(ClientSocketPoolBaseTest, LoadStateGroupLimit) { ClientSocketHandle handle; TestCompletionCallback callback; int rv = handle.Init( - TestGroupId("a"), params_, MEDIUM, SocketTag(), + TestGroupId("a"), params_, base::nullopt, MEDIUM, SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); @@ -2178,8 +2341,8 @@ TEST_F(ClientSocketPoolBaseTest, LoadStateGroupLimit) { // The first request should now be stalled at the socket group limit. ClientSocketHandle handle2; TestCompletionCallback callback2; - rv = handle2.Init(TestGroupId("a"), params_, HIGHEST, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, + rv = handle2.Init(TestGroupId("a"), params_, base::nullopt, HIGHEST, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback2.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); @@ -2212,7 +2375,7 @@ TEST_F(ClientSocketPoolBaseTest, LoadStatePoolLimit) { ClientSocketHandle handle; TestCompletionCallback callback; int rv = handle.Init( - TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(), + TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); @@ -2220,8 +2383,8 @@ TEST_F(ClientSocketPoolBaseTest, LoadStatePoolLimit) { // Request for socket from another pool. ClientSocketHandle handle2; TestCompletionCallback callback2; - rv = handle2.Init(TestGroupId("b"), params_, DEFAULT_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, + rv = handle2.Init(TestGroupId("b"), params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback2.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); @@ -2230,8 +2393,8 @@ TEST_F(ClientSocketPoolBaseTest, LoadStatePoolLimit) { // socket pool limit. ClientSocketHandle handle3; TestCompletionCallback callback3; - rv = handle3.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, + rv = handle3.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback2.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); @@ -2265,10 +2428,10 @@ TEST_F(ClientSocketPoolBaseTest, CertError) { TestCompletionCallback callback; EXPECT_EQ( ERR_CERT_COMMON_NAME_INVALID, - handle.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, callback.callback(), - ClientSocketPool::ProxyAuthCallback(), pool_.get(), - NetLogWithSource())); + handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback.callback(), ClientSocketPool::ProxyAuthCallback(), + pool_.get(), NetLogWithSource())); EXPECT_TRUE(handle.is_initialized()); EXPECT_TRUE(handle.socket()); } @@ -2281,10 +2444,10 @@ TEST_F(ClientSocketPoolBaseTest, AsyncCertError) { TestCompletionCallback callback; EXPECT_EQ( ERR_IO_PENDING, - handle.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, callback.callback(), - ClientSocketPool::ProxyAuthCallback(), pool_.get(), - NetLogWithSource())); + handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback.callback(), ClientSocketPool::ProxyAuthCallback(), + pool_.get(), NetLogWithSource())); EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState(TestGroupId("a"), &handle)); EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CERT_COMMON_NAME_INVALID)); @@ -2301,10 +2464,10 @@ TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateSynchronous) { TestCompletionCallback callback; EXPECT_EQ( ERR_CONNECTION_FAILED, - handle.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, callback.callback(), - ClientSocketPool::ProxyAuthCallback(), pool_.get(), - NetLogWithSource())); + handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback.callback(), ClientSocketPool::ProxyAuthCallback(), + pool_.get(), NetLogWithSource())); EXPECT_FALSE(handle.is_initialized()); EXPECT_FALSE(handle.socket()); EXPECT_TRUE(handle.is_ssl_error()); @@ -2320,10 +2483,10 @@ TEST_F(ClientSocketPoolBaseTest, AdditionalErrorStateAsynchronous) { TestCompletionCallback callback; EXPECT_EQ( ERR_IO_PENDING, - handle.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, callback.callback(), - ClientSocketPool::ProxyAuthCallback(), pool_.get(), - NetLogWithSource())); + handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback.callback(), ClientSocketPool::ProxyAuthCallback(), + pool_.get(), NetLogWithSource())); EXPECT_EQ(LOAD_STATE_CONNECTING, pool_->GetLoadState(TestGroupId("a"), &handle)); EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_FAILED)); @@ -2345,7 +2508,7 @@ TEST_F(ClientSocketPoolBaseTest, CleanupTimedOutIdleSocketsReuse) { ClientSocketHandle handle; TestCompletionCallback callback; int rv = handle.Init( - TestGroupId("a"), params_, LOWEST, SocketTag(), + TestGroupId("a"), params_, base::nullopt, LOWEST, SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource()); ASSERT_THAT(rv, IsError(ERR_IO_PENDING)); @@ -2366,7 +2529,7 @@ TEST_F(ClientSocketPoolBaseTest, CleanupTimedOutIdleSocketsReuse) { // synchronously. BoundTestNetLog log; rv = handle.Init( - TestGroupId("a"), params_, LOWEST, SocketTag(), + TestGroupId("a"), params_, base::nullopt, LOWEST, SocketTag(), ClientSocketPool::RespectLimits::ENABLED, CompletionOnceCallback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), log.bound()); ASSERT_THAT(rv, IsOk()); @@ -2401,7 +2564,7 @@ TEST_F(ClientSocketPoolBaseTest, CleanupTimedOutIdleSocketsNoReuse) { ClientSocketHandle handle; TestCompletionCallback callback; int rv = handle.Init( - TestGroupId("a"), params_, LOWEST, SocketTag(), + TestGroupId("a"), params_, base::nullopt, LOWEST, SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource()); ASSERT_THAT(rv, IsError(ERR_IO_PENDING)); @@ -2410,8 +2573,8 @@ TEST_F(ClientSocketPoolBaseTest, CleanupTimedOutIdleSocketsNoReuse) { ClientSocketHandle handle2; TestCompletionCallback callback2; - rv = handle2.Init(TestGroupId("a"), params_, LOWEST, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, + rv = handle2.Init(TestGroupId("a"), params_, base::nullopt, LOWEST, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback2.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource()); ASSERT_THAT(rv, IsError(ERR_IO_PENDING)); @@ -2443,8 +2606,8 @@ TEST_F(ClientSocketPoolBaseTest, CleanupTimedOutIdleSocketsNoReuse) { // A new socket will be created rather than reusing the idle one. BoundTestNetLog log; TestCompletionCallback callback3; - rv = handle.Init(TestGroupId("a"), params_, LOWEST, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, + rv = handle.Init(TestGroupId("a"), params_, base::nullopt, LOWEST, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback3.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), log.bound()); ASSERT_THAT(rv, IsError(ERR_IO_PENDING)); @@ -2477,31 +2640,31 @@ TEST_F(ClientSocketPoolBaseTest, MultipleReleasingDisconnectedSockets) { ClientSocketHandle handle; TestCompletionCallback callback; int rv = handle.Init( - TestGroupId("a"), params_, LOWEST, SocketTag(), + TestGroupId("a"), params_, base::nullopt, LOWEST, SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource()); EXPECT_THAT(rv, IsOk()); ClientSocketHandle handle2; TestCompletionCallback callback2; - rv = handle2.Init(TestGroupId("a"), params_, LOWEST, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, + rv = handle2.Init(TestGroupId("a"), params_, base::nullopt, LOWEST, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback2.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource()); EXPECT_THAT(rv, IsOk()); ClientSocketHandle handle3; TestCompletionCallback callback3; - rv = handle3.Init(TestGroupId("a"), params_, LOWEST, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, + rv = handle3.Init(TestGroupId("a"), params_, base::nullopt, LOWEST, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback3.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); ClientSocketHandle handle4; TestCompletionCallback callback4; - rv = handle4.Init(TestGroupId("a"), params_, LOWEST, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, + rv = handle4.Init(TestGroupId("a"), params_, base::nullopt, LOWEST, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback4.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); @@ -2538,35 +2701,37 @@ TEST_F(ClientSocketPoolBaseTest, SocketLimitReleasingSockets) { TestCompletionCallback callback_b[4]; for (int i = 0; i < 2; ++i) { - EXPECT_EQ( - OK, handle_a[i].Init(TestGroupId("a"), params_, LOWEST, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, - callback_a[i].callback(), - ClientSocketPool::ProxyAuthCallback(), pool_.get(), - NetLogWithSource())); - EXPECT_EQ( - OK, handle_b[i].Init(TestGroupId("b"), params_, LOWEST, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, - callback_b[i].callback(), - ClientSocketPool::ProxyAuthCallback(), pool_.get(), - NetLogWithSource())); + EXPECT_EQ(OK, handle_a[i].Init(TestGroupId("a"), params_, base::nullopt, + LOWEST, SocketTag(), + ClientSocketPool::RespectLimits::ENABLED, + callback_a[i].callback(), + ClientSocketPool::ProxyAuthCallback(), + pool_.get(), NetLogWithSource())); + EXPECT_EQ(OK, handle_b[i].Init(TestGroupId("b"), params_, base::nullopt, + LOWEST, SocketTag(), + ClientSocketPool::RespectLimits::ENABLED, + callback_b[i].callback(), + ClientSocketPool::ProxyAuthCallback(), + pool_.get(), NetLogWithSource())); } // Make 4 pending requests, 2 per group. for (int i = 2; i < 4; ++i) { - EXPECT_EQ(ERR_IO_PENDING, - handle_a[i].Init(TestGroupId("a"), params_, LOWEST, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, - callback_a[i].callback(), - ClientSocketPool::ProxyAuthCallback(), - pool_.get(), NetLogWithSource())); - EXPECT_EQ(ERR_IO_PENDING, - handle_b[i].Init(TestGroupId("b"), params_, LOWEST, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, - callback_b[i].callback(), - ClientSocketPool::ProxyAuthCallback(), - pool_.get(), NetLogWithSource())); + EXPECT_EQ( + ERR_IO_PENDING, + handle_a[i].Init(TestGroupId("a"), params_, base::nullopt, LOWEST, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback_a[i].callback(), + ClientSocketPool::ProxyAuthCallback(), pool_.get(), + NetLogWithSource())); + EXPECT_EQ( + ERR_IO_PENDING, + handle_b[i].Init(TestGroupId("b"), params_, base::nullopt, LOWEST, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback_b[i].callback(), + ClientSocketPool::ProxyAuthCallback(), pool_.get(), + NetLogWithSource())); } // Release b's socket first. The order is important, because in @@ -2655,11 +2820,12 @@ class TestReleasingSocketRequest : public TestCompletionCallbackBase { EXPECT_EQ( expected_result_, - handle2_.Init(TestGroupId("a"), CreateDummyParams(), DEFAULT_PRIORITY, - SocketTag(), ClientSocketPool::RespectLimits::ENABLED, - CompletionOnceCallback(), - ClientSocketPool::ProxyAuthCallback(), pool_, - NetLogWithSource())); + handle2_.Init( + TestGroupId("a"), + ClientSocketPool::SocketParams::CreateForHttpForTesting(), + base::nullopt, DEFAULT_PRIORITY, SocketTag(), + ClientSocketPool::RespectLimits::ENABLED, CompletionOnceCallback(), + ClientSocketPool::ProxyAuthCallback(), pool_, NetLogWithSource())); } TransportClientSocketPool* const pool_; @@ -2683,12 +2849,12 @@ TEST_F(ClientSocketPoolBaseTest, AdditionalErrorSocketsDontUseSlot) { connect_job_factory_->set_job_type( TestConnectJob::kMockPendingAdditionalErrorStateJob); TestReleasingSocketRequest req(pool_.get(), OK, false); - EXPECT_EQ( - ERR_IO_PENDING, - req.handle()->Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, - SocketTag(), ClientSocketPool::RespectLimits::ENABLED, - req.callback(), ClientSocketPool::ProxyAuthCallback(), - pool_.get(), NetLogWithSource())); + EXPECT_EQ(ERR_IO_PENDING, + req.handle()->Init( + TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + req.callback(), ClientSocketPool::ProxyAuthCallback(), + pool_.get(), NetLogWithSource())); // The next job should complete synchronously connect_job_factory_->set_job_type(TestConnectJob::kMockJob); @@ -2715,10 +2881,10 @@ TEST_F(ClientSocketPoolBaseTest, CallbackThatReleasesPool) { TestCompletionCallback callback; EXPECT_EQ( ERR_IO_PENDING, - handle.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, callback.callback(), - ClientSocketPool::ProxyAuthCallback(), pool_.get(), - NetLogWithSource())); + handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback.callback(), ClientSocketPool::ProxyAuthCallback(), + pool_.get(), NetLogWithSource())); pool_->FlushWithError(ERR_NETWORK_CHANGED); @@ -2734,10 +2900,10 @@ TEST_F(ClientSocketPoolBaseTest, DoNotReuseSocketAfterFlush) { TestCompletionCallback callback; EXPECT_EQ( ERR_IO_PENDING, - handle.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, callback.callback(), - ClientSocketPool::ProxyAuthCallback(), pool_.get(), - NetLogWithSource())); + handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback.callback(), ClientSocketPool::ProxyAuthCallback(), + pool_.get(), NetLogWithSource())); EXPECT_THAT(callback.WaitForResult(), IsOk()); EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type()); @@ -2748,10 +2914,10 @@ TEST_F(ClientSocketPoolBaseTest, DoNotReuseSocketAfterFlush) { EXPECT_EQ( ERR_IO_PENDING, - handle.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, callback.callback(), - ClientSocketPool::ProxyAuthCallback(), pool_.get(), - NetLogWithSource())); + handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback.callback(), ClientSocketPool::ProxyAuthCallback(), + pool_.get(), NetLogWithSource())); EXPECT_THAT(callback.WaitForResult(), IsOk()); EXPECT_EQ(ClientSocketHandle::UNUSED, handle.reuse_type()); } @@ -2778,12 +2944,13 @@ class ConnectWithinCallback : public TestCompletionCallbackBase { private: void OnComplete(int result) { SetResult(result); - EXPECT_EQ(ERR_IO_PENDING, - handle_.Init(group_id_, params_, DEFAULT_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, - nested_callback_.callback(), - ClientSocketPool::ProxyAuthCallback(), pool_, - NetLogWithSource())); + EXPECT_EQ( + ERR_IO_PENDING, + handle_.Init(group_id_, params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + nested_callback_.callback(), + ClientSocketPool::ProxyAuthCallback(), pool_, + NetLogWithSource())); } const ClientSocketPool::GroupId group_id_; @@ -2805,10 +2972,10 @@ TEST_F(ClientSocketPoolBaseTest, AbortAllRequestsOnFlush) { ConnectWithinCallback callback(TestGroupId("a"), params_, pool_.get()); EXPECT_EQ( ERR_IO_PENDING, - handle.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, callback.callback(), - ClientSocketPool::ProxyAuthCallback(), pool_.get(), - NetLogWithSource())); + handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback.callback(), ClientSocketPool::ProxyAuthCallback(), + pool_.get(), NetLogWithSource())); // Second job will be started during the first callback, and will // asynchronously complete with OK. @@ -2827,10 +2994,10 @@ TEST_F(ClientSocketPoolBaseTest, BackupSocketWaitsForHostResolution) { TestCompletionCallback callback; EXPECT_EQ( ERR_IO_PENDING, - handle.Init(TestGroupId("bar"), params_, DEFAULT_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, callback.callback(), - ClientSocketPool::ProxyAuthCallback(), pool_.get(), - NetLogWithSource())); + handle.Init(TestGroupId("bar"), params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback.callback(), ClientSocketPool::ProxyAuthCallback(), + pool_.get(), NetLogWithSource())); // The backup timer fires but doesn't start a new ConnectJob while resolving // the hostname. client_socket_factory_.SetJobLoadState(0, LOAD_STATE_RESOLVING_HOST); @@ -2857,10 +3024,10 @@ TEST_F(ClientSocketPoolBaseTest, NoBackupSocketWhenConnected) { TestCompletionCallback callback; EXPECT_EQ( ERR_IO_PENDING, - handle.Init(TestGroupId("bar"), params_, DEFAULT_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, callback.callback(), - ClientSocketPool::ProxyAuthCallback(), pool_.get(), - NetLogWithSource())); + handle.Init(TestGroupId("bar"), params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback.callback(), ClientSocketPool::ProxyAuthCallback(), + pool_.get(), NetLogWithSource())); // The backup timer fires but doesn't start a new ConnectJob while resolving // the hostname. client_socket_factory_.SetJobLoadState(0, LOAD_STATE_RESOLVING_HOST); @@ -2889,18 +3056,18 @@ TEST_F(ClientSocketPoolBaseTest, BackupSocketCancelAtMaxSockets) { TestCompletionCallback callback; EXPECT_EQ( ERR_IO_PENDING, - handle.Init(TestGroupId("bar"), params_, DEFAULT_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, callback.callback(), - ClientSocketPool::ProxyAuthCallback(), pool_.get(), - NetLogWithSource())); + handle.Init(TestGroupId("bar"), params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback.callback(), ClientSocketPool::ProxyAuthCallback(), + pool_.get(), NetLogWithSource())); // Start (MaxSockets - 1) connected sockets to reach max sockets. connect_job_factory_->set_job_type(TestConnectJob::kMockJob); ClientSocketHandle handles[kDefaultMaxSockets]; for (int i = 1; i < kDefaultMaxSockets; ++i) { TestCompletionCallback callback; - EXPECT_EQ(OK, handles[i].Init(TestGroupId("bar"), params_, DEFAULT_PRIORITY, - SocketTag(), + EXPECT_EQ(OK, handles[i].Init(TestGroupId("bar"), params_, base::nullopt, + DEFAULT_PRIORITY, SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback.callback(), ClientSocketPool::ProxyAuthCallback(), @@ -2930,10 +3097,10 @@ TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterCancelingAllRequests) { TestCompletionCallback callback; EXPECT_EQ( ERR_IO_PENDING, - handle.Init(TestGroupId("bar"), params_, DEFAULT_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, callback.callback(), - ClientSocketPool::ProxyAuthCallback(), pool_.get(), - NetLogWithSource())); + handle.Init(TestGroupId("bar"), params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback.callback(), ClientSocketPool::ProxyAuthCallback(), + pool_.get(), NetLogWithSource())); ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("bar"))); EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("bar"))); EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting( @@ -2962,17 +3129,17 @@ TEST_F(ClientSocketPoolBaseTest, CancelBackupSocketAfterFinishingAllRequests) { TestCompletionCallback callback; EXPECT_EQ( ERR_IO_PENDING, - handle.Init(TestGroupId("bar"), params_, DEFAULT_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, callback.callback(), - ClientSocketPool::ProxyAuthCallback(), pool_.get(), - NetLogWithSource())); + handle.Init(TestGroupId("bar"), params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback.callback(), ClientSocketPool::ProxyAuthCallback(), + pool_.get(), NetLogWithSource())); connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob); ClientSocketHandle handle2; TestCompletionCallback callback2; EXPECT_EQ( ERR_IO_PENDING, - handle2.Init(TestGroupId("bar"), params_, DEFAULT_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, + handle2.Init(TestGroupId("bar"), params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback2.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource())); ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("bar"))); @@ -2999,8 +3166,8 @@ TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingWaitingForConnect) { TestCompletionCallback callback; EXPECT_EQ( ERR_IO_PENDING, - handle1.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, + handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource())); EXPECT_THAT(callback.WaitForResult(), IsOk()); @@ -3014,8 +3181,8 @@ TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingWaitingForConnect) { ClientSocketHandle handle2; EXPECT_EQ( ERR_IO_PENDING, - handle2.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, + handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource())); // No idle sockets, and one connecting job. @@ -3055,8 +3222,8 @@ TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtGroupCapacity) { TestCompletionCallback callback; EXPECT_EQ( ERR_IO_PENDING, - handle1.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, + handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource())); EXPECT_THAT(callback.WaitForResult(), IsOk()); @@ -3070,8 +3237,8 @@ TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtGroupCapacity) { ClientSocketHandle handle2; EXPECT_EQ( ERR_IO_PENDING, - handle2.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, + handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource())); // No idle sockets, and one connecting job. @@ -3113,8 +3280,8 @@ TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtStall) { TestCompletionCallback callback; EXPECT_EQ( ERR_IO_PENDING, - handle1.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, + handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource())); EXPECT_THAT(callback.WaitForResult(), IsOk()); @@ -3128,8 +3295,8 @@ TEST_F(ClientSocketPoolBaseTest, DelayedSocketBindingAtStall) { ClientSocketHandle handle2; EXPECT_EQ( ERR_IO_PENDING, - handle2.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, + handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource())); // No idle sockets, and one connecting job. @@ -3174,8 +3341,8 @@ TEST_F(ClientSocketPoolBaseTest, SynchronouslyProcessOnePendingRequest) { TestCompletionCallback callback1; EXPECT_EQ( ERR_IO_PENDING, - handle1.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, + handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback1.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource())); EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a"))); @@ -3189,8 +3356,8 @@ TEST_F(ClientSocketPoolBaseTest, SynchronouslyProcessOnePendingRequest) { // when created. EXPECT_EQ( ERR_IO_PENDING, - handle2.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, + handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback2.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource())); @@ -3210,8 +3377,8 @@ TEST_F(ClientSocketPoolBaseTest, PreferUsedSocketToUnusedSocket) { TestCompletionCallback callback1; EXPECT_EQ( ERR_IO_PENDING, - handle1.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, + handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback1.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource())); @@ -3219,16 +3386,16 @@ TEST_F(ClientSocketPoolBaseTest, PreferUsedSocketToUnusedSocket) { TestCompletionCallback callback2; EXPECT_EQ( ERR_IO_PENDING, - handle2.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, + handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback2.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource())); ClientSocketHandle handle3; TestCompletionCallback callback3; EXPECT_EQ( ERR_IO_PENDING, - handle3.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, + handle3.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback3.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource())); @@ -3247,18 +3414,18 @@ TEST_F(ClientSocketPoolBaseTest, PreferUsedSocketToUnusedSocket) { handle3.Reset(); EXPECT_EQ(OK, handle1.Init( - TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, + TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback1.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource())); EXPECT_EQ(OK, handle2.Init( - TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, + TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback2.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource())); EXPECT_EQ(OK, handle3.Init( - TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, + TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback3.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource())); @@ -3271,7 +3438,8 @@ TEST_F(ClientSocketPoolBaseTest, RequestSockets) { CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup); connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob); - pool_->RequestSockets(TestGroupId("a"), params_, 2, NetLogWithSource()); + pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 2, + NetLogWithSource()); ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a"))); EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a"))); @@ -3285,8 +3453,8 @@ TEST_F(ClientSocketPoolBaseTest, RequestSockets) { TestCompletionCallback callback1; EXPECT_EQ( ERR_IO_PENDING, - handle1.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, + handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback1.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource())); @@ -3294,8 +3462,8 @@ TEST_F(ClientSocketPoolBaseTest, RequestSockets) { TestCompletionCallback callback2; EXPECT_EQ( ERR_IO_PENDING, - handle2.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, + handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback2.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource())); @@ -3327,8 +3495,8 @@ TEST_F(ClientSocketPoolBaseTest, RequestSocketsWhenAlreadyHaveAConnectJob) { TestCompletionCallback callback1; EXPECT_EQ( ERR_IO_PENDING, - handle1.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, + handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback1.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource())); @@ -3340,7 +3508,8 @@ TEST_F(ClientSocketPoolBaseTest, RequestSocketsWhenAlreadyHaveAConnectJob) { pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a"))); EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a"))); - pool_->RequestSockets(TestGroupId("a"), params_, 2, NetLogWithSource()); + pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 2, + NetLogWithSource()); EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a"))); EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroupForTesting( @@ -3353,8 +3522,8 @@ TEST_F(ClientSocketPoolBaseTest, RequestSocketsWhenAlreadyHaveAConnectJob) { TestCompletionCallback callback2; EXPECT_EQ( ERR_IO_PENDING, - handle2.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, + handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback2.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource())); @@ -3387,8 +3556,8 @@ TEST_F(ClientSocketPoolBaseTest, TestCompletionCallback callback1; EXPECT_EQ( ERR_IO_PENDING, - handle1.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, + handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback1.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource())); @@ -3396,8 +3565,8 @@ TEST_F(ClientSocketPoolBaseTest, TestCompletionCallback callback2; EXPECT_EQ( ERR_IO_PENDING, - handle2.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, + handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback2.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource())); @@ -3405,8 +3574,8 @@ TEST_F(ClientSocketPoolBaseTest, TestCompletionCallback callback3; EXPECT_EQ( ERR_IO_PENDING, - handle3.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, + handle3.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback3.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource())); @@ -3418,7 +3587,8 @@ TEST_F(ClientSocketPoolBaseTest, pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a"))); EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a"))); - pool_->RequestSockets(TestGroupId("a"), params_, 2, NetLogWithSource()); + pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 2, + NetLogWithSource()); EXPECT_EQ(3u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a"))); EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting( @@ -3448,8 +3618,8 @@ TEST_F(ClientSocketPoolBaseTest, RequestSocketsAtMaxSocketLimit) { ASSERT_FALSE(pool_->HasGroupForTesting(TestGroupId("a"))); - pool_->RequestSockets(TestGroupId("a"), params_, kDefaultMaxSockets, - NetLogWithSource()); + pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, + kDefaultMaxSockets, NetLogWithSource()); ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a"))); EXPECT_EQ(kDefaultMaxSockets, @@ -3465,8 +3635,8 @@ TEST_F(ClientSocketPoolBaseTest, RequestSocketsAtMaxSocketLimit) { ASSERT_FALSE(pool_->HasGroupForTesting(TestGroupId("b"))); - pool_->RequestSockets(TestGroupId("b"), params_, kDefaultMaxSockets, - NetLogWithSource()); + pool_->RequestSockets(TestGroupId("b"), params_, base::nullopt, + kDefaultMaxSockets, NetLogWithSource()); ASSERT_FALSE(pool_->HasGroupForTesting(TestGroupId("b"))); } @@ -3477,8 +3647,8 @@ TEST_F(ClientSocketPoolBaseTest, RequestSocketsHitMaxSocketLimit) { ASSERT_FALSE(pool_->HasGroupForTesting(TestGroupId("a"))); - pool_->RequestSockets(TestGroupId("a"), params_, kDefaultMaxSockets - 1, - NetLogWithSource()); + pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, + kDefaultMaxSockets - 1, NetLogWithSource()); ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a"))); EXPECT_EQ(kDefaultMaxSockets - 1, @@ -3495,8 +3665,8 @@ TEST_F(ClientSocketPoolBaseTest, RequestSocketsHitMaxSocketLimit) { ASSERT_FALSE(pool_->HasGroupForTesting(TestGroupId("b"))); - pool_->RequestSockets(TestGroupId("b"), params_, kDefaultMaxSockets, - NetLogWithSource()); + pool_->RequestSockets(TestGroupId("b"), params_, base::nullopt, + kDefaultMaxSockets, NetLogWithSource()); ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("b"))); EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("b"))); @@ -3511,8 +3681,8 @@ TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountIdleSockets) { TestCompletionCallback callback1; EXPECT_EQ( ERR_IO_PENDING, - handle1.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, + handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback1.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource())); ASSERT_THAT(callback1.WaitForResult(), IsOk()); @@ -3526,7 +3696,8 @@ TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountIdleSockets) { pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a"))); EXPECT_EQ(1u, pool_->IdleSocketCountInGroup(TestGroupId("a"))); - pool_->RequestSockets(TestGroupId("a"), params_, 2, NetLogWithSource()); + pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 2, + NetLogWithSource()); EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a"))); EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroupForTesting( @@ -3544,8 +3715,8 @@ TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountActiveSockets) { TestCompletionCallback callback1; EXPECT_EQ( ERR_IO_PENDING, - handle1.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, + handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback1.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource())); ASSERT_THAT(callback1.WaitForResult(), IsOk()); @@ -3559,7 +3730,8 @@ TEST_F(ClientSocketPoolBaseTest, RequestSocketsCountActiveSockets) { EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a"))); EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a"))); - pool_->RequestSockets(TestGroupId("a"), params_, 2, NetLogWithSource()); + pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 2, + NetLogWithSource()); EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a"))); EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroupForTesting( @@ -3574,8 +3746,8 @@ TEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronous) { CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup); connect_job_factory_->set_job_type(TestConnectJob::kMockJob); - pool_->RequestSockets(TestGroupId("a"), params_, kDefaultMaxSocketsPerGroup, - NetLogWithSource()); + pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, + kDefaultMaxSocketsPerGroup, NetLogWithSource()); ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a"))); EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a"))); @@ -3586,8 +3758,8 @@ TEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronous) { EXPECT_EQ(kDefaultMaxSocketsPerGroup, static_cast<int>(pool_->IdleSocketCountInGroup(TestGroupId("a")))); - pool_->RequestSockets(TestGroupId("b"), params_, kDefaultMaxSocketsPerGroup, - NetLogWithSource()); + pool_->RequestSockets(TestGroupId("b"), params_, base::nullopt, + kDefaultMaxSocketsPerGroup, NetLogWithSource()); EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("b"))); EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting( @@ -3602,15 +3774,15 @@ TEST_F(ClientSocketPoolBaseTest, RequestSocketsSynchronousError) { CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup); connect_job_factory_->set_job_type(TestConnectJob::kMockFailingJob); - pool_->RequestSockets(TestGroupId("a"), params_, kDefaultMaxSocketsPerGroup, - NetLogWithSource()); + pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, + kDefaultMaxSocketsPerGroup, NetLogWithSource()); ASSERT_FALSE(pool_->HasGroupForTesting(TestGroupId("a"))); connect_job_factory_->set_job_type( TestConnectJob::kMockAdditionalErrorStateJob); - pool_->RequestSockets(TestGroupId("a"), params_, kDefaultMaxSocketsPerGroup, - NetLogWithSource()); + pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, + kDefaultMaxSocketsPerGroup, NetLogWithSource()); ASSERT_FALSE(pool_->HasGroupForTesting(TestGroupId("a"))); } @@ -3619,7 +3791,8 @@ TEST_F(ClientSocketPoolBaseTest, RequestSocketsMultipleTimesDoesNothing) { CreatePool(4, 4); connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob); - pool_->RequestSockets(TestGroupId("a"), params_, 2, NetLogWithSource()); + pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 2, + NetLogWithSource()); ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a"))); EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a"))); @@ -3630,7 +3803,8 @@ TEST_F(ClientSocketPoolBaseTest, RequestSocketsMultipleTimesDoesNothing) { EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a"))); EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a"))); - pool_->RequestSockets(TestGroupId("a"), params_, 2, NetLogWithSource()); + pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 2, + NetLogWithSource()); EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a"))); EXPECT_EQ(2u, pool_->NumNeverAssignedConnectJobsInGroupForTesting( TestGroupId("a"))); @@ -3643,8 +3817,8 @@ TEST_F(ClientSocketPoolBaseTest, RequestSocketsMultipleTimesDoesNothing) { TestCompletionCallback callback1; EXPECT_EQ( ERR_IO_PENDING, - handle1.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, + handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback1.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource())); @@ -3663,8 +3837,8 @@ TEST_F(ClientSocketPoolBaseTest, RequestSocketsMultipleTimesDoesNothing) { TestCompletionCallback callback2; EXPECT_EQ( ERR_IO_PENDING, - handle2.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, + handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback2.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource())); client_socket_factory_.SignalJob(0); @@ -3689,7 +3863,8 @@ TEST_F(ClientSocketPoolBaseTest, RequestSocketsMultipleTimesDoesNothing) { EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("a"))); EXPECT_EQ(2u, pool_->IdleSocketCountInGroup(TestGroupId("a"))); - pool_->RequestSockets(TestGroupId("a"), params_, 2, NetLogWithSource()); + pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 2, + NetLogWithSource()); EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a"))); EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting( TestGroupId("a"))); @@ -3703,7 +3878,8 @@ TEST_F(ClientSocketPoolBaseTest, RequestSocketsDifferentNumSockets) { CreatePool(4, 4); connect_job_factory_->set_job_type(TestConnectJob::kMockPendingJob); - pool_->RequestSockets(TestGroupId("a"), params_, 1, NetLogWithSource()); + pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 1, + NetLogWithSource()); ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a"))); EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a"))); @@ -3713,7 +3889,8 @@ TEST_F(ClientSocketPoolBaseTest, RequestSocketsDifferentNumSockets) { pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a"))); EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a"))); - pool_->RequestSockets(TestGroupId("a"), params_, 2, NetLogWithSource()); + pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 2, + NetLogWithSource()); EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a"))); EXPECT_EQ(2u, pool_->NumNeverAssignedConnectJobsInGroupForTesting( TestGroupId("a"))); @@ -3721,7 +3898,8 @@ TEST_F(ClientSocketPoolBaseTest, RequestSocketsDifferentNumSockets) { pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a"))); EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a"))); - pool_->RequestSockets(TestGroupId("a"), params_, 3, NetLogWithSource()); + pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 3, + NetLogWithSource()); EXPECT_EQ(3u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a"))); EXPECT_EQ(3u, pool_->NumNeverAssignedConnectJobsInGroupForTesting( TestGroupId("a"))); @@ -3729,7 +3907,8 @@ TEST_F(ClientSocketPoolBaseTest, RequestSocketsDifferentNumSockets) { pool_->NumUnassignedConnectJobsInGroupForTesting(TestGroupId("a"))); EXPECT_EQ(0u, pool_->IdleSocketCountInGroup(TestGroupId("a"))); - pool_->RequestSockets(TestGroupId("a"), params_, 1, NetLogWithSource()); + pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 1, + NetLogWithSource()); EXPECT_EQ(3u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a"))); EXPECT_EQ(3u, pool_->NumNeverAssignedConnectJobsInGroupForTesting( TestGroupId("a"))); @@ -3742,7 +3921,8 @@ TEST_F(ClientSocketPoolBaseTest, PreconnectJobsTakenByNormalRequests) { CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup); connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob); - pool_->RequestSockets(TestGroupId("a"), params_, 1, NetLogWithSource()); + pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 1, + NetLogWithSource()); ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a"))); EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a"))); @@ -3756,8 +3936,8 @@ TEST_F(ClientSocketPoolBaseTest, PreconnectJobsTakenByNormalRequests) { TestCompletionCallback callback1; EXPECT_EQ( ERR_IO_PENDING, - handle1.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, + handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback1.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource())); @@ -3792,7 +3972,8 @@ TEST_F(ClientSocketPoolBaseTest, PreconnectJobsTakenByNormalRequests) { TEST_F(ClientSocketPoolBaseTest, ConnectedPreconnectJobsHaveNoConnectTimes) { CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup); connect_job_factory_->set_job_type(TestConnectJob::kMockJob); - pool_->RequestSockets(TestGroupId("a"), params_, 1, NetLogWithSource()); + pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 1, + NetLogWithSource()); ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a"))); EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a"))); @@ -3805,8 +3986,8 @@ TEST_F(ClientSocketPoolBaseTest, ConnectedPreconnectJobsHaveNoConnectTimes) { ClientSocketHandle handle; TestCompletionCallback callback; EXPECT_EQ(OK, handle.Init( - TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, + TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource())); @@ -3833,8 +4014,8 @@ TEST_F(ClientSocketPoolBaseTest, PreconnectClosesIdleSocketRemovesGroup) { TestCompletionCallback callback1; EXPECT_EQ( ERR_IO_PENDING, - handle1.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, + handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback1.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource())); ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a"))); @@ -3862,14 +4043,14 @@ TEST_F(ClientSocketPoolBaseTest, PreconnectClosesIdleSocketRemovesGroup) { TestCompletionCallback callback2; EXPECT_EQ( ERR_IO_PENDING, - handle1.Init(TestGroupId("b"), params_, DEFAULT_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, + handle1.Init(TestGroupId("b"), params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback1.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource())); EXPECT_EQ( ERR_IO_PENDING, - handle2.Init(TestGroupId("b"), params_, DEFAULT_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, + handle2.Init(TestGroupId("b"), params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback2.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource())); @@ -3896,7 +4077,8 @@ TEST_F(ClientSocketPoolBaseTest, PreconnectClosesIdleSocketRemovesGroup) { // Requesting 2 preconnected sockets for "a" should fail to allocate any more // sockets for "a", and "b" should still have 2 active sockets. - pool_->RequestSockets(TestGroupId("a"), params_, 2, NetLogWithSource()); + pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 2, + NetLogWithSource()); EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a"))); EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting( TestGroupId("a"))); @@ -3920,7 +4102,8 @@ TEST_F(ClientSocketPoolBaseTest, PreconnectClosesIdleSocketRemovesGroup) { EXPECT_EQ(2u, pool_->IdleSocketCountInGroup(TestGroupId("b"))); EXPECT_EQ(0, pool_->NumActiveSocketsInGroupForTesting(TestGroupId("b"))); - pool_->RequestSockets(TestGroupId("a"), params_, 2, NetLogWithSource()); + pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 2, + NetLogWithSource()); EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a"))); EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroupForTesting( TestGroupId("a"))); @@ -3945,7 +4128,8 @@ TEST_F(ClientSocketPoolBaseTest, PreconnectWithoutBackupJob) { connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob); connect_job_factory_->set_timeout_duration( base::TimeDelta::FromMilliseconds(500)); - pool_->RequestSockets(TestGroupId("a"), params_, 1, NetLogWithSource()); + pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 1, + NetLogWithSource()); EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a"))); EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroupForTesting( TestGroupId("a"))); @@ -3970,7 +4154,8 @@ TEST_F(ClientSocketPoolBaseTest, PreconnectWithBackupJob) { // Make the ConnectJob hang forever. connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob); - pool_->RequestSockets(TestGroupId("a"), params_, 1, NetLogWithSource()); + pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 1, + NetLogWithSource()); EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a"))); EXPECT_EQ(1u, pool_->NumNeverAssignedConnectJobsInGroupForTesting( TestGroupId("a"))); @@ -3985,10 +4170,10 @@ TEST_F(ClientSocketPoolBaseTest, PreconnectWithBackupJob) { TestCompletionCallback callback; EXPECT_EQ( ERR_IO_PENDING, - handle.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, callback.callback(), - ClientSocketPool::ProxyAuthCallback(), pool_.get(), - NetLogWithSource())); + handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback.callback(), ClientSocketPool::ProxyAuthCallback(), + pool_.get(), NetLogWithSource())); // Timer has started, but the backup connect job shouldn't be created yet. EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a"))); EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting( @@ -4016,7 +4201,8 @@ TEST_F(ClientSocketPoolBaseTest, PreconnectWithUnreadData) { CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup); connect_job_factory_->set_job_type(TestConnectJob::kMockUnreadDataJob); - pool_->RequestSockets(TestGroupId("a"), params_, 1, NetLogWithSource()); + pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 1, + NetLogWithSource()); ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a"))); EXPECT_EQ(0u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a"))); @@ -4032,8 +4218,8 @@ TEST_F(ClientSocketPoolBaseTest, PreconnectWithUnreadData) { ClientSocketHandle handle; TestCompletionCallback callback; EXPECT_EQ(OK, handle.Init( - TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, + TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource())); @@ -4064,8 +4250,8 @@ TEST_F(ClientSocketPoolBaseTest, RequestGetsAssignedJob) { TestCompletionCallback callback1; EXPECT_EQ( ERR_IO_PENDING, - handle1.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, + handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback1.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource())); @@ -4088,8 +4274,8 @@ TEST_F(ClientSocketPoolBaseTest, MultipleRequestsGetAssignedJobs) { TestCompletionCallback callback1; EXPECT_EQ( ERR_IO_PENDING, - handle1.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, + handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback1.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource())); @@ -4104,8 +4290,8 @@ TEST_F(ClientSocketPoolBaseTest, MultipleRequestsGetAssignedJobs) { TestCompletionCallback callback2; EXPECT_EQ( ERR_IO_PENDING, - handle2.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, + handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback2.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource())); @@ -4141,7 +4327,8 @@ TEST_F(ClientSocketPoolBaseTest, PreconnectJobGetsAssignedToRequest) { CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup); connect_job_factory_->set_job_type(TestConnectJob::kMockWaitingJob); - pool_->RequestSockets(TestGroupId("a"), params_, 1, NetLogWithSource()); + pool_->RequestSockets(TestGroupId("a"), params_, base::nullopt, 1, + NetLogWithSource()); ASSERT_TRUE(pool_->HasGroupForTesting(TestGroupId("a"))); EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a"))); @@ -4155,8 +4342,8 @@ TEST_F(ClientSocketPoolBaseTest, PreconnectJobGetsAssignedToRequest) { TestCompletionCallback callback1; EXPECT_EQ( ERR_IO_PENDING, - handle1.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, + handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback1.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource())); @@ -4179,8 +4366,8 @@ TEST_F(ClientSocketPoolBaseTest, HigherPriorityRequestStealsJob) { TestCompletionCallback callback1; EXPECT_EQ( ERR_IO_PENDING, - handle1.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, + handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback1.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource())); @@ -4199,8 +4386,8 @@ TEST_F(ClientSocketPoolBaseTest, HigherPriorityRequestStealsJob) { TestCompletionCallback callback2; EXPECT_EQ( ERR_IO_PENDING, - handle2.Init(TestGroupId("a"), params_, HIGHEST, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, + handle2.Init(TestGroupId("a"), params_, base::nullopt, HIGHEST, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback2.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource())); @@ -4225,12 +4412,13 @@ TEST_F(ClientSocketPoolBaseTest, RequestStealsJobFromLowestRequestWithJob) { ClientSocketHandle handle_lowest; TestCompletionCallback callback_lowest; - EXPECT_EQ(ERR_IO_PENDING, - handle_lowest.Init(TestGroupId("a"), params_, LOWEST, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, - callback_lowest.callback(), - ClientSocketPool::ProxyAuthCallback(), - pool_.get(), NetLogWithSource())); + EXPECT_EQ( + ERR_IO_PENDING, + handle_lowest.Init(TestGroupId("a"), params_, base::nullopt, LOWEST, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback_lowest.callback(), + ClientSocketPool::ProxyAuthCallback(), pool_.get(), + NetLogWithSource())); EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a"))); EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting( @@ -4241,12 +4429,13 @@ TEST_F(ClientSocketPoolBaseTest, RequestStealsJobFromLowestRequestWithJob) { ClientSocketHandle handle_highest; TestCompletionCallback callback_highest; - EXPECT_EQ(ERR_IO_PENDING, - handle_highest.Init(TestGroupId("a"), params_, HIGHEST, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, - callback_highest.callback(), - ClientSocketPool::ProxyAuthCallback(), - pool_.get(), NetLogWithSource())); + EXPECT_EQ( + ERR_IO_PENDING, + handle_highest.Init(TestGroupId("a"), params_, base::nullopt, HIGHEST, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback_highest.callback(), + ClientSocketPool::ProxyAuthCallback(), pool_.get(), + NetLogWithSource())); EXPECT_EQ(2u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a"))); EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting( @@ -4258,11 +4447,11 @@ TEST_F(ClientSocketPoolBaseTest, RequestStealsJobFromLowestRequestWithJob) { ClientSocketHandle handle_low; TestCompletionCallback callback_low; EXPECT_EQ(ERR_IO_PENDING, - handle_low.Init(TestGroupId("a"), params_, LOW, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, - callback_low.callback(), - ClientSocketPool::ProxyAuthCallback(), pool_.get(), - NetLogWithSource())); + handle_low.Init( + TestGroupId("a"), params_, base::nullopt, LOW, SocketTag(), + ClientSocketPool::RespectLimits::ENABLED, + callback_low.callback(), ClientSocketPool::ProxyAuthCallback(), + pool_.get(), NetLogWithSource())); EXPECT_EQ(3u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a"))); EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting( @@ -4273,12 +4462,13 @@ TEST_F(ClientSocketPoolBaseTest, RequestStealsJobFromLowestRequestWithJob) { ClientSocketHandle handle_lowest2; TestCompletionCallback callback_lowest2; - EXPECT_EQ(ERR_IO_PENDING, - handle_lowest2.Init(TestGroupId("a"), params_, LOWEST, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, - callback_lowest2.callback(), - ClientSocketPool::ProxyAuthCallback(), - pool_.get(), NetLogWithSource())); + EXPECT_EQ( + ERR_IO_PENDING, + handle_lowest2.Init(TestGroupId("a"), params_, base::nullopt, LOWEST, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback_lowest2.callback(), + ClientSocketPool::ProxyAuthCallback(), pool_.get(), + NetLogWithSource())); EXPECT_EQ(3u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a"))); EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting( @@ -4301,12 +4491,13 @@ TEST_F(ClientSocketPoolBaseTest, RequestStealsJobFromLowestRequestWithJob) { // lowest priority request with a job. ClientSocketHandle handle_medium; TestCompletionCallback callback_medium; - EXPECT_EQ(ERR_IO_PENDING, - handle_medium.Init(TestGroupId("a"), params_, MEDIUM, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, - callback_medium.callback(), - ClientSocketPool::ProxyAuthCallback(), - pool_.get(), NetLogWithSource())); + EXPECT_EQ( + ERR_IO_PENDING, + handle_medium.Init(TestGroupId("a"), params_, base::nullopt, MEDIUM, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback_medium.callback(), + ClientSocketPool::ProxyAuthCallback(), pool_.get(), + NetLogWithSource())); EXPECT_EQ(3u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a"))); EXPECT_EQ(0u, pool_->NumNeverAssignedConnectJobsInGroupForTesting( @@ -4334,8 +4525,8 @@ TEST_F(ClientSocketPoolBaseTest, ReprioritizeRequestStealsJob) { TestCompletionCallback callback1; EXPECT_EQ( ERR_IO_PENDING, - handle1.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, + handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback1.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource())); @@ -4350,8 +4541,8 @@ TEST_F(ClientSocketPoolBaseTest, ReprioritizeRequestStealsJob) { TestCompletionCallback callback2; EXPECT_EQ( ERR_IO_PENDING, - handle2.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, + handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback2.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource())); @@ -4385,8 +4576,8 @@ TEST_F(ClientSocketPoolBaseTest, CancelRequestReassignsJob) { TestCompletionCallback callback1; EXPECT_EQ( ERR_IO_PENDING, - handle1.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, + handle1.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback1.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource())); @@ -4404,8 +4595,8 @@ TEST_F(ClientSocketPoolBaseTest, CancelRequestReassignsJob) { TestCompletionCallback callback2; EXPECT_EQ( ERR_IO_PENDING, - handle2.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, + handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback2.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource())); @@ -4443,8 +4634,8 @@ TEST_F(ClientSocketPoolBaseTest, JobCompletionReassignsJob) { TestCompletionCallback callback1; EXPECT_EQ( ERR_IO_PENDING, - handle1.Init(TestGroupId("a"), params_, HIGHEST, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, + handle1.Init(TestGroupId("a"), params_, base::nullopt, HIGHEST, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback1.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource())); @@ -4459,8 +4650,8 @@ TEST_F(ClientSocketPoolBaseTest, JobCompletionReassignsJob) { TestCompletionCallback callback2; EXPECT_EQ( ERR_IO_PENDING, - handle2.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, + handle2.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback2.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource())); @@ -4505,14 +4696,16 @@ class MockLayeredPool : public HigherLayeredPool { int RequestSocket(TransportClientSocketPool* pool) { return handle_.Init( - group_id_, CreateDummyParams(), DEFAULT_PRIORITY, SocketTag(), + group_id_, ClientSocketPool::SocketParams::CreateForHttpForTesting(), + base::nullopt, DEFAULT_PRIORITY, SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback_.callback(), ClientSocketPool::ProxyAuthCallback(), pool, NetLogWithSource()); } int RequestSocketWithoutLimits(TransportClientSocketPool* pool) { return handle_.Init( - group_id_, CreateDummyParams(), MAXIMUM_PRIORITY, SocketTag(), + group_id_, ClientSocketPool::SocketParams::CreateForHttpForTesting(), + base::nullopt, MAXIMUM_PRIORITY, SocketTag(), ClientSocketPool::RespectLimits::DISABLED, callback_.callback(), ClientSocketPool::ProxyAuthCallback(), pool, NetLogWithSource()); } @@ -4555,10 +4748,10 @@ TEST_F(ClientSocketPoolBaseTest, CloseIdleSocketsHeldByLayeredPoolWhenNeeded) { TestCompletionCallback callback; EXPECT_EQ( ERR_IO_PENDING, - handle.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, callback.callback(), - ClientSocketPool::ProxyAuthCallback(), pool_.get(), - NetLogWithSource())); + handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback.callback(), ClientSocketPool::ProxyAuthCallback(), + pool_.get(), NetLogWithSource())); EXPECT_THAT(callback.WaitForResult(), IsOk()); } @@ -4579,10 +4772,10 @@ TEST_F(ClientSocketPoolBaseTest, TestCompletionCallback callback; EXPECT_EQ( ERR_IO_PENDING, - handle.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, callback.callback(), - ClientSocketPool::ProxyAuthCallback(), pool_.get(), - NetLogWithSource())); + handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback.callback(), ClientSocketPool::ProxyAuthCallback(), + pool_.get(), NetLogWithSource())); base::RunLoop().RunUntilIdle(); EXPECT_FALSE(callback.have_result()); } @@ -4601,11 +4794,12 @@ TEST_F(ClientSocketPoolBaseTest, // has the maximum number of connections already, it's not stalled). ClientSocketHandle handle1; TestCompletionCallback callback1; - EXPECT_EQ(OK, handle1.Init( - TestGroupId("group1"), params_, DEFAULT_PRIORITY, - SocketTag(), ClientSocketPool::RespectLimits::ENABLED, - callback1.callback(), ClientSocketPool::ProxyAuthCallback(), - pool_.get(), NetLogWithSource())); + EXPECT_EQ(OK, handle1.Init(TestGroupId("group1"), params_, base::nullopt, + DEFAULT_PRIORITY, SocketTag(), + ClientSocketPool::RespectLimits::ENABLED, + callback1.callback(), + ClientSocketPool::ProxyAuthCallback(), pool_.get(), + NetLogWithSource())); MockLayeredPool mock_layered_pool(pool_.get(), TestGroupId("group2")); EXPECT_THAT(mock_layered_pool.RequestSocket(pool_.get()), IsOk()); @@ -4614,12 +4808,12 @@ TEST_F(ClientSocketPoolBaseTest, &MockLayeredPool::ReleaseOneConnection)); ClientSocketHandle handle; TestCompletionCallback callback2; - EXPECT_EQ( - ERR_IO_PENDING, - handle.Init(TestGroupId("group2"), params_, DEFAULT_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, - callback2.callback(), ClientSocketPool::ProxyAuthCallback(), - pool_.get(), NetLogWithSource())); + EXPECT_EQ(ERR_IO_PENDING, + handle.Init( + TestGroupId("group2"), params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback2.callback(), ClientSocketPool::ProxyAuthCallback(), + pool_.get(), NetLogWithSource())); EXPECT_THAT(callback2.WaitForResult(), IsOk()); } @@ -4637,11 +4831,12 @@ TEST_F(ClientSocketPoolBaseTest, ClientSocketHandle handle1; TestCompletionCallback callback1; - EXPECT_EQ(OK, handle1.Init( - TestGroupId("group1"), params_, DEFAULT_PRIORITY, - SocketTag(), ClientSocketPool::RespectLimits::ENABLED, - callback1.callback(), ClientSocketPool::ProxyAuthCallback(), - pool_.get(), NetLogWithSource())); + EXPECT_EQ(OK, handle1.Init(TestGroupId("group1"), params_, base::nullopt, + DEFAULT_PRIORITY, SocketTag(), + ClientSocketPool::RespectLimits::ENABLED, + callback1.callback(), + ClientSocketPool::ProxyAuthCallback(), pool_.get(), + NetLogWithSource())); MockLayeredPool mock_layered_pool(pool_.get(), TestGroupId("group2")); EXPECT_THAT(mock_layered_pool.RequestSocket(pool_.get()), IsOk()); @@ -4653,12 +4848,12 @@ TEST_F(ClientSocketPoolBaseTest, // The third request is made when the socket pool is in a stalled state. ClientSocketHandle handle3; TestCompletionCallback callback3; - EXPECT_EQ( - ERR_IO_PENDING, - handle3.Init(TestGroupId("group3"), params_, DEFAULT_PRIORITY, - SocketTag(), ClientSocketPool::RespectLimits::ENABLED, - callback3.callback(), ClientSocketPool::ProxyAuthCallback(), - pool_.get(), NetLogWithSource())); + EXPECT_EQ(ERR_IO_PENDING, + handle3.Init( + TestGroupId("group3"), params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback3.callback(), ClientSocketPool::ProxyAuthCallback(), + pool_.get(), NetLogWithSource())); base::RunLoop().RunUntilIdle(); EXPECT_FALSE(callback3.have_result()); @@ -4669,12 +4864,12 @@ TEST_F(ClientSocketPoolBaseTest, mock_layered_pool.set_can_release_connection(true); ClientSocketHandle handle4; TestCompletionCallback callback4; - EXPECT_EQ( - ERR_IO_PENDING, - handle4.Init(TestGroupId("group3"), params_, DEFAULT_PRIORITY, - SocketTag(), ClientSocketPool::RespectLimits::ENABLED, - callback4.callback(), ClientSocketPool::ProxyAuthCallback(), - pool_.get(), NetLogWithSource())); + EXPECT_EQ(ERR_IO_PENDING, + handle4.Init( + TestGroupId("group3"), params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback4.callback(), ClientSocketPool::ProxyAuthCallback(), + pool_.get(), NetLogWithSource())); EXPECT_THAT(callback3.WaitForResult(), IsOk()); EXPECT_FALSE(callback4.have_result()); @@ -4701,11 +4896,12 @@ TEST_F(ClientSocketPoolBaseTest, ClientSocketHandle handle1; TestCompletionCallback callback1; - EXPECT_EQ(OK, handle1.Init( - TestGroupId("group1"), params_, DEFAULT_PRIORITY, - SocketTag(), ClientSocketPool::RespectLimits::ENABLED, - callback1.callback(), ClientSocketPool::ProxyAuthCallback(), - pool_.get(), NetLogWithSource())); + EXPECT_EQ(OK, handle1.Init(TestGroupId("group1"), params_, base::nullopt, + DEFAULT_PRIORITY, SocketTag(), + ClientSocketPool::RespectLimits::ENABLED, + callback1.callback(), + ClientSocketPool::ProxyAuthCallback(), pool_.get(), + NetLogWithSource())); MockLayeredPool mock_layered_pool(pool_.get(), TestGroupId("group2")); EXPECT_THAT(mock_layered_pool.RequestSocket(pool_.get()), IsOk()); @@ -4719,8 +4915,8 @@ TEST_F(ClientSocketPoolBaseTest, TestCompletionCallback callback3; EXPECT_EQ( ERR_IO_PENDING, - handle3.Init(TestGroupId("group3"), params_, MEDIUM, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, + handle3.Init(TestGroupId("group3"), params_, base::nullopt, MEDIUM, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback3.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource())); @@ -4734,8 +4930,8 @@ TEST_F(ClientSocketPoolBaseTest, TestCompletionCallback callback4; EXPECT_EQ( ERR_IO_PENDING, - handle4.Init(TestGroupId("group3"), params_, HIGHEST, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, + handle4.Init(TestGroupId("group3"), params_, base::nullopt, HIGHEST, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback4.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource())); EXPECT_THAT(callback4.WaitForResult(), IsOk()); @@ -4766,10 +4962,10 @@ TEST_F(ClientSocketPoolBaseTest, TestCompletionCallback callback; EXPECT_EQ( ERR_IO_PENDING, - handle.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, callback.callback(), - ClientSocketPool::ProxyAuthCallback(), pool_.get(), - NetLogWithSource())); + handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback.callback(), ClientSocketPool::ProxyAuthCallback(), + pool_.get(), NetLogWithSource())); EXPECT_THAT(callback.WaitForResult(), IsOk()); } @@ -4848,10 +5044,10 @@ TEST_F(ClientSocketPoolBaseTest, ProxyAuthNoAuthCallback) { TestCompletionCallback callback; EXPECT_EQ( ERR_IO_PENDING, - handle.Init(TestGroupId("a"), params_, DEFAULT_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, callback.callback(), - ClientSocketPool::ProxyAuthCallback(), pool_.get(), - NetLogWithSource())); + handle.Init(TestGroupId("a"), params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback.callback(), ClientSocketPool::ProxyAuthCallback(), + pool_.get(), NetLogWithSource())); EXPECT_EQ(1u, pool_->NumConnectJobsInGroupForTesting(TestGroupId("a"))); @@ -4876,8 +5072,8 @@ class TestAuthHelper { ClientSocketPool::RespectLimits::ENABLED, const ClientSocketPool::GroupId& group_id_in = TestGroupId("a")) { EXPECT_EQ(ERR_IO_PENDING, - handle_.Init(group_id_in, params, priority, SocketTag(), - respect_limits, callback_.callback(), + handle_.Init(group_id_in, params, base::nullopt, priority, + SocketTag(), respect_limits, callback_.callback(), base::BindRepeating(&TestAuthHelper::AuthCallback, base::Unretained(this)), pool, NetLogWithSource())); @@ -5345,10 +5541,10 @@ TEST_F(ClientSocketPoolBaseTest, RefreshGroupCreatesNewConnectJobs) { ClientSocketHandle handle; TestCompletionCallback callback; EXPECT_THAT( - handle.Init(kGroupId, params_, DEFAULT_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, callback.callback(), - ClientSocketPool::ProxyAuthCallback(), pool_.get(), - NetLogWithSource()), + handle.Init(kGroupId, params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback.callback(), ClientSocketPool::ProxyAuthCallback(), + pool_.get(), NetLogWithSource()), IsError(ERR_IO_PENDING)); // Switch connect job types, so creating a new ConnectJob will result in @@ -5369,7 +5565,8 @@ TEST_F(ClientSocketPoolBaseTest, RefreshGroupClosesIdleConnectJobs) { CreatePool(kDefaultMaxSockets, kDefaultMaxSocketsPerGroup); const ClientSocketPool::GroupId kGroupId = TestGroupId("a"); - pool_->RequestSockets(kGroupId, params_, 2, NetLogWithSource()); + pool_->RequestSockets(kGroupId, params_, base::nullopt, 2, + NetLogWithSource()); ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId)); EXPECT_EQ(2, pool_->IdleSocketCount()); EXPECT_EQ(2u, pool_->IdleSocketCountInGroup(kGroupId)); @@ -5385,7 +5582,8 @@ TEST_F(ClientSocketPoolBaseTest, const ClientSocketPool::GroupId kGroupId = TestGroupId("a"); const ClientSocketPool::GroupId kOtherGroupId = TestGroupId("b"); - pool_->RequestSockets(kOtherGroupId, params_, 2, NetLogWithSource()); + pool_->RequestSockets(kOtherGroupId, params_, base::nullopt, 2, + NetLogWithSource()); ASSERT_TRUE(pool_->HasGroupForTesting(kOtherGroupId)); EXPECT_EQ(2, pool_->IdleSocketCount()); EXPECT_EQ(2u, pool_->IdleSocketCountInGroup(kOtherGroupId)); @@ -5403,10 +5601,10 @@ TEST_F(ClientSocketPoolBaseTest, RefreshGroupPreventsSocketReuse) { ClientSocketHandle handle; TestCompletionCallback callback; EXPECT_THAT( - handle.Init(kGroupId, params_, DEFAULT_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, callback.callback(), - ClientSocketPool::ProxyAuthCallback(), pool_.get(), - NetLogWithSource()), + handle.Init(kGroupId, params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback.callback(), ClientSocketPool::ProxyAuthCallback(), + pool_.get(), NetLogWithSource()), IsOk()); ASSERT_TRUE(pool_->HasGroupForTesting(kGroupId)); EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kGroupId)); @@ -5427,10 +5625,10 @@ TEST_F(ClientSocketPoolBaseTest, ClientSocketHandle handle; TestCompletionCallback callback; EXPECT_THAT( - handle.Init(kOtherGroupId, params_, DEFAULT_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, callback.callback(), - ClientSocketPool::ProxyAuthCallback(), pool_.get(), - NetLogWithSource()), + handle.Init(kOtherGroupId, params_, base::nullopt, DEFAULT_PRIORITY, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback.callback(), ClientSocketPool::ProxyAuthCallback(), + pool_.get(), NetLogWithSource()), IsOk()); ASSERT_TRUE(pool_->HasGroupForTesting(kOtherGroupId)); EXPECT_EQ(1, pool_->NumActiveSocketsInGroupForTesting(kOtherGroupId)); diff --git a/chromium/net/socket/client_socket_pool_manager.cc b/chromium/net/socket/client_socket_pool_manager.cc index 26b36d17b3e..3e1f92b374a 100644 --- a/chromium/net/socket/client_socket_pool_manager.cc +++ b/chromium/net/socket/client_socket_pool_manager.cc @@ -8,18 +8,16 @@ #include "base/logging.h" #include "base/metrics/field_trial_params.h" +#include "base/optional.h" #include "base/stl_util.h" #include "base/strings/stringprintf.h" #include "net/base/features.h" #include "net/base/load_flags.h" -#include "net/http/http_proxy_connect_job.h" #include "net/http/http_stream_factory.h" #include "net/proxy_resolution/proxy_info.h" #include "net/socket/client_socket_handle.h" #include "net/socket/client_socket_pool.h" -#include "net/socket/socks_connect_job.h" -#include "net/socket/ssl_connect_job.h" -#include "net/socket/transport_connect_job.h" +#include "net/socket/connect_job.h" #include "net/ssl/ssl_config.h" namespace net { @@ -65,120 +63,39 @@ static_assert(base::size(g_max_sockets_per_proxy_server) == HttpNetworkSession::NUM_SOCKET_POOL_TYPES, "max sockets per proxy server length mismatch"); -// The meat of the implementation for the InitSocketHandleForHttpRequest, -// InitSocketHandleForRawConnect and PreconnectSocketsForHttpRequest methods. -// -// DO NOT ADD ANY ARGUMENTS TO THIS METHOD. -// -// TODO(https://crbug.com/921369) In order to resolve longstanding issues -// related to pooling distinguishable sockets together, reduce the arguments to -// just those that are used to populate |connection_group|, and those used to -// locate the socket pool to use. -scoped_refptr<ClientSocketPool::SocketParams> CreateSocketParamsAndGetGroupId( +ClientSocketPool::GroupId CreateGroupId( ClientSocketPoolManager::SocketGroupType group_type, const HostPortPair& endpoint, const ProxyInfo& proxy_info, - // This argument should be removed. - const SSLConfig& ssl_config_for_origin, - // This argument should be removed. - const SSLConfig& ssl_config_for_proxy, - // This argument should be removed. - bool force_tunnel, PrivacyMode privacy_mode, - // TODO(https://crbug.com/912727): This argument should be removed. - const OnHostResolutionCallback& resolution_callback, - ClientSocketPool::GroupId* connection_group) { - scoped_refptr<HttpProxySocketParams> http_proxy_params; - scoped_refptr<SOCKSSocketParams> socks_params; - - const bool using_ssl = group_type == ClientSocketPoolManager::SSL_GROUP; - + const NetworkIsolationKey& network_isolation_key) { // Build the string used to uniquely identify connections of this type. // Determine the host and port to connect to. DCHECK(!endpoint.IsEmpty()); + ClientSocketPool::SocketType socket_type = ClientSocketPool::SocketType::kHttp; + if (group_type == ClientSocketPoolManager::SSL_GROUP) + socket_type = ClientSocketPool::SocketType::kSsl; - if (group_type == ClientSocketPoolManager::FTP_GROUP) { - // Combining FTP with forced SPDY over SSL would be a "path to madness". - // Make sure we never do that. - DCHECK(!using_ssl); - socket_type = ClientSocketPool::SocketType::kFtp; - } - if (using_ssl) { - if (!ssl_config_for_origin.version_interference_probe) { - socket_type = ClientSocketPool::SocketType::kSsl; - } else { - socket_type = ClientSocketPool::SocketType::kSslVersionInterferenceProbe; - } - } - - *connection_group = ClientSocketPool::GroupId( - endpoint, socket_type, privacy_mode == PRIVACY_MODE_ENABLED); - - if (!proxy_info.is_direct()) { - ProxyServer proxy_server = proxy_info.proxy_server(); - scoped_refptr<TransportSocketParams> proxy_tcp_params = - base::MakeRefCounted<TransportSocketParams>( - proxy_server.host_port_pair(), resolution_callback); - - if (proxy_info.is_http() || proxy_info.is_https() || proxy_info.is_quic()) { - scoped_refptr<SSLSocketParams> ssl_params; - if (!proxy_info.is_http()) { - // Set ssl_params, and unset proxy_tcp_params - ssl_params = base::MakeRefCounted<SSLSocketParams>( - std::move(proxy_tcp_params), nullptr, nullptr, - proxy_server.host_port_pair(), ssl_config_for_proxy, - PRIVACY_MODE_DISABLED); - proxy_tcp_params = nullptr; - } - - http_proxy_params = base::MakeRefCounted<HttpProxySocketParams>( - std::move(proxy_tcp_params), std::move(ssl_params), - proxy_info.is_quic(), endpoint, proxy_server.is_trusted_proxy(), - force_tunnel || using_ssl, - NetworkTrafficAnnotationTag(proxy_info.traffic_annotation())); - } else { - DCHECK(proxy_info.is_socks()); - socks_params = base::MakeRefCounted<SOCKSSocketParams>( - std::move(proxy_tcp_params), - proxy_server.scheme() == ProxyServer::SCHEME_SOCKS5, endpoint, - NetworkTrafficAnnotationTag(proxy_info.traffic_annotation())); - } - } - - // Deal with SSL - which layers on top of any given proxy. - if (using_ssl) { - scoped_refptr<TransportSocketParams> ssl_tcp_params; - if (proxy_info.is_direct()) { - ssl_tcp_params = base::MakeRefCounted<TransportSocketParams>( - endpoint, resolution_callback); - } - scoped_refptr<SSLSocketParams> ssl_params = - base::MakeRefCounted<SSLSocketParams>( - std::move(ssl_tcp_params), std::move(socks_params), - std::move(http_proxy_params), endpoint, ssl_config_for_origin, - privacy_mode); - return ClientSocketPool::SocketParams::CreateFromSSLSocketParams( - std::move(ssl_params)); - } - - if (proxy_info.is_http() || proxy_info.is_https()) { - return ClientSocketPool::SocketParams::CreateFromHttpProxySocketParams( - std::move(http_proxy_params)); - } - - if (proxy_info.is_socks()) { - return ClientSocketPool::SocketParams::CreateFromSOCKSSocketParams( - std::move(socks_params)); - } + return ClientSocketPool::GroupId(endpoint, socket_type, privacy_mode, + network_isolation_key); +} - DCHECK(proxy_info.is_direct()); - scoped_refptr<TransportSocketParams> tcp_params = - base::MakeRefCounted<TransportSocketParams>(endpoint, - resolution_callback); - return ClientSocketPool::SocketParams::CreateFromTransportSocketParams( - std::move(tcp_params)); +// TODO(https://crbug.com/921369) In order to resolve longstanding issues +// related to pooling distinguishable sockets together, get rid of SocketParams +// entirely. +scoped_refptr<ClientSocketPool::SocketParams> CreateSocketParams( + const ClientSocketPool::GroupId& group_id, + const ProxyServer& proxy_server, + const SSLConfig& ssl_config_for_origin, + const SSLConfig& ssl_config_for_proxy) { + bool using_ssl = group_id.socket_type() == ClientSocketPool::SocketType::kSsl; + bool using_proxy_ssl = proxy_server.is_http_like() && !proxy_server.is_http(); + return base::MakeRefCounted<ClientSocketPool::SocketParams>( + using_ssl ? std::make_unique<SSLConfig>(ssl_config_for_origin) : nullptr, + using_proxy_ssl ? std::make_unique<SSLConfig>(ssl_config_for_proxy) + : nullptr); } int InitSocketPoolHelper( @@ -190,14 +107,14 @@ int InitSocketPoolHelper( const ProxyInfo& proxy_info, const SSLConfig& ssl_config_for_origin, const SSLConfig& ssl_config_for_proxy, - bool force_tunnel, + bool is_for_websockets, PrivacyMode privacy_mode, + const NetworkIsolationKey& network_isolation_key, const SocketTag& socket_tag, const NetLogWithSource& net_log, int num_preconnect_streams, ClientSocketHandle* socket_handle, HttpNetworkSession::SocketPoolType socket_pool_type, - const OnHostResolutionCallback& resolution_callback, CompletionOnceCallback callback, const ClientSocketPool::ProxyAuthCallback& proxy_auth_callback) { bool using_ssl = group_type == ClientSocketPoolManager::SSL_GROUP; @@ -209,12 +126,12 @@ int InitSocketPoolHelper( origin_host_port.set_port(session->params().testing_fixed_https_port); } - ClientSocketPool::GroupId connection_group; + ClientSocketPool::GroupId connection_group = + CreateGroupId(group_type, origin_host_port, proxy_info, privacy_mode, + network_isolation_key); scoped_refptr<ClientSocketPool::SocketParams> socket_params = - CreateSocketParamsAndGetGroupId( - group_type, origin_host_port, proxy_info, ssl_config_for_origin, - ssl_config_for_proxy, force_tunnel, privacy_mode, resolution_callback, - &connection_group); + CreateSocketParams(connection_group, proxy_info.proxy_server(), + ssl_config_for_origin, ssl_config_for_proxy); ClientSocketPool* pool = session->GetSocketPool(socket_pool_type, proxy_info.proxy_server()); @@ -223,15 +140,20 @@ int InitSocketPoolHelper( if ((request_load_flags & LOAD_IGNORE_LIMITS) != 0) respect_limits = ClientSocketPool::RespectLimits::DISABLED; + base::Optional<NetworkTrafficAnnotationTag> proxy_annotation = + proxy_info.is_direct() ? base::nullopt + : base::Optional<NetworkTrafficAnnotationTag>( + proxy_info.traffic_annotation()); if (num_preconnect_streams) { pool->RequestSockets(connection_group, std::move(socket_params), - num_preconnect_streams, net_log); + proxy_annotation, num_preconnect_streams, net_log); return OK; } - return socket_handle->Init( - connection_group, std::move(socket_params), request_priority, socket_tag, - respect_limits, std::move(callback), proxy_auth_callback, pool, net_log); + return socket_handle->Init(connection_group, std::move(socket_params), + proxy_annotation, request_priority, socket_tag, + respect_limits, std::move(callback), + proxy_auth_callback, pool, net_log); } } // namespace @@ -319,19 +241,20 @@ int InitSocketHandleForHttpRequest( const SSLConfig& ssl_config_for_origin, const SSLConfig& ssl_config_for_proxy, PrivacyMode privacy_mode, + const NetworkIsolationKey& network_isolation_key, const SocketTag& socket_tag, const NetLogWithSource& net_log, ClientSocketHandle* socket_handle, - const OnHostResolutionCallback& resolution_callback, CompletionOnceCallback callback, const ClientSocketPool::ProxyAuthCallback& proxy_auth_callback) { DCHECK(socket_handle); return InitSocketPoolHelper( group_type, endpoint, request_load_flags, request_priority, session, proxy_info, ssl_config_for_origin, ssl_config_for_proxy, - /*force_tunnel=*/false, privacy_mode, socket_tag, net_log, 0, - socket_handle, HttpNetworkSession::NORMAL_SOCKET_POOL, - resolution_callback, std::move(callback), proxy_auth_callback); + false /* is_for_websockets */, privacy_mode, network_isolation_key, + socket_tag, net_log, 0, socket_handle, + HttpNetworkSession::NORMAL_SOCKET_POOL, std::move(callback), + proxy_auth_callback); } int InitSocketHandleForWebSocketRequest( @@ -344,9 +267,9 @@ int InitSocketHandleForWebSocketRequest( const SSLConfig& ssl_config_for_origin, const SSLConfig& ssl_config_for_proxy, PrivacyMode privacy_mode, + const NetworkIsolationKey& network_isolation_key, const NetLogWithSource& net_log, ClientSocketHandle* socket_handle, - const OnHostResolutionCallback& resolution_callback, CompletionOnceCallback callback, const ClientSocketPool::ProxyAuthCallback& proxy_auth_callback) { DCHECK(socket_handle); @@ -357,36 +280,10 @@ int InitSocketHandleForWebSocketRequest( return InitSocketPoolHelper( group_type, endpoint, request_load_flags, request_priority, session, proxy_info, ssl_config_for_origin, ssl_config_for_proxy, - /*force_tunnel=*/true, privacy_mode, SocketTag(), net_log, 0, - socket_handle, HttpNetworkSession::WEBSOCKET_SOCKET_POOL, - resolution_callback, std::move(callback), proxy_auth_callback); -} - -NET_EXPORT std::unique_ptr<ConnectJob> CreateConnectJobForRawConnect( - const HostPortPair& host_port_pair, - bool use_tls, - const CommonConnectJobParams* common_connect_job_params, - RequestPriority request_priority, - const ProxyInfo& proxy_info, - const SSLConfig& ssl_config_for_origin, - const SSLConfig& ssl_config_for_proxy, - const NetLogWithSource& net_log, - ConnectJob::Delegate* connect_job_delegate) { - // QUIC proxies are currently not supported through this method. - DCHECK(!proxy_info.is_quic()); - - ClientSocketPool::GroupId unused_connection_group; - scoped_refptr<ClientSocketPool::SocketParams> socket_params = - CreateSocketParamsAndGetGroupId( - use_tls ? ClientSocketPoolManager::SSL_GROUP - : ClientSocketPoolManager::NORMAL_GROUP, - host_port_pair, proxy_info, ssl_config_for_origin, - ssl_config_for_proxy, true /* force_tunnel */, - net::PRIVACY_MODE_DISABLED, OnHostResolutionCallback(), - &unused_connection_group); - return socket_params->create_connect_job_callback().Run( - request_priority, SocketTag(), common_connect_job_params, - connect_job_delegate); + true /* is_for_websockets */, privacy_mode, network_isolation_key, + SocketTag(), net_log, 0, socket_handle, + HttpNetworkSession::WEBSOCKET_SOCKET_POOL, std::move(callback), + proxy_auth_callback); } int PreconnectSocketsForHttpRequest( @@ -404,12 +301,15 @@ int PreconnectSocketsForHttpRequest( // QUIC proxies are currently not supported through this method. DCHECK(!proxy_info.is_quic()); + // TODO(https://crbug.com/966896): Get this field from the caller. + NetworkIsolationKey network_isolation_key; + return InitSocketPoolHelper( group_type, endpoint, request_load_flags, request_priority, session, proxy_info, ssl_config_for_origin, ssl_config_for_proxy, - /*force_tunnel=*/false, privacy_mode, SocketTag(), net_log, - num_preconnect_streams, nullptr, HttpNetworkSession::NORMAL_SOCKET_POOL, - OnHostResolutionCallback(), CompletionOnceCallback(), + false /* force_tunnel */, privacy_mode, network_isolation_key, + SocketTag(), net_log, num_preconnect_streams, nullptr, + HttpNetworkSession::NORMAL_SOCKET_POOL, CompletionOnceCallback(), ClientSocketPool::ProxyAuthCallback()); } diff --git a/chromium/net/socket/client_socket_pool_manager.h b/chromium/net/socket/client_socket_pool_manager.h index 0a7a9e74abe..b10a75622c8 100644 --- a/chromium/net/socket/client_socket_pool_manager.h +++ b/chromium/net/socket/client_socket_pool_manager.h @@ -26,12 +26,10 @@ class ProcessMemoryDump; namespace net { -typedef base::Callback<int(const AddressList&, const NetLogWithSource& net_log)> - OnHostResolutionCallback; - class ClientSocketHandle; class HostPortPair; class NetLogWithSource; +class NetworkIsolationKey; class ProxyInfo; class ProxyServer; @@ -46,7 +44,6 @@ class NET_EXPORT_PRIVATE ClientSocketPoolManager { enum SocketGroupType { SSL_GROUP, // For all TLS sockets. NORMAL_GROUP, // For normal HTTP sockets. - FTP_GROUP // For FTP sockets (over an HTTP proxy). }; ClientSocketPoolManager(); @@ -109,10 +106,10 @@ int InitSocketHandleForHttpRequest( const SSLConfig& ssl_config_for_origin, const SSLConfig& ssl_config_for_proxy, PrivacyMode privacy_mode, + const NetworkIsolationKey& network_isolation_key, const SocketTag& socket_tag, const NetLogWithSource& net_log, ClientSocketHandle* socket_handle, - const OnHostResolutionCallback& resolution_callback, CompletionOnceCallback callback, const ClientSocketPool::ProxyAuthCallback& proxy_auth_callback); @@ -135,30 +132,12 @@ int InitSocketHandleForWebSocketRequest( const SSLConfig& ssl_config_for_origin, const SSLConfig& ssl_config_for_proxy, PrivacyMode privacy_mode, + const NetworkIsolationKey& network_isolation_key, const NetLogWithSource& net_log, ClientSocketHandle* socket_handle, - const OnHostResolutionCallback& resolution_callback, CompletionOnceCallback callback, const ClientSocketPool::ProxyAuthCallback& proxy_auth_callback); -// Deprecated: Please do not use this outside of //net and //services/network. -// A helper method that uses the passed in proxy to initialize a ConnectJob that -// does not use a SocketPool, but does use the passed in -// CommonConnectJobParams's SpdySessionPool. Use this method for a raw socket -// connection to a host-port pair (that needs to tunnel through the proxies). If -// |use_tls| is true, will establish a TLS connection on top of the established -// connection. -NET_EXPORT std::unique_ptr<ConnectJob> CreateConnectJobForRawConnect( - const HostPortPair& host_port_pair, - bool use_tls, - const CommonConnectJobParams* common_connect_job_params, - RequestPriority request_priority, - const ProxyInfo& proxy_info, - const SSLConfig& ssl_config_for_origin, - const SSLConfig& ssl_config_for_proxy, - const NetLogWithSource& net_log, - ConnectJob::Delegate* connect_job_delegate); - // Similar to InitSocketHandleForHttpRequest except that it initiates the // desired number of preconnect streams from the relevant socket pool. int PreconnectSocketsForHttpRequest( diff --git a/chromium/net/socket/client_socket_pool_manager_impl.cc b/chromium/net/socket/client_socket_pool_manager_impl.cc index a63032d5626..4b4d334fc79 100644 --- a/chromium/net/socket/client_socket_pool_manager_impl.cc +++ b/chromium/net/socket/client_socket_pool_manager_impl.cc @@ -79,13 +79,14 @@ ClientSocketPool* ClientSocketPoolManagerImpl::GetSocketPool( if (pool_type_ == HttpNetworkSession::WEBSOCKET_SOCKET_POOL && proxy_server.is_direct()) { new_pool = std::make_unique<WebSocketTransportClientSocketPool>( - sockets_per_proxy_server, sockets_per_group, + sockets_per_proxy_server, sockets_per_group, proxy_server, &websocket_common_connect_job_params_); } else { new_pool = std::make_unique<TransportClientSocketPool>( sockets_per_proxy_server, sockets_per_group, - unused_idle_socket_timeout(pool_type_), &common_connect_job_params_, - ssl_config_service_); + unused_idle_socket_timeout(pool_type_), proxy_server, + pool_type_ == HttpNetworkSession::WEBSOCKET_SOCKET_POOL, + &common_connect_job_params_, ssl_config_service_); } std::pair<SocketPoolMap::iterator, bool> ret = diff --git a/chromium/net/socket/client_socket_pool_unittest.cc b/chromium/net/socket/client_socket_pool_unittest.cc index cd0755a978c..c543feb7e34 100644 --- a/chromium/net/socket/client_socket_pool_unittest.cc +++ b/chromium/net/socket/client_socket_pool_unittest.cc @@ -7,14 +7,24 @@ #include <string> #include <vector> +#include "base/test/scoped_feature_list.h" +#include "net/base/features.h" #include "net/base/host_port_pair.h" +#include "net/base/network_isolation_key.h" +#include "net/base/privacy_mode.h" #include "testing/gtest/include/gtest/gtest.h" +#include "url/gurl.h" +#include "url/origin.h" namespace net { namespace { TEST(ClientSocketPool, GroupIdOperators) { + base::test::ScopedFeatureList feature_list; + feature_list.InitAndEnableFeature( + features::kPartitionConnectionsByNetworkIsolationKey); + // Each of these lists is in "<" order, as defined by Group::operator< on the // corresponding field. @@ -26,11 +36,17 @@ TEST(ClientSocketPool, GroupIdOperators) { const ClientSocketPool::SocketType kSocketTypes[] = { ClientSocketPool::SocketType::kHttp, ClientSocketPool::SocketType::kSsl, - ClientSocketPool::SocketType::kSslVersionInterferenceProbe, - ClientSocketPool::SocketType::kFtp, }; - const bool kPrivacyModes[] = {false, true}; + const PrivacyMode kPrivacyModes[] = { + PrivacyMode::PRIVACY_MODE_DISABLED, + PrivacyMode::PRIVACY_MODE_ENABLED, + }; + + const NetworkIsolationKey kNetworkIsolationKeys[] = { + NetworkIsolationKey(url::Origin::Create(GURL("http://a.test/"))), + NetworkIsolationKey(url::Origin::Create(GURL("http://b.test/"))), + }; // All previously created |group_ids|. They should all be less than the // current group under consideration. @@ -44,83 +60,106 @@ TEST(ClientSocketPool, GroupIdOperators) { for (const auto& privacy_mode : kPrivacyModes) { SCOPED_TRACE(privacy_mode); - ClientSocketPool::GroupId group_id(host_port_pair, socket_type, - privacy_mode); - for (const auto& lower_group_id : group_ids) { - EXPECT_FALSE(lower_group_id == group_id); - EXPECT_TRUE(lower_group_id < group_id); - EXPECT_FALSE(group_id < lower_group_id); + for (const auto& network_isolation_key : kNetworkIsolationKeys) { + SCOPED_TRACE(network_isolation_key.ToString()); + + ClientSocketPool::GroupId group_id( + host_port_pair, socket_type, privacy_mode, network_isolation_key); + for (const auto& lower_group_id : group_ids) { + EXPECT_FALSE(lower_group_id == group_id); + EXPECT_TRUE(lower_group_id < group_id); + EXPECT_FALSE(group_id < lower_group_id); + } + + group_ids.push_back(group_id); + + // Compare |group_id| to itself. Use two different copies of + // |group_id|'s value, since to protect against bugs where an object + // only equals itself. + EXPECT_TRUE(group_ids.back() == group_id); + EXPECT_FALSE(group_ids.back() < group_id); + EXPECT_FALSE(group_id < group_ids.back()); } - - group_ids.push_back(group_id); - - // Compare |group_id| to itself. Use two different copies of - // |group_id|'s value, since to protect against bugs where an object - // only equals itself. - EXPECT_TRUE(group_ids.back() == group_id); - EXPECT_FALSE(group_ids.back() < group_id); - EXPECT_FALSE(group_id < group_ids.back()); } } } } TEST(ClientSocketPool, GroupIdToString) { - EXPECT_EQ("foo:80", - ClientSocketPool::GroupId(HostPortPair("foo", 80), - ClientSocketPool::SocketType::kHttp, - false /* privacy_mode */) - .ToString()); - EXPECT_EQ("bar:443", - ClientSocketPool::GroupId(HostPortPair("bar", 443), - ClientSocketPool::SocketType::kHttp, - false /* privacy_mode */) - .ToString()); - EXPECT_EQ("pm/bar:80", - ClientSocketPool::GroupId(HostPortPair("bar", 80), - ClientSocketPool::SocketType::kHttp, - true /* privacy_mode */) - .ToString()); + base::test::ScopedFeatureList feature_list; + feature_list.InitAndEnableFeature( + features::kPartitionConnectionsByNetworkIsolationKey); - EXPECT_EQ("ssl/foo:80", - ClientSocketPool::GroupId(HostPortPair("foo", 80), - ClientSocketPool::SocketType::kSsl, - false /* privacy_mode */) + EXPECT_EQ("foo:80 <null>", + ClientSocketPool::GroupId( + HostPortPair("foo", 80), ClientSocketPool::SocketType::kHttp, + PrivacyMode::PRIVACY_MODE_DISABLED, NetworkIsolationKey()) .ToString()); - EXPECT_EQ("ssl/bar:443", - ClientSocketPool::GroupId(HostPortPair("bar", 443), - ClientSocketPool::SocketType::kSsl, - false /* privacy_mode */) + EXPECT_EQ("bar:443 <null>", + ClientSocketPool::GroupId( + HostPortPair("bar", 443), ClientSocketPool::SocketType::kHttp, + PrivacyMode::PRIVACY_MODE_DISABLED, NetworkIsolationKey()) .ToString()); - EXPECT_EQ("pm/ssl/bar:80", - ClientSocketPool::GroupId(HostPortPair("bar", 80), - ClientSocketPool::SocketType::kSsl, - true /* privacy_mode */) + EXPECT_EQ("pm/bar:80 <null>", + ClientSocketPool::GroupId( + HostPortPair("bar", 80), ClientSocketPool::SocketType::kHttp, + PrivacyMode::PRIVACY_MODE_ENABLED, NetworkIsolationKey()) .ToString()); - EXPECT_EQ("version-interference-probe/ssl/foo:443", + EXPECT_EQ("ssl/foo:80 <null>", ClientSocketPool::GroupId( - HostPortPair("foo", 443), - ClientSocketPool::SocketType::kSslVersionInterferenceProbe, - false /* privacy_mode */) + HostPortPair("foo", 80), ClientSocketPool::SocketType::kSsl, + PrivacyMode::PRIVACY_MODE_DISABLED, NetworkIsolationKey()) .ToString()); - EXPECT_EQ("pm/version-interference-probe/ssl/bar:444", + EXPECT_EQ("ssl/bar:443 <null>", ClientSocketPool::GroupId( - HostPortPair("bar", 444), - ClientSocketPool::SocketType::kSslVersionInterferenceProbe, - true /* privacy_mode */) + HostPortPair("bar", 443), ClientSocketPool::SocketType::kSsl, + PrivacyMode::PRIVACY_MODE_DISABLED, NetworkIsolationKey()) .ToString()); - - EXPECT_EQ("ftp/foo:80", - ClientSocketPool::GroupId(HostPortPair("foo", 80), - ClientSocketPool::SocketType::kFtp, - false /* privacy_mode */) - .ToString()); - EXPECT_EQ("pm/ftp/bar:81", - ClientSocketPool::GroupId(HostPortPair("bar", 81), - ClientSocketPool::SocketType::kFtp, - true /* privacy_mode */) + EXPECT_EQ("pm/ssl/bar:80 <null>", + ClientSocketPool::GroupId( + HostPortPair("bar", 80), ClientSocketPool::SocketType::kSsl, + PrivacyMode::PRIVACY_MODE_ENABLED, NetworkIsolationKey()) .ToString()); + + EXPECT_EQ( + "ssl/foo:443 <https://foo.com>", + ClientSocketPool::GroupId( + HostPortPair("foo", 443), ClientSocketPool::SocketType::kSsl, + PrivacyMode::PRIVACY_MODE_DISABLED, + NetworkIsolationKey(url::Origin::Create(GURL("https://foo.com")))) + .ToString()); +} + +TEST(ClientSocketPool, PartitionConnectionsByNetworkIsolationKeyDisabled) { + // Partitioning connections by NetworkIsolationKey is disabled by default, so + // test both the explicitly and implicitly disabled cases. + for (bool explicitly_disabled : {false, true}) { + base::test::ScopedFeatureList feature_list; + if (explicitly_disabled) { + feature_list.InitAndDisableFeature( + features::kPartitionConnectionsByNetworkIsolationKey); + } + + ClientSocketPool::GroupId group_id1( + HostPortPair("foo", 443), ClientSocketPool::SocketType::kSsl, + PrivacyMode::PRIVACY_MODE_DISABLED, + NetworkIsolationKey(url::Origin::Create(GURL("https://foo.com")))); + + ClientSocketPool::GroupId group_id2( + HostPortPair("foo", 443), ClientSocketPool::SocketType::kSsl, + PrivacyMode::PRIVACY_MODE_DISABLED, + NetworkIsolationKey(url::Origin::Create(GURL("http://bar.com")))); + + EXPECT_FALSE(group_id1.network_isolation_key().IsFullyPopulated()); + EXPECT_FALSE(group_id2.network_isolation_key().IsFullyPopulated()); + EXPECT_EQ(group_id1.network_isolation_key(), + group_id2.network_isolation_key()); + EXPECT_EQ(group_id1, group_id2); + + EXPECT_EQ("ssl/foo:443", group_id1.ToString()); + EXPECT_EQ("ssl/foo:443", group_id2.ToString()); + } } } // namespace diff --git a/chromium/net/socket/connect_job.cc b/chromium/net/socket/connect_job.cc index 1102ac18f4a..871d0f5bcbd 100644 --- a/chromium/net/socket/connect_job.cc +++ b/chromium/net/socket/connect_job.cc @@ -10,10 +10,17 @@ #include "net/base/net_errors.h" #include "net/base/trace_constants.h" #include "net/http/http_auth_controller.h" +#include "net/http/http_proxy_connect_job.h" #include "net/log/net_log.h" #include "net/log/net_log_event_type.h" #include "net/socket/client_socket_handle.h" +#include "net/socket/socket_tag.h" +#include "net/socket/socks_connect_job.h" +#include "net/socket/ssl_connect_job.h" #include "net/socket/stream_socket.h" +#include "net/socket/transport_connect_job.h" +#include "net/ssl/ssl_config.h" +#include "net/traffic_annotation/network_traffic_annotation.h" namespace net { @@ -23,7 +30,7 @@ CommonConnectJobParams::CommonConnectJobParams( HttpAuthCache* http_auth_cache, HttpAuthHandlerFactory* http_auth_handler_factory, SpdySessionPool* spdy_session_pool, - const quic::QuicTransportVersionVector* quic_supported_versions, + const quic::ParsedQuicVersionVector* quic_supported_versions, QuicStreamFactory* quic_stream_factory, ProxyDelegate* proxy_delegate, const HttpUserAgentSettings* http_user_agent_settings, @@ -91,6 +98,92 @@ ConnectJob::~ConnectJob() { net_log().EndEvent(NetLogEventType::CONNECT_JOB); } +std::unique_ptr<ConnectJob> ConnectJob::CreateConnectJob( + bool using_ssl, + const HostPortPair& endpoint, + const ProxyServer& proxy_server, + const base::Optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag, + const SSLConfig* ssl_config_for_origin, + const SSLConfig* ssl_config_for_proxy, + bool force_tunnel, + PrivacyMode privacy_mode, + const OnHostResolutionCallback& resolution_callback, + RequestPriority request_priority, + SocketTag socket_tag, + const NetworkIsolationKey& network_isolation_key, + const CommonConnectJobParams* common_connect_job_params, + ConnectJob::Delegate* delegate) { + scoped_refptr<HttpProxySocketParams> http_proxy_params; + scoped_refptr<SOCKSSocketParams> socks_params; + + if (!proxy_server.is_direct()) { + auto proxy_tcp_params = base::MakeRefCounted<TransportSocketParams>( + proxy_server.host_port_pair(), resolution_callback); + + if (proxy_server.is_http() || proxy_server.is_https() || + proxy_server.is_quic()) { + scoped_refptr<SSLSocketParams> ssl_params; + if (!proxy_server.is_http()) { + DCHECK(ssl_config_for_proxy); + // Set ssl_params, and unset proxy_tcp_params + ssl_params = base::MakeRefCounted<SSLSocketParams>( + std::move(proxy_tcp_params), nullptr, nullptr, + proxy_server.host_port_pair(), *ssl_config_for_proxy, + PRIVACY_MODE_DISABLED); + proxy_tcp_params = nullptr; + } + + http_proxy_params = base::MakeRefCounted<HttpProxySocketParams>( + std::move(proxy_tcp_params), std::move(ssl_params), + proxy_server.is_quic(), endpoint, proxy_server.is_trusted_proxy(), + force_tunnel || using_ssl, *proxy_annotation_tag, + network_isolation_key); + } else { + DCHECK(proxy_server.is_socks()); + socks_params = base::MakeRefCounted<SOCKSSocketParams>( + std::move(proxy_tcp_params), + proxy_server.scheme() == ProxyServer::SCHEME_SOCKS5, endpoint, + *proxy_annotation_tag); + } + } + + // Deal with SSL - which layers on top of any given proxy. + if (using_ssl) { + DCHECK(ssl_config_for_origin); + scoped_refptr<TransportSocketParams> ssl_tcp_params; + if (proxy_server.is_direct()) { + ssl_tcp_params = base::MakeRefCounted<TransportSocketParams>( + endpoint, resolution_callback); + } + auto ssl_params = base::MakeRefCounted<SSLSocketParams>( + std::move(ssl_tcp_params), std::move(socks_params), + std::move(http_proxy_params), endpoint, *ssl_config_for_origin, + privacy_mode); + return std::make_unique<SSLConnectJob>( + request_priority, socket_tag, common_connect_job_params, + std::move(ssl_params), delegate, nullptr /* net_log */); + } + + if (proxy_server.is_http() || proxy_server.is_https()) { + return std::make_unique<HttpProxyConnectJob>( + request_priority, socket_tag, common_connect_job_params, + std::move(http_proxy_params), delegate, nullptr /* net_log */); + } + + if (proxy_server.is_socks()) { + return std::make_unique<SOCKSConnectJob>( + request_priority, socket_tag, common_connect_job_params, + std::move(socks_params), delegate, nullptr /* net_log */); + } + + DCHECK(proxy_server.is_direct()); + auto tcp_params = base::MakeRefCounted<TransportSocketParams>( + endpoint, resolution_callback); + return TransportConnectJob::CreateTransportConnectJob( + std::move(tcp_params), request_priority, socket_tag, + common_connect_job_params, delegate, nullptr /* net_log */); +} + std::unique_ptr<StreamSocket> ConnectJob::PassSocket() { return std::move(socket_); } @@ -121,10 +214,6 @@ ConnectionAttempts ConnectJob::GetConnectionAttempts() const { return ConnectionAttempts(); } -std::unique_ptr<StreamSocket> ConnectJob::PassProxySocketOnFailure() { - return nullptr; -} - bool ConnectJob::IsSSLError() const { return false; } diff --git a/chromium/net/socket/connect_job.h b/chromium/net/socket/connect_job.h index 2d9883bb279..6a267fad4fa 100644 --- a/chromium/net/socket/connect_job.h +++ b/chromium/net/socket/connect_job.h @@ -11,8 +11,10 @@ #include "base/callback_forward.h" #include "base/macros.h" #include "base/memory/ref_counted.h" +#include "base/optional.h" #include "base/time/time.h" #include "base/timer/timer.h" +#include "net/base/address_list.h" #include "net/base/load_states.h" #include "net/base/load_timing_info.h" #include "net/base/net_export.h" @@ -27,6 +29,7 @@ namespace net { class ClientSocketFactory; +class HostPortPair; class HostResolver; class HttpAuthCache; class HttpAuthController; @@ -34,12 +37,18 @@ class HttpAuthHandlerFactory; class HttpResponseInfo; class HttpUserAgentSettings; class NetLog; +class NetLogWithSource; +class NetworkIsolationKey; class NetworkQualityEstimator; +struct NetworkTrafficAnnotationTag; class ProxyDelegate; +class ProxyServer; class SocketPerformanceWatcherFactory; +struct SSLConfig; class StreamSocket; class WebSocketEndpointLockManager; class QuicStreamFactory; +class SocketTag; class SpdySessionPool; class SSLCertRequestInfo; @@ -55,7 +64,7 @@ struct NET_EXPORT_PRIVATE CommonConnectJobParams { HttpAuthCache* http_auth_cache, HttpAuthHandlerFactory* http_auth_handler_factory, SpdySessionPool* spdy_session_pool, - const quic::QuicTransportVersionVector* quic_supported_versions, + const quic::ParsedQuicVersionVector* quic_supported_versions, QuicStreamFactory* quic_stream_factory, ProxyDelegate* proxy_delegate, const HttpUserAgentSettings* http_user_agent_settings, @@ -75,7 +84,7 @@ struct NET_EXPORT_PRIVATE CommonConnectJobParams { HttpAuthCache* http_auth_cache; HttpAuthHandlerFactory* http_auth_handler_factory; SpdySessionPool* spdy_session_pool; - const quic::QuicTransportVersionVector* quic_supported_versions; + const quic::ParsedQuicVersionVector* quic_supported_versions; QuicStreamFactory* quic_stream_factory; ProxyDelegate* proxy_delegate; const HttpUserAgentSettings* http_user_agent_settings; @@ -89,6 +98,28 @@ struct NET_EXPORT_PRIVATE CommonConnectJobParams { WebSocketEndpointLockManager* websocket_endpoint_lock_manager; }; +// When a host resolution completes, OnHostResolutionCallback() is invoked. If +// it returns |kContinue|, the ConnectJob can continue immediately. If it +// returns |kMayBeDeletedAsync|, the ConnectJob may be slated for asychronous +// destruction, so should post a task before continuing, in case it will be +// deleted. The purpose of kMayBeDeletedAsync is to avoid needlessly creating +// and connecting a socket when it might not be needed. +enum class OnHostResolutionCallbackResult { + kContinue, + kMayBeDeletedAsync, +}; + +// If non-null, invoked when host resolution completes. May not destroy the +// ConnectJob synchronously, but may signal the ConnectJob may be destroyed +// asynchronously. See OnHostResolutionCallbackResult above. +// +// |address_list| is the list of addresses the host being connected to was +// resolved to, with the port fields populated to the port being connected to. +using OnHostResolutionCallback = + base::RepeatingCallback<OnHostResolutionCallbackResult( + const HostPortPair& host_port_pair, + const AddressList& address_list)>; + // ConnectJob provides an abstract interface for "connecting" a socket. // The connection may involve host resolution, tcp connection, ssl connection, // etc. @@ -143,6 +174,25 @@ class NET_EXPORT_PRIVATE ConnectJob { NetLogEventType net_log_connect_event_type); virtual ~ConnectJob(); + // Creates a ConnectJob with the specified parameters. + // |common_connect_job_params| and |delegate| must outlive the returned + // ConnectJob. + static std::unique_ptr<ConnectJob> CreateConnectJob( + bool using_ssl, + const HostPortPair& endpoint, + const ProxyServer& proxy_server, + const base::Optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag, + const SSLConfig* ssl_config_for_origin, + const SSLConfig* ssl_config_for_proxy, + bool force_tunnel, + PrivacyMode privacy_mode, + const OnHostResolutionCallback& resolution_callback, + RequestPriority request_priority, + SocketTag socket_tag, + const NetworkIsolationKey& network_isolation_key, + const CommonConnectJobParams* common_connect_job_params, + ConnectJob::Delegate* delegate); + // Accessors const NetLogWithSource& net_log() { return net_log_; } RequestPriority priority() const { return priority_; } @@ -189,11 +239,6 @@ class NET_EXPORT_PRIVATE ConnectJob { // proxy. virtual ConnectionAttempts GetConnectionAttempts() const; - // On connect failure, returns the nested proxy socket, if there is one. - // Returns nullptr otherwise. Only returns a non-null value for SSL sockets on - // top of proxy sockets. - virtual std::unique_ptr<StreamSocket> PassProxySocketOnFailure(); - // If the ConnectJob failed, returns true if the failure occurred after SSL // negotiation started. If the ConnectJob succeeded, the returned value is // undefined. diff --git a/chromium/net/socket/fuzzed_socket_factory.cc b/chromium/net/socket/fuzzed_socket_factory.cc index 1e933ab3642..7736fa429e3 100644 --- a/chromium/net/socket/fuzzed_socket_factory.cc +++ b/chromium/net/socket/fuzzed_socket_factory.cc @@ -151,7 +151,6 @@ std::unique_ptr<ProxyClientSocket> FuzzedSocketFactory::CreateProxyClientSocket( bool using_spdy, NextProto negotiated_protocol, ProxyDelegate* proxy_delegate, - bool is_https_proxy, const NetworkTrafficAnnotationTag& traffic_annotation) { NOTIMPLEMENTED(); return nullptr; diff --git a/chromium/net/socket/fuzzed_socket_factory.h b/chromium/net/socket/fuzzed_socket_factory.h index e09fba10e06..4002d0060c9 100644 --- a/chromium/net/socket/fuzzed_socket_factory.h +++ b/chromium/net/socket/fuzzed_socket_factory.h @@ -63,7 +63,6 @@ class FuzzedSocketFactory : public ClientSocketFactory { bool using_spdy, NextProto negotiated_protocol, ProxyDelegate* proxy_delegate, - bool is_https_proxy, const NetworkTrafficAnnotationTag& traffic_annotation) override; // Sets whether Connect()ions on returned sockets can be asynchronously diff --git a/chromium/net/socket/socket.cc b/chromium/net/socket/socket.cc index 39e3db0d6d7..09d619e2a07 100644 --- a/chromium/net/socket/socket.cc +++ b/chromium/net/socket/socket.cc @@ -8,9 +8,6 @@ namespace net { -const base::Feature Socket::kReadIfReadyExperiment{ - "SocketReadIfReady", base::FEATURE_ENABLED_BY_DEFAULT}; - int Socket::ReadIfReady(IOBuffer* buf, int buf_len, CompletionOnceCallback callback) { diff --git a/chromium/net/socket/socket.h b/chromium/net/socket/socket.h index e834108e0dd..d0b91b75449 100644 --- a/chromium/net/socket/socket.h +++ b/chromium/net/socket/socket.h @@ -7,7 +7,6 @@ #include <stdint.h> -#include "base/feature_list.h" #include "net/base/completion_once_callback.h" #include "net/base/net_export.h" #include "net/traffic_annotation/network_traffic_annotation.h" @@ -19,9 +18,6 @@ class IOBuffer; // Represents a read/write socket. class NET_EXPORT Socket { public: - // Name of the field trial for using ReadyIfReady() instead of Read(). - static const base::Feature kReadIfReadyExperiment; - virtual ~Socket() {} // Reads data, up to |buf_len| bytes, from the socket. The number of bytes diff --git a/chromium/net/socket/socket_bio_adapter.cc b/chromium/net/socket/socket_bio_adapter.cc index f7975b8a219..6e2496972e3 100644 --- a/chromium/net/socket/socket_bio_adapter.cc +++ b/chromium/net/socket/socket_bio_adapter.cc @@ -9,7 +9,6 @@ #include <algorithm> #include "base/bind.h" -#include "base/feature_list.h" #include "base/location.h" #include "base/logging.h" #include "base/threading/thread_task_runner_handle.h" @@ -123,15 +122,12 @@ int SocketBIOAdapter::BIORead(char* out, int len) { DCHECK(!read_buffer_); DCHECK_EQ(0, read_offset_); read_buffer_ = base::MakeRefCounted<IOBuffer>(read_buffer_capacity_); - int result = ERR_READ_IF_READY_NOT_IMPLEMENTED; - if (base::FeatureList::IsEnabled(Socket::kReadIfReadyExperiment)) { - result = socket_->ReadIfReady( - read_buffer_.get(), read_buffer_capacity_, - base::Bind(&SocketBIOAdapter::OnSocketReadIfReadyComplete, - weak_factory_.GetWeakPtr())); - if (result == ERR_IO_PENDING) - read_buffer_ = nullptr; - } + int result = socket_->ReadIfReady( + read_buffer_.get(), read_buffer_capacity_, + base::BindOnce(&SocketBIOAdapter::OnSocketReadIfReadyComplete, + weak_factory_.GetWeakPtr())); + if (result == ERR_IO_PENDING) + read_buffer_ = nullptr; if (result == ERR_READ_IF_READY_NOT_IMPLEMENTED) { result = socket_->Read(read_buffer_.get(), read_buffer_capacity_, read_callback_); diff --git a/chromium/net/socket/socket_bio_adapter_unittest.cc b/chromium/net/socket/socket_bio_adapter_unittest.cc index 2a20df9d8b9..f779c3a7b85 100644 --- a/chromium/net/socket/socket_bio_adapter_unittest.cc +++ b/chromium/net/socket/socket_bio_adapter_unittest.cc @@ -13,7 +13,6 @@ #include "base/logging.h" #include "base/macros.h" #include "base/run_loop.h" -#include "base/test/scoped_feature_list.h" #include "crypto/openssl_util.h" #include "net/base/address_list.h" #include "net/base/completion_once_callback.h" @@ -31,12 +30,10 @@ namespace net { enum ReadIfReadySupport { - // ReadIfReady() field trial is enabled, and ReadyIfReady() is implemented. - READ_IF_READY_ENABLED_SUPPORTED, - // ReadIfReady() field trial is enabled, but ReadyIfReady() is unimplemented. - READ_IF_READY_ENABLED_NOT_SUPPORTED, - // ReadIfReady() field trial is disabled. - READ_IF_READY_DISABLED, + // ReadyIfReady() is implemented. + READ_IF_READY_SUPPORTED, + // ReadyIfReady() is unimplemented. + READ_IF_READY_NOT_SUPPORTED, }; class SocketBIOAdapterTest : public testing::TestWithParam<ReadIfReadySupport>, @@ -44,10 +41,7 @@ class SocketBIOAdapterTest : public testing::TestWithParam<ReadIfReadySupport>, public WithScopedTaskEnvironment { protected: void SetUp() override { - if (GetParam() == READ_IF_READY_DISABLED) { - scoped_feature_list_.InitAndDisableFeature( - Socket::kReadIfReadyExperiment); - } else if (GetParam() == READ_IF_READY_ENABLED_SUPPORTED) { + if (GetParam() == READ_IF_READY_SUPPORTED) { factory_.set_enable_read_if_ready(true); } } @@ -161,14 +155,12 @@ class SocketBIOAdapterTest : public testing::TestWithParam<ReadIfReadySupport>, bool expect_write_ready_ = false; MockClientSocketFactory factory_; std::unique_ptr<SocketBIOAdapter>* reset_on_write_ready_ = nullptr; - base::test::ScopedFeatureList scoped_feature_list_; }; INSTANTIATE_TEST_SUITE_P(/* no prefix */, SocketBIOAdapterTest, - testing::Values(READ_IF_READY_ENABLED_SUPPORTED, - READ_IF_READY_ENABLED_NOT_SUPPORTED, - READ_IF_READY_DISABLED)); + testing::Values(READ_IF_READY_SUPPORTED, + READ_IF_READY_NOT_SUPPORTED)); // Test that data can be read synchronously. TEST_P(SocketBIOAdapterTest, ReadSync) { @@ -234,7 +226,7 @@ TEST_P(SocketBIOAdapterTest, ReadAsync) { // After waiting, the data is available if Read() is used. WaitForReadReady(); - if (GetParam() == READ_IF_READY_ENABLED_SUPPORTED) { + if (GetParam() == READ_IF_READY_SUPPORTED) { EXPECT_FALSE(adapter->HasPendingReadData()); } else { EXPECT_TRUE(adapter->HasPendingReadData()); @@ -256,7 +248,7 @@ TEST_P(SocketBIOAdapterTest, ReadAsync) { // After waiting, the data is available if Read() is used. WaitForReadReady(); - if (GetParam() == READ_IF_READY_ENABLED_SUPPORTED) { + if (GetParam() == READ_IF_READY_SUPPORTED) { EXPECT_FALSE(adapter->HasPendingReadData()); } else { EXPECT_TRUE(adapter->HasPendingReadData()); diff --git a/chromium/net/socket/socket_net_log_params.cc b/chromium/net/socket/socket_net_log_params.cc index 726cebef263..bde45306a4c 100644 --- a/chromium/net/socket/socket_net_log_params.cc +++ b/chromium/net/socket/socket_net_log_params.cc @@ -17,41 +17,37 @@ namespace net { namespace { -std::unique_ptr<base::Value> NetLogSocketErrorCallback( - int net_error, - int os_error, - NetLogCaptureMode /* capture_mode */) { - std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); - dict->SetInteger("net_error", net_error); - dict->SetInteger("os_error", os_error); +base::Value NetLogSocketErrorCallback(int net_error, + int os_error, + NetLogCaptureMode /* capture_mode */) { + base::DictionaryValue dict; + dict.SetInteger("net_error", net_error); + dict.SetInteger("os_error", os_error); return std::move(dict); } -std::unique_ptr<base::Value> NetLogHostPortPairCallback( - const HostPortPair* host_and_port, - NetLogCaptureMode /* capture_mode */) { - std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); - dict->SetString("host_and_port", host_and_port->ToString()); +base::Value NetLogHostPortPairCallback(const HostPortPair* host_and_port, + NetLogCaptureMode /* capture_mode */) { + base::DictionaryValue dict; + dict.SetString("host_and_port", host_and_port->ToString()); return std::move(dict); } -std::unique_ptr<base::Value> NetLogIPEndPointCallback( - const IPEndPoint* address, - NetLogCaptureMode /* capture_mode */) { - std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); - dict->SetString("address", address->ToString()); +base::Value NetLogIPEndPointCallback(const IPEndPoint* address, + NetLogCaptureMode /* capture_mode */) { + base::DictionaryValue dict; + dict.SetString("address", address->ToString()); return std::move(dict); } -std::unique_ptr<base::Value> NetLogSourceAddressCallback( - const struct sockaddr* net_address, - socklen_t address_len, - NetLogCaptureMode /* capture_mode */) { - std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); +base::Value NetLogSourceAddressCallback(const struct sockaddr* net_address, + socklen_t address_len, + NetLogCaptureMode /* capture_mode */) { + base::DictionaryValue dict; IPEndPoint ipe; bool result = ipe.FromSockAddr(net_address, address_len); DCHECK(result); - dict->SetString("source_address", ipe.ToString()); + dict.SetString("source_address", ipe.ToString()); return std::move(dict); } diff --git a/chromium/net/socket/socket_tag.cc b/chromium/net/socket/socket_tag.cc index 0e0a2175137..ad550a0592a 100644 --- a/chromium/net/socket/socket_tag.cc +++ b/chromium/net/socket/socket_tag.cc @@ -51,4 +51,4 @@ void SocketTag::Apply(SocketDescriptor socket) const { #endif // OS_ANDROID } -} // namespace net
\ No newline at end of file +} // namespace net diff --git a/chromium/net/socket/socket_tag.h b/chromium/net/socket/socket_tag.h index eb89a43df77..89f7508e977 100644 --- a/chromium/net/socket/socket_tag.h +++ b/chromium/net/socket/socket_tag.h @@ -63,4 +63,4 @@ class NET_EXPORT SocketTag { } // namespace net -#endif // NET_SOCKET_SOCKET_TAG_H_
\ No newline at end of file +#endif // NET_SOCKET_SOCKET_TAG_H_ diff --git a/chromium/net/socket/socket_test_util.cc b/chromium/net/socket/socket_test_util.cc index ca99f5a434b..bb05c92bba5 100644 --- a/chromium/net/socket/socket_test_util.cc +++ b/chromium/net/socket/socket_test_util.cc @@ -32,6 +32,7 @@ #include "net/base/hex_utils.h" #include "net/base/ip_address.h" #include "net/base/load_timing_info.h" +#include "net/base/proxy_server.h" #include "net/http/http_network_session.h" #include "net/http/http_request_headers.h" #include "net/http/http_response_headers.h" @@ -44,6 +45,7 @@ #include "net/ssl/ssl_cert_request_info.h" #include "net/ssl/ssl_connection_status_flags.h" #include "net/ssl/ssl_info.h" +#include "net/traffic_annotation/network_traffic_annotation.h" #include "net/traffic_annotation/network_traffic_annotation_test_helper.h" #include "testing/gtest/include/gtest/gtest.h" @@ -810,6 +812,10 @@ std::unique_ptr<SSLClientSocket> MockClientSocketFactory::CreateSSLClientSocket( EXPECT_FALSE(ssl_config.client_cert); } } + if (next_ssl_data->expected_false_start_enabled) { + EXPECT_EQ(*next_ssl_data->expected_false_start_enabled, + ssl_config.false_start_enabled); + } return std::unique_ptr<SSLClientSocket>(new MockSSLClientSocket( std::move(stream_socket), host_and_port, ssl_config, next_ssl_data)); } @@ -825,7 +831,6 @@ MockClientSocketFactory::CreateProxyClientSocket( bool using_spdy, NextProto negotiated_protocol, ProxyDelegate* proxy_delegate, - bool is_https_proxy, const NetworkTrafficAnnotationTag& traffic_annotation) { if (use_mock_proxy_client_sockets_) { ProxyClientSocketDataProvider* next_proxy_data = mock_proxy_data_.GetNext(); @@ -835,7 +840,7 @@ MockClientSocketFactory::CreateProxyClientSocket( return GetDefaultFactory()->CreateProxyClientSocket( std::move(stream_socket), user_agent, endpoint, proxy_server, http_auth_controller, tunnel, using_spdy, negotiated_protocol, - proxy_delegate, is_https_proxy, traffic_annotation); + proxy_delegate, traffic_annotation); } } @@ -2108,6 +2113,8 @@ MockTransportClientSocketPool::MockTransportClientSocketPool( max_sockets, max_sockets_per_group, base::TimeDelta::FromSeconds(10) /* unused_idle_socket_timeout */, + ProxyServer::Direct(), + false /* is_for_websockets */, common_connect_job_params, nullptr /* ssl_config_service */), client_socket_factory_(common_connect_job_params->client_socket_factory), @@ -2120,6 +2127,7 @@ MockTransportClientSocketPool::~MockTransportClientSocketPool() = default; int MockTransportClientSocketPool::RequestSocket( const ClientSocketPool::GroupId& group_id, scoped_refptr<ClientSocketPool::SocketParams> socket_params, + const base::Optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag, RequestPriority priority, const SocketTag& socket_tag, RespectLimits respect_limits, @@ -2153,7 +2161,8 @@ void MockTransportClientSocketPool::SetPriority( void MockTransportClientSocketPool::CancelRequest( const ClientSocketPool::GroupId& group_id, - ClientSocketHandle* handle) { + ClientSocketHandle* handle, + bool cancel_connect_job) { for (std::unique_ptr<MockConnectJob>& it : job_list_) { if (it->CancelHandle(handle)) { cancel_count_++; diff --git a/chromium/net/socket/socket_test_util.h b/chromium/net/socket/socket_test_util.h index 6ace270ce23..05d4c51e62d 100644 --- a/chromium/net/socket/socket_test_util.h +++ b/chromium/net/socket/socket_test_util.h @@ -45,7 +45,6 @@ #include "net/socket/transport_client_socket_pool.h" #include "net/ssl/ssl_config_service.h" #include "net/ssl/ssl_info.h" -#include "net/traffic_annotation/network_traffic_annotation.h" #include "testing/gtest/include/gtest/gtest.h" namespace base { @@ -56,6 +55,7 @@ namespace net { struct CommonConnectJobParams; class NetLog; +struct NetworkTrafficAnnotationTag; class X509Certificate; const NetworkChangeNotifier::NetworkHandle kDefaultNetworkForTests = 1; @@ -482,6 +482,7 @@ struct SSLSocketDataProvider { uint16_t expected_ssl_version_max; base::Optional<bool> expected_send_client_cert; scoped_refptr<X509Certificate> expected_client_cert; + base::Optional<bool> expected_false_start_enabled; bool is_connect_data_consumed = false; bool is_confirm_data_consumed = false; @@ -662,7 +663,6 @@ class MockClientSocketFactory : public ClientSocketFactory { bool using_spdy, NextProto negotiated_protocol, ProxyDelegate* proxy_delegate, - bool is_https_proxy, const NetworkTrafficAnnotationTag& traffic_annotation) override; const std::vector<uint16_t>& udp_client_socket_ports() const { return udp_client_socket_ports_; @@ -1140,9 +1140,9 @@ class ClientSocketPoolTest { new TestSocketRequest(&request_order_, &completion_count_)); requests_.push_back(base::WrapUnique(request)); int rv = request->handle()->Init( - group_id, socket_params, priority, SocketTag(), respect_limits, - request->callback(), ClientSocketPool::ProxyAuthCallback(), socket_pool, - NetLogWithSource()); + group_id, socket_params, base::nullopt /* proxy_annotation_tag */, + priority, SocketTag(), respect_limits, request->callback(), + ClientSocketPool::ProxyAuthCallback(), socket_pool, NetLogWithSource()); if (rv != ERR_IO_PENDING) request_order_.push_back(request); return rv; @@ -1238,20 +1238,23 @@ class MockTransportClientSocketPool : public TransportClientSocketPool { int cancel_count() const { return cancel_count_; } // TransportClientSocketPool implementation. - int RequestSocket(const GroupId& group_id, - scoped_refptr<ClientSocketPool::SocketParams> socket_params, - RequestPriority priority, - const SocketTag& socket_tag, - RespectLimits respect_limits, - ClientSocketHandle* handle, - CompletionOnceCallback callback, - const ProxyAuthCallback& on_auth_callback, - const NetLogWithSource& net_log) override; + int RequestSocket( + const GroupId& group_id, + scoped_refptr<ClientSocketPool::SocketParams> socket_params, + const base::Optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag, + RequestPriority priority, + const SocketTag& socket_tag, + RespectLimits respect_limits, + ClientSocketHandle* handle, + CompletionOnceCallback callback, + const ProxyAuthCallback& on_auth_callback, + const NetLogWithSource& net_log) override; void SetPriority(const GroupId& group_id, ClientSocketHandle* handle, RequestPriority priority) override; void CancelRequest(const GroupId& group_id, - ClientSocketHandle* handle) override; + ClientSocketHandle* handle, + bool cancel_connect_job) override; void ReleaseSocket(const GroupId& group_id, std::unique_ptr<StreamSocket> socket, int64_t generation) override; diff --git a/chromium/net/socket/ssl_client_socket_impl.cc b/chromium/net/socket/ssl_client_socket_impl.cc index 5aa5e59ce61..857dc8a00a8 100644 --- a/chromium/net/socket/ssl_client_socket_impl.cc +++ b/chromium/net/socket/ssl_client_socket_impl.cc @@ -78,55 +78,51 @@ const int kCertVerifyPending = 1; // Default size of the internal BoringSSL buffers. const int kDefaultOpenSSLBufferSize = 17 * 1024; -std::unique_ptr<base::Value> NetLogPrivateKeyOperationCallback( - uint16_t algorithm, - SSLPrivateKey* key, - NetLogCaptureMode mode) { - std::unique_ptr<base::DictionaryValue> value(new base::DictionaryValue); - value->SetString("algorithm", SSL_get_signature_algorithm_name( - algorithm, 0 /* exclude curve */)); - value->SetString("provider", key->GetProviderName()); +base::Value NetLogPrivateKeyOperationCallback(uint16_t algorithm, + SSLPrivateKey* key, + NetLogCaptureMode mode) { + base::DictionaryValue value; + value.SetString("algorithm", SSL_get_signature_algorithm_name( + algorithm, 0 /* exclude curve */)); + value.SetString("provider", key->GetProviderName()); return std::move(value); } -std::unique_ptr<base::Value> NetLogSSLInfoCallback( - SSLClientSocketImpl* socket, - NetLogCaptureMode capture_mode) { +base::Value NetLogSSLInfoCallback(SSLClientSocketImpl* socket, + NetLogCaptureMode capture_mode) { SSLInfo ssl_info; if (!socket->GetSSLInfo(&ssl_info)) - return nullptr; + return base::Value(); - std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); + base::DictionaryValue dict; const char* version_str; SSLVersionToString(&version_str, SSLConnectionStatusToVersion(ssl_info.connection_status)); - dict->SetString("version", version_str); - dict->SetBoolean("is_resumed", - ssl_info.handshake_type == SSLInfo::HANDSHAKE_RESUME); - dict->SetInteger("cipher_suite", SSLConnectionStatusToCipherSuite( - ssl_info.connection_status)); + dict.SetString("version", version_str); + dict.SetBoolean("is_resumed", + ssl_info.handshake_type == SSLInfo::HANDSHAKE_RESUME); + dict.SetInteger("cipher_suite", + SSLConnectionStatusToCipherSuite(ssl_info.connection_status)); - dict->SetString("next_proto", - NextProtoToString(socket->GetNegotiatedProtocol())); + dict.SetString("next_proto", + NextProtoToString(socket->GetNegotiatedProtocol())); return std::move(dict); } -std::unique_ptr<base::Value> NetLogSSLAlertCallback( - const void* bytes, - size_t len, - NetLogCaptureMode capture_mode) { - std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); - dict->SetKey("bytes", NetLogBinaryValue(bytes, len)); +base::Value NetLogSSLAlertCallback(const void* bytes, + size_t len, + NetLogCaptureMode capture_mode) { + base::DictionaryValue dict; + dict.SetKey("bytes", NetLogBinaryValue(bytes, len)); return std::move(dict); } -std::unique_ptr<base::Value> NetLogSSLMessageCallback( - bool is_write, - const void* bytes, - size_t len, - NetLogCaptureMode capture_mode) { - std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); +base::Value NetLogSSLMessageCallback(bool is_write, + const void* bytes, + size_t len, + NetLogCaptureMode capture_mode) { + base::DictionaryValue dict; if (len == 0) { NOTREACHED(); return std::move(dict); @@ -135,7 +131,7 @@ std::unique_ptr<base::Value> NetLogSSLMessageCallback( // The handshake message type is the first byte. Include it so elided messages // still report their type. uint8_t type = reinterpret_cast<const uint8_t*>(bytes)[0]; - dict->SetInteger("type", type); + dict.SetInteger("type", type); // Elide client certificate messages unless logging socket bytes. The client // certificate does not contain information needed to impersonate the user @@ -143,7 +139,7 @@ std::unique_ptr<base::Value> NetLogSSLMessageCallback( // information on the user's identity. if (!is_write || type != SSL3_MT_CERTIFICATE || capture_mode.include_socket_bytes()) { - dict->SetKey("bytes", NetLogBinaryValue(bytes, len)); + dict.SetKey("bytes", NetLogBinaryValue(bytes, len)); } return std::move(dict); @@ -964,11 +960,6 @@ int SSLClientSocketImpl::DoHandshakeComplete(int result) { return OK; } - if (ssl_config_.version_interference_probe) { - DCHECK_LT(ssl_config_.version_max, TLS1_3_VERSION); - return ERR_SSL_VERSION_INTERFERENCE; - } - if (IsCachingEnabled()) { ssl_client_session_cache_->ResetLookupCount(GetSessionCacheKey()); } @@ -1147,10 +1138,16 @@ ssl_verify_result_t SSLClientSocketImpl::VerifyCert() { base::StringPiece ocsp_response( reinterpret_cast<const char*>(ocsp_response_raw), ocsp_response_len); + const uint8_t* sct_list_raw; + size_t sct_list_len; + SSL_get0_signed_cert_timestamp_list(ssl_.get(), &sct_list_raw, &sct_list_len); + base::StringPiece sct_list(reinterpret_cast<const char*>(sct_list_raw), + sct_list_len); + cert_verification_result_ = cert_verifier_->Verify( - CertVerifier::RequestParams(server_cert_, host_and_port_.host(), - ssl_config_.GetCertVerifyFlags(), - ocsp_response.as_string()), + CertVerifier::RequestParams( + server_cert_, host_and_port_.host(), ssl_config_.GetCertVerifyFlags(), + ocsp_response.as_string(), sct_list.as_string()), &server_cert_verify_result_, base::BindOnce(&SSLClientSocketImpl::OnVerifyComplete, base::Unretained(this)), @@ -1625,11 +1622,7 @@ void SSLClientSocketImpl::AddCTInfoToSSLInfo(SSLInfo* ssl_info) const { } std::string SSLClientSocketImpl::GetSessionCacheKey() const { - std::string result = host_and_port_.ToString(); - - result.push_back('/'); - result.push_back(ssl_config_.version_interference_probe ? '1' : '0'); - return result; + return host_and_port_.ToString(); } bool SSLClientSocketImpl::IsRenegotiationAllowed() const { diff --git a/chromium/net/socket/ssl_client_socket_unittest.cc b/chromium/net/socket/ssl_client_socket_unittest.cc index d58d8efccb4..f07bdcd6a37 100644 --- a/chromium/net/socket/ssl_client_socket_unittest.cc +++ b/chromium/net/socket/ssl_client_socket_unittest.cc @@ -8,6 +8,7 @@ #include <string.h> #include <algorithm> +#include <tuple> #include <utility> #include "base/bind.h" @@ -765,8 +766,6 @@ class MockCTVerifier : public CTVerifier { base::StringPiece, SignedCertificateTimestampAndStatusList*, const NetLogWithSource&)); - MOCK_METHOD1(SetObserver, void(CTVerifier::Observer*)); - MOCK_CONST_METHOD0(GetObserver, CTVerifier::Observer*()); }; // A mock CTPolicyEnforcer that returns a custom verification result. @@ -810,9 +809,19 @@ class SSLClientSocketTest : public PlatformTest, } protected: - // The address of the spawned test server, after calling StartTestServer(). + // The address of the test server, after calling StartEmbeddedTestServer() or + // StartTestServer(). const AddressList& addr() const { return addr_; } + // The hostname of the test server, after calling StartEmbeddedTestServer() or + // StartTestServer(). + const HostPortPair& host_port_pair() const { return host_port_pair_; } + + // The EmbeddedTestServer object, after calling StartEmbeddedTestServer(). + EmbeddedTestServer* embedded_test_server() { + return embedded_test_server_.get(); + } + // The SpawnedTestServer object, after calling StartTestServer(). const SpawnedTestServer* spawned_test_server() const { return spawned_test_server_.get(); @@ -830,11 +839,39 @@ class SSLClientSocketTest : public PlatformTest, context_.ct_policy_enforcer = policy_enforcer; } - // Starts the test server with SSL configuration |ssl_options|. Returns true + // Starts the embedded test server with the specified parameters. Returns true // on success. + bool StartEmbeddedTestServer(EmbeddedTestServer::ServerCertificate cert, + const SSLServerConfig& server_config) { + spawned_test_server_ = nullptr; + embedded_test_server_ = + std::make_unique<EmbeddedTestServer>(EmbeddedTestServer::TYPE_HTTPS); + RegisterEmbeddedTestServerHandlers(embedded_test_server_.get()); + embedded_test_server_->SetSSLConfig(cert, server_config); + if (!embedded_test_server_->Start()) { + LOG(ERROR) << "Could not start EmbeddedTestServer"; + return false; + } + + if (!embedded_test_server_->GetAddressList(&addr_)) { + LOG(ERROR) << "Could not get EmbeddedTestServer address list"; + return false; + } + host_port_pair_ = embedded_test_server_->host_port_pair(); + return true; + } + + // May be overridden by the subclass to customize the EmbeddedTestServer. + virtual void RegisterEmbeddedTestServerHandlers(EmbeddedTestServer* server) { + server->AddDefaultHandlers(base::FilePath()); + } + + // Starts the spawned test server with SSL configuration |ssl_options|. + // Returns true on success. Prefer StartEmbeddedTestServer(). bool StartTestServer(const SpawnedTestServer::SSLOptions& ssl_options) { - spawned_test_server_.reset(new SpawnedTestServer( - SpawnedTestServer::TYPE_HTTPS, ssl_options, base::FilePath())); + embedded_test_server_ = nullptr; + spawned_test_server_ = std::make_unique<SpawnedTestServer>( + SpawnedTestServer::TYPE_HTTPS, ssl_options, base::FilePath()); if (!spawned_test_server_->Start()) { LOG(ERROR) << "Could not start SpawnedTestServer"; return false; @@ -844,6 +881,7 @@ class SSLClientSocketTest : public PlatformTest, LOG(ERROR) << "Could not get SpawnedTestServer address list"; return false; } + host_port_pair_ = spawned_test_server_->host_port_pair(); return true; } @@ -889,8 +927,8 @@ class SSLClientSocketTest : public PlatformTest, bool CreateAndConnectSSLClientSocket(const SSLConfig& ssl_config, int* result) { - return CreateAndConnectSSLClientSocketWithHost( - ssl_config, spawned_test_server()->host_port_pair(), result); + return CreateAndConnectSSLClientSocketWithHost(ssl_config, host_port_pair(), + result); } // Adds the server certificate with provided cert status. @@ -920,21 +958,106 @@ class SSLClientSocketTest : public PlatformTest, private: std::unique_ptr<SpawnedTestServer> spawned_test_server_; + std::unique_ptr<EmbeddedTestServer> embedded_test_server_; TestCompletionCallback callback_; AddressList addr_; + HostPortPair host_port_pair_; +}; + +enum ReadIfReadyTransport { + // ReadIfReady() is implemented by the underlying transport. + READ_IF_READY_SUPPORTED, + // ReadIfReady() is not implemented by the underlying transport. + READ_IF_READY_NOT_SUPPORTED, +}; + +enum ReadIfReadySSL { + // Test reads by calling ReadIfReady() on the SSL socket. + TEST_SSL_READ_IF_READY, + // Test reads by calling Read() on the SSL socket. + TEST_SSL_READ, +}; + +class StreamSocketWithoutReadIfReady : public WrappedStreamSocket { + public: + explicit StreamSocketWithoutReadIfReady( + std::unique_ptr<StreamSocket> transport) + : WrappedStreamSocket(std::move(transport)) {} + + int ReadIfReady(IOBuffer* buf, + int buf_len, + CompletionOnceCallback callback) override { + return ERR_READ_IF_READY_NOT_IMPLEMENTED; + } + + int CancelReadIfReady() override { return ERR_READ_IF_READY_NOT_IMPLEMENTED; } +}; + +class ClientSocketFactoryWithoutReadIfReady : public ClientSocketFactory { + public: + explicit ClientSocketFactoryWithoutReadIfReady(ClientSocketFactory* factory) + : factory_(factory) {} + + std::unique_ptr<DatagramClientSocket> CreateDatagramClientSocket( + DatagramSocket::BindType bind_type, + NetLog* net_log, + const NetLogSource& source) override { + return factory_->CreateDatagramClientSocket(bind_type, net_log, source); + } + + std::unique_ptr<TransportClientSocket> CreateTransportClientSocket( + const AddressList& addresses, + std::unique_ptr<SocketPerformanceWatcher> socket_performance_watcher, + NetLog* net_log, + const NetLogSource& source) override { + return factory_->CreateTransportClientSocket( + addresses, std::move(socket_performance_watcher), net_log, source); + } + + std::unique_ptr<SSLClientSocket> CreateSSLClientSocket( + std::unique_ptr<StreamSocket> stream_socket, + const HostPortPair& host_and_port, + const SSLConfig& ssl_config, + const SSLClientSocketContext& context) override { + stream_socket = std::make_unique<StreamSocketWithoutReadIfReady>( + std::move(stream_socket)); + return factory_->CreateSSLClientSocket(std::move(stream_socket), + host_and_port, ssl_config, context); + } + + std::unique_ptr<ProxyClientSocket> CreateProxyClientSocket( + std::unique_ptr<StreamSocket> stream_socket, + const std::string& user_agent, + const HostPortPair& endpoint, + const ProxyServer& proxy_server, + HttpAuthController* http_auth_controller, + bool tunnel, + bool using_spdy, + NextProto negotiated_protocol, + ProxyDelegate* proxy_delegate, + const NetworkTrafficAnnotationTag& traffic_annotation) override { + return factory_->CreateProxyClientSocket( + std::move(stream_socket), user_agent, endpoint, proxy_server, + http_auth_controller, tunnel, using_spdy, negotiated_protocol, + proxy_delegate, traffic_annotation); + } + + private: + ClientSocketFactory* const factory_; }; // If GetParam(), try ReadIfReady() and fall back to Read() if needed. -class SSLClientSocketReadTest : public SSLClientSocketTest, - public ::testing::WithParamInterface<bool> { +class SSLClientSocketReadTest + : public SSLClientSocketTest, + public ::testing::WithParamInterface< + std::tuple<ReadIfReadyTransport, ReadIfReadySSL>> { protected: - SSLClientSocketReadTest() - : SSLClientSocketTest(), read_if_ready_enabled_(GetParam()) {} - - void SetUp() override { - if (!read_if_ready_enabled()) { - scoped_feature_list_.InitAndDisableFeature( - Socket::kReadIfReadyExperiment); + SSLClientSocketReadTest() : SSLClientSocketTest() { + if (!read_if_ready_supported()) { + wrapped_socket_factory_ = + std::make_unique<ClientSocketFactoryWithoutReadIfReady>( + socket_factory_); + socket_factory_ = wrapped_socket_factory_.get(); } } @@ -944,7 +1067,7 @@ class SSLClientSocketReadTest : public SSLClientSocketTest, IOBuffer* buf, int buf_len, CompletionOnceCallback callback) { - if (read_if_ready_enabled()) + if (test_ssl_read_if_ready()) return socket->ReadIfReady(buf, buf_len, std::move(callback)); return socket->Read(buf, buf_len, std::move(callback)); } @@ -955,7 +1078,7 @@ class SSLClientSocketReadTest : public SSLClientSocketTest, int buf_len, TestCompletionCallback* callback, int rv) { - if (!read_if_ready_enabled()) + if (!test_ssl_read_if_ready()) return callback->GetResult(rv); while (rv == ERR_IO_PENDING) { rv = callback->GetResult(rv); @@ -975,16 +1098,24 @@ class SSLClientSocketReadTest : public SSLClientSocketTest, return WaitForReadCompletion(socket, buf, buf_len, &callback, rv); } - bool read_if_ready_enabled() const { return read_if_ready_enabled_; } + bool test_ssl_read_if_ready() const { + return std::get<1>(GetParam()) == TEST_SSL_READ_IF_READY; + } + + bool read_if_ready_supported() const { + return std::get<0>(GetParam()) == READ_IF_READY_SUPPORTED; + } private: - base::test::ScopedFeatureList scoped_feature_list_; - const bool read_if_ready_enabled_; + std::unique_ptr<ClientSocketFactory> wrapped_socket_factory_; }; -INSTANTIATE_TEST_SUITE_P(/* no prefix */, - SSLClientSocketReadTest, - ::testing::Bool()); +INSTANTIATE_TEST_SUITE_P( + /* no prefix */, + SSLClientSocketReadTest, + ::testing::Combine( + ::testing::Values(READ_IF_READY_SUPPORTED, READ_IF_READY_NOT_SUPPORTED), + ::testing::Values(TEST_SSL_READ_IF_READY, TEST_SSL_READ))); // Verifies the correctness of GetSSLCertRequestInfo. class SSLClientSocketCertRequestInfoTest : public SSLClientSocketTest { @@ -1186,30 +1317,20 @@ class SSLClientSocketZeroRTTTest : public SSLClientSocketTest { SSLClientSocketZeroRTTTest() : SSLClientSocketTest() {} bool StartServer() { - test_server_.reset( - new EmbeddedTestServer(net::EmbeddedTestServer::TYPE_HTTPS)); SSLServerConfig server_config; server_config.early_data_enabled = true; server_config.version_max = SSL_PROTOCOL_VERSION_TLS1_3; - test_server_->AddDefaultHandlers(base::FilePath()); - test_server_->RegisterRequestHandler( - base::BindRepeating(&HandleZeroRTTRequest)); - test_server_->SetSSLConfig(net::EmbeddedTestServer::CERT_OK, server_config); - if (!test_server_->Start()) { - LOG(ERROR) << "Could not start EmbeddedTestServer"; - return false; - } + return StartEmbeddedTestServer(EmbeddedTestServer::CERT_OK, server_config); + } - if (!test_server_->GetAddressList(&address_)) { - LOG(ERROR) << "Could not get EmbeddedTestServer address list"; - return false; - } - return true; + void RegisterEmbeddedTestServerHandlers(EmbeddedTestServer* server) override { + SSLClientSocketTest::RegisterEmbeddedTestServerHandlers(server); + server->RegisterRequestHandler(base::BindRepeating(&HandleZeroRTTRequest)); } void SetServerConfig(SSLServerConfig server_config) { - test_server_->ResetSSLConfig(net::EmbeddedTestServer::CERT_OK, - server_config); + embedded_test_server()->ResetSSLConfig(net::EmbeddedTestServer::CERT_OK, + server_config); } FakeBlockingStreamSocket* MakeClient(bool early_data_enabled) { @@ -1218,7 +1339,7 @@ class SSLClientSocketZeroRTTTest : public SSLClientSocketTest { ssl_config.early_data_enabled = early_data_enabled; real_transport_.reset( - new TCPClientSocket(address_, nullptr, nullptr, NetLogSource())); + new TCPClientSocket(addr(), nullptr, nullptr, NetLogSource())); std::unique_ptr<FakeBlockingStreamSocket> transport( new FakeBlockingStreamSocket(std::move(real_transport_))); FakeBlockingStreamSocket* raw_transport = transport.get(); @@ -1226,8 +1347,8 @@ class SSLClientSocketZeroRTTTest : public SSLClientSocketTest { int rv = callback_.GetResult(transport->Connect(callback_.callback())); EXPECT_THAT(rv, IsOk()); - ssl_socket_ = CreateSSLClientSocket( - std::move(transport), test_server_->host_port_pair(), ssl_config); + ssl_socket_ = CreateSSLClientSocket(std::move(transport), host_port_pair(), + ssl_config); EXPECT_FALSE(ssl_socket_->IsConnected()); return raw_transport; @@ -1279,8 +1400,6 @@ class SSLClientSocketZeroRTTTest : public SSLClientSocketTest { SSLClientSocket* ssl_socket() { return ssl_socket_.get(); } private: - std::unique_ptr<EmbeddedTestServer> test_server_; - AddressList address_; TestCompletionCallback callback_; std::unique_ptr<StreamSocket> real_transport_; std::unique_ptr<SSLClientSocket> ssl_socket_; @@ -1941,7 +2060,7 @@ TEST_P(SSLClientSocketReadTest, Read_DeleteWhilePendingFullDuplex) { // |read_callback| deletes |sock| so if ReadIfReady() is used, we will get OK // asynchronously but can't continue reading because the socket is gone. rv = read_callback.WaitForResult(); - if (read_if_ready_enabled()) { + if (test_ssl_read_if_ready()) { EXPECT_THAT(rv, IsOk()); } else { EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET)); @@ -3087,37 +3206,6 @@ TEST_F(SSLClientSocketTest, NoDHE) { EXPECT_THAT(rv, IsError(ERR_SSL_VERSION_OR_CIPHER_MISMATCH)); } -// Tests that the version_interference_probe option rejects successful -// connections and passes errors through. -TEST_F(SSLClientSocketTest, VersionInterferenceProbe) { - ASSERT_TRUE(StartTestServer(SpawnedTestServer::SSLOptions())); - - SSLConfig ssl_config; - ssl_config.version_max = SSL_PROTOCOL_VERSION_TLS1_2; - ssl_config.version_interference_probe = true; - - // Successful connections map to a dedicated error. - int rv; - ASSERT_TRUE(CreateAndConnectSSLClientSocket(ssl_config, &rv)); - EXPECT_THAT(rv, IsError(ERR_SSL_VERSION_INTERFERENCE)); - - // Failed connections pass through. - TestCompletionCallback callback; - std::unique_ptr<StreamSocket> real_transport( - new TCPClientSocket(addr(), nullptr, nullptr, NetLogSource())); - std::unique_ptr<SynchronousErrorStreamSocket> transport( - new SynchronousErrorStreamSocket(std::move(real_transport))); - rv = callback.GetResult(transport->Connect(callback.callback())); - EXPECT_THAT(rv, IsOk()); - SynchronousErrorStreamSocket* raw_transport = transport.get(); - std::unique_ptr<SSLClientSocket> sock(CreateSSLClientSocket( - std::move(transport), spawned_test_server()->host_port_pair(), - ssl_config)); - raw_transport->SetNextWriteError(ERR_CONNECTION_RESET); - rv = callback.GetResult(sock->Connect(callback.callback())); - EXPECT_THAT(rv, IsError(ERR_CONNECTION_RESET)); -} - TEST_F(SSLClientSocketTest, RequireECDHE) { // Run test server without ECDHE. SpawnedTestServer::SSLOptions ssl_options; @@ -4728,7 +4816,7 @@ TEST_P(SSLClientSocketReadTest, DumpMemoryStats) { StreamSocket::SocketMemoryStats stats2; sock_->DumpMemoryStats(&stats2); - if (read_if_ready_enabled()) { + if (read_if_ready_supported()) { EXPECT_EQ(0u, stats2.buffer_size); EXPECT_EQ(stats.cert_size, stats2.total_size); } else { @@ -4816,6 +4904,104 @@ TEST_P(SSLClientSocketReadTest, IdleAfterRead) { EXPECT_EQ(stats.cert_size, stats.total_size); } +// Test that certificate errors are properly reported when the underlying +// transport is itself a TLS connection, such as when tunneling over an HTTPS +// proxy. See https://crbug.com/959305. +TEST_F(SSLClientSocketTest, SSLOverSSLBadCertificate) { + // Load a pair of certificates. + base::FilePath certs_dir = GetTestCertsDirectory(); + scoped_refptr<net::X509Certificate> ok_cert = + ImportCertFromFile(certs_dir, "ok_cert.pem"); + ASSERT_TRUE(ok_cert); + bssl::UniquePtr<EVP_PKEY> ok_pkey = + key_util::LoadEVP_PKEYFromPEM(certs_dir.AppendASCII("ok_cert.pem")); + ASSERT_TRUE(ok_pkey); + + scoped_refptr<net::X509Certificate> expired_cert = + ImportCertFromFile(certs_dir, "expired_cert.pem"); + ASSERT_TRUE(expired_cert); + bssl::UniquePtr<EVP_PKEY> expired_pkey = + key_util::LoadEVP_PKEYFromPEM(certs_dir.AppendASCII("expired_cert.pem")); + ASSERT_TRUE(expired_pkey); + + CertVerifyResult expired_result; + expired_result.verified_cert = expired_cert; + expired_result.cert_status = CERT_STATUS_DATE_INVALID; + cert_verifier_->AddResultForCert(expired_cert, expired_result, + ERR_CERT_DATE_INVALID); + + // Set up a TCP server. + TCPServerSocket server_listener(nullptr, NetLogSource()); + ASSERT_THAT( + server_listener.Listen(IPEndPoint(IPAddress::IPv4Localhost(), 0), 1), + IsOk()); + IPEndPoint server_address; + ASSERT_THAT(server_listener.GetLocalAddress(&server_address), IsOk()); + + // Connect a TCP client and server socket. + TestCompletionCallback server_callback; + std::unique_ptr<StreamSocket> server_transport; + int server_rv = + server_listener.Accept(&server_transport, server_callback.callback()); + + TestCompletionCallback client_callback; + auto client_transport = std::make_unique<TCPClientSocket>( + AddressList(server_address), nullptr, nullptr, NetLogSource()); + int client_rv = client_transport->Connect(client_callback.callback()); + + ASSERT_THAT(server_callback.GetResult(server_rv), IsOk()); + ASSERT_THAT(client_callback.GetResult(client_rv), IsOk()); + + // Set up a pair of SSL servers. + std::unique_ptr<crypto::RSAPrivateKey> ok_key = + crypto::RSAPrivateKey::CreateFromKey(ok_pkey.get()); + ASSERT_TRUE(ok_key); + std::unique_ptr<SSLServerContext> ok_server_context = + CreateSSLServerContext(ok_cert.get(), *ok_key.get(), SSLServerConfig()); + + std::unique_ptr<crypto::RSAPrivateKey> expired_key = + crypto::RSAPrivateKey::CreateFromKey(expired_pkey.get()); + ASSERT_TRUE(expired_key); + std::unique_ptr<SSLServerContext> expired_server_context = + CreateSSLServerContext(expired_cert.get(), *expired_key.get(), + SSLServerConfig()); + + // Complete the proxy SSL handshake with ok_cert.pem. This should succeed. + std::unique_ptr<SSLClientSocket> client = + CreateSSLClientSocket(std::move(client_transport), + HostPortPair("proxy.test", 443), SSLConfig()); + std::unique_ptr<SSLServerSocket> server = + ok_server_context->CreateSSLServerSocket(std::move(server_transport)); + + client_rv = client->Connect(client_callback.callback()); + server_rv = server->Handshake(server_callback.callback()); + ASSERT_THAT(client_callback.GetResult(client_rv), IsOk()); + ASSERT_THAT(server_callback.GetResult(server_rv), IsOk()); + + // Run the tunneled SSL handshake on with expired_cert.pem. This should fail. + client = CreateSSLClientSocket(std::move(client), + HostPortPair("server.test", 443), SSLConfig()); + server = expired_server_context->CreateSSLServerSocket(std::move(server)); + + client_rv = client->Connect(client_callback.callback()); + server_rv = server->Handshake(server_callback.callback()); + + // The client should observe the bad certificate error. + EXPECT_THAT(client_callback.GetResult(client_rv), + IsError(ERR_CERT_DATE_INVALID)); + SSLInfo ssl_info; + ASSERT_TRUE(client->GetSSLInfo(&ssl_info)); + EXPECT_EQ(ssl_info.cert_status, expired_result.cert_status); + + // TODO(https://crbug.com/912383): The server sees + // ERR_BAD_SSL_CLIENT_AUTH_CERT because its peer (the client) alerts it with + // bad_certificate. The alert-mapping code assumes it is running on a client, + // so it translates bad_certificate to ERR_BAD_SSL_CLIENT_AUTH_CERT, which + // shouldn't be the error for a bad server certificate. + EXPECT_THAT(server_callback.GetResult(server_rv), + IsError(ERR_BAD_SSL_CLIENT_AUTH_CERT)); +} + TEST_F(SSLClientSocketTest, Tag) { ASSERT_TRUE(StartTestServer(SpawnedTestServer::SSLOptions())); diff --git a/chromium/net/socket/ssl_connect_job.cc b/chromium/net/socket/ssl_connect_job.cc index be9951688d7..3c512cd60f1 100644 --- a/chromium/net/socket/ssl_connect_job.cc +++ b/chromium/net/socket/ssl_connect_job.cc @@ -115,8 +115,7 @@ SSLConnectJob::SSLConnectJob( params_(std::move(params)), callback_(base::BindRepeating(&SSLConnectJob::OnIOComplete, base::Unretained(this))), - ssl_negotiation_started_(false), - proxy_redirect_(false) {} + ssl_negotiation_started_(false) {} SSLConnectJob::~SSLConnectJob() { // In the case the job was canceled, need to delete nested job first to @@ -180,12 +179,6 @@ ConnectionAttempts SSLConnectJob::GetConnectionAttempts() const { return connection_attempts_; } -std::unique_ptr<StreamSocket> SSLConnectJob::PassProxySocketOnFailure() { - if (proxy_redirect_) - return std::move(nested_socket_); - return nullptr; -} - bool SSLConnectJob::IsSSLError() const { return ssl_negotiation_started_; } @@ -322,9 +315,6 @@ int SSLConnectJob::DoTunnelConnectComplete(int result) { // |GetAdditionalErrorState|, we can easily set the state. if (result == ERR_SSL_CLIENT_AUTH_CERT_NEEDED) { ssl_cert_request_info_ = nested_connect_job_->GetCertRequestInfo(); - } else if (result == ERR_HTTPS_PROXY_TUNNEL_RESPONSE_REDIRECT) { - proxy_redirect_ = true; - connect_timing_ = nested_connect_job_->connect_timing(); } return result; } @@ -395,10 +385,18 @@ int SSLConnectJob::DoSSLConnectComplete(int result) { bool has_ssl_info = ssl_socket_->GetSSLInfo(&ssl_info); DCHECK(has_ssl_info); - UMA_HISTOGRAM_ENUMERATION( - "Net.SSLVersion", - SSLConnectionStatusToVersion(ssl_info.connection_status), - SSL_CONNECTION_VERSION_MAX); + SSLVersion version = + SSLConnectionStatusToVersion(ssl_info.connection_status); + UMA_HISTOGRAM_ENUMERATION("Net.SSLVersion", version, + SSL_CONNECTION_VERSION_MAX); + if (IsGoogleHost(host)) { + // Google hosts all support TLS 1.2, so any occurrences of TLS 1.0 or TLS + // 1.1 will be from an outdated insecure TLS MITM proxy, such as some + // antivirus configurations. TLS 1.0 and 1.1 are deprecated, so record + // these to see how prevalent they are. See https://crbug.com/896013. + UMA_HISTOGRAM_ENUMERATION("Net.SSLVersionGoogle", version, + SSL_CONNECTION_VERSION_MAX); + } uint16_t cipher_suite = SSLConnectionStatusToCipherSuite(ssl_info.connection_status); @@ -429,14 +427,10 @@ int SSLConnectJob::DoSSLConnectComplete(int result) { } } - // Don't double-count the version interference probes. - if (!params_->ssl_config().version_interference_probe) { - base::UmaHistogramSparse("Net.SSL_Connection_Error", std::abs(result)); - - if (tls13_supported) { - base::UmaHistogramSparse("Net.SSL_Connection_Error_TLS13Experiment", - std::abs(result)); - } + base::UmaHistogramSparse("Net.SSL_Connection_Error", std::abs(result)); + if (tls13_supported) { + base::UmaHistogramSparse("Net.SSL_Connection_Error_TLS13Experiment", + std::abs(result)); } if (result == OK || IsCertificateError(result)) { diff --git a/chromium/net/socket/ssl_connect_job.h b/chromium/net/socket/ssl_connect_job.h index 8ed4480996e..bc198867b4f 100644 --- a/chromium/net/socket/ssl_connect_job.h +++ b/chromium/net/socket/ssl_connect_job.h @@ -100,7 +100,6 @@ class NET_EXPORT_PRIVATE SSLConnectJob : public ConnectJob, base::OnceClosure restart_with_auth_callback, ConnectJob* job) override; ConnectionAttempts GetConnectionAttempts() const override; - std::unique_ptr<StreamSocket> PassProxySocketOnFailure() override; bool IsSSLError() const override; scoped_refptr<SSLCertRequestInfo> GetCertRequestInfo() override; @@ -159,9 +158,6 @@ class NET_EXPORT_PRIVATE SSLConnectJob : public ConnectJob, scoped_refptr<SSLCertRequestInfo> ssl_cert_request_info_; - // True if a proxy returned a redirect, resulting in an error. - bool proxy_redirect_; - ConnectionAttempts connection_attempts_; // The address of the server the connect job is connected to. Populated if // and only if the connect job is connected *directly* to the server (not diff --git a/chromium/net/socket/ssl_connect_job_unittest.cc b/chromium/net/socket/ssl_connect_job_unittest.cc index 801dda718b6..799d2325c70 100644 --- a/chromium/net/socket/ssl_connect_job_unittest.cc +++ b/chromium/net/socket/ssl_connect_job_unittest.cc @@ -17,6 +17,7 @@ #include "net/base/auth.h" #include "net/base/load_timing_info.h" #include "net/base/net_errors.h" +#include "net/base/network_isolation_key.h" #include "net/cert/ct_policy_enforcer.h" #include "net/cert/mock_cert_verifier.h" #include "net/cert/multi_log_ct_verifier.h" @@ -107,7 +108,8 @@ class SSLConnectJobTest : public WithScopedTaskEnvironment, HostPortPair("host", 80), /*is_trusted_proxy=*/false, /*tunnel=*/true, - TRAFFIC_ANNOTATION_FOR_TESTS)), + TRAFFIC_ANNOTATION_FOR_TESTS, + NetworkIsolationKey())), common_connect_job_params_(session_->CreateCommonConnectJobParams()) { ssl_config_service_->GetSSLConfig(&ssl_config_); diff --git a/chromium/net/socket/tcp_client_socket.cc b/chromium/net/socket/tcp_client_socket.cc index 7f0af9aed4c..c6970172beb 100644 --- a/chromium/net/socket/tcp_client_socket.cc +++ b/chromium/net/socket/tcp_client_socket.cc @@ -18,6 +18,10 @@ #include "net/socket/socket_performance_watcher.h" #include "net/traffic_annotation/network_traffic_annotation.h" +#if defined(TCP_CLIENT_SOCKET_OBSERVES_SUSPEND) +#include "base/power_monitor/power_monitor.h" +#endif + namespace net { class NetLogWithSource; @@ -44,6 +48,11 @@ TCPClientSocket::TCPClientSocket(std::unique_ptr<TCPSocket> connected_socket, TCPClientSocket::~TCPClientSocket() { Disconnect(); +#if defined(TCP_CLIENT_SOCKET_OBSERVES_SUSPEND) + base::PowerMonitor* power_monitor = base::PowerMonitor::Get(); + if (power_monitor) + power_monitor->RemoveObserver(this); +#endif // defined(TCP_CLIENT_SOCKET_OBSERVES_SUSPEND) } std::unique_ptr<TCPClientSocket> TCPClientSocket::CreateFromBoundSocket( @@ -98,6 +107,14 @@ int TCPClientSocket::Connect(CompletionOnceCallback callback) { if (socket_->IsValid() && current_address_index_ >= 0) return OK; + DCHECK(!read_callback_); + DCHECK(!write_callback_); + + if (was_disconnected_on_suspend_) { + Disconnect(); + was_disconnected_on_suspend_ = false; + } + socket_->StartLoggingMultipleConnectAttempts(addresses_); // We will try to connect to each address in addresses_. Start with the @@ -126,10 +143,17 @@ TCPClientSocket::TCPClientSocket(std::unique_ptr<TCPSocket> socket, next_connect_state_(CONNECT_STATE_NONE), previously_disconnected_(false), total_received_bytes_(0), - was_ever_used_(false) { + was_ever_used_(false), + was_disconnected_on_suspend_(false), + weak_ptr_factory_(this) { DCHECK(socket_); if (socket_->IsValid()) socket_->SetDefaultOptionsForClient(); +#if defined(TCP_CLIENT_SOCKET_OBSERVES_SUSPEND) + base::PowerMonitor* power_monitor = base::PowerMonitor::Get(); + if (power_monitor) + power_monitor->AddObserver(this); +#endif // defined(TCP_CLIENT_SOCKET_OBSERVES_SUSPEND) } int TCPClientSocket::ReadCommon(IOBuffer* buf, @@ -137,17 +161,23 @@ int TCPClientSocket::ReadCommon(IOBuffer* buf, CompletionOnceCallback callback, bool read_if_ready) { DCHECK(!callback.is_null()); + DCHECK(read_callback_.is_null()); + + if (was_disconnected_on_suspend_) + return ERR_NETWORK_IO_SUSPENDED; // |socket_| is owned by |this| and the callback won't be run once |socket_| // is gone/closed. Therefore, it is safe to use base::Unretained() here. - CompletionOnceCallback read_callback = - base::BindOnce(&TCPClientSocket::DidCompleteRead, base::Unretained(this), - std::move(callback)); + CompletionOnceCallback complete_read_callback = + base::BindOnce(&TCPClientSocket::DidCompleteRead, base::Unretained(this)); int result = read_if_ready - ? socket_->ReadIfReady(buf, buf_len, std::move(read_callback)) - : socket_->Read(buf, buf_len, std::move(read_callback)); - if (result > 0) { + ? socket_->ReadIfReady(buf, buf_len, + std::move(complete_read_callback)) + : socket_->Read(buf, buf_len, std::move(complete_read_callback)); + if (result == ERR_IO_PENDING) { + read_callback_ = std::move(callback); + } else if (result > 0) { was_ever_used_ = true; total_received_bytes_ += result; } @@ -222,11 +252,7 @@ int TCPClientSocket::DoConnect() { if (socket_->socket_performance_watcher() && current_address_index_ != 0) socket_->socket_performance_watcher()->OnConnectionChanged(); - // |socket_| is owned by this class and the callback won't be run once - // |socket_| is gone. Therefore, it is safe to use base::Unretained() here. - return socket_->Connect(endpoint, - base::Bind(&TCPClientSocket::DidCompleteConnect, - base::Unretained(this))); + return ConnectInternal(endpoint); } int TCPClientSocket::DoConnectComplete(int result) { @@ -236,6 +262,10 @@ int TCPClientSocket::DoConnectComplete(int result) { connection_attempts_.push_back( ConnectionAttempt(addresses_[current_address_index_], result)); + // Don't try the next address if entering suspend mode. + if (result == ERR_NETWORK_IO_SUSPENDED) + return result; + // Close whatever partially connected socket we currently have. DoDisconnect(); @@ -250,19 +280,40 @@ int TCPClientSocket::DoConnectComplete(int result) { return result; } +int TCPClientSocket::ConnectInternal(const IPEndPoint& endpoint) { + // |socket_| is owned by this class and the callback won't be run once + // |socket_| is gone. Therefore, it is safe to use base::Unretained() here. + return socket_->Connect(endpoint, + base::BindOnce(&TCPClientSocket::DidCompleteConnect, + base::Unretained(this))); +} + void TCPClientSocket::Disconnect() { DoDisconnect(); current_address_index_ = -1; bind_address_.reset(); + + // Cancel any pending callbacks. Not done in DoDisconnect() because that's + // called on connection failure, when the connect callback will need to be + // invoked. + was_disconnected_on_suspend_ = false; + connect_callback_.Reset(); + read_callback_.Reset(); + write_callback_.Reset(); } void TCPClientSocket::DoDisconnect() { total_received_bytes_ = 0; EmitTCPMetricsHistogramsOnDisconnect(); + // If connecting or already connected, record that the socket has been // disconnected. previously_disconnected_ = socket_->IsValid() && current_address_index_ >= 0; socket_->Close(); + + // Invalidate weak pointers, so if in the middle of a callback in OnSuspend, + // and something destroys this, no other callback is invoked. + weak_ptr_factory_.InvalidateWeakPtrs(); } bool TCPClientSocket::IsConnected() const { @@ -324,6 +375,8 @@ int TCPClientSocket::ReadIfReady(IOBuffer* buf, } int TCPClientSocket::CancelReadIfReady() { + DCHECK(read_callback_); + read_callback_.Reset(); return socket_->CancelReadIfReady(); } @@ -333,16 +386,22 @@ int TCPClientSocket::Write( CompletionOnceCallback callback, const NetworkTrafficAnnotationTag& traffic_annotation) { DCHECK(!callback.is_null()); + DCHECK(write_callback_.is_null()); + + if (was_disconnected_on_suspend_) + return ERR_NETWORK_IO_SUSPENDED; // |socket_| is owned by this class and the callback won't be run once // |socket_| is gone. Therefore, it is safe to use base::Unretained() here. - CompletionOnceCallback write_callback = - base::BindOnce(&TCPClientSocket::DidCompleteWrite, base::Unretained(this), - std::move(callback)); - int result = socket_->Write(buf, buf_len, std::move(write_callback), + CompletionOnceCallback complete_write_callback = base::BindOnce( + &TCPClientSocket::DidCompleteWrite, base::Unretained(this)); + int result = socket_->Write(buf, buf_len, std::move(complete_write_callback), traffic_annotation); - if (result > 0) + if (result == ERR_IO_PENDING) { + write_callback_ = std::move(callback); + } else if (result > 0) { was_ever_used_ = true; + } return result; } @@ -352,7 +411,7 @@ int TCPClientSocket::SetReceiveBufferSize(int32_t size) { } int TCPClientSocket::SetSendBufferSize(int32_t size) { - return socket_->SetSendBufferSize(size); + return socket_->SetSendBufferSize(size); } SocketDescriptor TCPClientSocket::SocketDescriptorForTesting() const { @@ -381,6 +440,48 @@ void TCPClientSocket::ApplySocketTag(const SocketTag& tag) { socket_->ApplySocketTag(tag); } +void TCPClientSocket::OnSuspend() { +#if defined(TCP_CLIENT_SOCKET_OBSERVES_SUSPEND) + // If the socket is connected, or connecting, act as if current and future + // operations on the socket fail with ERR_NETWORK_IO_SUSPENDED, until the + // socket is reconnected. + + if (next_connect_state_ != CONNECT_STATE_NONE) { + socket_->Close(); + DidCompleteConnect(ERR_NETWORK_IO_SUSPENDED); + return; + } + + // Nothing to do. Use IsValid() rather than IsConnected() because it results + // in more testable code, as when calling OnSuspend mode on two sockets + // connected to each other will otherwise cause two sockets to behave + // differently from each other. + if (!socket_->IsValid()) + return; + + // Use Close() rather than Disconnect() / DoDisconnect() to avoid mutating + // state, which more closely matches normal read/write error behavior. + socket_->Close(); + + was_disconnected_on_suspend_ = true; + + // Grab a weak pointer just in case calling read callback results in |this| + // being destroyed, or disconnected. In either case, should not run the write + // callback. + base::WeakPtr<TCPClientSocket> weak_this = weak_ptr_factory_.GetWeakPtr(); + + // Have to grab the write callback now, as it's theoretically possible for the + // read callback to reconnects the socket, that reconnection to complete + // synchronously, and then for it to start a new write. That also means this + // code can't use DidCompleteWrite(). + CompletionOnceCallback write_callback = std::move(write_callback_); + if (read_callback_) + DidCompleteRead(ERR_NETWORK_IO_SUSPENDED); + if (weak_this && write_callback) + std::move(write_callback).Run(ERR_NETWORK_IO_SUSPENDED); +#endif // defined(TCP_CLIENT_SOCKET_OBSERVES_SUSPEND) +} + void TCPClientSocket::DidCompleteConnect(int result) { DCHECK_EQ(next_connect_state_, CONNECT_STATE_CONNECT_COMPLETE); DCHECK_NE(result, ERR_IO_PENDING); @@ -393,17 +494,18 @@ void TCPClientSocket::DidCompleteConnect(int result) { } } -void TCPClientSocket::DidCompleteRead(CompletionOnceCallback callback, - int result) { +void TCPClientSocket::DidCompleteRead(int result) { + DCHECK(!read_callback_.is_null()); + if (result > 0) total_received_bytes_ += result; - - DidCompleteReadWrite(std::move(callback), result); + DidCompleteReadWrite(std::move(read_callback_), result); } -void TCPClientSocket::DidCompleteWrite(CompletionOnceCallback callback, - int result) { - DidCompleteReadWrite(std::move(callback), result); +void TCPClientSocket::DidCompleteWrite(int result) { + DCHECK(!write_callback_.is_null()); + + DidCompleteReadWrite(std::move(write_callback_), result); } void TCPClientSocket::DidCompleteReadWrite(CompletionOnceCallback callback, diff --git a/chromium/net/socket/tcp_client_socket.h b/chromium/net/socket/tcp_client_socket.h index 8b6aa30dae0..1bf00384458 100644 --- a/chromium/net/socket/tcp_client_socket.h +++ b/chromium/net/socket/tcp_client_socket.h @@ -11,6 +11,9 @@ #include "base/compiler_specific.h" #include "base/macros.h" +#include "base/memory/weak_ptr.h" +#include "base/power_monitor/power_observer.h" +#include "build/build_config.h" #include "net/base/address_list.h" #include "net/base/completion_once_callback.h" #include "net/base/net_export.h" @@ -21,14 +24,30 @@ #include "net/socket/transport_client_socket.h" #include "net/traffic_annotation/network_traffic_annotation.h" +// PowerMonitor exists on Android, but doesn't get suspend mode signals. It +// doesn't exist in NaCl, so don't use it to watch for suspend events on those +// platforms. +#if !defined(OS_ANDROID) && !defined(OS_NACL) +// Define SOCKETS_OBSERVE_SUSPEND if sockets should watch for suspend events so +// they can fail pending socket operations on suspend. Otherwise, connections +// hang for varying lengths of time when leaving suspend mode before failing +// with TCP keepalive errors (~1 minute on macOS 10.14, up to several minutes on +// Windows 10 1803). Firefox doesn't seems to need this logic, for unclear +// reasons (experimentally, it doesn't seem to be the differences in the keep +// alive settings it sets TCP sockets). +#define TCP_CLIENT_SOCKET_OBSERVES_SUSPEND +#endif + namespace net { +class IPEndPoint; class NetLog; struct NetLogSource; class SocketPerformanceWatcher; // A client socket that uses TCP as the transport layer. -class NET_EXPORT TCPClientSocket : public TransportClientSocket { +class NET_EXPORT TCPClientSocket : public TransportClientSocket, + public base::PowerObserver { public: // The IP address(es) and port number to connect to. The TCP socket will try // each IP address in the list until it succeeds in establishing a @@ -98,6 +117,9 @@ class NET_EXPORT TCPClientSocket : public TransportClientSocket { // release ownership of the descriptor. SocketDescriptor SocketDescriptorForTesting() const; + // base::PowerObserver methods: + void OnSuspend() override; + private: // State machine for connecting the socket. enum ConnectState { @@ -127,13 +149,17 @@ class NET_EXPORT TCPClientSocket : public TransportClientSocket { int DoConnect(); int DoConnectComplete(int result); + // Calls the connect method of |socket_|. Used in tests, to ensure a socket + // never connects. + virtual int ConnectInternal(const IPEndPoint& endpoint); + // Helper used by Disconnect(), which disconnects minus resetting // current_address_index_ and bind_address_. void DoDisconnect(); void DidCompleteConnect(int result); - void DidCompleteRead(CompletionOnceCallback callback, int result); - void DidCompleteWrite(CompletionOnceCallback callback, int result); + void DidCompleteRead(int result); + void DidCompleteWrite(int result); void DidCompleteReadWrite(CompletionOnceCallback callback, int result); int OpenSocket(AddressFamily family); @@ -154,8 +180,11 @@ class NET_EXPORT TCPClientSocket : public TransportClientSocket { // Where we are in above list. Set to -1 if uninitialized. int current_address_index_; - // External callback; called when connect is complete. + // External callbacks; called when corresponding operations are complete. + // Cleared when no such operation is pending. CompletionOnceCallback connect_callback_; + CompletionOnceCallback read_callback_; + CompletionOnceCallback write_callback_; // The next state for the Connect() state machine. ConnectState next_connect_state_; @@ -173,6 +202,13 @@ class NET_EXPORT TCPClientSocket : public TransportClientSocket { bool was_ever_used_; + // Set to true if the socket was disconnected due to entering suspend mode. + // Once set, read/write operations return ERR_NETWORK_IO_SUSPENDED, until + // Connect() or Disconnect() is called. + bool was_disconnected_on_suspend_; + + base::WeakPtrFactory<TCPClientSocket> weak_ptr_factory_; + DISALLOW_COPY_AND_ASSIGN(TCPClientSocket); }; diff --git a/chromium/net/socket/tcp_client_socket_unittest.cc b/chromium/net/socket/tcp_client_socket_unittest.cc index 60508c3b7b8..d2268247d92 100644 --- a/chromium/net/socket/tcp_client_socket_unittest.cc +++ b/chromium/net/socket/tcp_client_socket_unittest.cc @@ -10,6 +10,9 @@ #include <stddef.h> +#include "base/power_monitor/power_monitor.h" +#include "base/power_monitor/power_monitor_source.h" +#include "base/test/bind_test_util.h" #include "base/test/scoped_task_environment.h" #include "build/build_config.h" #include "net/base/ip_address.h" @@ -26,6 +29,13 @@ #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" +// This matches logic in tcp_client_socket.cc. Only used once, but defining it +// in this file instead of just inlining the OS checks where its used makes it +// more grep-able. +#if !defined(OS_ANDROID) && !defined(OS_NACL) +#define TCP_CLIENT_SOCKET_OBSERVES_SUSPEND +#endif + using net::test::IsError; using net::test::IsOk; using testing::Not; @@ -38,12 +48,89 @@ namespace net { namespace { +// Test power monitor source that can simulate entering suspend mode. Can't use +// the one in base/ because it insists on bringing its own MessageLoop. +class TestPowerMonitorSource : public base::PowerMonitorSource { + public: + TestPowerMonitorSource() = default; + ~TestPowerMonitorSource() override = default; + + void Shutdown() override {} + + void Suspend() { ProcessPowerEvent(SUSPEND_EVENT); } + + void Resume() { ProcessPowerEvent(RESUME_EVENT); } + + bool IsOnBatteryPowerImpl() override { return false; } + + private: + DISALLOW_COPY_AND_ASSIGN(TestPowerMonitorSource); +}; + +class TCPClientSocketTest : public testing::Test { + public: + TCPClientSocketTest() + : scoped_task_environment_( + base::test::ScopedTaskEnvironment::MainThreadType::IO) { + std::unique_ptr<TestPowerMonitorSource> power_monitor_source = + std::make_unique<TestPowerMonitorSource>(); + power_monitor_source_ = power_monitor_source.get(); + power_monitor_ = + std::make_unique<base::PowerMonitor>(std::move(power_monitor_source)); + } + + void Suspend() { power_monitor_source_->Suspend(); } + void Resume() { power_monitor_source_->Resume(); } + + void CreateConnectedSockets( + std::unique_ptr<StreamSocket>* accepted_socket, + std::unique_ptr<TCPClientSocket>* client_socket, + std::unique_ptr<ServerSocket>* server_socket_opt = nullptr) { + IPAddress local_address = IPAddress::IPv4Localhost(); + + std::unique_ptr<TCPServerSocket> server_socket = + std::make_unique<TCPServerSocket>(nullptr, NetLogSource()); + ASSERT_THAT(server_socket->Listen(IPEndPoint(local_address, 0), 1), IsOk()); + IPEndPoint server_address; + ASSERT_THAT(server_socket->GetLocalAddress(&server_address), IsOk()); + + *client_socket = std::make_unique<TCPClientSocket>( + AddressList(server_address), nullptr, nullptr, NetLogSource()); + + EXPECT_THAT((*client_socket)->Bind(IPEndPoint(local_address, 0)), IsOk()); + + IPEndPoint local_address_result; + EXPECT_THAT((*client_socket)->GetLocalAddress(&local_address_result), + IsOk()); + EXPECT_EQ(local_address, local_address_result.address()); + + TestCompletionCallback connect_callback; + int connect_result = (*client_socket)->Connect(connect_callback.callback()); + + TestCompletionCallback accept_callback; + int result = + server_socket->Accept(accepted_socket, accept_callback.callback()); + result = accept_callback.GetResult(result); + ASSERT_THAT(result, IsOk()); + + ASSERT_THAT(connect_callback.GetResult(connect_result), IsOk()); + + EXPECT_TRUE((*client_socket)->IsConnected()); + EXPECT_TRUE((*accepted_socket)->IsConnected()); + if (server_socket_opt) + *server_socket_opt = std::move(server_socket); + } + + private: + base::test::ScopedTaskEnvironment scoped_task_environment_; + + std::unique_ptr<base::PowerMonitor> power_monitor_; + TestPowerMonitorSource* power_monitor_source_; +}; + // Try binding a socket to loopback interface and verify that we can // still connect to a server on the same interface. -TEST(TCPClientSocketTest, BindLoopbackToLoopback) { - base::test::ScopedTaskEnvironment scoped_task_environment( - base::test::ScopedTaskEnvironment::MainThreadType::IO); - +TEST_F(TCPClientSocketTest, BindLoopbackToLoopback) { IPAddress lo_address = IPAddress::IPv4Localhost(); TCPServerSocket server(nullptr, NetLogSource()); @@ -80,10 +167,7 @@ TEST(TCPClientSocketTest, BindLoopbackToLoopback) { // Try to bind socket to the loopback interface and connect to an // external address, verify that connection fails. -TEST(TCPClientSocketTest, BindLoopbackToExternal) { - base::test::ScopedTaskEnvironment scoped_task_environment( - base::test::ScopedTaskEnvironment::MainThreadType::IO); - +TEST_F(TCPClientSocketTest, BindLoopbackToExternal) { IPAddress external_ip(72, 14, 213, 105); TCPClientSocket socket(AddressList::CreateFromIPAddress(external_ip, 80), nullptr, nullptr, NetLogSource()); @@ -100,13 +184,13 @@ TEST(TCPClientSocketTest, BindLoopbackToExternal) { // Bind a socket to the IPv4 loopback interface and try to connect to // the IPv6 loopback interface, verify that connection fails. -TEST(TCPClientSocketTest, BindLoopbackToIPv6) { +TEST_F(TCPClientSocketTest, BindLoopbackToIPv6) { TCPServerSocket server(nullptr, NetLogSource()); int listen_result = server.Listen(IPEndPoint(IPAddress::IPv6Localhost(), 0), 1); if (listen_result != OK) { LOG(ERROR) << "Failed to listen on ::1 - probably because IPv6 is disabled." - " Skipping the test"; + " Skipping the test"; return; } @@ -123,10 +207,7 @@ TEST(TCPClientSocketTest, BindLoopbackToIPv6) { EXPECT_THAT(connect_callback.GetResult(result), Not(IsOk())); } -TEST(TCPClientSocketTest, WasEverUsed) { - base::test::ScopedTaskEnvironment scoped_task_environment( - base::test::ScopedTaskEnvironment::MainThreadType::IO); - +TEST_F(TCPClientSocketTest, WasEverUsed) { IPAddress lo_address = IPAddress::IPv4Localhost(); TCPServerSocket server(nullptr, NetLogSource()); ASSERT_THAT(server.Listen(IPEndPoint(lo_address, 0), 1), IsOk()); @@ -201,7 +282,7 @@ class TestSocketPerformanceWatcher : public SocketPerformanceWatcher { #endif // Tests if the socket performance watcher is notified if the same socket is // used for a different connection. -TEST(TCPClientSocketTest, MAYBE_TestSocketPerformanceWatcher) { +TEST_F(TCPClientSocketTest, MAYBE_TestSocketPerformanceWatcher) { const size_t kNumIPs = 2; IPAddressList ip_list; for (size_t i = 0; i < kNumIPs; ++i) @@ -228,15 +309,12 @@ TEST(TCPClientSocketTest, MAYBE_TestSocketPerformanceWatcher) { // On Android, where socket tagging is supported, verify that // TCPClientSocket::Tag works as expected. #if defined(OS_ANDROID) -TEST(TCPClientSocketTest, Tag) { +TEST_F(TCPClientSocketTest, Tag) { if (!CanGetTaggedBytes()) { DVLOG(0) << "Skipping test - GetTaggedBytes unsupported."; return; } - base::test::ScopedTaskEnvironment scoped_task_environment( - base::test::ScopedTaskEnvironment::MainThreadType::IO); - // Start test server. EmbeddedTestServer test_server; test_server.AddDefaultHandlers(base::FilePath()); @@ -288,15 +366,12 @@ TEST(TCPClientSocketTest, Tag) { s.Disconnect(); } -TEST(TCPClientSocketTest, TagAfterConnect) { +TEST_F(TCPClientSocketTest, TagAfterConnect) { if (!CanGetTaggedBytes()) { DVLOG(0) << "Skipping test - GetTaggedBytes unsupported."; return; } - base::test::ScopedTaskEnvironment scoped_task_environment( - base::test::ScopedTaskEnvironment::MainThreadType::IO); - // Start test server. EmbeddedTestServer test_server; test_server.AddDefaultHandlers(base::FilePath()); @@ -343,7 +418,338 @@ TEST(TCPClientSocketTest, TagAfterConnect) { s.Disconnect(); } -#endif +#endif // defined(OS_ANDROID) + +// Tests for closing sockets on suspend mode. +#if defined(TCP_CLIENT_SOCKET_OBSERVES_SUSPEND) + +// Entering suspend mode shouldn't affect sockets that haven't connected yet, or +// listening server sockets. +TEST_F(TCPClientSocketTest, SuspendBeforeConnect) { + IPAddress lo_address = IPAddress::IPv4Localhost(); + + TCPServerSocket server(nullptr, NetLogSource()); + ASSERT_THAT(server.Listen(IPEndPoint(lo_address, 0), 1), IsOk()); + IPEndPoint server_address; + ASSERT_THAT(server.GetLocalAddress(&server_address), IsOk()); + + TCPClientSocket socket(AddressList(server_address), nullptr, nullptr, + NetLogSource()); + + EXPECT_THAT(socket.Bind(IPEndPoint(lo_address, 0)), IsOk()); + + IPEndPoint local_address_result; + EXPECT_THAT(socket.GetLocalAddress(&local_address_result), IsOk()); + EXPECT_EQ(lo_address, local_address_result.address()); + + TestCompletionCallback accept_callback; + std::unique_ptr<StreamSocket> accepted_socket; + ASSERT_THAT(server.Accept(&accepted_socket, accept_callback.callback()), + IsError(ERR_IO_PENDING)); + + Suspend(); + // Power notifications happen asynchronously, so have to wait for the socket + // to be notified of the suspend event. + base::RunLoop().RunUntilIdle(); + + TestCompletionCallback connect_callback; + int connect_result = socket.Connect(connect_callback.callback()); + + ASSERT_THAT(accept_callback.WaitForResult(), IsOk()); + + ASSERT_THAT(connect_callback.GetResult(connect_result), IsOk()); + + EXPECT_TRUE(socket.IsConnected()); + EXPECT_TRUE(accepted_socket->IsConnected()); +} + +// TCP socket that hangs when establishing a connection. This is needed to make +// sure establishing a connection doesn't succeed synchronously. +class NeverConnectingTCPClientSocket : public TCPClientSocket { + public: + NeverConnectingTCPClientSocket( + const AddressList& addresses, + std::unique_ptr<SocketPerformanceWatcher> socket_performance_watcher, + net::NetLog* net_log, + const net::NetLogSource& source) + : TCPClientSocket(addresses, + std::move(socket_performance_watcher), + net_log, + source) {} + + private: + int ConnectInternal(const IPEndPoint& endpoint) override { + return ERR_IO_PENDING; + } +}; + +TEST_F(TCPClientSocketTest, SuspendDuringConnect) { + IPAddress lo_address = IPAddress::IPv4Localhost(); + + TCPServerSocket server(nullptr, NetLogSource()); + ASSERT_THAT(server.Listen(IPEndPoint(lo_address, 0), 1), IsOk()); + IPEndPoint server_address; + ASSERT_THAT(server.GetLocalAddress(&server_address), IsOk()); + + NeverConnectingTCPClientSocket socket(AddressList(server_address), nullptr, + nullptr, NetLogSource()); + + EXPECT_THAT(socket.Bind(IPEndPoint(lo_address, 0)), IsOk()); + + IPEndPoint local_address_result; + EXPECT_THAT(socket.GetLocalAddress(&local_address_result), IsOk()); + EXPECT_EQ(lo_address, local_address_result.address()); + + TestCompletionCallback connect_callback; + int rv = socket.Connect(connect_callback.callback()); + ASSERT_THAT(rv, IsError(ERR_IO_PENDING)); + Suspend(); + EXPECT_THAT(connect_callback.WaitForResult(), + IsError(ERR_NETWORK_IO_SUSPENDED)); +} + +TEST_F(TCPClientSocketTest, SuspendDuringConnectMultipleAddresses) { + IPAddress lo_address = IPAddress::IPv4Localhost(); + + TCPServerSocket server(nullptr, NetLogSource()); + ASSERT_THAT(server.Listen(IPEndPoint(IPAddress(0, 0, 0, 0), 0), 1), IsOk()); + IPEndPoint server_address; + ASSERT_THAT(server.GetLocalAddress(&server_address), IsOk()); + + AddressList address_list; + address_list.push_back( + IPEndPoint(IPAddress(127, 0, 0, 1), server_address.port())); + address_list.push_back( + IPEndPoint(IPAddress(127, 0, 0, 2), server_address.port())); + NeverConnectingTCPClientSocket socket(address_list, nullptr, nullptr, + NetLogSource()); + + EXPECT_THAT(socket.Bind(IPEndPoint(lo_address, 0)), IsOk()); + + IPEndPoint local_address_result; + EXPECT_THAT(socket.GetLocalAddress(&local_address_result), IsOk()); + EXPECT_EQ(lo_address, local_address_result.address()); + + TestCompletionCallback connect_callback; + int rv = socket.Connect(connect_callback.callback()); + ASSERT_THAT(rv, IsError(ERR_IO_PENDING)); + Suspend(); + EXPECT_THAT(connect_callback.WaitForResult(), + IsError(ERR_NETWORK_IO_SUSPENDED)); +} + +TEST_F(TCPClientSocketTest, SuspendWhileIdle) { + std::unique_ptr<StreamSocket> accepted_socket; + std::unique_ptr<TCPClientSocket> client_socket; + std::unique_ptr<ServerSocket> server_socket; + CreateConnectedSockets(&accepted_socket, &client_socket, &server_socket); + + Suspend(); + // Power notifications happen asynchronously. + base::RunLoop().RunUntilIdle(); + + scoped_refptr<IOBuffer> buffer = base::MakeRefCounted<IOBuffer>(1); + buffer->data()[0] = '1'; + TestCompletionCallback callback; + // Check that the client socket is disconnected, and actions fail with + // ERR_NETWORK_IO_SUSPENDED. + EXPECT_FALSE(client_socket->IsConnected()); + EXPECT_THAT(client_socket->Read(buffer.get(), 1, callback.callback()), + IsError(ERR_NETWORK_IO_SUSPENDED)); + EXPECT_THAT(client_socket->Write(buffer.get(), 1, callback.callback(), + TRAFFIC_ANNOTATION_FOR_TESTS), + IsError(ERR_NETWORK_IO_SUSPENDED)); + + // Check that the accepted socket is disconnected, and actions fail with + // ERR_NETWORK_IO_SUSPENDED. + EXPECT_FALSE(accepted_socket->IsConnected()); + EXPECT_THAT(accepted_socket->Read(buffer.get(), 1, callback.callback()), + IsError(ERR_NETWORK_IO_SUSPENDED)); + EXPECT_THAT(accepted_socket->Write(buffer.get(), 1, callback.callback(), + TRAFFIC_ANNOTATION_FOR_TESTS), + IsError(ERR_NETWORK_IO_SUSPENDED)); + + // Reconnecting the socket should work. + TestCompletionCallback connect_callback; + int connect_result = client_socket->Connect(connect_callback.callback()); + accepted_socket.reset(); + TestCompletionCallback accept_callback; + int accept_result = + server_socket->Accept(&accepted_socket, accept_callback.callback()); + ASSERT_THAT(accept_callback.GetResult(accept_result), IsOk()); + EXPECT_THAT(connect_callback.GetResult(connect_result), IsOk()); +} + +TEST_F(TCPClientSocketTest, SuspendDuringRead) { + std::unique_ptr<StreamSocket> accepted_socket; + std::unique_ptr<TCPClientSocket> client_socket; + CreateConnectedSockets(&accepted_socket, &client_socket); + + // Start a read. This shouldn't complete, since the other end of the pipe + // writes no data. + scoped_refptr<IOBuffer> read_buffer = base::MakeRefCounted<IOBuffer>(1); + read_buffer->data()[0] = '1'; + TestCompletionCallback callback; + ASSERT_THAT(client_socket->Read(read_buffer.get(), 1, callback.callback()), + IsError(ERR_IO_PENDING)); + + // Simulate a suspend event. Can't use a real power event, as it would affect + // |accepted_socket| as well. + client_socket->OnSuspend(); + EXPECT_THAT(callback.WaitForResult(), IsError(ERR_NETWORK_IO_SUSPENDED)); + + // Check that the client socket really is disconnected. + EXPECT_FALSE(client_socket->IsConnected()); + EXPECT_THAT(client_socket->Read(read_buffer.get(), 1, callback.callback()), + IsError(ERR_NETWORK_IO_SUSPENDED)); + EXPECT_THAT(client_socket->Write(read_buffer.get(), 1, callback.callback(), + TRAFFIC_ANNOTATION_FOR_TESTS), + IsError(ERR_NETWORK_IO_SUSPENDED)); +} + +TEST_F(TCPClientSocketTest, SuspendDuringWrite) { + std::unique_ptr<StreamSocket> accepted_socket; + std::unique_ptr<TCPClientSocket> client_socket; + CreateConnectedSockets(&accepted_socket, &client_socket); + + // Write to the socket until a write doesn't complete synchronously. + const int kBufferSize = 4096; + scoped_refptr<IOBuffer> write_buffer = + base::MakeRefCounted<IOBuffer>(kBufferSize); + memset(write_buffer->data(), '1', kBufferSize); + TestCompletionCallback callback; + while (true) { + int rv = + client_socket->Write(write_buffer.get(), kBufferSize, + callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS); + if (rv == ERR_IO_PENDING) + break; + ASSERT_GT(rv, 0); + } + + // Simulate a suspend event. Can't use a real power event, as it would affect + // |accepted_socket| as well. + client_socket->OnSuspend(); + EXPECT_THAT(callback.WaitForResult(), IsError(ERR_NETWORK_IO_SUSPENDED)); + + // Check that the client socket really is disconnected. + EXPECT_FALSE(client_socket->IsConnected()); + EXPECT_THAT(client_socket->Read(write_buffer.get(), 1, callback.callback()), + IsError(ERR_NETWORK_IO_SUSPENDED)); + EXPECT_THAT(client_socket->Write(write_buffer.get(), 1, callback.callback(), + TRAFFIC_ANNOTATION_FOR_TESTS), + IsError(ERR_NETWORK_IO_SUSPENDED)); +} + +TEST_F(TCPClientSocketTest, SuspendDuringReadAndWrite) { + enum class ReadCallbackAction { + kNone, + kDestroySocket, + kDisconnectSocket, + kReconnectSocket, + }; + + for (ReadCallbackAction read_callback_action : { + ReadCallbackAction::kNone, + ReadCallbackAction::kDestroySocket, + ReadCallbackAction::kDisconnectSocket, + ReadCallbackAction::kReconnectSocket, + }) { + std::unique_ptr<StreamSocket> accepted_socket; + std::unique_ptr<TCPClientSocket> client_socket; + std::unique_ptr<ServerSocket> server_socket; + CreateConnectedSockets(&accepted_socket, &client_socket, &server_socket); + + // Start a read. This shouldn't complete, since the other end of the pipe + // writes no data. + scoped_refptr<IOBuffer> read_buffer = base::MakeRefCounted<IOBuffer>(1); + read_buffer->data()[0] = '1'; + TestCompletionCallback read_callback; + + // Used int the ReadCallbackAction::kReconnectSocket case, since can't run a + // nested message loop in the read callback. + TestCompletionCallback nested_connect_callback; + int nested_connect_result; + + CompletionOnceCallback read_completion_once_callback = + base::BindLambdaForTesting([&](int result) { + EXPECT_FALSE(client_socket->IsConnected()); + switch (read_callback_action) { + case ReadCallbackAction::kNone: + break; + case ReadCallbackAction::kDestroySocket: + client_socket.reset(); + break; + case ReadCallbackAction::kDisconnectSocket: + client_socket->Disconnect(); + break; + case ReadCallbackAction::kReconnectSocket: { + TestCompletionCallback connect_callback; + nested_connect_result = + client_socket->Connect(nested_connect_callback.callback()); + break; + } + } + read_callback.callback().Run(result); + }); + ASSERT_THAT(client_socket->Read(read_buffer.get(), 1, + std::move(read_completion_once_callback)), + IsError(ERR_IO_PENDING)); + + // Write to the socket until a write doesn't complete synchronously. + const int kBufferSize = 4096; + scoped_refptr<IOBuffer> write_buffer = + base::MakeRefCounted<IOBuffer>(kBufferSize); + memset(write_buffer->data(), '1', kBufferSize); + TestCompletionCallback write_callback; + while (true) { + int rv = client_socket->Write(write_buffer.get(), kBufferSize, + write_callback.callback(), + TRAFFIC_ANNOTATION_FOR_TESTS); + if (rv == ERR_IO_PENDING) + break; + ASSERT_GT(rv, 0); + } + + // Simulate a suspend event. Can't use a real power event, as it would + // affect |accepted_socket| as well. + client_socket->OnSuspend(); + EXPECT_THAT(read_callback.WaitForResult(), + IsError(ERR_NETWORK_IO_SUSPENDED)); + if (read_callback_action == ReadCallbackAction::kNone) { + EXPECT_THAT(write_callback.WaitForResult(), + IsError(ERR_NETWORK_IO_SUSPENDED)); + + // Check that the client socket really is disconnected. + EXPECT_FALSE(client_socket->IsConnected()); + EXPECT_THAT( + client_socket->Read(read_buffer.get(), 1, read_callback.callback()), + IsError(ERR_NETWORK_IO_SUSPENDED)); + EXPECT_THAT( + client_socket->Write(write_buffer.get(), 1, write_callback.callback(), + TRAFFIC_ANNOTATION_FOR_TESTS), + IsError(ERR_NETWORK_IO_SUSPENDED)); + } else { + // Each of the actions taken in the read callback will cancel the pending + // write callback. + EXPECT_FALSE(write_callback.have_result()); + } + + if (read_callback_action == ReadCallbackAction::kReconnectSocket) { + // Finish establishing a connection, just to make sure the reconnect case + // completely works. + accepted_socket.reset(); + TestCompletionCallback accept_callback; + int accept_result = + server_socket->Accept(&accepted_socket, accept_callback.callback()); + ASSERT_THAT(accept_callback.GetResult(accept_result), IsOk()); + EXPECT_THAT(nested_connect_callback.GetResult(nested_connect_result), + IsOk()); + } + } +} + +#endif // defined(TCP_CLIENT_SOCKET_OBSERVES_SUSPEND) } // namespace diff --git a/chromium/net/socket/transport_client_socket_pool.cc b/chromium/net/socket/transport_client_socket_pool.cc index a0c6cbee14e..3a1fb84662c 100644 --- a/chromium/net/socket/transport_client_socket_pool.cc +++ b/chromium/net/socket/transport_client_socket_pool.cc @@ -22,9 +22,11 @@ #include "base/trace_event/process_memory_dump.h" #include "base/values.h" #include "net/base/net_errors.h" +#include "net/base/proxy_server.h" #include "net/log/net_log.h" #include "net/log/net_log_event_type.h" #include "net/log/net_log_source.h" +#include "net/traffic_annotation/network_traffic_annotation.h" using base::TimeDelta; @@ -36,50 +38,59 @@ namespace { // after a certain timeout has passed without receiving an ACK. bool g_connect_backup_jobs_enabled = true; -std::unique_ptr<base::Value> NetLogCreateConnectJobCallback( +base::Value NetLogCreateConnectJobCallback( bool backup_job, const ClientSocketPool::GroupId* group_id, net::NetLogCaptureMode capture_mode) { - auto dict = std::make_unique<base::DictionaryValue>(); - dict->SetBoolean("backup_job", backup_job); - dict->SetString("group_id", group_id->ToString()); + base::DictionaryValue dict; + dict.SetBoolean("backup_job", backup_job); + dict.SetString("group_id", group_id->ToString()); return std::move(dict); } +} // namespace + // ConnectJobFactory implementation that creates the standard ConnectJob // classes, using SocketParams. -class TransportConnectJobFactory +class TransportClientSocketPool::ConnectJobFactoryImpl : public TransportClientSocketPool::ConnectJobFactory { public: - explicit TransportConnectJobFactory( - const CommonConnectJobParams* common_connect_job_params) - : common_connect_job_params_(common_connect_job_params) { + ConnectJobFactoryImpl(const ProxyServer& proxy_server, + bool is_for_websockets, + const CommonConnectJobParams* common_connect_job_params) + : proxy_server_(proxy_server), + is_for_websockets_(is_for_websockets), + common_connect_job_params_(common_connect_job_params) { // This class should not be used with WebSockets. Note that // |common_connect_job_params| may be nullptr in tests. DCHECK(!common_connect_job_params || !common_connect_job_params->websocket_endpoint_lock_manager); } - ~TransportConnectJobFactory() override = default; + ~ConnectJobFactoryImpl() override = default; - // ClientSocketPoolBase::ConnectJobFactory methods. + // TransportClientSocketPool::ConnectJobFactory methods. std::unique_ptr<ConnectJob> NewConnectJob( + ClientSocketPool::GroupId group_id, + scoped_refptr<ClientSocketPool::SocketParams> socket_params, + const base::Optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag, RequestPriority request_priority, SocketTag socket_tag, - scoped_refptr<ClientSocketPool::SocketParams> socket_params, ConnectJob::Delegate* delegate) const override { - return socket_params->create_connect_job_callback().Run( - request_priority, socket_tag, common_connect_job_params_, delegate); + return CreateConnectJob(group_id, socket_params, proxy_server_, + proxy_annotation_tag, is_for_websockets_, + common_connect_job_params_, request_priority, + socket_tag, delegate); } private: + const ProxyServer proxy_server_; + const bool is_for_websockets_; const CommonConnectJobParams* common_connect_job_params_; - DISALLOW_COPY_AND_ASSIGN(TransportConnectJobFactory); + DISALLOW_COPY_AND_ASSIGN(ConnectJobFactoryImpl); }; -} // namespace - TransportClientSocketPool::Request::Request( ClientSocketHandle* handle, CompletionOnceCallback callback, @@ -89,6 +100,7 @@ TransportClientSocketPool::Request::Request( RespectLimits respect_limits, Flags flags, scoped_refptr<SocketParams> socket_params, + const base::Optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag, const NetLogWithSource& net_log) : handle_(handle), callback_(std::move(callback)), @@ -97,6 +109,7 @@ TransportClientSocketPool::Request::Request( respect_limits_(respect_limits), flags_(flags), socket_params_(std::move(socket_params)), + proxy_annotation_tag_(proxy_annotation_tag), net_log_(net_log), socket_tag_(socket_tag), job_(nullptr) { @@ -104,9 +117,7 @@ TransportClientSocketPool::Request::Request( DCHECK_EQ(priority_, MAXIMUM_PRIORITY); } -TransportClientSocketPool::Request::~Request() { - liveness_ = DEAD; -} +TransportClientSocketPool::Request::~Request() {} void TransportClientSocketPool::Request::AssignJob(ConnectJob* job) { DCHECK(job); @@ -123,24 +134,24 @@ ConnectJob* TransportClientSocketPool::Request::ReleaseJob() { return job; } -void TransportClientSocketPool::Request::CrashIfInvalid() const { - CHECK_EQ(liveness_, ALIVE); -} - TransportClientSocketPool::TransportClientSocketPool( int max_sockets, int max_sockets_per_group, base::TimeDelta unused_idle_socket_timeout, + const ProxyServer& proxy_server, + bool is_for_websockets, const CommonConnectJobParams* common_connect_job_params, SSLConfigService* ssl_config_service) - : TransportClientSocketPool(max_sockets, - max_sockets_per_group, - unused_idle_socket_timeout, - ClientSocketPool::used_idle_socket_timeout(), - std::make_unique<TransportConnectJobFactory>( - common_connect_job_params), - ssl_config_service, - true /* connect_backup_jobs_enabled */) {} + : TransportClientSocketPool( + max_sockets, + max_sockets_per_group, + unused_idle_socket_timeout, + ClientSocketPool::used_idle_socket_timeout(), + std::make_unique<ConnectJobFactoryImpl>(proxy_server, + is_for_websockets, + common_connect_job_params), + ssl_config_service, + true /* connect_backup_jobs_enabled */) {} TransportClientSocketPool::~TransportClientSocketPool() { // Clean up any idle sockets and pending connect jobs. Assert that we have no @@ -228,6 +239,7 @@ void TransportClientSocketPool::RemoveHigherLayeredPool( int TransportClientSocketPool::RequestSocket( const GroupId& group_id, scoped_refptr<SocketParams> params, + const base::Optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag, RequestPriority priority, const SocketTag& socket_tag, RespectLimits respect_limits, @@ -242,7 +254,7 @@ int TransportClientSocketPool::RequestSocket( std::unique_ptr<Request> request = std::make_unique<Request>( handle, std::move(callback), proxy_auth_callback, priority, socket_tag, - respect_limits, NORMAL, std::move(params), net_log); + respect_limits, NORMAL, std::move(params), proxy_annotation_tag, net_log); // Cleanup any timed-out idle sockets. CleanupIdleSockets(false); @@ -279,6 +291,7 @@ int TransportClientSocketPool::RequestSocket( void TransportClientSocketPool::RequestSockets( const GroupId& group_id, scoped_refptr<SocketParams> params, + const base::Optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag, int num_sockets, const NetLogWithSource& net_log) { if (net_log.IsCapturing()) { @@ -291,7 +304,7 @@ void TransportClientSocketPool::RequestSockets( Request request(nullptr /* no handle */, CompletionOnceCallback(), ProxyAuthCallback(), IDLE, SocketTag(), RespectLimits::ENABLED, NO_IDLE_SOCKETS, std::move(params), - net_log); + proxy_annotation_tag, net_log); // Cleanup any timed-out idle sockets. CleanupIdleSockets(false); @@ -400,9 +413,9 @@ int TransportClientSocketPool::RequestSocketInternal(const GroupId& group_id, group = GetOrCreateGroup(group_id); connecting_socket_count_++; std::unique_ptr<ConnectJob> owned_connect_job( - connect_job_factory_->NewConnectJob(request.priority(), - request.socket_tag(), - request.socket_params(), group)); + connect_job_factory_->NewConnectJob( + group_id, request.socket_params(), request.proxy_annotation_tag(), + request.priority(), request.socket_tag(), group)); owned_connect_job->net_log().AddEvent( NetLogEventType::SOCKET_POOL_CONNECT_JOB_CREATED, base::BindRepeating(&NetLogCreateConnectJobCallback, @@ -417,39 +430,34 @@ int TransportClientSocketPool::RequestSocketInternal(const GroupId& group_id, group->AddJob(std::move(owned_connect_job), preconnecting); int rv = connect_job->Connect(); - if (rv == OK) { - LogBoundConnectJobToRequest(connect_job->net_log().source(), request); - if (!preconnecting) { - HandOutSocket(connect_job->PassSocket(), ClientSocketHandle::UNUSED, - connect_job->connect_timing(), handle, base::TimeDelta(), - group, request.net_log()); - } else { - AddIdleSocket(connect_job->PassSocket(), group); - } - RemoveConnectJob(connect_job, group); - } else if (rv == ERR_IO_PENDING) { + if (rv == ERR_IO_PENDING) { // If we didn't have any sockets in this group, set a timer for potentially // creating a new one. If the SYN is lost, this backup socket may complete // before the slow socket, improving end user latency. if (connect_backup_jobs_enabled_ && was_group_empty) group->StartBackupJobTimer(group_id); + return rv; + } + + LogBoundConnectJobToRequest(connect_job->net_log().source(), request); + if (preconnecting) { + if (rv == OK) + AddIdleSocket(connect_job->PassSocket(), group); } else { - LogBoundConnectJobToRequest(connect_job->net_log().source(), request); - std::unique_ptr<StreamSocket> error_socket; - if (!preconnecting) { - DCHECK(handle); + DCHECK(handle); + if (rv != OK) handle->SetAdditionalErrorState(connect_job); - error_socket = connect_job->PassSocket(); - } - if (error_socket) { - HandOutSocket(std::move(error_socket), ClientSocketHandle::UNUSED, - connect_job->connect_timing(), handle, base::TimeDelta(), - group, request.net_log()); + std::unique_ptr<StreamSocket> socket = connect_job->PassSocket(); + if (socket) { + HandOutSocket(std::move(socket), ClientSocketHandle::UNUSED, + connect_job->connect_timing(), handle, + base::TimeDelta() /* idle_time */, group, + request.net_log()); } - RemoveConnectJob(connect_job, group); - if (group->IsEmpty()) - RemoveGroup(group_id); } + RemoveConnectJob(connect_job, group); + if (group->IsEmpty()) + RemoveGroup(group_id); return rv; } @@ -539,15 +547,23 @@ void TransportClientSocketPool::SetPriority(const GroupId& group_id, } void TransportClientSocketPool::CancelRequest(const GroupId& group_id, - ClientSocketHandle* handle) { + ClientSocketHandle* handle, + bool cancel_connect_job) { auto callback_it = pending_callback_map_.find(handle); if (callback_it != pending_callback_map_.end()) { int result = callback_it->second.result; pending_callback_map_.erase(callback_it); std::unique_ptr<StreamSocket> socket = handle->PassSocket(); if (socket) { - if (result != OK) + if (result != OK) { socket->Disconnect(); + } else if (cancel_connect_job) { + // Close the socket if |cancel_connect_job| is true and there are no + // other pending requests. + Group* group = GetOrCreateGroup(group_id); + if (group->unbound_request_count() == 0) + socket->Disconnect(); + } ReleaseSocket(handle->group_id(), std::move(socket), handle->group_generation()); } @@ -571,12 +587,16 @@ void TransportClientSocketPool::CancelRequest(const GroupId& group_id, request->net_log().AddEvent(NetLogEventType::CANCELLED); request->net_log().EndEvent(NetLogEventType::SOCKET_POOL); - // We let the job run, unless we're at the socket limit and there is - // not another request waiting on the job. + // Let the job run, unless |cancel_connect_job| is true, or we're at the + // socket limit and there are no other requests waiting on the job. + bool reached_limit = ReachedMaxSocketsLimit(); if (group->jobs().size() > group->unbound_request_count() && - ReachedMaxSocketsLimit()) { + (cancel_connect_job || reached_limit)) { RemoveConnectJob(group->jobs().begin()->get(), group); - CheckForStalledSocketGroups(); + if (group->IsEmpty()) + RemoveGroup(group->group_id()); + if (reached_limit) + CheckForStalledSocketGroups(); } } } @@ -1173,105 +1193,79 @@ void TransportClientSocketPool::OnConnectJobComplete(Group* group, DCHECK_NE(ERR_IO_PENDING, result); DCHECK(group_map_.find(group->group_id()) != group_map_.end()); DCHECK_EQ(group, group_map_[group->group_id()]); + DCHECK(result != OK || job->socket() != nullptr); - std::unique_ptr<StreamSocket> socket = job->PassSocket(); - - // Copies of these are needed because |job| may be deleted before they are - // accessed. - NetLogWithSource job_log = job->net_log(); - LoadTimingInfo::ConnectTiming connect_timing = job->connect_timing(); - - // Check if the ConnectJob is already bound to a Request. If so, complete the - // request. - // - // TODO(mmenke) this logic resembles the case where the job is assigned to a - // request below. Look into merging the logic. + // Check if the ConnectJob is already bound to a Request. If so, result is + // returned to that specific request. base::Optional<Group::BoundRequest> bound_request = group->FindAndRemoveBoundRequestForConnectJob(job); + Request* request = nullptr; + std::unique_ptr<Request> owned_request; if (bound_request) { --connecting_socket_count_; - // If the ConnectJob is from a previous generation, and the socket pools - // weren't flushed with an error, add the request back to the group, and - // kick off another request. - if (bound_request->generation != group->generation() && - bound_request->pending_error == OK) { - group->InsertUnboundRequest(std::move(bound_request->request)); - OnAvailableSocketSlot(group->group_id(), group); - CheckForStalledSocketGroups(); - return; - } - bool handed_out_socket = false; + // If the socket pools were previously flushed with an error, return that + // error to the bound request and discard the socket. if (bound_request->pending_error != OK) { - result = bound_request->pending_error; - } else { - bound_request->request->handle()->SetAdditionalErrorState(job); - if (socket) { - handed_out_socket = true; - HandOutSocket(std::move(socket), ClientSocketHandle::UNUSED, - connect_timing, bound_request->request->handle(), - base::TimeDelta(), group, - bound_request->request->net_log()); - } - } - bound_request->request->net_log().EndEventWithNetErrorCode( - NetLogEventType::SOCKET_POOL, result); - InvokeUserCallbackLater(bound_request->request->handle(), - bound_request->request->release_callback(), result, - bound_request->request->socket_tag()); - if (!handed_out_socket) { + InvokeUserCallbackLater(bound_request->request->handle(), + bound_request->request->release_callback(), + bound_request->pending_error, + bound_request->request->socket_tag()); + bound_request->request->net_log().EndEventWithNetErrorCode( + NetLogEventType::SOCKET_POOL, bound_request->pending_error); OnAvailableSocketSlot(group->group_id(), group); CheckForStalledSocketGroups(); + return; } - return; - } - // RemoveConnectJob(job, _) must be called by all branches below; - // otherwise, |job| will be leaked. - - if (result == OK) { - DCHECK(socket.get()); - std::unique_ptr<Request> request = group->PopNextUnboundRequest(); - RemoveConnectJob(job, group); - if (request) { - LogBoundConnectJobToRequest(job_log.source(), *request); - HandOutSocket(std::move(socket), ClientSocketHandle::UNUSED, - connect_timing, request->handle(), base::TimeDelta(), group, - request->net_log()); - request->net_log().EndEvent(NetLogEventType::SOCKET_POOL); - InvokeUserCallbackLater(request->handle(), request->release_callback(), - result, request->socket_tag()); - } else { - AddIdleSocket(std::move(socket), group); + // If the ConnectJob is from a previous generation, add the request back to + // the group, and kick off another request. The socket will be discarded. + if (bound_request->generation != group->generation()) { + group->InsertUnboundRequest(std::move(bound_request->request)); OnAvailableSocketSlot(group->group_id(), group); CheckForStalledSocketGroups(); + return; } + + request = bound_request->request.get(); } else { - // If we got a socket, it must contain error information so pass that - // up so that the caller can retrieve it. - bool handed_out_socket = false; - std::unique_ptr<Request> request = group->PopNextUnboundRequest(); - if (request) { - LogBoundConnectJobToRequest(job_log.source(), *request); - request->handle()->SetAdditionalErrorState(job); - RemoveConnectJob(job, group); - if (socket.get()) { - handed_out_socket = true; - HandOutSocket(std::move(socket), ClientSocketHandle::UNUSED, - connect_timing, request->handle(), base::TimeDelta(), - group, request->net_log()); - } - request->net_log().EndEventWithNetErrorCode(NetLogEventType::SOCKET_POOL, - result); - InvokeUserCallbackLater(request->handle(), request->release_callback(), - result, request->socket_tag()); - } else { + // In this case, RemoveConnectJob(job, _) must be called before exiting this + // method. Otherwise, |job| will be leaked. + owned_request = group->PopNextUnboundRequest(); + request = owned_request.get(); + + if (!request) { + if (result == OK) + AddIdleSocket(job->PassSocket(), group); RemoveConnectJob(job, group); - } - if (!handed_out_socket) { OnAvailableSocketSlot(group->group_id(), group); CheckForStalledSocketGroups(); + return; } + + LogBoundConnectJobToRequest(job->net_log().source(), *request); + } + + // The case where there's no request is handled above. + DCHECK(request); + + if (result != OK) + request->handle()->SetAdditionalErrorState(job); + if (job->socket()) { + HandOutSocket(job->PassSocket(), ClientSocketHandle::UNUSED, + job->connect_timing(), request->handle(), base::TimeDelta(), + group, request->net_log()); + } + request->net_log().EndEventWithNetErrorCode(NetLogEventType::SOCKET_POOL, + result); + InvokeUserCallbackLater(request->handle(), request->release_callback(), + result, request->socket_tag()); + if (!bound_request) + RemoveConnectJob(job, group); + // If no socket was handed out, there's a new socket slot available. + if (!request->handle()->socket()) { + OnAvailableSocketSlot(group->group_id(), group); + CheckForStalledSocketGroups(); } } @@ -1363,9 +1357,9 @@ void TransportClientSocketPool::RefreshGroup(const GroupId& group_id) { TransportClientSocketPool::Group::Group( const GroupId& group_id, - TransportClientSocketPool* client_socket_pool_base_helper) + TransportClientSocketPool* client_socket_pool) : group_id_(group_id), - client_socket_pool_base_helper_(client_socket_pool_base_helper), + client_socket_pool_(client_socket_pool), never_assigned_job_count_(0), unbound_requests_(NUM_PRIORITIES), active_socket_count_(0), @@ -1382,7 +1376,7 @@ TransportClientSocketPool::Group::~Group() { void TransportClientSocketPool::Group::OnConnectJobComplete(int result, ConnectJob* job) { DCHECK_NE(ERR_IO_PENDING, result); - client_socket_pool_base_helper_->OnConnectJobComplete(this, result, job); + client_socket_pool_->OnConnectJobComplete(this, result, job); } void TransportClientSocketPool::Group::OnNeedsProxyAuth( @@ -1390,9 +1384,9 @@ void TransportClientSocketPool::Group::OnNeedsProxyAuth( HttpAuthController* auth_controller, base::OnceClosure restart_with_auth_callback, ConnectJob* job) { - client_socket_pool_base_helper_->OnNeedsProxyAuth( - this, response, auth_controller, std::move(restart_with_auth_callback), - job); + client_socket_pool_->OnNeedsProxyAuth(this, response, auth_controller, + std::move(restart_with_auth_callback), + job); } void TransportClientSocketPool::Group::StartBackupJobTimer( @@ -1403,10 +1397,10 @@ void TransportClientSocketPool::Group::StartBackupJobTimer( // Unretained here is okay because |backup_job_timer_| is // automatically cancelled when it's destroyed. - backup_job_timer_.Start( - FROM_HERE, client_socket_pool_base_helper_->ConnectRetryInterval(), - base::BindOnce(&Group::OnBackupJobTimerFired, base::Unretained(this), - group_id)); + backup_job_timer_.Start(FROM_HERE, + client_socket_pool_->ConnectRetryInterval(), + base::BindOnce(&Group::OnBackupJobTimerFired, + base::Unretained(this), group_id)); } bool TransportClientSocketPool::Group::BackupJobTimerIsRunning() const { @@ -1502,9 +1496,8 @@ void TransportClientSocketPool::Group::OnBackupJobTimerFired( // If our old job is waiting on DNS, or if we can't create any sockets // right now due to limits, just reset the timer. - if (client_socket_pool_base_helper_->ReachedMaxSocketsLimit() || - !HasAvailableSocketSlot( - client_socket_pool_base_helper_->max_sockets_per_group_) || + if (client_socket_pool_->ReachedMaxSocketsLimit() || + !HasAvailableSocketSlot(client_socket_pool_->max_sockets_per_group_) || (*jobs_.begin())->GetLoadState() == LOAD_STATE_RESOLVING_HOST) { StartBackupJobTimer(group_id); return; @@ -1515,19 +1508,19 @@ void TransportClientSocketPool::Group::OnBackupJobTimerFired( Request* request = unbound_requests_.FirstMax().value().get(); std::unique_ptr<ConnectJob> owned_backup_job = - client_socket_pool_base_helper_->connect_job_factory_->NewConnectJob( - request->priority(), request->socket_tag(), request->socket_params(), - this); + client_socket_pool_->connect_job_factory_->NewConnectJob( + group_id, request->socket_params(), request->proxy_annotation_tag(), + request->priority(), request->socket_tag(), this); owned_backup_job->net_log().AddEvent( NetLogEventType::SOCKET_POOL_CONNECT_JOB_CREATED, base::BindRepeating(&NetLogCreateConnectJobCallback, true /* backup_job */, &group_id_)); ConnectJob* backup_job = owned_backup_job.get(); AddJob(std::move(owned_backup_job), false); - client_socket_pool_base_helper_->connecting_socket_count_++; + client_socket_pool_->connecting_socket_count_++; int rv = backup_job->Connect(); if (rv != ERR_IO_PENDING) { - client_socket_pool_base_helper_->OnConnectJobComplete(this, rv, backup_job); + client_socket_pool_->OnConnectJobComplete(this, rv, backup_job); } } @@ -1843,7 +1836,6 @@ TransportClientSocketPool::Group::RemoveUnboundRequest( if (unbound_requests_.empty()) backup_job_timer_.Stop(); - request->CrashIfInvalid(); SanityCheck(); return request; } diff --git a/chromium/net/socket/transport_client_socket_pool.h b/chromium/net/socket/transport_client_socket_pool.h index d87f0d582de..2f61148245d 100644 --- a/chromium/net/socket/transport_client_socket_pool.h +++ b/chromium/net/socket/transport_client_socket_pool.h @@ -20,6 +20,7 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" +#include "base/optional.h" #include "base/time/time.h" #include "base/timer/timer.h" #include "net/base/address_list.h" @@ -52,6 +53,8 @@ namespace net { struct CommonConnectJobParams; struct NetLogSource; +class ProxyServer; +struct NetworkTrafficAnnotationTag; // TransportClientSocketPool establishes network connections through using // ConnectJobs, and maintains a list of idle persistent sockets available for @@ -83,17 +86,19 @@ class NET_EXPORT_PRIVATE TransportClientSocketPool public: // If |proxy_auth_callback| is null, proxy auth challenges will // result in an error. - Request(ClientSocketHandle* handle, - CompletionOnceCallback callback, - const ProxyAuthCallback& proxy_auth_callback, - RequestPriority priority, - const SocketTag& socket_tag, - RespectLimits respect_limits, - Flags flags, - scoped_refptr<SocketParams> socket_params, - const NetLogWithSource& net_log); - - virtual ~Request(); + Request( + ClientSocketHandle* handle, + CompletionOnceCallback callback, + const ProxyAuthCallback& proxy_auth_callback, + RequestPriority priority, + const SocketTag& socket_tag, + RespectLimits respect_limits, + Flags flags, + scoped_refptr<SocketParams> socket_params, + const base::Optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag, + const NetLogWithSource& net_log); + + ~Request(); ClientSocketHandle* handle() const { return handle_; } CompletionOnceCallback release_callback() { return std::move(callback_); } @@ -105,6 +110,10 @@ class NET_EXPORT_PRIVATE TransportClientSocketPool RespectLimits respect_limits() const { return respect_limits_; } Flags flags() const { return flags_; } SocketParams* socket_params() const { return socket_params_.get(); } + const base::Optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag() + const { + return proxy_annotation_tag_; + } const NetLogWithSource& net_log() const { return net_log_; } const SocketTag& socket_tag() const { return socket_tag_; } ConnectJob* job() const { return job_; } @@ -117,16 +126,7 @@ class NET_EXPORT_PRIVATE TransportClientSocketPool // request with a job. ConnectJob* ReleaseJob(); - // TODO(eroman): Temporary until crbug.com/467797 is solved. - void CrashIfInvalid() const; - private: - // TODO(eroman): Temporary until crbug.com/467797 is solved. - enum Liveness { - ALIVE = 0xCA11AB13, - DEAD = 0xDEADBEEF, - }; - ClientSocketHandle* const handle_; CompletionOnceCallback callback_; const ProxyAuthCallback proxy_auth_callback_; @@ -134,13 +134,11 @@ class NET_EXPORT_PRIVATE TransportClientSocketPool const RespectLimits respect_limits_; const Flags flags_; const scoped_refptr<SocketParams> socket_params_; + const base::Optional<NetworkTrafficAnnotationTag> proxy_annotation_tag_; const NetLogWithSource net_log_; const SocketTag socket_tag_; ConnectJob* job_; - // TODO(eroman): Temporary until crbug.com/467797 is solved. - Liveness liveness_ = ALIVE; - DISALLOW_COPY_AND_ASSIGN(Request); }; @@ -150,9 +148,11 @@ class NET_EXPORT_PRIVATE TransportClientSocketPool virtual ~ConnectJobFactory() {} virtual std::unique_ptr<ConnectJob> NewConnectJob( + ClientSocketPool::GroupId group_id, + scoped_refptr<ClientSocketPool::SocketParams> socket_params, + const base::Optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag, RequestPriority request_priority, SocketTag socket_tag, - scoped_refptr<SocketParams> socket_params, ConnectJob::Delegate* delegate) const = 0; private: @@ -163,6 +163,8 @@ class NET_EXPORT_PRIVATE TransportClientSocketPool int max_sockets, int max_sockets_per_group, base::TimeDelta unused_idle_socket_timeout, + const ProxyServer& proxy_server, + bool is_for_websockets, const CommonConnectJobParams* common_connect_job_params, SSLConfigService* ssl_config_service); @@ -191,24 +193,29 @@ class NET_EXPORT_PRIVATE TransportClientSocketPool void RemoveHigherLayeredPool(HigherLayeredPool* higher_pool) override; // ClientSocketPool implementation: - int RequestSocket(const GroupId& group_id, - scoped_refptr<SocketParams> params, - RequestPriority priority, - const SocketTag& socket_tag, - RespectLimits respect_limits, - ClientSocketHandle* handle, - CompletionOnceCallback callback, - const ProxyAuthCallback& proxy_auth_callback, - const NetLogWithSource& net_log) override; - void RequestSockets(const GroupId& group_id, - scoped_refptr<SocketParams> params, - int num_sockets, - const NetLogWithSource& net_log) override; + int RequestSocket( + const GroupId& group_id, + scoped_refptr<SocketParams> params, + const base::Optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag, + RequestPriority priority, + const SocketTag& socket_tag, + RespectLimits respect_limits, + ClientSocketHandle* handle, + CompletionOnceCallback callback, + const ProxyAuthCallback& proxy_auth_callback, + const NetLogWithSource& net_log) override; + void RequestSockets( + const GroupId& group_id, + scoped_refptr<SocketParams> params, + const base::Optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag, + int num_sockets, + const NetLogWithSource& net_log) override; void SetPriority(const GroupId& group_id, ClientSocketHandle* handle, RequestPriority priority) override; void CancelRequest(const GroupId& group_id, - ClientSocketHandle* handle) override; + ClientSocketHandle* handle, + bool cancel_connect_job) override; void ReleaseSocket(const GroupId& group_id, std::unique_ptr<StreamSocket> socket, int64_t group_generation) override; @@ -264,6 +271,8 @@ class NET_EXPORT_PRIVATE TransportClientSocketPool void OnIPAddressChanged() override; private: + class ConnectJobFactoryImpl; + // Entry for a persistent socket which became idle at time |start_time|. struct IdleSocket { IdleSocket() : socket(nullptr) {} @@ -338,7 +347,7 @@ class NET_EXPORT_PRIVATE TransportClientSocketPool }; Group(const GroupId& group_id, - TransportClientSocketPool* client_socket_pool_base_helper); + TransportClientSocketPool* client_socket_pool); ~Group() override; // ConnectJob::Delegate methods: @@ -535,7 +544,7 @@ class NET_EXPORT_PRIVATE TransportClientSocketPool void SanityCheck() const; const GroupId group_id_; - TransportClientSocketPool* const client_socket_pool_base_helper_; + TransportClientSocketPool* const client_socket_pool_; // Total number of ConnectJobs that have never been assigned to a Request. // Since jobs use late binding to requests, which ConnectJobs have or have diff --git a/chromium/net/socket/transport_client_socket_pool_test_util.cc b/chromium/net/socket/transport_client_socket_pool_test_util.cc index d540dd8ab3a..bf8b36601a4 100644 --- a/chromium/net/socket/transport_client_socket_pool_test_util.cc +++ b/chromium/net/socket/transport_client_socket_pool_test_util.cc @@ -463,7 +463,6 @@ MockTransportClientSocketFactory::CreateProxyClientSocket( bool using_spdy, NextProto negotiated_protocol, ProxyDelegate* proxy_delegate, - bool is_https_proxy, const NetworkTrafficAnnotationTag& traffic_annotation) { NOTIMPLEMENTED(); return nullptr; diff --git a/chromium/net/socket/transport_client_socket_pool_test_util.h b/chromium/net/socket/transport_client_socket_pool_test_util.h index ac2b73e2137..38a9744138f 100644 --- a/chromium/net/socket/transport_client_socket_pool_test_util.h +++ b/chromium/net/socket/transport_client_socket_pool_test_util.h @@ -103,7 +103,6 @@ class MockTransportClientSocketFactory : public ClientSocketFactory { bool using_spdy, NextProto negotiated_protocol, ProxyDelegate* proxy_delegate, - bool is_https_proxy, const NetworkTrafficAnnotationTag& traffic_annotation) override; int allocation_count() const { return allocation_count_; } diff --git a/chromium/net/socket/transport_client_socket_pool_unittest.cc b/chromium/net/socket/transport_client_socket_pool_unittest.cc index 497ce144485..d8d59caf1f5 100644 --- a/chromium/net/socket/transport_client_socket_pool_unittest.cc +++ b/chromium/net/socket/transport_client_socket_pool_unittest.cc @@ -10,6 +10,7 @@ #include "base/bind_helpers.h" #include "base/callback.h" #include "base/memory/ref_counted.h" +#include "base/optional.h" #include "base/run_loop.h" #include "base/stl_util.h" #include "base/test/bind_test_util.h" @@ -22,6 +23,8 @@ #include "net/base/load_timing_info.h" #include "net/base/load_timing_info_test_util.h" #include "net/base/net_errors.h" +#include "net/base/privacy_mode.h" +#include "net/base/proxy_server.h" #include "net/base/test_completion_callback.h" #include "net/cert/ct_policy_enforcer.h" #include "net/cert/mock_cert_verifier.h" @@ -106,11 +109,8 @@ class TransportClientSocketPoolTest : public ::testing::Test, TransportClientSocketPool::set_connect_backup_jobs_enabled(true)), group_id_(HostPortPair("www.google.com", 80), ClientSocketPool::SocketType::kHttp, - false /* privacy_mode */), - params_(ClientSocketPool::SocketParams::CreateFromTransportSocketParams( - base::MakeRefCounted<TransportSocketParams>( - HostPortPair("www.google.com", 80), - OnHostResolutionCallback()))), + PrivacyMode::PRIVACY_MODE_DISABLED), + params_(ClientSocketPool::SocketParams::CreateForHttpForTesting()), client_socket_factory_(&net_log_) { std::unique_ptr<MockCertVerifier> cert_verifier = std::make_unique<MockCertVerifier>(); @@ -125,6 +125,7 @@ class TransportClientSocketPoolTest : public ::testing::Test, common_connect_job_params_->client_socket_factory = &client_socket_factory_; pool_ = std::make_unique<TransportClientSocketPool>( kMaxSockets, kMaxSocketsPerGroup, kUnusedIdleSocketTimeout, + ProxyServer::Direct(), false /* is_for_websockets */, common_connect_job_params_.get(), session_deps_.ssl_config_service.get()); @@ -135,6 +136,7 @@ class TransportClientSocketPoolTest : public ::testing::Test, &tagging_client_socket_factory_; tagging_pool_ = std::make_unique<TransportClientSocketPool>( kMaxSockets, kMaxSocketsPerGroup, kUnusedIdleSocketTimeout, + ProxyServer::Direct(), false /* is_for_websockets */, tagging_common_connect_job_params_.get(), session_deps_.ssl_config_service.get()); @@ -145,6 +147,7 @@ class TransportClientSocketPoolTest : public ::testing::Test, ClientSocketFactory::GetDefaultFactory(); pool_for_real_sockets_ = std::make_unique<TransportClientSocketPool>( kMaxSockets, kMaxSocketsPerGroup, kUnusedIdleSocketTimeout, + ProxyServer::Direct(), false /* is_for_websockets */, common_connect_job_params_for_real_sockets_.get(), session_deps_.ssl_config_service.get()); } @@ -157,14 +160,11 @@ class TransportClientSocketPoolTest : public ::testing::Test, int StartRequest(const std::string& host_name, RequestPriority priority) { ClientSocketPool::GroupId group_id(HostPortPair(host_name, 80), ClientSocketPool::SocketType::kHttp, - false /* privacy_mode */); - scoped_refptr<ClientSocketPool::SocketParams> params( - ClientSocketPool::SocketParams::CreateFromTransportSocketParams( - base::MakeRefCounted<TransportSocketParams>( - group_id.destination(), OnHostResolutionCallback()))); + PrivacyMode::PRIVACY_MODE_DISABLED); return test_base_.StartRequestUsingPool( pool_.get(), group_id, priority, - ClientSocketPool::RespectLimits::ENABLED, params); + ClientSocketPool::RespectLimits::ENABLED, + ClientSocketPool::SocketParams::CreateForHttpForTesting()); } int GetOrderOfRequest(size_t index) { @@ -184,9 +184,9 @@ class TransportClientSocketPoolTest : public ::testing::Test, } size_t completion_count() const { return test_base_.completion_count(); } - SSLConfig GetSSLConfig() const { - SSLConfig ssl_config; - session_deps_.ssl_config_service->GetSSLConfig(&ssl_config); + std::unique_ptr<SSLConfig> GetSSLConfig() const { + std::unique_ptr<SSLConfig> ssl_config = std::make_unique<SSLConfig>(); + session_deps_.ssl_config_service->GetSSLConfig(ssl_config.get()); return ssl_config; } @@ -231,10 +231,11 @@ class TransportClientSocketPoolTest : public ::testing::Test, TEST_F(TransportClientSocketPoolTest, Basic) { TestCompletionCallback callback; ClientSocketHandle handle; - int rv = handle.Init( - group_id_, params_, LOW, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, callback.callback(), - ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource()); + int rv = + handle.Init(group_id_, params_, base::nullopt /* proxy_annotation_tag */, + LOW, SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback.callback(), ClientSocketPool::ProxyAuthCallback(), + pool_.get(), NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); EXPECT_FALSE(handle.is_initialized()); EXPECT_FALSE(handle.socket()); @@ -255,8 +256,9 @@ TEST_F(TransportClientSocketPoolTest, SetResolvePriorityOnInit) { ClientSocketHandle handle; EXPECT_EQ( ERR_IO_PENDING, - handle.Init(group_id_, params_, priority, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, + handle.Init(group_id_, params_, + base::nullopt /* proxy_annotation_tag */, priority, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource())); EXPECT_EQ(priority, session_deps_.host_resolver->last_request_priority()); @@ -268,50 +270,56 @@ TEST_F(TransportClientSocketPoolTest, ReprioritizeRequests) { TestCompletionCallback callback1; ClientSocketHandle handle1; - int rv1 = handle1.Init( - group_id_, params_, LOW, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, callback1.callback(), - ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource()); + int rv1 = + handle1.Init(group_id_, params_, base::nullopt /* proxy_annotation_tag */, + LOW, SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback1.callback(), ClientSocketPool::ProxyAuthCallback(), + pool_.get(), NetLogWithSource()); EXPECT_THAT(rv1, IsError(ERR_IO_PENDING)); TestCompletionCallback callback2; ClientSocketHandle handle2; int rv2 = handle2.Init( - group_id_, params_, HIGHEST, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, callback2.callback(), - ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource()); + group_id_, params_, base::nullopt /* proxy_annotation_tag */, HIGHEST, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback2.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), + NetLogWithSource()); EXPECT_THAT(rv2, IsError(ERR_IO_PENDING)); TestCompletionCallback callback3; ClientSocketHandle handle3; int rv3 = handle3.Init( - group_id_, params_, LOWEST, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, callback3.callback(), - ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource()); + group_id_, params_, base::nullopt /* proxy_annotation_tag */, LOWEST, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback3.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), + NetLogWithSource()); EXPECT_THAT(rv3, IsError(ERR_IO_PENDING)); TestCompletionCallback callback4; ClientSocketHandle handle4; int rv4 = handle4.Init( - group_id_, params_, MEDIUM, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, callback4.callback(), - ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource()); + group_id_, params_, base::nullopt /* proxy_annotation_tag */, MEDIUM, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback4.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), + NetLogWithSource()); EXPECT_THAT(rv4, IsError(ERR_IO_PENDING)); TestCompletionCallback callback5; ClientSocketHandle handle5; int rv5 = handle5.Init( - group_id_, params_, HIGHEST, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, callback5.callback(), - ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource()); + group_id_, params_, base::nullopt /* proxy_annotation_tag */, HIGHEST, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback5.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), + NetLogWithSource()); EXPECT_THAT(rv5, IsError(ERR_IO_PENDING)); TestCompletionCallback callback6; ClientSocketHandle handle6; - int rv6 = handle6.Init( - group_id_, params_, LOW, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, callback6.callback(), - ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource()); + int rv6 = + handle6.Init(group_id_, params_, base::nullopt /* proxy_annotation_tag */, + LOW, SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback6.callback(), ClientSocketPool::ProxyAuthCallback(), + pool_.get(), NetLogWithSource()); EXPECT_THAT(rv6, IsError(ERR_IO_PENDING)); // New jobs are created for each of the first 6 requests with the @@ -338,9 +346,10 @@ TEST_F(TransportClientSocketPoolTest, ReprioritizeRequests) { TestCompletionCallback callback7; ClientSocketHandle handle7; int rv7 = handle7.Init( - group_id_, params_, HIGHEST, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, callback7.callback(), - ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource()); + group_id_, params_, base::nullopt /* proxy_annotation_tag */, HIGHEST, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback7.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), + NetLogWithSource()); EXPECT_THAT(rv7, IsError(ERR_IO_PENDING)); // Request Job Priority // ======= === ======== @@ -362,9 +371,10 @@ TEST_F(TransportClientSocketPoolTest, ReprioritizeRequests) { TestCompletionCallback callback8; ClientSocketHandle handle8; int rv8 = handle8.Init( - group_id_, params_, HIGHEST, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, callback8.callback(), - ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource()); + group_id_, params_, base::nullopt /* proxy_annotation_tag */, HIGHEST, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback8.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), + NetLogWithSource()); EXPECT_THAT(rv8, IsError(ERR_IO_PENDING)); // Request Job Priority // ======= === ======== @@ -504,27 +514,30 @@ TEST_F(TransportClientSocketPoolTest, ReprioritizeRequests) { } TEST_F(TransportClientSocketPoolTest, RequestIgnoringLimitsIsReprioritized) { - TransportClientSocketPool pool(kMaxSockets, 1, kUnusedIdleSocketTimeout, - common_connect_job_params_.get(), - nullptr /* ssl_config_service */); + TransportClientSocketPool pool( + kMaxSockets, 1, kUnusedIdleSocketTimeout, ProxyServer::Direct(), + false /* is_for_websockets */, common_connect_job_params_.get(), + nullptr /* ssl_config_service */); // Creates a job which ignores limits whose priority is MAXIMUM_PRIORITY. TestCompletionCallback callback1; ClientSocketHandle handle1; int rv1 = handle1.Init( - group_id_, params_, MAXIMUM_PRIORITY, SocketTag(), - ClientSocketPool::RespectLimits::DISABLED, callback1.callback(), - ClientSocketPool::ProxyAuthCallback(), &pool, NetLogWithSource()); + group_id_, params_, base::nullopt /* proxy_annotation_tag */, + MAXIMUM_PRIORITY, SocketTag(), ClientSocketPool::RespectLimits::DISABLED, + callback1.callback(), ClientSocketPool::ProxyAuthCallback(), &pool, + NetLogWithSource()); EXPECT_THAT(rv1, IsError(ERR_IO_PENDING)); EXPECT_EQ(MAXIMUM_PRIORITY, session_deps_.host_resolver->request_priority(1)); TestCompletionCallback callback2; ClientSocketHandle handle2; - int rv2 = handle2.Init( - group_id_, params_, LOW, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, callback2.callback(), - ClientSocketPool::ProxyAuthCallback(), &pool, NetLogWithSource()); + int rv2 = + handle2.Init(group_id_, params_, base::nullopt /* proxy_annotation_tag */, + LOW, SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback2.callback(), ClientSocketPool::ProxyAuthCallback(), + &pool, NetLogWithSource()); EXPECT_THAT(rv2, IsError(ERR_IO_PENDING)); // |handle2| gets assigned the job, which is reprioritized. @@ -539,7 +552,8 @@ TEST_F(TransportClientSocketPoolTest, InitHostResolutionFailure) { ClientSocketHandle handle; EXPECT_EQ( ERR_IO_PENDING, - handle.Init(group_id_, params_, kDefaultPriority, SocketTag(), + handle.Init(group_id_, params_, base::nullopt /* proxy_annotation_tag */, + kDefaultPriority, SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource())); @@ -557,7 +571,8 @@ TEST_F(TransportClientSocketPoolTest, InitConnectionFailure) { ClientSocketHandle handle; EXPECT_EQ( ERR_IO_PENDING, - handle.Init(group_id_, params_, kDefaultPriority, SocketTag(), + handle.Init(group_id_, params_, base::nullopt /* proxy_annotation_tag */, + kDefaultPriority, SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource())); @@ -572,7 +587,8 @@ TEST_F(TransportClientSocketPoolTest, InitConnectionFailure) { session_deps_.host_resolver->set_synchronous_mode(true); EXPECT_EQ( ERR_CONNECTION_FAILED, - handle.Init(group_id_, params_, kDefaultPriority, SocketTag(), + handle.Init(group_id_, params_, base::nullopt /* proxy_annotation_tag */, + kDefaultPriority, SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource())); @@ -687,7 +703,8 @@ TEST_F(TransportClientSocketPoolTest, CancelRequestClearGroup) { ClientSocketHandle handle; EXPECT_EQ( ERR_IO_PENDING, - handle.Init(group_id_, params_, kDefaultPriority, SocketTag(), + handle.Init(group_id_, params_, base::nullopt /* proxy_annotation_tag */, + kDefaultPriority, SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource())); @@ -702,13 +719,15 @@ TEST_F(TransportClientSocketPoolTest, TwoRequestsCancelOne) { EXPECT_EQ( ERR_IO_PENDING, - handle.Init(group_id_, params_, kDefaultPriority, SocketTag(), + handle.Init(group_id_, params_, base::nullopt /* proxy_annotation_tag */, + kDefaultPriority, SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource())); EXPECT_EQ( ERR_IO_PENDING, - handle2.Init(group_id_, params_, kDefaultPriority, SocketTag(), + handle2.Init(group_id_, params_, base::nullopt /* proxy_annotation_tag */, + kDefaultPriority, SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback2.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource())); @@ -726,7 +745,8 @@ TEST_F(TransportClientSocketPoolTest, ConnectCancelConnect) { TestCompletionCallback callback; EXPECT_EQ( ERR_IO_PENDING, - handle.Init(group_id_, params_, kDefaultPriority, SocketTag(), + handle.Init(group_id_, params_, base::nullopt /* proxy_annotation_tag */, + kDefaultPriority, SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource())); @@ -736,7 +756,8 @@ TEST_F(TransportClientSocketPoolTest, ConnectCancelConnect) { TestCompletionCallback callback2; EXPECT_EQ( ERR_IO_PENDING, - handle.Init(group_id_, params_, kDefaultPriority, SocketTag(), + handle.Init(group_id_, params_, base::nullopt /* proxy_annotation_tag */, + kDefaultPriority, SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback2.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource())); @@ -848,10 +869,11 @@ class RequestSocketCallback : public TestCompletionCallbackBase { handle_->Reset(); base::RunLoop(base::RunLoop::Type::kNestableTasksAllowed).RunUntilIdle(); within_callback_ = true; - int rv = handle_->Init(group_id_, socket_params_, LOWEST, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, - callback(), ClientSocketPool::ProxyAuthCallback(), - pool_, NetLogWithSource()); + int rv = handle_->Init( + group_id_, socket_params_, base::nullopt /* proxy_annotation_tag */, + LOWEST, SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback(), ClientSocketPool::ProxyAuthCallback(), pool_, + NetLogWithSource()); EXPECT_THAT(rv, IsOk()); } } @@ -868,14 +890,11 @@ class RequestSocketCallback : public TestCompletionCallbackBase { TEST_F(TransportClientSocketPoolTest, RequestTwice) { ClientSocketHandle handle; RequestSocketCallback callback(group_id_, params_, &handle, pool_.get()); - scoped_refptr<ClientSocketPool::SocketParams> dest( - ClientSocketPool::SocketParams::CreateFromTransportSocketParams( - base::MakeRefCounted<TransportSocketParams>( - HostPortPair("www.google.com", 80), OnHostResolutionCallback()))); - int rv = handle.Init( - group_id_, params_, LOWEST, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, callback.callback(), - ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource()); + int rv = + handle.Init(group_id_, params_, base::nullopt /* proxy_annotation_tag */, + LOWEST, SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback.callback(), ClientSocketPool::ProxyAuthCallback(), + pool_.get(), NetLogWithSource()); ASSERT_THAT(rv, IsError(ERR_IO_PENDING)); // The callback is going to request "www.google.com". We want it to complete @@ -938,10 +957,11 @@ TEST_F(TransportClientSocketPoolTest, FailingActiveRequestWithPendingRequests) { TEST_F(TransportClientSocketPoolTest, IdleSocketLoadTiming) { TestCompletionCallback callback; ClientSocketHandle handle; - int rv = handle.Init( - group_id_, params_, LOW, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, callback.callback(), - ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource()); + int rv = + handle.Init(group_id_, params_, base::nullopt /* proxy_annotation_tag */, + LOW, SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback.callback(), ClientSocketPool::ProxyAuthCallback(), + pool_.get(), NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); EXPECT_FALSE(handle.is_initialized()); EXPECT_FALSE(handle.socket()); @@ -958,8 +978,8 @@ TEST_F(TransportClientSocketPoolTest, IdleSocketLoadTiming) { // Now we should have 1 idle socket. EXPECT_EQ(1, pool_->IdleSocketCount()); - rv = handle.Init(group_id_, params_, LOW, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, + rv = handle.Init(group_id_, params_, base::nullopt /* proxy_annotation_tag */, + LOW, SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource()); EXPECT_THAT(rv, IsOk()); @@ -970,10 +990,11 @@ TEST_F(TransportClientSocketPoolTest, IdleSocketLoadTiming) { TEST_F(TransportClientSocketPoolTest, CloseIdleSocketsOnIPAddressChange) { TestCompletionCallback callback; ClientSocketHandle handle; - int rv = handle.Init( - group_id_, params_, LOW, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, callback.callback(), - ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource()); + int rv = + handle.Init(group_id_, params_, base::nullopt /* proxy_annotation_tag */, + LOW, SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback.callback(), ClientSocketPool::ProxyAuthCallback(), + pool_.get(), NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); EXPECT_FALSE(handle.is_initialized()); EXPECT_FALSE(handle.socket()); @@ -1005,23 +1026,21 @@ TEST_F(TransportClientSocketPoolTest, SSLCertError) { const HostPortPair kHostPortPair("ssl.server.test", 443); - scoped_refptr<TransportSocketParams> tcp_params = - base::MakeRefCounted<TransportSocketParams>(kHostPortPair, - OnHostResolutionCallback()); - scoped_refptr<SSLSocketParams> params( - new SSLSocketParams(tcp_params, nullptr, nullptr, kHostPortPair, - GetSSLConfig(), PRIVACY_MODE_DISABLED)); + scoped_refptr<ClientSocketPool::SocketParams> socket_params = + base::MakeRefCounted<ClientSocketPool::SocketParams>( + GetSSLConfig() /* ssl_config_for_origin */, + nullptr /* ssl_config_for_proxy */); ClientSocketHandle handle; TestCompletionCallback callback; - int rv = handle.Init( - ClientSocketPool::GroupId(kHostPortPair, - ClientSocketPool::SocketType::kSsl, - false /* privacy_mode */), - ClientSocketPool::SocketParams::CreateFromSSLSocketParams(params), MEDIUM, - SocketTag(), ClientSocketPool::RespectLimits::ENABLED, - callback.callback(), ClientSocketPool::ProxyAuthCallback(), - tagging_pool_.get(), NetLogWithSource()); + int rv = + handle.Init(ClientSocketPool::GroupId(kHostPortPair, + ClientSocketPool::SocketType::kSsl, + PrivacyMode::PRIVACY_MODE_DISABLED), + socket_params, base::nullopt /* proxy_annotation_tag */, + MEDIUM, SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback.callback(), ClientSocketPool::ProxyAuthCallback(), + tagging_pool_.get(), NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); EXPECT_FALSE(handle.is_initialized()); EXPECT_FALSE(handle.socket()); @@ -1034,10 +1053,11 @@ TEST_F(TransportClientSocketPoolTest, SSLCertError) { TEST_F(TransportClientSocketPoolTest, CloseIdleSocketsOnSSLConfigChange) { TestCompletionCallback callback; ClientSocketHandle handle; - int rv = handle.Init( - group_id_, params_, LOW, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, callback.callback(), - ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource()); + int rv = + handle.Init(group_id_, params_, base::nullopt /* proxy_annotation_tag */, + LOW, SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback.callback(), ClientSocketPool::ProxyAuthCallback(), + pool_.get(), NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); EXPECT_FALSE(handle.is_initialized()); EXPECT_FALSE(handle.socket()); @@ -1093,9 +1113,10 @@ TEST_F(TransportClientSocketPoolTest, BackupSocketConnect) { TestCompletionCallback callback; ClientSocketHandle handle; int rv = handle.Init( - group_id_, params_, LOW, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, callback.callback(), - ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource()); + group_id_, params_, base::nullopt /* proxy_annotation_tag */, LOW, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), + NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); EXPECT_FALSE(handle.is_initialized()); EXPECT_FALSE(handle.socket()); @@ -1137,9 +1158,10 @@ TEST_F(TransportClientSocketPoolTest, BackupSocketCancel) { TestCompletionCallback callback; ClientSocketHandle handle; int rv = handle.Init( - group_id_, params_, LOW, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, callback.callback(), - ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource()); + group_id_, params_, base::nullopt /* proxy_annotation_tag */, LOW, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback.callback(), ClientSocketPool::ProxyAuthCallback(), pool_.get(), + NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); EXPECT_FALSE(handle.is_initialized()); EXPECT_FALSE(handle.socket()); @@ -1184,10 +1206,11 @@ TEST_F(TransportClientSocketPoolTest, BackupSocketFailAfterStall) { TestCompletionCallback callback; ClientSocketHandle handle; - int rv = handle.Init( - group_id_, params_, LOW, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, callback.callback(), - ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource()); + int rv = + handle.Init(group_id_, params_, base::nullopt /* proxy_annotation_tag */, + LOW, SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback.callback(), ClientSocketPool::ProxyAuthCallback(), + pool_.get(), NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); EXPECT_FALSE(handle.is_initialized()); EXPECT_FALSE(handle.socket()); @@ -1234,10 +1257,11 @@ TEST_F(TransportClientSocketPoolTest, BackupSocketFailAfterDelay) { TestCompletionCallback callback; ClientSocketHandle handle; - int rv = handle.Init( - group_id_, params_, LOW, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, callback.callback(), - ClientSocketPool::ProxyAuthCallback(), pool_.get(), NetLogWithSource()); + int rv = + handle.Init(group_id_, params_, base::nullopt /* proxy_annotation_tag */, + LOW, SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback.callback(), ClientSocketPool::ProxyAuthCallback(), + pool_.get(), NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); EXPECT_FALSE(handle.is_initialized()); EXPECT_FALSE(handle.socket()); @@ -1267,30 +1291,33 @@ TEST_F(TransportClientSocketPoolTest, BackupSocketFailAfterDelay) { // Test the case that SOCKSSocketParams are provided. TEST_F(TransportClientSocketPoolTest, SOCKS) { - const HostPortPair kDesination("host", 80); + const HostPortPair kDestination("host", 80); + + TransportClientSocketPool proxy_pool( + kMaxSockets, kMaxSocketsPerGroup, kUnusedIdleSocketTimeout, + ProxyServer::FromURI("socks5://foopy", + ProxyServer::SCHEME_HTTP /* default_scheme */), + false /* is_for_websockets */, tagging_common_connect_job_params_.get(), + session_deps_.ssl_config_service.get()); + for (IoMode socket_io_mode : {SYNCHRONOUS, ASYNC}) { - scoped_refptr<TransportSocketParams> tcp_params = - base::MakeRefCounted<TransportSocketParams>(HostPortPair("proxy", 80), - OnHostResolutionCallback()); - scoped_refptr<ClientSocketPool::SocketParams> socks_params( - ClientSocketPool::SocketParams::CreateFromSOCKSSocketParams( - base::MakeRefCounted<SOCKSSocketParams>( - tcp_params, true /* socks_v5 */, kDesination, - TRAFFIC_ANNOTATION_FOR_TESTS))); + scoped_refptr<ClientSocketPool::SocketParams> socket_params = + base::MakeRefCounted<ClientSocketPool::SocketParams>( + nullptr /* ssl_config_for_origin */, + nullptr /* ssl_config_for_proxy */); SOCKS5MockData data(socket_io_mode); data.data_provider()->set_connect_data(MockConnect(socket_io_mode, OK)); tagging_client_socket_factory_.AddSocketDataProvider(data.data_provider()); ClientSocketHandle handle; TestCompletionCallback callback; - int rv = - handle.Init(ClientSocketPool::GroupId( - kDesination, ClientSocketPool::SocketType::kSsl, - false /* privacy_mode */), - socks_params, LOW, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, - callback.callback(), ClientSocketPool::ProxyAuthCallback(), - tagging_pool_.get(), NetLogWithSource()); + int rv = handle.Init( + ClientSocketPool::GroupId(kDestination, + ClientSocketPool::SocketType::kHttp, + PrivacyMode::PRIVACY_MODE_DISABLED), + socket_params, TRAFFIC_ANNOTATION_FOR_TESTS, LOW, SocketTag(), + ClientSocketPool::RespectLimits::ENABLED, callback.callback(), + ClientSocketPool::ProxyAuthCallback(), &proxy_pool, NetLogWithSource()); EXPECT_THAT(callback.GetResult(rv), IsOk()); EXPECT_TRUE(handle.is_initialized()); EXPECT_TRUE(handle.socket()); @@ -1306,14 +1333,16 @@ TEST_F(TransportClientSocketPoolTest, SOCKS) { // See https://crbug.com/940848 TEST_F(TransportClientSocketPoolTest, SpdyOneConnectJobTwoRequestsError) { const HostPortPair kEndpoint("unresolvable.host.name", 443); - const HostPortPair kProxy("unresolvable.proxy.name", 443); session_deps_.host_resolver->set_synchronous_mode(true); // Create a socket pool which only allows a single connection at a time. - TransportClientSocketPool pool(1, 1, kUnusedIdleSocketTimeout, - tagging_common_connect_job_params_.get(), - session_deps_.ssl_config_service.get()); + TransportClientSocketPool pool( + 1, 1, kUnusedIdleSocketTimeout, + ProxyServer::FromURI("https://unresolvable.proxy.name", + ProxyServer::SCHEME_HTTP /* default_scheme */), + false /* is_for_websockets */, tagging_common_connect_job_params_.get(), + session_deps_.ssl_config_service.get()); // First connection attempt will get an error after creating the SpdyStream. @@ -1345,49 +1374,33 @@ TEST_F(TransportClientSocketPoolTest, SpdyOneConnectJobTwoRequestsError) { SSLSocketDataProvider ssl_data2(SYNCHRONOUS, OK); tagging_client_socket_factory_.AddSSLSocketDataProvider(&ssl_data2); - scoped_refptr<TransportSocketParams> transport_params = - base::MakeRefCounted<TransportSocketParams>(kProxy, - OnHostResolutionCallback()); - - scoped_refptr<SSLSocketParams> proxy_ssl_params = - base::MakeRefCounted<SSLSocketParams>( - transport_params, nullptr /* socks_proxy_params */, - nullptr /* http_proxy_params */, kProxy, GetSSLConfig(), - PRIVACY_MODE_DISABLED); - - scoped_refptr<HttpProxySocketParams> http_proxy_params = - base::MakeRefCounted<HttpProxySocketParams>( - nullptr /* transport_params */, proxy_ssl_params, false /* is_quic */, - kEndpoint, false /* is_trusted_proxy */, true /* tunnel */, - TRAFFIC_ANNOTATION_FOR_TESTS); - scoped_refptr<SSLSocketParams> endpoint_ssl_params = - base::MakeRefCounted<SSLSocketParams>( - nullptr /* direct_params */, nullptr /* socks_proxy_params */, - http_proxy_params, kEndpoint, GetSSLConfig(), PRIVACY_MODE_DISABLED); - - scoped_refptr<ClientSocketPool::SocketParams> pool_params = - ClientSocketPool::SocketParams::CreateFromSSLSocketParams( - endpoint_ssl_params); - - ClientSocketPool::GroupId group_id( - kEndpoint, ClientSocketPool::SocketType::kSsl, false /* privacy_mode */); + scoped_refptr<ClientSocketPool::SocketParams> socket_params = + base::MakeRefCounted<ClientSocketPool::SocketParams>( + GetSSLConfig() /* ssl_config_for_origin */, + GetSSLConfig() /* ssl_config_for_proxy */); + + ClientSocketPool::GroupId group_id(kEndpoint, + ClientSocketPool::SocketType::kSsl, + PrivacyMode::PRIVACY_MODE_DISABLED); // Start the first connection attempt. TestCompletionCallback callback1; ClientSocketHandle handle1; int rv1 = handle1.Init( - group_id, pool_params, HIGHEST, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, callback1.callback(), - ClientSocketPool::ProxyAuthCallback(), &pool, NetLogWithSource()); + group_id, socket_params, TRAFFIC_ANNOTATION_FOR_TESTS, HIGHEST, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback1.callback(), ClientSocketPool::ProxyAuthCallback(), &pool, + NetLogWithSource()); ASSERT_THAT(rv1, IsError(ERR_IO_PENDING)); // Create a second request with a lower priority. TestCompletionCallback callback2; ClientSocketHandle handle2; int rv2 = handle2.Init( - group_id, pool_params, LOWEST, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, callback2.callback(), - ClientSocketPool::ProxyAuthCallback(), &pool, NetLogWithSource()); + group_id, socket_params, TRAFFIC_ANNOTATION_FOR_TESTS, LOWEST, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback2.callback(), ClientSocketPool::ProxyAuthCallback(), &pool, + NetLogWithSource()); ASSERT_THAT(rv2, IsError(ERR_IO_PENDING)); // First connection fails after creating a SpdySession and a SpdyStream on @@ -1415,9 +1428,12 @@ TEST_F(TransportClientSocketPoolTest, SpdyAuthOneConnectJobTwoRequests) { session_deps_.host_resolver->set_synchronous_mode(true); // Create a socket pool which only allows a single connection at a time. - TransportClientSocketPool pool(1, 1, kUnusedIdleSocketTimeout, - tagging_common_connect_job_params_.get(), - session_deps_.ssl_config_service.get()); + TransportClientSocketPool pool( + 1, 1, kUnusedIdleSocketTimeout, + ProxyServer::FromURI("https://unresolvable.proxy.name", + ProxyServer::SCHEME_HTTP /* default_scheme */), + false /* is_for_websockets */, tagging_common_connect_job_params_.get(), + session_deps_.ssl_config_service.get()); SpdyTestUtil spdy_util; spdy::SpdySerializedFrame connect(spdy_util.ConstructSpdyConnect( @@ -1462,38 +1478,21 @@ TEST_F(TransportClientSocketPoolTest, SpdyAuthOneConnectJobTwoRequests) { SSLSocketDataProvider ssl_data2(SYNCHRONOUS, OK); tagging_client_socket_factory_.AddSSLSocketDataProvider(&ssl_data2); - scoped_refptr<TransportSocketParams> transport_params = - base::MakeRefCounted<TransportSocketParams>(kProxy, - OnHostResolutionCallback()); - - scoped_refptr<SSLSocketParams> proxy_ssl_params = - base::MakeRefCounted<SSLSocketParams>( - transport_params, nullptr /* socks_proxy_params */, - nullptr /* http_proxy_params */, kProxy, GetSSLConfig(), - PRIVACY_MODE_DISABLED); - - scoped_refptr<HttpProxySocketParams> http_proxy_params = - base::MakeRefCounted<HttpProxySocketParams>( - nullptr /* transport_params */, proxy_ssl_params, false /* is_quic */, - kEndpoint, false /* is_trusted_proxy */, true /* tunnel */, - TRAFFIC_ANNOTATION_FOR_TESTS); - scoped_refptr<SSLSocketParams> endpoint_ssl_params = - base::MakeRefCounted<SSLSocketParams>( - nullptr /* direct_params */, nullptr /* socks_proxy_params */, - http_proxy_params, kEndpoint, GetSSLConfig(), PRIVACY_MODE_DISABLED); - - scoped_refptr<ClientSocketPool::SocketParams> pool_params = - ClientSocketPool::SocketParams::CreateFromSSLSocketParams( - endpoint_ssl_params); - - ClientSocketPool::GroupId group_id( - kEndpoint, ClientSocketPool::SocketType::kSsl, false /* privacy_mode */); + scoped_refptr<ClientSocketPool::SocketParams> socket_params = + base::MakeRefCounted<ClientSocketPool::SocketParams>( + GetSSLConfig() /* ssl_config_for_origin */, + GetSSLConfig() /* ssl_config_for_proxy */); + + ClientSocketPool::GroupId group_id(kEndpoint, + ClientSocketPool::SocketType::kSsl, + PrivacyMode::PRIVACY_MODE_DISABLED); // Start the first connection attempt. TestCompletionCallback callback1; ClientSocketHandle handle1; base::RunLoop run_loop; - int rv1 = handle1.Init(group_id, pool_params, HIGHEST, SocketTag(), + int rv1 = handle1.Init(group_id, socket_params, TRAFFIC_ANNOTATION_FOR_TESTS, + HIGHEST, SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback1.callback(), base::BindLambdaForTesting( @@ -1509,9 +1508,10 @@ TEST_F(TransportClientSocketPoolTest, SpdyAuthOneConnectJobTwoRequests) { TestCompletionCallback callback2; ClientSocketHandle handle2; int rv2 = handle2.Init( - group_id, pool_params, LOWEST, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, callback2.callback(), - ClientSocketPool::ProxyAuthCallback(), &pool, NetLogWithSource()); + group_id, socket_params, TRAFFIC_ANNOTATION_FOR_TESTS, LOWEST, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback2.callback(), ClientSocketPool::ProxyAuthCallback(), &pool, + NetLogWithSource()); ASSERT_THAT(rv2, IsError(ERR_IO_PENDING)); // The ConnectJob connection sees the auth challenge and HTTP2 error, which @@ -1530,7 +1530,6 @@ TEST_F(TransportClientSocketPoolTest, SpdyAuthOneConnectJobTwoRequests) { TEST_F(TransportClientSocketPoolTest, HttpTunnelSetupRedirect) { const HostPortPair kEndpoint("host.test", 443); - const HostPortPair kProxy("proxy.test", 443); const std::string kRedirectTarget = "https://some.other.host.test/"; @@ -1548,6 +1547,16 @@ TEST_F(TransportClientSocketPoolTest, HttpTunnelSetupRedirect) { for (bool use_https_proxy : {false, true}) { SCOPED_TRACE(use_https_proxy); + + TransportClientSocketPool proxy_pool( + kMaxSockets, kMaxSocketsPerGroup, kUnusedIdleSocketTimeout, + ProxyServer::FromURI( + use_https_proxy ? "https://proxy.test" : "http://proxy.test", + ProxyServer::SCHEME_HTTP /* default_scheme */), + false /* is_for_websockets */, + tagging_common_connect_job_params_.get(), + session_deps_.ssl_config_service.get()); + MockWrite writes[] = { MockWrite(ASYNC, 0, "CONNECT host.test:443 HTTP/1.1\r\n" @@ -1566,74 +1575,24 @@ TEST_F(TransportClientSocketPoolTest, HttpTunnelSetupRedirect) { ClientSocketHandle handle; TestCompletionCallback callback; - scoped_refptr<TransportSocketParams> transport_params = - base::MakeRefCounted<TransportSocketParams>( - kProxy, OnHostResolutionCallback()); - - scoped_refptr<SSLSocketParams> proxy_ssl_params = - base::MakeRefCounted<SSLSocketParams>( - transport_params, nullptr /* socks_proxy_params */, - nullptr /* http_proxy_params */, kProxy, GetSSLConfig(), - PRIVACY_MODE_DISABLED); - - scoped_refptr<HttpProxySocketParams> http_proxy_params = - base::MakeRefCounted<HttpProxySocketParams>( - use_https_proxy ? nullptr : transport_params, - use_https_proxy ? proxy_ssl_params : nullptr, false /* is_quic */, - kEndpoint, false /* is_trusted_proxy */, true /* tunnel */, - TRAFFIC_ANNOTATION_FOR_TESTS); - scoped_refptr<SSLSocketParams> endpoint_ssl_params = - base::MakeRefCounted<SSLSocketParams>( - nullptr /* direct_params */, nullptr /* socks_proxy_params */, - http_proxy_params, kEndpoint, GetSSLConfig(), - PRIVACY_MODE_DISABLED); - - // Whether the proxy is HTTPS or not, always connecting to an HTTPS site - // through it. - scoped_refptr<ClientSocketPool::SocketParams> pool_params = - ClientSocketPool::SocketParams::CreateFromSSLSocketParams( - endpoint_ssl_params); + scoped_refptr<ClientSocketPool::SocketParams> socket_params = + base::MakeRefCounted<ClientSocketPool::SocketParams>( + GetSSLConfig() /* ssl_config_for_origin */, + GetSSLConfig() /* ssl_config_for_proxy */); int rv = handle.Init( ClientSocketPool::GroupId(kEndpoint, ClientSocketPool::SocketType::kSsl, - false /* privacy_mode */), - pool_params, LOW, SocketTag(), + PrivacyMode::PRIVACY_MODE_DISABLED), + socket_params, TRAFFIC_ANNOTATION_FOR_TESTS, LOW, SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback.callback(), - ClientSocketPool::ProxyAuthCallback(), tagging_pool_.get(), + ClientSocketPool::ProxyAuthCallback(), &proxy_pool, NetLogWithSource()); rv = callback.GetResult(rv); - if (!use_https_proxy) { - // We don't trust 302 responses to CONNECT from HTTP proxies. - EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED)); - EXPECT_FALSE(handle.is_initialized()); - EXPECT_FALSE(handle.release_pending_http_proxy_socket()); - } else { - // Expect ProxyClientSocket to return the proxy's response, sanitized. - EXPECT_THAT(rv, IsError(ERR_HTTPS_PROXY_TUNNEL_RESPONSE_REDIRECT)); - EXPECT_FALSE(handle.is_initialized()); - - std::unique_ptr<StreamSocket> stream_socket = - handle.release_pending_http_proxy_socket(); - ASSERT_TRUE(stream_socket); - const ProxyClientSocket* tunnel_socket = - static_cast<ProxyClientSocket*>(stream_socket.get()); - const HttpResponseInfo* response = - tunnel_socket->GetConnectResponseInfo(); - const HttpResponseHeaders* headers = response->headers.get(); - - // Make sure Set-Cookie header was stripped. - EXPECT_FALSE(headers->HasHeader("set-cookie")); - - // Make sure Content-Length: 0 header was added. - EXPECT_TRUE(headers->HasHeaderValue("content-length", "0")); - - // Make sure Location header was included and correct. - std::string location; - EXPECT_TRUE(headers->IsRedirect(&location)); - EXPECT_EQ(location, kRedirectTarget); - } + // We don't trust 302 responses to CONNECT. + EXPECT_THAT(rv, IsError(ERR_TUNNEL_CONNECTION_FAILED)); + EXPECT_FALSE(handle.is_initialized()); } } } @@ -1661,17 +1620,16 @@ TEST_F(TransportClientSocketPoolTest, Tag) { // Test socket is tagged before connected. uint64_t old_traffic = GetTaggedBytes(tag_val1); const ClientSocketPool::GroupId kGroupId(test_server.host_port_pair(), - ClientSocketPool::SocketType::kSsl, - false /* privacy_mode */); + ClientSocketPool::SocketType::kHttp, + PrivacyMode::PRIVACY_MODE_DISABLED); scoped_refptr<ClientSocketPool::SocketParams> params = - ClientSocketPool::SocketParams::CreateFromTransportSocketParams( - base::MakeRefCounted<TransportSocketParams>( - test_server.host_port_pair(), OnHostResolutionCallback())); + ClientSocketPool::SocketParams::CreateForHttpForTesting(); TestCompletionCallback callback; - int rv = handle.Init( - kGroupId, params, LOW, tag1, ClientSocketPool::RespectLimits::ENABLED, - callback.callback(), ClientSocketPool::ProxyAuthCallback(), - pool_for_real_sockets_.get(), NetLogWithSource()); + int rv = + handle.Init(kGroupId, params, base::nullopt /* proxy_annotation_tag */, + LOW, tag1, ClientSocketPool::RespectLimits::ENABLED, + callback.callback(), ClientSocketPool::ProxyAuthCallback(), + pool_for_real_sockets_.get(), NetLogWithSource()); EXPECT_THAT(callback.GetResult(rv), IsOk()); EXPECT_TRUE(handle.socket()); EXPECT_TRUE(handle.socket()->IsConnected()); @@ -1681,8 +1639,8 @@ TEST_F(TransportClientSocketPoolTest, Tag) { StreamSocket* socket = handle.socket(); handle.Reset(); old_traffic = GetTaggedBytes(tag_val2); - rv = handle.Init(kGroupId, params, LOW, tag2, - ClientSocketPool::RespectLimits::ENABLED, + rv = handle.Init(kGroupId, params, base::nullopt /* proxy_annotation_tag */, + LOW, tag2, ClientSocketPool::RespectLimits::ENABLED, callback.callback(), ClientSocketPool::ProxyAuthCallback(), pool_for_real_sockets_.get(), NetLogWithSource()); EXPECT_THAT(rv, IsOk()); @@ -1704,15 +1662,15 @@ TEST_F(TransportClientSocketPoolTest, Tag) { // Test connect jobs that are orphaned and then adopted, appropriately apply // new tag. Request socket with |tag1|. TestCompletionCallback callback2; - rv = handle.Init(kGroupId, params, LOW, tag1, - ClientSocketPool::RespectLimits::ENABLED, + rv = handle.Init(kGroupId, params, base::nullopt /* proxy_annotation_tag */, + LOW, tag1, ClientSocketPool::RespectLimits::ENABLED, callback2.callback(), ClientSocketPool::ProxyAuthCallback(), pool_for_real_sockets_.get(), NetLogWithSource()); EXPECT_TRUE(rv == OK || rv == ERR_IO_PENDING) << "Result: " << rv; // Abort and request socket with |tag2|. handle.Reset(); - rv = handle.Init(kGroupId, params, LOW, tag2, - ClientSocketPool::RespectLimits::ENABLED, + rv = handle.Init(kGroupId, params, base::nullopt /* proxy_annotation_tag */, + LOW, tag2, ClientSocketPool::RespectLimits::ENABLED, callback.callback(), ClientSocketPool::ProxyAuthCallback(), pool_for_real_sockets_.get(), NetLogWithSource()); EXPECT_THAT(callback.GetResult(rv), IsOk()); @@ -1730,8 +1688,8 @@ TEST_F(TransportClientSocketPoolTest, Tag) { handle.Reset(); // Eat the left over connect job from the second request. // TODO(pauljensen): remove when crbug.com/800731 fixed. - rv = handle.Init(kGroupId, params, LOW, tag1, - ClientSocketPool::RespectLimits::ENABLED, + rv = handle.Init(kGroupId, params, base::nullopt /* proxy_annotation_tag */, + LOW, tag1, ClientSocketPool::RespectLimits::ENABLED, callback.callback(), ClientSocketPool::ProxyAuthCallback(), pool_for_real_sockets_.get(), NetLogWithSource()); EXPECT_THAT(rv, IsOk()); @@ -1743,15 +1701,16 @@ TEST_F(TransportClientSocketPoolTest, Tag) { // first but expect its socket to get vended to the higher priority request. ClientSocketHandle handle_high_pri; TestCompletionCallback callback_high_pri; - rv = handle.Init(kGroupId, params, LOW, tag1, - ClientSocketPool::RespectLimits::ENABLED, + rv = handle.Init(kGroupId, params, base::nullopt /* proxy_annotation_tag */, + LOW, tag1, ClientSocketPool::RespectLimits::ENABLED, callback.callback(), ClientSocketPool::ProxyAuthCallback(), pool_for_real_sockets_.get(), NetLogWithSource()); EXPECT_TRUE(rv == OK || rv == ERR_IO_PENDING) << "Result: " << rv; int rv_high_pri = handle_high_pri.Init( - kGroupId, params, HIGHEST, tag2, ClientSocketPool::RespectLimits::ENABLED, - callback_high_pri.callback(), ClientSocketPool::ProxyAuthCallback(), - pool_for_real_sockets_.get(), NetLogWithSource()); + kGroupId, params, base::nullopt /* proxy_annotation_tag */, HIGHEST, tag2, + ClientSocketPool::RespectLimits::ENABLED, callback_high_pri.callback(), + ClientSocketPool::ProxyAuthCallback(), pool_for_real_sockets_.get(), + NetLogWithSource()); EXPECT_THAT(callback_high_pri.GetResult(rv_high_pri), IsOk()); EXPECT_TRUE(handle_high_pri.socket()); EXPECT_TRUE(handle_high_pri.socket()->IsConnected()); @@ -1777,20 +1736,23 @@ TEST_F(TransportClientSocketPoolTest, Tag) { TEST_F(TransportClientSocketPoolTest, TagSOCKSProxy) { session_deps_.host_resolver->set_synchronous_mode(true); + TransportClientSocketPool proxy_pool( + kMaxSockets, kMaxSocketsPerGroup, kUnusedIdleSocketTimeout, + ProxyServer::FromURI("socks5://proxy", + ProxyServer::SCHEME_HTTP /* default_scheme */), + false /* is_for_websockets */, tagging_common_connect_job_params_.get(), + session_deps_.ssl_config_service.get()); + SocketTag tag1(SocketTag::UNSET_UID, 0x12345678); SocketTag tag2(getuid(), 0x87654321); const HostPortPair kDestination("host", 80); const ClientSocketPool::GroupId kGroupId(kDestination, ClientSocketPool::SocketType::kHttp, - false /* privacy_mode */); - scoped_refptr<TransportSocketParams> tcp_params = - base::MakeRefCounted<TransportSocketParams>(HostPortPair("proxy", 80), - OnHostResolutionCallback()); - scoped_refptr<ClientSocketPool::SocketParams> socks_params( - ClientSocketPool::SocketParams::CreateFromSOCKSSocketParams( - base::MakeRefCounted<SOCKSSocketParams>( - tcp_params, true /* socks_v5 */, kDestination, - TRAFFIC_ANNOTATION_FOR_TESTS))); + PrivacyMode::PRIVACY_MODE_DISABLED); + scoped_refptr<ClientSocketPool::SocketParams> socks_params = + base::MakeRefCounted<ClientSocketPool::SocketParams>( + nullptr /* ssl_config_for_origin */, + nullptr /* ssl_config_for_proxy */); // Test socket is tagged when created synchronously. SOCKS5MockData data_sync(SYNCHRONOUS); @@ -1798,11 +1760,10 @@ TEST_F(TransportClientSocketPoolTest, TagSOCKSProxy) { tagging_client_socket_factory_.AddSocketDataProvider( data_sync.data_provider()); ClientSocketHandle handle; - int rv = handle.Init(kGroupId, socks_params, LOW, tag1, - ClientSocketPool::RespectLimits::ENABLED, - CompletionOnceCallback(), - ClientSocketPool::ProxyAuthCallback(), - tagging_pool_.get(), NetLogWithSource()); + int rv = handle.Init( + kGroupId, socks_params, TRAFFIC_ANNOTATION_FOR_TESTS, LOW, tag1, + ClientSocketPool::RespectLimits::ENABLED, CompletionOnceCallback(), + ClientSocketPool::ProxyAuthCallback(), &proxy_pool, NetLogWithSource()); EXPECT_THAT(rv, IsOk()); EXPECT_TRUE(handle.is_initialized()); EXPECT_TRUE(handle.socket()); @@ -1814,11 +1775,10 @@ TEST_F(TransportClientSocketPoolTest, TagSOCKSProxy) { // Test socket is tagged when reused synchronously. StreamSocket* socket = handle.socket(); handle.Reset(); - rv = handle.Init(kGroupId, socks_params, LOW, tag2, - ClientSocketPool::RespectLimits::ENABLED, - CompletionOnceCallback(), - ClientSocketPool::ProxyAuthCallback(), tagging_pool_.get(), - NetLogWithSource()); + rv = handle.Init( + kGroupId, socks_params, TRAFFIC_ANNOTATION_FOR_TESTS, LOW, tag2, + ClientSocketPool::RespectLimits::ENABLED, CompletionOnceCallback(), + ClientSocketPool::ProxyAuthCallback(), &proxy_pool, NetLogWithSource()); EXPECT_THAT(rv, IsOk()); EXPECT_TRUE(handle.socket()); EXPECT_TRUE(handle.socket()->IsConnected()); @@ -1833,10 +1793,10 @@ TEST_F(TransportClientSocketPoolTest, TagSOCKSProxy) { tagging_client_socket_factory_.AddSocketDataProvider( data_async.data_provider()); TestCompletionCallback callback; - rv = handle.Init(kGroupId, socks_params, LOW, tag1, - ClientSocketPool::RespectLimits::ENABLED, + rv = handle.Init(kGroupId, socks_params, TRAFFIC_ANNOTATION_FOR_TESTS, LOW, + tag1, ClientSocketPool::RespectLimits::ENABLED, callback.callback(), ClientSocketPool::ProxyAuthCallback(), - tagging_pool_.get(), NetLogWithSource()); + &proxy_pool, NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); EXPECT_THAT(callback.WaitForResult(), IsOk()); EXPECT_TRUE(handle.is_initialized()); @@ -1849,11 +1809,10 @@ TEST_F(TransportClientSocketPoolTest, TagSOCKSProxy) { // Test socket is tagged when reused after being created asynchronously. socket = handle.socket(); handle.Reset(); - rv = handle.Init(kGroupId, socks_params, LOW, tag2, - ClientSocketPool::RespectLimits::ENABLED, - CompletionOnceCallback(), - ClientSocketPool::ProxyAuthCallback(), tagging_pool_.get(), - NetLogWithSource()); + rv = handle.Init( + kGroupId, socks_params, TRAFFIC_ANNOTATION_FOR_TESTS, LOW, tag2, + ClientSocketPool::RespectLimits::ENABLED, CompletionOnceCallback(), + ClientSocketPool::ProxyAuthCallback(), &proxy_pool, NetLogWithSource()); EXPECT_THAT(rv, IsOk()); EXPECT_TRUE(handle.socket()); EXPECT_TRUE(handle.socket()->IsConnected()); @@ -1874,12 +1833,6 @@ TEST_F(TransportClientSocketPoolTest, TagSSLDirect) { test_server.AddDefaultHandlers(base::FilePath()); ASSERT_TRUE(test_server.Start()); - // TLS 1.3 sockets aren't reused until the read side has been pumped. - // TODO(crbug.com/906668): Support pumping the read side and setting the - // socket to be reusable. - SSLConfig ssl_config = GetSSLConfig(); - ssl_config.version_max = SSL_PROTOCOL_VERSION_TLS1_2; - TestCompletionCallback callback; ClientSocketHandle handle; int32_t tag_val1 = 0x12345678; @@ -1888,19 +1841,17 @@ TEST_F(TransportClientSocketPoolTest, TagSSLDirect) { SocketTag tag2(getuid(), tag_val2); const ClientSocketPool::GroupId kGroupId(test_server.host_port_pair(), ClientSocketPool::SocketType::kSsl, - false /* privacy_mode */); - scoped_refptr<TransportSocketParams> tcp_params = - base::MakeRefCounted<TransportSocketParams>(test_server.host_port_pair(), - OnHostResolutionCallback()); - scoped_refptr<SSLSocketParams> params(new SSLSocketParams( - tcp_params, nullptr, nullptr, test_server.host_port_pair(), ssl_config, - PRIVACY_MODE_DISABLED)); + PrivacyMode::PRIVACY_MODE_DISABLED); + + scoped_refptr<ClientSocketPool::SocketParams> socket_params = + base::MakeRefCounted<ClientSocketPool::SocketParams>( + std::make_unique<SSLConfig>() /* ssl_config_for_origin */, + nullptr /* ssl_config_for_proxy */); // Test socket is tagged before connected. uint64_t old_traffic = GetTaggedBytes(tag_val1); int rv = handle.Init( - kGroupId, - ClientSocketPool::SocketParams::CreateFromSSLSocketParams(params), LOW, + kGroupId, socket_params, base::nullopt /* proxy_annotation_tag */, LOW, tag1, ClientSocketPool::RespectLimits::ENABLED, callback.callback(), ClientSocketPool::ProxyAuthCallback(), pool_for_real_sockets_.get(), NetLogWithSource()); @@ -1914,12 +1865,11 @@ TEST_F(TransportClientSocketPoolTest, TagSSLDirect) { handle.Reset(); old_traffic = GetTaggedBytes(tag_val2); TestCompletionCallback callback2; - rv = handle.Init( - kGroupId, - ClientSocketPool::SocketParams::CreateFromSSLSocketParams(params), LOW, - tag2, ClientSocketPool::RespectLimits::ENABLED, callback2.callback(), - ClientSocketPool::ProxyAuthCallback(), pool_for_real_sockets_.get(), - NetLogWithSource()); + rv = handle.Init(kGroupId, socket_params, + base::nullopt /* proxy_annotation_tag */, LOW, tag2, + ClientSocketPool::RespectLimits::ENABLED, + callback2.callback(), ClientSocketPool::ProxyAuthCallback(), + pool_for_real_sockets_.get(), NetLogWithSource()); EXPECT_THAT(rv, IsOk()); EXPECT_TRUE(handle.socket()); EXPECT_TRUE(handle.socket()->IsConnected()); @@ -1961,20 +1911,17 @@ TEST_F(TransportClientSocketPoolTest, TagSSLDirectTwoSockets) { SocketTag tag2(getuid(), tag_val2); const ClientSocketPool::GroupId kGroupId(test_server.host_port_pair(), ClientSocketPool::SocketType::kSsl, - false /* privacy_mode */); - scoped_refptr<TransportSocketParams> tcp_params = - base::MakeRefCounted<TransportSocketParams>(test_server.host_port_pair(), - OnHostResolutionCallback()); - scoped_refptr<SSLSocketParams> params(new SSLSocketParams( - tcp_params, nullptr, nullptr, test_server.host_port_pair(), - GetSSLConfig(), PRIVACY_MODE_DISABLED)); + PrivacyMode::PRIVACY_MODE_DISABLED); + scoped_refptr<ClientSocketPool::SocketParams> socket_params = + base::MakeRefCounted<ClientSocketPool::SocketParams>( + GetSSLConfig() /* ssl_config_for_origin */, + nullptr /* ssl_config_for_proxy */); // Test connect jobs that are orphaned and then adopted, appropriately apply // new tag. Request socket with |tag1|. TestCompletionCallback callback; int rv = handle.Init( - kGroupId, - ClientSocketPool::SocketParams::CreateFromSSLSocketParams(params), LOW, + kGroupId, socket_params, base::nullopt /* proxy_annotation_tag */, LOW, tag1, ClientSocketPool::RespectLimits::ENABLED, callback.callback(), ClientSocketPool::ProxyAuthCallback(), pool_for_real_sockets_.get(), NetLogWithSource()); @@ -1982,12 +1929,11 @@ TEST_F(TransportClientSocketPoolTest, TagSSLDirectTwoSockets) { // Abort and request socket with |tag2|. handle.Reset(); TestCompletionCallback callback2; - rv = handle.Init( - kGroupId, - ClientSocketPool::SocketParams::CreateFromSSLSocketParams(params), LOW, - tag2, ClientSocketPool::RespectLimits::ENABLED, callback2.callback(), - ClientSocketPool::ProxyAuthCallback(), pool_for_real_sockets_.get(), - NetLogWithSource()); + rv = handle.Init(kGroupId, socket_params, + base::nullopt /* proxy_annotation_tag */, LOW, tag2, + ClientSocketPool::RespectLimits::ENABLED, + callback2.callback(), ClientSocketPool::ProxyAuthCallback(), + pool_for_real_sockets_.get(), NetLogWithSource()); EXPECT_THAT(callback2.GetResult(rv), IsOk()); EXPECT_TRUE(handle.socket()); EXPECT_TRUE(handle.socket()->IsConnected()); @@ -2028,13 +1974,11 @@ TEST_F(TransportClientSocketPoolTest, TagSSLDirectTwoSocketsFullPool) { SocketTag tag2(getuid(), tag_val2); const ClientSocketPool::GroupId kGroupId(test_server.host_port_pair(), ClientSocketPool::SocketType::kSsl, - false /* privacy_mode */); - scoped_refptr<TransportSocketParams> tcp_params = - base::MakeRefCounted<TransportSocketParams>(test_server.host_port_pair(), - OnHostResolutionCallback()); - scoped_refptr<SSLSocketParams> params(new SSLSocketParams( - tcp_params, nullptr, nullptr, test_server.host_port_pair(), - GetSSLConfig(), PRIVACY_MODE_DISABLED)); + PrivacyMode::PRIVACY_MODE_DISABLED); + scoped_refptr<ClientSocketPool::SocketParams> socket_params = + base::MakeRefCounted<ClientSocketPool::SocketParams>( + GetSSLConfig() /* ssl_config_for_origin */, + nullptr /* ssl_config_for_proxy */); // Test that sockets paused by a full underlying socket pool are properly // connected and tagged when underlying pool is freed up. @@ -2043,12 +1987,10 @@ TEST_F(TransportClientSocketPoolTest, TagSSLDirectTwoSocketsFullPool) { int rv; for (auto& tcp_handle : tcp_handles) { rv = tcp_handle.Init( - kGroupId, - ClientSocketPool::SocketParams::CreateFromTransportSocketParams( - tcp_params), - LOW, tag1, ClientSocketPool::RespectLimits::ENABLED, - callback.callback(), ClientSocketPool::ProxyAuthCallback(), - pool_for_real_sockets_.get(), NetLogWithSource()); + kGroupId, socket_params, base::nullopt /* proxy_annotation_tag */, LOW, + tag1, ClientSocketPool::RespectLimits::ENABLED, callback.callback(), + ClientSocketPool::ProxyAuthCallback(), pool_for_real_sockets_.get(), + NetLogWithSource()); EXPECT_THAT(callback.GetResult(rv), IsOk()); EXPECT_TRUE(tcp_handle.socket()); EXPECT_TRUE(tcp_handle.socket()->IsConnected()); @@ -2056,18 +1998,16 @@ TEST_F(TransportClientSocketPoolTest, TagSSLDirectTwoSocketsFullPool) { // Request two SSL sockets. ClientSocketHandle handle_to_be_canceled; rv = handle_to_be_canceled.Init( - kGroupId, - ClientSocketPool::SocketParams::CreateFromSSLSocketParams(params), LOW, + kGroupId, socket_params, base::nullopt /* proxy_annotation_tag */, LOW, tag1, ClientSocketPool::RespectLimits::ENABLED, callback.callback(), ClientSocketPool::ProxyAuthCallback(), pool_for_real_sockets_.get(), NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); - rv = handle.Init( - kGroupId, - ClientSocketPool::SocketParams::CreateFromSSLSocketParams(params), LOW, - tag2, ClientSocketPool::RespectLimits::ENABLED, callback.callback(), - ClientSocketPool::ProxyAuthCallback(), pool_for_real_sockets_.get(), - NetLogWithSource()); + rv = handle.Init(kGroupId, socket_params, + base::nullopt /* proxy_annotation_tag */, LOW, tag2, + ClientSocketPool::RespectLimits::ENABLED, + callback.callback(), ClientSocketPool::ProxyAuthCallback(), + pool_for_real_sockets_.get(), NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); // Cancel first request. handle_to_be_canceled.Reset(); @@ -2099,6 +2039,13 @@ TEST_F(TransportClientSocketPoolTest, TagHttpProxyNoTunnel) { SocketTag tag1(SocketTag::UNSET_UID, 0x12345678); SocketTag tag2(getuid(), 0x87654321); + TransportClientSocketPool proxy_pool( + kMaxSockets, kMaxSocketsPerGroup, kUnusedIdleSocketTimeout, + ProxyServer::FromURI("http://proxy", + ProxyServer::SCHEME_HTTP /* default_scheme */), + false /* is_for_websockets */, tagging_common_connect_job_params_.get(), + session_deps_.ssl_config_service.get()); + session_deps_.host_resolver->set_synchronous_mode(true); SequencedSocketData socket_data; socket_data.set_connect_data(MockConnect(SYNCHRONOUS, OK)); @@ -2106,24 +2053,19 @@ TEST_F(TransportClientSocketPoolTest, TagHttpProxyNoTunnel) { const HostPortPair kDestination("www.google.com", 80); const ClientSocketPool::GroupId kGroupId(kDestination, - ClientSocketPool::SocketType::kSsl, - false /* privacy_mode */); - scoped_refptr<ClientSocketPool::SocketParams> params = - ClientSocketPool::SocketParams::CreateFromHttpProxySocketParams( - base::MakeRefCounted<HttpProxySocketParams>( - base::MakeRefCounted<TransportSocketParams>( - HostPortPair("http.proxy.host", 80), - OnHostResolutionCallback()), - nullptr /* ssl_params */, false /* is_quic */, kDestination, - false /* is_trusted_proxy */, false /* tunnel */, - TRAFFIC_ANNOTATION_FOR_TESTS)); + ClientSocketPool::SocketType::kHttp, + PrivacyMode::PRIVACY_MODE_DISABLED); + scoped_refptr<ClientSocketPool::SocketParams> socket_params = + base::MakeRefCounted<ClientSocketPool::SocketParams>( + nullptr /* ssl_config_for_origin */, + nullptr /* ssl_config_for_proxy */); // Verify requested socket is tagged properly. ClientSocketHandle handle; int rv = handle.Init( - kGroupId, params, LOW, tag1, ClientSocketPool::RespectLimits::ENABLED, - CompletionOnceCallback(), ClientSocketPool::ProxyAuthCallback(), - tagging_pool_.get(), NetLogWithSource()); + kGroupId, socket_params, TRAFFIC_ANNOTATION_FOR_TESTS, LOW, tag1, + ClientSocketPool::RespectLimits::ENABLED, CompletionOnceCallback(), + ClientSocketPool::ProxyAuthCallback(), &proxy_pool, NetLogWithSource()); EXPECT_THAT(rv, IsOk()); EXPECT_TRUE(handle.is_initialized()); ASSERT_TRUE(handle.socket()); @@ -2137,9 +2079,9 @@ TEST_F(TransportClientSocketPoolTest, TagHttpProxyNoTunnel) { StreamSocket* socket = handle.socket(); handle.Reset(); rv = handle.Init( - kGroupId, params, LOW, tag2, ClientSocketPool::RespectLimits::ENABLED, - CompletionOnceCallback(), ClientSocketPool::ProxyAuthCallback(), - tagging_pool_.get(), NetLogWithSource()); + kGroupId, socket_params, TRAFFIC_ANNOTATION_FOR_TESTS, LOW, tag2, + ClientSocketPool::RespectLimits::ENABLED, CompletionOnceCallback(), + ClientSocketPool::ProxyAuthCallback(), &proxy_pool, NetLogWithSource()); EXPECT_THAT(rv, IsOk()); EXPECT_TRUE(handle.socket()); EXPECT_TRUE(handle.socket()->IsConnected()); @@ -2157,6 +2099,13 @@ TEST_F(TransportClientSocketPoolTest, TagHttpProxyTunnel) { SocketTag tag1(SocketTag::UNSET_UID, 0x12345678); SocketTag tag2(getuid(), 0x87654321); + TransportClientSocketPool proxy_pool( + kMaxSockets, kMaxSocketsPerGroup, kUnusedIdleSocketTimeout, + ProxyServer::FromURI("http://proxy", + ProxyServer::SCHEME_HTTP /* default_scheme */), + false /* is_for_websockets */, tagging_common_connect_job_params_.get(), + session_deps_.ssl_config_service.get()); + session_deps_.host_resolver->set_synchronous_mode(true); std::string request = @@ -2172,27 +2121,25 @@ TEST_F(TransportClientSocketPoolTest, TagHttpProxyTunnel) { SequencedSocketData socket_data(MockConnect(SYNCHRONOUS, OK), reads, writes); tagging_client_socket_factory_.AddSocketDataProvider(&socket_data); + SSLSocketDataProvider ssl_data(SYNCHRONOUS, OK); + tagging_client_socket_factory_.AddSSLSocketDataProvider(&ssl_data); const HostPortPair kDestination("www.google.com", 443); const ClientSocketPool::GroupId kGroupId(kDestination, ClientSocketPool::SocketType::kSsl, - false /* privacy_mode */); - scoped_refptr<ClientSocketPool::SocketParams> params = - ClientSocketPool::SocketParams::CreateFromHttpProxySocketParams( - base::MakeRefCounted<HttpProxySocketParams>( - base::MakeRefCounted<TransportSocketParams>( - HostPortPair("http.proxy.host", 80), - OnHostResolutionCallback()), - nullptr /* ssl_params */, quic::QUIC_VERSION_UNSUPPORTED, - kDestination, false /* is_trusted_proxy */, true /* tunnel */, - TRAFFIC_ANNOTATION_FOR_TESTS)); + PrivacyMode::PRIVACY_MODE_DISABLED); + + scoped_refptr<ClientSocketPool::SocketParams> socket_params = + base::MakeRefCounted<ClientSocketPool::SocketParams>( + GetSSLConfig() /* ssl_config_for_origin */, + nullptr /* ssl_config_for_proxy */); // Verify requested socket is tagged properly. ClientSocketHandle handle; int rv = handle.Init( - kGroupId, params, LOW, tag1, ClientSocketPool::RespectLimits::ENABLED, - CompletionOnceCallback(), ClientSocketPool::ProxyAuthCallback(), - tagging_pool_.get(), NetLogWithSource()); + kGroupId, socket_params, TRAFFIC_ANNOTATION_FOR_TESTS, LOW, tag1, + ClientSocketPool::RespectLimits::ENABLED, CompletionOnceCallback(), + ClientSocketPool::ProxyAuthCallback(), &proxy_pool, NetLogWithSource()); EXPECT_THAT(rv, IsOk()); EXPECT_TRUE(handle.is_initialized()); ASSERT_TRUE(handle.socket()); @@ -2206,9 +2153,9 @@ TEST_F(TransportClientSocketPoolTest, TagHttpProxyTunnel) { StreamSocket* socket = handle.socket(); handle.Reset(); rv = handle.Init( - kGroupId, params, LOW, tag2, ClientSocketPool::RespectLimits::ENABLED, - CompletionOnceCallback(), ClientSocketPool::ProxyAuthCallback(), - tagging_pool_.get(), NetLogWithSource()); + kGroupId, socket_params, TRAFFIC_ANNOTATION_FOR_TESTS, LOW, tag2, + ClientSocketPool::RespectLimits::ENABLED, CompletionOnceCallback(), + ClientSocketPool::ProxyAuthCallback(), &proxy_pool, NetLogWithSource()); EXPECT_THAT(rv, IsOk()); EXPECT_TRUE(handle.socket()); EXPECT_TRUE(handle.socket()->IsConnected()); @@ -2295,20 +2242,21 @@ TEST_F(TransportClientSocketPoolMockNowSourceTest, IdleUnusedSocketTimeout) { base::span<MockRead>(), kWrites); { // Create 1 socket. - scoped_refptr<TransportSocketParams> transport_params( - base::MakeRefCounted<TransportSocketParams>( - kHostPortPair1, OnHostResolutionCallback())); + scoped_refptr<ClientSocketPool::SocketParams> socket_params = + base::MakeRefCounted<ClientSocketPool::SocketParams>( + nullptr /* ssl_config_for_origin */, + nullptr /* ssl_config_for_proxy */); session_deps.socket_factory->AddSocketDataProvider(&provider_socket_1); ClientSocketHandle connection; TestCompletionCallback callback; int rv = connection.Init( ClientSocketPool::GroupId(kHostPortPair1, ClientSocketPool::SocketType::kHttp, - false /* privacy_mode */), - ClientSocketPool::SocketParams::CreateFromTransportSocketParams( - transport_params), - MEDIUM, SocketTag(), ClientSocketPool::RespectLimits::ENABLED, - callback.callback(), ClientSocketPool::ProxyAuthCallback(), + PrivacyMode::PRIVACY_MODE_DISABLED), + ClientSocketPool::SocketParams::CreateForHttpForTesting(), + base::nullopt /* proxy_annotation_tag */, MEDIUM, SocketTag(), + ClientSocketPool::RespectLimits::ENABLED, callback.callback(), + ClientSocketPool::ProxyAuthCallback(), session->GetSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct()), NetLogWithSource()); @@ -2339,9 +2287,10 @@ TEST_F(TransportClientSocketPoolMockNowSourceTest, IdleUnusedSocketTimeout) { { // Request a new socket to trigger cleanup of idle timedout sockets. - scoped_refptr<TransportSocketParams> transport_params( - base::MakeRefCounted<TransportSocketParams>( - kHostPortPair2, OnHostResolutionCallback())); + scoped_refptr<ClientSocketPool::SocketParams> socket_params = + base::MakeRefCounted<ClientSocketPool::SocketParams>( + nullptr /* ssl_config_for_origin */, + nullptr /* ssl_config_for_proxy */); SequencedSocketData provider_socket_2(MockConnect(ASYNC, OK), base::span<MockRead>(), base::span<MockWrite>()); @@ -2351,10 +2300,9 @@ TEST_F(TransportClientSocketPoolMockNowSourceTest, IdleUnusedSocketTimeout) { int rv = connection.Init( ClientSocketPool::GroupId(kHostPortPair2, ClientSocketPool::SocketType::kHttp, - false /* privacy_mode */), - ClientSocketPool::SocketParams::CreateFromTransportSocketParams( - transport_params), - MEDIUM, SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + PrivacyMode::PRIVACY_MODE_DISABLED), + socket_params, base::nullopt /* proxy_annotation_tag */, MEDIUM, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback.callback(), ClientSocketPool::ProxyAuthCallback(), session->GetSocketPool(HttpNetworkSession::NORMAL_SOCKET_POOL, ProxyServer::Direct()), diff --git a/chromium/net/socket/transport_connect_job.cc b/chromium/net/socket/transport_connect_job.cc index 30707ffac17..047ac7add56 100644 --- a/chromium/net/socket/transport_connect_job.cc +++ b/chromium/net/socket/transport_connect_job.cc @@ -12,6 +12,7 @@ #include "base/logging.h" #include "base/metrics/histogram_macros.h" #include "base/strings/string_util.h" +#include "base/threading/thread_task_runner_handle.h" #include "base/trace_event/trace_event.h" #include "base/values.h" #include "net/base/ip_endpoint.h" @@ -100,7 +101,8 @@ TransportConnectJob::TransportConnectJob( NetLogEventType::TRANSPORT_CONNECT_JOB_CONNECT), params_(params), next_state_(STATE_NONE), - resolve_result_(OK) { + resolve_result_(OK), + weak_ptr_factory_(this) { // This is only set for WebSockets. DCHECK(!common_connect_job_params->websocket_endpoint_lock_manager); } @@ -278,15 +280,22 @@ int TransportConnectJob::DoResolveHostComplete(int result) { return result; DCHECK(request_->GetAddressResults()); - // Invoke callback, and abort if it fails. + next_state_ = STATE_TRANSPORT_CONNECT; + + // Invoke callback. If it indicates |this| may be slated for deletion, then + // only continue after a PostTask. if (!params_->host_resolution_callback().is_null()) { - result = params_->host_resolution_callback().Run( - request_->GetAddressResults().value(), net_log()); - if (result != OK) - return result; + OnHostResolutionCallbackResult callback_result = + params_->host_resolution_callback().Run( + params_->destination(), request_->GetAddressResults().value()); + if (callback_result == OnHostResolutionCallbackResult::kMayBeDeletedAsync) { + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::BindOnce(&TransportConnectJob::OnIOComplete, + weak_ptr_factory_.GetWeakPtr(), OK)); + return ERR_IO_PENDING; + } } - next_state_ = STATE_TRANSPORT_CONNECT; return result; } diff --git a/chromium/net/socket/transport_connect_job.h b/chromium/net/socket/transport_connect_job.h index b25ebc5389a..0258e52eb42 100644 --- a/chromium/net/socket/transport_connect_job.h +++ b/chromium/net/socket/transport_connect_job.h @@ -8,8 +8,10 @@ #include <memory> #include <string> +#include "base/callback.h" #include "base/macros.h" #include "base/memory/ref_counted.h" +#include "base/memory/weak_ptr.h" #include "base/time/time.h" #include "base/timer/timer.h" #include "net/base/host_port_pair.h" @@ -24,10 +26,6 @@ namespace net { class NetLogWithSource; class SocketTag; -typedef base::RepeatingCallback<int(const AddressList&, - const NetLogWithSource& net_log)> - OnHostResolutionCallback; - class NET_EXPORT_PRIVATE TransportSocketParams : public base::RefCounted<TransportSocketParams> { public: @@ -172,6 +170,8 @@ class NET_EXPORT_PRIVATE TransportConnectJob : public ConnectJob { ConnectionAttempts connection_attempts_; ConnectionAttempts fallback_connection_attempts_; + base::WeakPtrFactory<TransportConnectJob> weak_ptr_factory_; + DISALLOW_COPY_AND_ASSIGN(TransportConnectJob); }; diff --git a/chromium/net/socket/udp_net_log_parameters.cc b/chromium/net/socket/udp_net_log_parameters.cc index 4efcbd98040..d6b6fad3af7 100644 --- a/chromium/net/socket/udp_net_log_parameters.cc +++ b/chromium/net/socket/udp_net_log_parameters.cc @@ -15,28 +15,27 @@ namespace net { namespace { -std::unique_ptr<base::Value> NetLogUDPDataTranferCallback( - int byte_count, - const char* bytes, - const IPEndPoint* address, - NetLogCaptureMode capture_mode) { - std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); - dict->SetInteger("byte_count", byte_count); +base::Value NetLogUDPDataTranferCallback(int byte_count, + const char* bytes, + const IPEndPoint* address, + NetLogCaptureMode capture_mode) { + base::DictionaryValue dict; + dict.SetInteger("byte_count", byte_count); if (capture_mode.include_socket_bytes()) - dict->SetKey("bytes", NetLogBinaryValue(bytes, byte_count)); + dict.SetKey("bytes", NetLogBinaryValue(bytes, byte_count)); if (address) - dict->SetString("address", address->ToString()); + dict.SetString("address", address->ToString()); return std::move(dict); } -std::unique_ptr<base::Value> NetLogUDPConnectCallback( +base::Value NetLogUDPConnectCallback( const IPEndPoint* address, NetworkChangeNotifier::NetworkHandle network, NetLogCaptureMode /* capture_mode */) { - std::unique_ptr<base::DictionaryValue> dict(new base::DictionaryValue()); - dict->SetString("address", address->ToString()); + base::DictionaryValue dict; + dict.SetString("address", address->ToString()); if (network != NetworkChangeNotifier::kInvalidNetworkHandle) - dict->SetInteger("bound_to_network", network); + dict.SetInteger("bound_to_network", network); return std::move(dict); } diff --git a/chromium/net/socket/udp_socket_unittest.cc b/chromium/net/socket/udp_socket_unittest.cc index 17f7d117a73..b89b518b4bc 100644 --- a/chromium/net/socket/udp_socket_unittest.cc +++ b/chromium/net/socket/udp_socket_unittest.cc @@ -49,6 +49,7 @@ using net::test::IsError; using net::test::IsOk; +using testing::DoAll; using testing::Not; namespace net { @@ -316,7 +317,7 @@ TEST_F(UDPSocketTest, PartialRecv) { // - Android: devices attached to testbots don't have default network, so // broadcasting to 255.255.255.255 returns error -109 (Address not reachable). // crbug.com/139144. -// - Fuchsia: TODO(fuchsia): broadcast support is not implemented yet. +// - Fuchsia: TODO(crbug.com/959314): broadcast support is not implemented yet. #define MAYBE_LocalBroadcast DISABLED_LocalBroadcast #else #define MAYBE_LocalBroadcast LocalBroadcast @@ -410,14 +411,7 @@ TEST_F(UDPSocketTest, ConnectRandomBind) { } } -#if defined(OS_FUCHSIA) -// Currently the test fails on Fuchsia because netstack allows to connect IPv4 -// socket to IPv6 address. This issue is tracked by NET-596. -#define MAYBE_ConnectFail DISABLED_ConnectFail -#else -#define MAYBE_ConnectFail ConnectFail -#endif -TEST_F(UDPSocketTest, MAYBE_ConnectFail) { +TEST_F(UDPSocketTest, ConnectFail) { UDPSocket socket(DatagramSocket::DEFAULT_BIND, nullptr, NetLogSource()); EXPECT_THAT(socket.Open(ADDRESS_FAMILY_IPV4), IsOk()); @@ -566,13 +560,7 @@ TEST_F(UDPSocketTest, ServerGetPeerAddress) { EXPECT_EQ(rv, ERR_SOCKET_NOT_CONNECTED); } -#if defined(OS_FUCHSIA) -// TODO(crbug.com/945590): Re-enable after the breaking SDK change has landed. -#define MAYBE_ClientSetDoNotFragment DISABLED_ClientSetDoNotFragment -#else -#define MAYBE_ClientSetDoNotFragment ClientSetDoNotFragment -#endif -TEST_F(UDPSocketTest, MAYBE_ClientSetDoNotFragment) { +TEST_F(UDPSocketTest, ClientSetDoNotFragment) { for (std::string ip : {"127.0.0.1", "::1"}) { UDPClientSocket client(DatagramSocket::DEFAULT_BIND, nullptr, NetLogSource()); @@ -595,13 +583,7 @@ TEST_F(UDPSocketTest, MAYBE_ClientSetDoNotFragment) { } } -#if defined(OS_FUCHSIA) -// TODO(crbug.com/945590): Re-enable after the breaking SDK change has landed. -#define MAYBE_ServerSetDoNotFragment DISABLED_ServerSetDoNotFragment -#else -#define MAYBE_ServerSetDoNotFragment ServerSetDoNotFragment -#endif -TEST_F(UDPSocketTest, MAYBE_ServerSetDoNotFragment) { +TEST_F(UDPSocketTest, ServerSetDoNotFragment) { for (std::string ip : {"127.0.0.1", "::1"}) { IPEndPoint bind_address; ASSERT_TRUE(CreateUDPAddress(ip, 0, &bind_address)); @@ -658,17 +640,6 @@ TEST_F(UDPSocketTest, JoinMulticastGroup) { UDPSocket socket(DatagramSocket::DEFAULT_BIND, nullptr, NetLogSource()); EXPECT_THAT(socket.Open(bind_address.GetFamily()), IsOk()); -#if defined(OS_FUCHSIA) - // Fuchsia currently doesn't support automatic interface selection for - // multicast, so interface index needs to be set explicitly. - // See https://fuchsia.atlassian.net/browse/NET-195 . - NetworkInterfaceList interfaces; - ASSERT_TRUE(GetNetworkList(&interfaces, 0)); - ASSERT_FALSE(interfaces.empty()); - EXPECT_THAT(socket.SetMulticastInterface(interfaces[0].interface_index), - IsOk()); -#endif // defined(OS_FUCHSIA) - EXPECT_THAT(socket.Bind(bind_address), IsOk()); EXPECT_THAT(socket.JoinGroup(group_ip), IsOk()); // Joining group multiple times. diff --git a/chromium/net/socket/unix_domain_server_socket_posix.h b/chromium/net/socket/unix_domain_server_socket_posix.h index 8bccc067cb3..01433e44606 100644 --- a/chromium/net/socket/unix_domain_server_socket_posix.h +++ b/chromium/net/socket/unix_domain_server_socket_posix.h @@ -42,7 +42,7 @@ class NET_EXPORT UnixDomainServerSocket : public ServerSocket { // Callback that returns whether the already connected client, identified by // its credentials, is allowed to keep the connection open. Note that // the socket is closed immediately in case the callback returns false. - typedef base::Callback<bool (const Credentials&)> AuthCallback; + using AuthCallback = base::RepeatingCallback<bool(const Credentials&)>; UnixDomainServerSocket(const AuthCallback& auth_callack, bool use_abstract_namespace); diff --git a/chromium/net/socket/websocket_transport_client_socket_pool.cc b/chromium/net/socket/websocket_transport_client_socket_pool.cc index 7fa0c762fad..820288f6c66 100644 --- a/chromium/net/socket/websocket_transport_client_socket_pool.cc +++ b/chromium/net/socket/websocket_transport_client_socket_pool.cc @@ -23,14 +23,17 @@ #include "net/socket/connect_job.h" #include "net/socket/websocket_endpoint_lock_manager.h" #include "net/socket/websocket_transport_connect_job.h" +#include "net/traffic_annotation/network_traffic_annotation.h" namespace net { WebSocketTransportClientSocketPool::WebSocketTransportClientSocketPool( int max_sockets, int max_sockets_per_group, + const ProxyServer& proxy_server, const CommonConnectJobParams* common_connect_job_params) - : common_connect_job_params_(common_connect_job_params), + : proxy_server_(proxy_server), + common_connect_job_params_(common_connect_job_params), max_sockets_(max_sockets), handed_out_socket_count_(0), flushing_(false), @@ -61,6 +64,7 @@ void WebSocketTransportClientSocketPool::UnlockEndpoint( int WebSocketTransportClientSocketPool::RequestSocket( const GroupId& group_id, scoped_refptr<SocketParams> params, + const base::Optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag, RequestPriority priority, const SocketTag& socket_tag, RespectLimits respect_limits, @@ -79,8 +83,8 @@ int WebSocketTransportClientSocketPool::RequestSocket( if (ReachedMaxSocketsLimit() && respect_limits == ClientSocketPool::RespectLimits::ENABLED) { request_net_log.AddEvent(NetLogEventType::SOCKET_POOL_STALLED_MAX_SOCKETS); - stalled_request_queue_.emplace_back(group_id, params, priority, handle, - std::move(callback), + stalled_request_queue_.emplace_back(group_id, params, proxy_annotation_tag, + priority, handle, std::move(callback), proxy_auth_callback, request_net_log); auto iterator = stalled_request_queue_.end(); --iterator; @@ -99,14 +103,10 @@ int WebSocketTransportClientSocketPool::RequestSocket( std::make_unique<ConnectJobDelegate>(this, std::move(callback), handle, request_net_log); - // For WebSockets, only the main socket pool uses a - // WebSocketTransportClientSocketPool, so there's no need to pass in any - // nested socket pools for the proxy case, which use standard proxy socket - // pool types on top of a standard TransportClientSocketPool. std::unique_ptr<ConnectJob> connect_job = - params->create_connect_job_callback().Run(priority, SocketTag(), - common_connect_job_params_, - connect_job_delegate.get()); + CreateConnectJob(group_id, params, proxy_server_, proxy_annotation_tag, + true /* is_for_websockets */, common_connect_job_params_, + priority, SocketTag(), connect_job_delegate.get()); int result = connect_job_delegate->Connect(std::move(connect_job)); @@ -131,6 +131,7 @@ int WebSocketTransportClientSocketPool::RequestSocket( void WebSocketTransportClientSocketPool::RequestSockets( const GroupId& group_id, scoped_refptr<SocketParams> params, + const base::Optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag, int num_sockets, const NetLogWithSource& net_log) { NOTIMPLEMENTED(); @@ -150,7 +151,8 @@ void WebSocketTransportClientSocketPool::SetPriority(const GroupId& group_id, void WebSocketTransportClientSocketPool::CancelRequest( const GroupId& group_id, - ClientSocketHandle* handle) { + ClientSocketHandle* handle, + bool cancel_connect_job) { DCHECK(!handle->is_initialized()); if (DeleteStalledRequest(handle)) return; @@ -423,7 +425,8 @@ void WebSocketTransportClientSocketPool::ActivateStalledRequest() { base::AdaptCallbackForRepeating(std::move(request.callback)); int rv = RequestSocket( - request.group_id, request.params, request.priority, SocketTag(), + request.group_id, request.params, request.proxy_annotation_tag, + request.priority, SocketTag(), // Stalled requests can't have |respect_limits| // DISABLED. RespectLimits::ENABLED, request.handle, copyable_callback, @@ -490,6 +493,7 @@ WebSocketTransportClientSocketPool::ConnectJobDelegate::connect_job_net_log() { WebSocketTransportClientSocketPool::StalledRequest::StalledRequest( const GroupId& group_id, const scoped_refptr<SocketParams>& params, + const base::Optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag, RequestPriority priority, ClientSocketHandle* handle, CompletionOnceCallback callback, @@ -497,6 +501,7 @@ WebSocketTransportClientSocketPool::StalledRequest::StalledRequest( const NetLogWithSource& net_log) : group_id(group_id), params(params), + proxy_annotation_tag(proxy_annotation_tag), priority(priority), handle(handle), callback(std::move(callback)), diff --git a/chromium/net/socket/websocket_transport_client_socket_pool.h b/chromium/net/socket/websocket_transport_client_socket_pool.h index e9ff2233a6a..f1d5f0d9497 100644 --- a/chromium/net/socket/websocket_transport_client_socket_pool.h +++ b/chromium/net/socket/websocket_transport_client_socket_pool.h @@ -15,9 +15,11 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" #include "base/memory/weak_ptr.h" +#include "base/optional.h" #include "base/time/time.h" #include "base/timer/timer.h" #include "net/base/net_export.h" +#include "net/base/proxy_server.h" #include "net/log/net_log_with_source.h" #include "net/socket/client_socket_pool.h" #include "net/socket/connect_job.h" @@ -33,6 +35,7 @@ class ProcessMemoryDump; namespace net { struct CommonConnectJobParams; +struct NetworkTrafficAnnotationTag; class WebSocketTransportConnectJob; class NET_EXPORT_PRIVATE WebSocketTransportClientSocketPool @@ -41,6 +44,7 @@ class NET_EXPORT_PRIVATE WebSocketTransportClientSocketPool WebSocketTransportClientSocketPool( int max_sockets, int max_sockets_per_group, + const ProxyServer& proxy_server, const CommonConnectJobParams* common_connect_job_params); ~WebSocketTransportClientSocketPool() override; @@ -55,24 +59,29 @@ class NET_EXPORT_PRIVATE WebSocketTransportClientSocketPool WebSocketEndpointLockManager* websocket_endpoint_lock_manager); // ClientSocketPool implementation. - int RequestSocket(const GroupId& group_id, - scoped_refptr<SocketParams> params, - RequestPriority priority, - const SocketTag& socket_tag, - RespectLimits respect_limits, - ClientSocketHandle* handle, - CompletionOnceCallback callback, - const ProxyAuthCallback& proxy_auth_callback, - const NetLogWithSource& net_log) override; - void RequestSockets(const GroupId& group_id, - scoped_refptr<SocketParams> params, - int num_sockets, - const NetLogWithSource& net_log) override; + int RequestSocket( + const GroupId& group_id, + scoped_refptr<SocketParams> params, + const base::Optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag, + RequestPriority priority, + const SocketTag& socket_tag, + RespectLimits respect_limits, + ClientSocketHandle* handle, + CompletionOnceCallback callback, + const ProxyAuthCallback& proxy_auth_callback, + const NetLogWithSource& net_log) override; + void RequestSockets( + const GroupId& group_id, + scoped_refptr<SocketParams> params, + const base::Optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag, + int num_sockets, + const NetLogWithSource& net_log) override; void SetPriority(const GroupId& group_id, ClientSocketHandle* handle, RequestPriority priority) override; void CancelRequest(const GroupId& group_id, - ClientSocketHandle* handle) override; + ClientSocketHandle* handle, + bool cancel_connect_job) override; void ReleaseSocket(const GroupId& group_id, std::unique_ptr<StreamSocket> socket, int64_t generation) override; @@ -136,18 +145,21 @@ class NET_EXPORT_PRIVATE WebSocketTransportClientSocketPool // Store the arguments from a call to RequestSocket() that has stalled so we // can replay it when there are available socket slots. struct StalledRequest { - StalledRequest(const GroupId& group_id, - const scoped_refptr<SocketParams>& params, - RequestPriority priority, - ClientSocketHandle* handle, - CompletionOnceCallback callback, - const ProxyAuthCallback& proxy_auth_callback, - const NetLogWithSource& net_log); + StalledRequest( + const GroupId& group_id, + const scoped_refptr<SocketParams>& params, + const base::Optional<NetworkTrafficAnnotationTag>& proxy_annotation_tag, + RequestPriority priority, + ClientSocketHandle* handle, + CompletionOnceCallback callback, + const ProxyAuthCallback& proxy_auth_callback, + const NetLogWithSource& net_log); StalledRequest(StalledRequest&& other); ~StalledRequest(); const GroupId group_id; const scoped_refptr<SocketParams> params; + const base::Optional<NetworkTrafficAnnotationTag> proxy_annotation_tag; const RequestPriority priority; ClientSocketHandle* const handle; CompletionOnceCallback callback; @@ -189,6 +201,7 @@ class NET_EXPORT_PRIVATE WebSocketTransportClientSocketPool void ActivateStalledRequest(); bool DeleteStalledRequest(ClientSocketHandle* handle); + const ProxyServer proxy_server_; const CommonConnectJobParams* const common_connect_job_params_; std::set<const ClientSocketHandle*> pending_callbacks_; PendingConnectsMap pending_connects_; diff --git a/chromium/net/socket/websocket_transport_client_socket_pool_unittest.cc b/chromium/net/socket/websocket_transport_client_socket_pool_unittest.cc index 53b4b02c8a6..944fcac5443 100644 --- a/chromium/net/socket/websocket_transport_client_socket_pool_unittest.cc +++ b/chromium/net/socket/websocket_transport_client_socket_pool_unittest.cc @@ -10,6 +10,7 @@ #include "base/bind_helpers.h" #include "base/callback.h" #include "base/location.h" +#include "base/optional.h" #include "base/run_loop.h" #include "base/single_thread_task_runner.h" #include "base/stl_util.h" @@ -20,6 +21,8 @@ #include "net/base/load_timing_info.h" #include "net/base/load_timing_info_test_util.h" #include "net/base/net_errors.h" +#include "net/base/privacy_mode.h" +#include "net/base/proxy_server.h" #include "net/base/test_completion_callback.h" #include "net/dns/mock_host_resolver.h" #include "net/log/test_net_log.h" @@ -63,11 +66,8 @@ class WebSocketTransportClientSocketPoolTest WebSocketTransportClientSocketPoolTest() : group_id_(HostPortPair("www.google.com", 80), ClientSocketPool::SocketType::kHttp, - false /* privacy_mode */), - params_(ClientSocketPool::SocketParams::CreateFromTransportSocketParams( - base::MakeRefCounted<TransportSocketParams>( - HostPortPair("www.google.com", 80), - OnHostResolutionCallback()))), + PrivacyMode::PRIVACY_MODE_DISABLED), + params_(ClientSocketPool::SocketParams::CreateForHttpForTesting()), host_resolver_(new MockHostResolver), client_socket_factory_(&net_log_), common_connect_job_params_( @@ -86,7 +86,10 @@ class WebSocketTransportClientSocketPoolTest nullptr /* network_quality_estimator */, nullptr /* netlog */, &websocket_endpoint_lock_manager_), - pool_(kMaxSockets, kMaxSocketsPerGroup, &common_connect_job_params_) { + pool_(kMaxSockets, + kMaxSocketsPerGroup, + ProxyServer::Direct(), + &common_connect_job_params_) { websocket_endpoint_lock_manager_.SetUnlockDelayForTesting( base::TimeDelta()); } @@ -144,10 +147,11 @@ class WebSocketTransportClientSocketPoolTest TEST_F(WebSocketTransportClientSocketPoolTest, Basic) { TestCompletionCallback callback; ClientSocketHandle handle; - int rv = handle.Init( - group_id_, params_, LOW, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, callback.callback(), - ClientSocketPool::ProxyAuthCallback(), &pool_, NetLogWithSource()); + int rv = + handle.Init(group_id_, params_, base::nullopt /* proxy_annotation_tag */, + LOW, SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback.callback(), ClientSocketPool::ProxyAuthCallback(), + &pool_, NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); EXPECT_FALSE(handle.is_initialized()); EXPECT_FALSE(handle.socket()); @@ -167,8 +171,9 @@ TEST_F(WebSocketTransportClientSocketPoolTest, SetResolvePriorityOnInit) { ClientSocketHandle handle; EXPECT_EQ( ERR_IO_PENDING, - handle.Init(group_id_, params_, priority, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, + handle.Init(group_id_, params_, + base::nullopt /* proxy_annotation_tag */, priority, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback.callback(), ClientSocketPool::ProxyAuthCallback(), &pool_, NetLogWithSource())); EXPECT_EQ(priority, host_resolver_->last_request_priority()); @@ -176,20 +181,20 @@ TEST_F(WebSocketTransportClientSocketPoolTest, SetResolvePriorityOnInit) { } TEST_F(WebSocketTransportClientSocketPoolTest, InitHostResolutionFailure) { - host_resolver_->rules()->AddSimulatedFailure("unresolvable.host.name"); + HostPortPair host_port_pair("unresolvable.host.name", 80); + host_resolver_->rules()->AddSimulatedFailure(host_port_pair.host()); TestCompletionCallback callback; ClientSocketHandle handle; - HostPortPair host_port_pair("unresolvable.host.name", 80); - scoped_refptr<ClientSocketPool::SocketParams> dest( - ClientSocketPool::SocketParams::CreateFromTransportSocketParams( - base::MakeRefCounted<TransportSocketParams>( - host_port_pair, OnHostResolutionCallback()))); EXPECT_EQ( ERR_IO_PENDING, - handle.Init(group_id_, dest, kDefaultPriority, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, callback.callback(), - ClientSocketPool::ProxyAuthCallback(), &pool_, - NetLogWithSource())); + handle.Init(ClientSocketPool::GroupId(host_port_pair, + ClientSocketPool::SocketType::kHttp, + PRIVACY_MODE_DISABLED), + ClientSocketPool::SocketParams::CreateForHttpForTesting(), + base::nullopt /* proxy_annotation_tag */, kDefaultPriority, + SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback.callback(), ClientSocketPool::ProxyAuthCallback(), + &pool_, NetLogWithSource())); EXPECT_THAT(callback.WaitForResult(), IsError(ERR_NAME_NOT_RESOLVED)); } @@ -200,7 +205,8 @@ TEST_F(WebSocketTransportClientSocketPoolTest, InitConnectionFailure) { ClientSocketHandle handle; EXPECT_EQ( ERR_IO_PENDING, - handle.Init(group_id_, params_, kDefaultPriority, SocketTag(), + handle.Init(group_id_, params_, base::nullopt /* proxy_annotation_tag */, + kDefaultPriority, SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback.callback(), ClientSocketPool::ProxyAuthCallback(), &pool_, NetLogWithSource())); @@ -210,7 +216,8 @@ TEST_F(WebSocketTransportClientSocketPoolTest, InitConnectionFailure) { host_resolver_->set_synchronous_mode(true); EXPECT_EQ( ERR_CONNECTION_FAILED, - handle.Init(group_id_, params_, kDefaultPriority, SocketTag(), + handle.Init(group_id_, params_, base::nullopt /* proxy_annotation_tag */, + kDefaultPriority, SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback.callback(), ClientSocketPool::ProxyAuthCallback(), &pool_, NetLogWithSource())); @@ -289,7 +296,8 @@ TEST_F(WebSocketTransportClientSocketPoolTest, CancelRequestClearGroup) { ClientSocketHandle handle; EXPECT_EQ( ERR_IO_PENDING, - handle.Init(group_id_, params_, kDefaultPriority, SocketTag(), + handle.Init(group_id_, params_, base::nullopt /* proxy_annotation_tag */, + kDefaultPriority, SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback.callback(), ClientSocketPool::ProxyAuthCallback(), &pool_, NetLogWithSource())); @@ -304,13 +312,15 @@ TEST_F(WebSocketTransportClientSocketPoolTest, TwoRequestsCancelOne) { EXPECT_EQ( ERR_IO_PENDING, - handle.Init(group_id_, params_, kDefaultPriority, SocketTag(), + handle.Init(group_id_, params_, base::nullopt /* proxy_annotation_tag */, + kDefaultPriority, SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback.callback(), ClientSocketPool::ProxyAuthCallback(), &pool_, NetLogWithSource())); EXPECT_EQ( ERR_IO_PENDING, - handle2.Init(group_id_, params_, kDefaultPriority, SocketTag(), + handle2.Init(group_id_, params_, base::nullopt /* proxy_annotation_tag */, + kDefaultPriority, SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback2.callback(), ClientSocketPool::ProxyAuthCallback(), &pool_, NetLogWithSource())); @@ -328,7 +338,8 @@ TEST_F(WebSocketTransportClientSocketPoolTest, ConnectCancelConnect) { TestCompletionCallback callback; EXPECT_EQ( ERR_IO_PENDING, - handle.Init(group_id_, params_, kDefaultPriority, SocketTag(), + handle.Init(group_id_, params_, base::nullopt /* proxy_annotation_tag */, + kDefaultPriority, SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback.callback(), ClientSocketPool::ProxyAuthCallback(), &pool_, NetLogWithSource())); @@ -338,7 +349,8 @@ TEST_F(WebSocketTransportClientSocketPoolTest, ConnectCancelConnect) { TestCompletionCallback callback2; EXPECT_EQ( ERR_IO_PENDING, - handle.Init(group_id_, params_, kDefaultPriority, SocketTag(), + handle.Init(group_id_, params_, base::nullopt /* proxy_annotation_tag */, + kDefaultPriority, SocketTag(), ClientSocketPool::RespectLimits::ENABLED, callback2.callback(), ClientSocketPool::ProxyAuthCallback(), &pool_, NetLogWithSource())); @@ -411,12 +423,9 @@ void RequestSocketOnComplete(const ClientSocketPool::GroupId& group_id, handle->socket()->Disconnect(); handle->Reset(); - scoped_refptr<ClientSocketPool::SocketParams> dest( - ClientSocketPool::SocketParams::CreateFromTransportSocketParams( - base::MakeRefCounted<TransportSocketParams>( - HostPortPair("www.google.com", 80), OnHostResolutionCallback()))); int rv = handle->Init( - group_id, dest, LOWEST, SocketTag(), + group_id, ClientSocketPool::SocketParams::CreateForHttpForTesting(), + base::nullopt /* proxy_annotation_tag */, LOWEST, SocketTag(), ClientSocketPool::RespectLimits::ENABLED, nested_callback->callback(), ClientSocketPool::ProxyAuthCallback(), pool, NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); @@ -429,17 +438,14 @@ void RequestSocketOnComplete(const ClientSocketPool::GroupId& group_id, // ClientSocketHandle for the second socket, after disconnecting the first. TEST_F(WebSocketTransportClientSocketPoolTest, RequestTwice) { ClientSocketHandle handle; - scoped_refptr<ClientSocketPool::SocketParams> dest( - ClientSocketPool::SocketParams::CreateFromTransportSocketParams( - base::MakeRefCounted<TransportSocketParams>( - HostPortPair("www.google.com", 80), OnHostResolutionCallback()))); TestCompletionCallback second_result_callback; - int rv = handle.Init(group_id_, dest, LOWEST, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, - base::BindOnce(&RequestSocketOnComplete, group_id_, - &handle, &pool_, &second_result_callback), - ClientSocketPool::ProxyAuthCallback(), &pool_, - NetLogWithSource()); + int rv = handle.Init( + group_id_, ClientSocketPool::SocketParams::CreateForHttpForTesting(), + base::nullopt /* proxy_annotation_tag */, LOWEST, SocketTag(), + ClientSocketPool::RespectLimits::ENABLED, + base::BindOnce(&RequestSocketOnComplete, group_id_, &handle, &pool_, + &second_result_callback), + ClientSocketPool::ProxyAuthCallback(), &pool_, NetLogWithSource()); ASSERT_THAT(rv, IsError(ERR_IO_PENDING)); EXPECT_THAT(second_result_callback.WaitForResult(), IsOk()); @@ -510,10 +516,11 @@ TEST_F(WebSocketTransportClientSocketPoolTest, LockReleasedOnHandleReset) { TEST_F(WebSocketTransportClientSocketPoolTest, LockReleasedOnHandleDelete) { TestCompletionCallback callback; std::unique_ptr<ClientSocketHandle> handle(new ClientSocketHandle); - int rv = handle->Init( - group_id_, params_, LOW, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, callback.callback(), - ClientSocketPool::ProxyAuthCallback(), &pool_, NetLogWithSource()); + int rv = + handle->Init(group_id_, params_, base::nullopt /* proxy_annotation_tag */, + LOW, SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback.callback(), ClientSocketPool::ProxyAuthCallback(), + &pool_, NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING)); @@ -552,7 +559,8 @@ TEST_F(WebSocketTransportClientSocketPoolTest, EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING)); EXPECT_THAT(StartRequest(kDefaultPriority), IsError(ERR_IO_PENDING)); RunUntilIdle(); - pool_.CancelRequest(group_id_, request(0)->handle()); + pool_.CancelRequest(group_id_, request(0)->handle(), + false /* cancel_connect_job */); EXPECT_THAT(request(1)->WaitForResult(), IsOk()); } @@ -574,10 +582,11 @@ TEST_F(WebSocketTransportClientSocketPoolTest, TestCompletionCallback callback; ClientSocketHandle handle; - int rv = handle.Init( - group_id_, params_, LOW, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, callback.callback(), - ClientSocketPool::ProxyAuthCallback(), &pool_, NetLogWithSource()); + int rv = + handle.Init(group_id_, params_, base::nullopt /* proxy_annotation_tag */, + LOW, SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback.callback(), ClientSocketPool::ProxyAuthCallback(), + &pool_, NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); EXPECT_FALSE(handle.is_initialized()); EXPECT_FALSE(handle.socket()); @@ -612,10 +621,11 @@ TEST_F(WebSocketTransportClientSocketPoolTest, TestCompletionCallback callback; ClientSocketHandle handle; - int rv = handle.Init( - group_id_, params_, LOW, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, callback.callback(), - ClientSocketPool::ProxyAuthCallback(), &pool_, NetLogWithSource()); + int rv = + handle.Init(group_id_, params_, base::nullopt /* proxy_annotation_tag */, + LOW, SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback.callback(), ClientSocketPool::ProxyAuthCallback(), + &pool_, NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); EXPECT_FALSE(handle.is_initialized()); EXPECT_FALSE(handle.socket()); @@ -640,10 +650,11 @@ TEST_F(WebSocketTransportClientSocketPoolTest, TestCompletionCallback callback; ClientSocketHandle handle; - int rv = handle.Init( - group_id_, params_, LOW, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, callback.callback(), - ClientSocketPool::ProxyAuthCallback(), &pool_, NetLogWithSource()); + int rv = + handle.Init(group_id_, params_, base::nullopt /* proxy_annotation_tag */, + LOW, SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback.callback(), ClientSocketPool::ProxyAuthCallback(), + &pool_, NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); EXPECT_FALSE(handle.is_initialized()); EXPECT_FALSE(handle.socket()); @@ -666,10 +677,11 @@ TEST_F(WebSocketTransportClientSocketPoolTest, IPv4HasNoFallback) { TestCompletionCallback callback; ClientSocketHandle handle; - int rv = handle.Init( - group_id_, params_, LOW, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, callback.callback(), - ClientSocketPool::ProxyAuthCallback(), &pool_, NetLogWithSource()); + int rv = + handle.Init(group_id_, params_, base::nullopt /* proxy_annotation_tag */, + LOW, SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback.callback(), ClientSocketPool::ProxyAuthCallback(), + &pool_, NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); EXPECT_FALSE(handle.is_initialized()); EXPECT_FALSE(handle.socket()); @@ -703,10 +715,11 @@ TEST_F(WebSocketTransportClientSocketPoolTest, IPv6InstantFail) { host_resolver_->set_synchronous_mode(true); TestCompletionCallback callback; ClientSocketHandle handle; - int rv = handle.Init( - group_id_, params_, LOW, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, callback.callback(), - ClientSocketPool::ProxyAuthCallback(), &pool_, NetLogWithSource()); + int rv = + handle.Init(group_id_, params_, base::nullopt /* proxy_annotation_tag */, + LOW, SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback.callback(), ClientSocketPool::ProxyAuthCallback(), + &pool_, NetLogWithSource()); EXPECT_THAT(rv, IsOk()); ASSERT_TRUE(handle.socket()); @@ -735,10 +748,11 @@ TEST_F(WebSocketTransportClientSocketPoolTest, IPv6RapidFail) { TestCompletionCallback callback; ClientSocketHandle handle; - int rv = handle.Init( - group_id_, params_, LOW, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, callback.callback(), - ClientSocketPool::ProxyAuthCallback(), &pool_, NetLogWithSource()); + int rv = + handle.Init(group_id_, params_, base::nullopt /* proxy_annotation_tag */, + LOW, SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback.callback(), ClientSocketPool::ProxyAuthCallback(), + &pool_, NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); EXPECT_FALSE(handle.socket()); @@ -767,10 +781,11 @@ TEST_F(WebSocketTransportClientSocketPoolTest, FirstSuccessWins) { TestCompletionCallback callback; ClientSocketHandle handle; - int rv = handle.Init( - group_id_, params_, LOW, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, callback.callback(), - ClientSocketPool::ProxyAuthCallback(), &pool_, NetLogWithSource()); + int rv = + handle.Init(group_id_, params_, base::nullopt /* proxy_annotation_tag */, + LOW, SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback.callback(), ClientSocketPool::ProxyAuthCallback(), + &pool_, NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); ASSERT_FALSE(handle.socket()); @@ -815,10 +830,11 @@ TEST_F(WebSocketTransportClientSocketPoolTest, LastFailureWins) { TestCompletionCallback callback; ClientSocketHandle handle; base::TimeTicks start(base::TimeTicks::Now()); - int rv = handle.Init( - group_id_, params_, LOW, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, callback.callback(), - ClientSocketPool::ProxyAuthCallback(), &pool_, NetLogWithSource()); + int rv = + handle.Init(group_id_, params_, base::nullopt /* proxy_annotation_tag */, + LOW, SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback.callback(), ClientSocketPool::ProxyAuthCallback(), + &pool_, NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); EXPECT_THAT(callback.WaitForResult(), IsError(ERR_CONNECTION_FAILED)); @@ -850,10 +866,11 @@ TEST_F(WebSocketTransportClientSocketPoolTest, DISABLED_OverallTimeoutApplies) { TestCompletionCallback callback; ClientSocketHandle handle; - int rv = handle.Init( - group_id_, params_, LOW, SocketTag(), - ClientSocketPool::RespectLimits::ENABLED, callback.callback(), - ClientSocketPool::ProxyAuthCallback(), &pool_, NetLogWithSource()); + int rv = + handle.Init(group_id_, params_, base::nullopt /* proxy_annotation_tag */, + LOW, SocketTag(), ClientSocketPool::RespectLimits::ENABLED, + callback.callback(), ClientSocketPool::ProxyAuthCallback(), + &pool_, NetLogWithSource()); EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); EXPECT_THAT(callback.WaitForResult(), IsError(ERR_TIMED_OUT)); diff --git a/chromium/net/socket/websocket_transport_connect_job.cc b/chromium/net/socket/websocket_transport_connect_job.cc index 0a28e158520..1b80ee69585 100644 --- a/chromium/net/socket/websocket_transport_connect_job.cc +++ b/chromium/net/socket/websocket_transport_connect_job.cc @@ -7,6 +7,7 @@ #include "base/bind.h" #include "base/location.h" #include "base/logging.h" +#include "base/threading/thread_task_runner_handle.h" #include "base/time/time.h" #include "base/trace_event/trace_event.h" #include "base/values.h" @@ -40,7 +41,8 @@ WebSocketTransportConnectJob::WebSocketTransportConnectJob( next_state_(STATE_NONE), race_result_(TransportConnectJob::RACE_UNKNOWN), had_ipv4_(false), - had_ipv6_(false) { + had_ipv6_(false), + weak_ptr_factory_(this) { DCHECK(common_connect_job_params->websocket_endpoint_lock_manager); } @@ -127,15 +129,22 @@ int WebSocketTransportConnectJob::DoResolveHostComplete(int result) { return result; DCHECK(request_->GetAddressResults()); - // Invoke callback, and abort if it fails. + next_state_ = STATE_TRANSPORT_CONNECT; + + // Invoke callback. If it indicates |this| may be slated for deletion, then + // only continue after a PostTask. if (!params_->host_resolution_callback().is_null()) { - result = params_->host_resolution_callback().Run( - request_->GetAddressResults().value(), net_log()); - if (result != OK) - return result; + OnHostResolutionCallbackResult callback_result = + params_->host_resolution_callback().Run( + params_->destination(), request_->GetAddressResults().value()); + if (callback_result == OnHostResolutionCallbackResult::kMayBeDeletedAsync) { + base::ThreadTaskRunnerHandle::Get()->PostTask( + FROM_HERE, base::BindOnce(&WebSocketTransportConnectJob::OnIOComplete, + weak_ptr_factory_.GetWeakPtr(), OK)); + return ERR_IO_PENDING; + } } - next_state_ = STATE_TRANSPORT_CONNECT; return result; } diff --git a/chromium/net/socket/websocket_transport_connect_job.h b/chromium/net/socket/websocket_transport_connect_job.h index 1ebf709d02f..6ba51a0840c 100644 --- a/chromium/net/socket/websocket_transport_connect_job.h +++ b/chromium/net/socket/websocket_transport_connect_job.h @@ -11,6 +11,7 @@ #include "base/macros.h" #include "base/memory/ref_counted.h" +#include "base/memory/weak_ptr.h" #include "base/time/time.h" #include "base/timer/timer.h" #include "net/base/net_export.h" @@ -105,6 +106,8 @@ class NET_EXPORT_PRIVATE WebSocketTransportConnectJob : public ConnectJob { bool had_ipv4_; bool had_ipv6_; + base::WeakPtrFactory<WebSocketTransportConnectJob> weak_ptr_factory_; + DISALLOW_COPY_AND_ASSIGN(WebSocketTransportConnectJob); }; |