#ifdef UNSAFE_BUFFERS_BUILD
#pragma allow_unsafe_buffers
#endif
#include "net/socket/transport_client_socket_pool.h"
#include <memory>
#include <optional>
#include <utility>
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/functional/callback_helpers.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/ref_counted.h"
#include "base/run_loop.h"
#include "base/test/bind.h"
#include "base/test/scoped_feature_list.h"
#include "base/threading/platform_thread.h"
#include "build/build_config.h"
#include "net/base/completion_once_callback.h"
#include "net/base/features.h"
#include "net/base/ip_endpoint.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_anonymization_key.h"
#include "net/base/privacy_mode.h"
#include "net/base/proxy_chain.h"
#include "net/base/proxy_server.h"
#include "net/base/proxy_string_util.h"
#include "net/base/schemeful_site.h"
#include "net/base/test_completion_callback.h"
#include "net/cert/mock_cert_verifier.h"
#include "net/dns/mock_host_resolver.h"
#include "net/dns/public/secure_dns_policy.h"
#include "net/http/http_network_session.h"
#include "net/http/http_proxy_connect_job.h"
#include "net/http/transport_security_state.h"
#include "net/log/net_log.h"
#include "net/log/net_log_with_source.h"
#include "net/log/test_net_log.h"
#include "net/proxy_resolution/configured_proxy_resolution_service.h"
#include "net/socket/client_socket_handle.h"
#include "net/socket/connect_job.h"
#include "net/socket/socket_tag.h"
#include "net/socket/socket_test_util.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_client_socket_pool.h"
#include "net/socket/transport_client_socket_pool_test_util.h"
#include "net/socket/transport_connect_job.h"
#include "net/spdy/spdy_test_util_common.h"
#include "net/ssl/ssl_config_service.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "net/test/gtest_util.h"
#include "net/test/test_with_task_environment.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"
#include "url/gurl.h"
#include "url/scheme_host_port.h"
#include "url/url_constants.h"
IsError;
IsOk;
namespace net {
namespace {
const int kMaxSockets = …;
const int kMaxSocketsPerGroup = …;
constexpr base::TimeDelta kUnusedIdleSocketTimeout = …;
const RequestPriority kDefaultPriority = …;
class SOCKS5MockData { … };
class TransportClientSocketPoolTest : public ::testing::Test,
public WithTaskEnvironment { … };
TEST_F(TransportClientSocketPoolTest, Basic) { … }
TEST_F(TransportClientSocketPoolTest, SetResolvePriorityOnInit) { … }
TEST_F(TransportClientSocketPoolTest, SetSecureDnsPolicy) { … }
TEST_F(TransportClientSocketPoolTest, ReprioritizeRequests) { … }
TEST_F(TransportClientSocketPoolTest, RequestIgnoringLimitsIsReprioritized) { … }
TEST_F(TransportClientSocketPoolTest, InitHostResolutionFailure) { … }
TEST_F(TransportClientSocketPoolTest, InitConnectionFailure) { … }
TEST_F(TransportClientSocketPoolTest, PendingRequests) { … }
TEST_F(TransportClientSocketPoolTest, PendingRequests_NoKeepAlive) { … }
TEST_F(TransportClientSocketPoolTest, CancelRequestClearGroup) { … }
TEST_F(TransportClientSocketPoolTest, TwoRequestsCancelOne) { … }
TEST_F(TransportClientSocketPoolTest, ConnectCancelConnect) { … }
TEST_F(TransportClientSocketPoolTest, CancelRequest) { … }
class RequestSocketCallback : public TestCompletionCallbackBase { … };
TEST_F(TransportClientSocketPoolTest, RequestTwice) { … }
TEST_F(TransportClientSocketPoolTest, CancelActiveRequestWithPendingRequests) { … }
TEST_F(TransportClientSocketPoolTest, FailingActiveRequestWithPendingRequests) { … }
TEST_F(TransportClientSocketPoolTest, IdleSocketLoadTiming) { … }
TEST_F(TransportClientSocketPoolTest, CloseIdleSocketsOnIPAddressChange) { … }
TEST(TransportClientSocketPoolStandaloneTest, DontCleanupOnIPAddressChange) { … }
TEST_F(TransportClientSocketPoolTest, SSLCertError) { … }
namespace {
class TransportClientSocketPoolSSLConfigChangeTest
: public TransportClientSocketPoolTest,
public ::testing::WithParamInterface<
SSLClientContext::SSLConfigChangeType> { … };
}
TEST_P(TransportClientSocketPoolSSLConfigChangeTest, GracefulConfigChange) { … }
INSTANTIATE_TEST_SUITE_P(…);
TEST_F(TransportClientSocketPoolTest, BackupSocketConnect) { … }
TEST_F(TransportClientSocketPoolTest, BackupSocketCancel) { … }
TEST_F(TransportClientSocketPoolTest, BackupSocketFailAfterStall) { … }
TEST_F(TransportClientSocketPoolTest, BackupSocketFailAfterDelay) { … }
TEST_F(TransportClientSocketPoolTest, SOCKS) { … }
TEST_F(TransportClientSocketPoolTest, SpdyOneConnectJobTwoRequestsError) { … }
TEST_F(TransportClientSocketPoolTest, SpdyAuthOneConnectJobTwoRequests) { … }
TEST_F(TransportClientSocketPoolTest, HttpTunnelSetupRedirect) { … }
TEST_F(TransportClientSocketPoolTest, NetworkAnonymizationKey) { … }
TEST_F(TransportClientSocketPoolTest, NetworkAnonymizationKeySsl) { … }
TEST_F(TransportClientSocketPoolTest, NetworkAnonymizationKeyHttpProxy) { … }
TEST_F(TransportClientSocketPoolTest, NetworkAnonymizationKeyHttpsProxy) { … }
TEST_F(TransportClientSocketPoolTest, NetworkAnonymizationKeySocks4Proxy) { … }
TEST_F(TransportClientSocketPoolTest, NetworkAnonymizationKeySocks5Proxy) { … }
TEST_F(TransportClientSocketPoolTest, HasActiveSocket) { … }
#if BUILDFLAG(IS_ANDROID)
TEST_F(TransportClientSocketPoolTest, Tag) {
if (!CanGetTaggedBytes()) {
DVLOG(0) << "Skipping test - GetTaggedBytes unsupported.";
return;
}
EmbeddedTestServer test_server;
test_server.AddDefaultHandlers(base::FilePath());
ASSERT_TRUE(test_server.Start());
ClientSocketHandle handle;
int32_t tag_val1 = 0x12345678;
SocketTag tag1(SocketTag::UNSET_UID, tag_val1);
int32_t tag_val2 = 0x87654321;
SocketTag tag2(getuid(), tag_val2);
uint64_t old_traffic = GetTaggedBytes(tag_val1);
const ClientSocketPool::GroupId kGroupId(
url::SchemeHostPort(test_server.base_url()),
PrivacyMode::PRIVACY_MODE_DISABLED, NetworkAnonymizationKey(),
SecureDnsPolicy::kAllow, false);
scoped_refptr<ClientSocketPool::SocketParams> params =
ClientSocketPool::SocketParams::CreateForHttpForTesting();
TestCompletionCallback callback;
int rv =
handle.Init(kGroupId, params, std::nullopt ,
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());
EXPECT_GT(GetTaggedBytes(tag_val1), old_traffic);
StreamSocket* socket = handle.socket();
handle.Reset();
old_traffic = GetTaggedBytes(tag_val2);
rv = handle.Init(kGroupId, params, std::nullopt ,
LOW, tag2, ClientSocketPool::RespectLimits::ENABLED,
callback.callback(), ClientSocketPool::ProxyAuthCallback(),
pool_for_real_sockets_.get(), NetLogWithSource());
EXPECT_THAT(rv, IsOk());
EXPECT_TRUE(handle.socket());
EXPECT_TRUE(handle.socket()->IsConnected());
EXPECT_EQ(handle.socket(), socket);
const char kRequest[] = "GET / HTTP/1.0\n\n";
scoped_refptr<IOBuffer> write_buffer =
base::MakeRefCounted<StringIOBuffer>(kRequest);
rv =
handle.socket()->Write(write_buffer.get(), strlen(kRequest),
callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS);
EXPECT_EQ(static_cast<int>(strlen(kRequest)), callback.GetResult(rv));
EXPECT_GT(GetTaggedBytes(tag_val2), old_traffic);
handle.socket()->Disconnect();
handle.Reset();
TestCompletionCallback callback2;
rv = handle.Init(kGroupId, params, std::nullopt ,
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;
handle.Reset();
rv = handle.Init(kGroupId, params, std::nullopt ,
LOW, tag2, 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());
old_traffic = GetTaggedBytes(tag_val2);
rv =
handle.socket()->Write(write_buffer.get(), strlen(kRequest),
callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS);
EXPECT_EQ(static_cast<int>(strlen(kRequest)), callback.GetResult(rv));
EXPECT_GT(GetTaggedBytes(tag_val2), old_traffic);
handle.socket()->Disconnect();
handle.Reset();
rv = handle.Init(kGroupId, params, std::nullopt ,
LOW, tag1, ClientSocketPool::RespectLimits::ENABLED,
callback.callback(), ClientSocketPool::ProxyAuthCallback(),
pool_for_real_sockets_.get(), NetLogWithSource());
EXPECT_THAT(rv, IsOk());
handle.socket()->Disconnect();
handle.Reset();
ClientSocketHandle handle_high_pri;
TestCompletionCallback callback_high_pri;
rv = handle.Init(kGroupId, params, std::nullopt ,
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, std::nullopt , 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());
EXPECT_THAT(callback.GetResult(rv), IsOk());
EXPECT_TRUE(handle.socket());
EXPECT_TRUE(handle.socket()->IsConnected());
old_traffic = GetTaggedBytes(tag_val2);
rv = handle_high_pri.socket()->Write(write_buffer.get(), strlen(kRequest),
callback.callback(),
TRAFFIC_ANNOTATION_FOR_TESTS);
EXPECT_EQ(static_cast<int>(strlen(kRequest)), callback.GetResult(rv));
EXPECT_GT(GetTaggedBytes(tag_val2), old_traffic);
old_traffic = GetTaggedBytes(tag_val1);
rv =
handle.socket()->Write(write_buffer.get(), strlen(kRequest),
callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS);
EXPECT_EQ(static_cast<int>(strlen(kRequest)), callback.GetResult(rv));
EXPECT_GT(GetTaggedBytes(tag_val1), old_traffic);
}
TEST_F(TransportClientSocketPoolTest, TagSOCKSProxy) {
session_deps_.host_resolver->set_synchronous_mode(true);
TransportClientSocketPool proxy_pool(
kMaxSockets, kMaxSocketsPerGroup, kUnusedIdleSocketTimeout,
ProxyUriToProxyChain("socks5://proxy",
ProxyServer::SCHEME_HTTP),
false, tagging_common_connect_job_params_.get());
SocketTag tag1(SocketTag::UNSET_UID, 0x12345678);
SocketTag tag2(getuid(), 0x87654321);
const url::SchemeHostPort kDestination(url::kHttpScheme, "host", 80);
const ClientSocketPool::GroupId kGroupId(
kDestination, PrivacyMode::PRIVACY_MODE_DISABLED,
NetworkAnonymizationKey(), SecureDnsPolicy::kAllow,
false);
scoped_refptr<ClientSocketPool::SocketParams> socks_params =
ClientSocketPool::SocketParams::CreateForHttpForTesting();
SOCKS5MockData data_sync(SYNCHRONOUS);
data_sync.data_provider()->set_connect_data(MockConnect(SYNCHRONOUS, OK));
tagging_client_socket_factory_.AddSocketDataProvider(
data_sync.data_provider());
ClientSocketHandle handle;
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());
EXPECT_EQ(tagging_client_socket_factory_.GetLastProducedTCPSocket()->tag(),
tag1);
EXPECT_TRUE(tagging_client_socket_factory_.GetLastProducedTCPSocket()
->tagged_before_connected());
StreamSocket* socket = handle.socket();
handle.Reset();
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());
EXPECT_EQ(handle.socket(), socket);
EXPECT_EQ(tagging_client_socket_factory_.GetLastProducedTCPSocket()->tag(),
tag2);
handle.socket()->Disconnect();
handle.Reset();
SOCKS5MockData data_async(ASYNC);
tagging_client_socket_factory_.AddSocketDataProvider(
data_async.data_provider());
TestCompletionCallback callback;
rv = handle.Init(kGroupId, socks_params, TRAFFIC_ANNOTATION_FOR_TESTS, LOW,
tag1, ClientSocketPool::RespectLimits::ENABLED,
callback.callback(), ClientSocketPool::ProxyAuthCallback(),
&proxy_pool, NetLogWithSource());
EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
EXPECT_THAT(callback.WaitForResult(), IsOk());
EXPECT_TRUE(handle.is_initialized());
EXPECT_TRUE(handle.socket());
EXPECT_EQ(tagging_client_socket_factory_.GetLastProducedTCPSocket()->tag(),
tag1);
EXPECT_TRUE(tagging_client_socket_factory_.GetLastProducedTCPSocket()
->tagged_before_connected());
socket = handle.socket();
handle.Reset();
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());
EXPECT_EQ(handle.socket(), socket);
EXPECT_EQ(tagging_client_socket_factory_.GetLastProducedTCPSocket()->tag(),
tag2);
}
TEST_F(TransportClientSocketPoolTest, TagSSLDirect) {
if (!CanGetTaggedBytes()) {
DVLOG(0) << "Skipping test - GetTaggedBytes unsupported.";
return;
}
EmbeddedTestServer test_server(net::EmbeddedTestServer::TYPE_HTTPS);
test_server.SetSSLConfig(net::EmbeddedTestServer::CERT_OK, SSLServerConfig());
test_server.AddDefaultHandlers(base::FilePath());
ASSERT_TRUE(test_server.Start());
TestCompletionCallback callback;
ClientSocketHandle handle;
int32_t tag_val1 = 0x12345678;
SocketTag tag1(SocketTag::UNSET_UID, tag_val1);
int32_t tag_val2 = 0x87654321;
SocketTag tag2(getuid(), tag_val2);
const ClientSocketPool::GroupId kGroupId(
url::SchemeHostPort(test_server.base_url()),
PrivacyMode::PRIVACY_MODE_DISABLED, NetworkAnonymizationKey(),
SecureDnsPolicy::kAllow, false);
scoped_refptr<ClientSocketPool::SocketParams> socket_params =
base::MakeRefCounted<ClientSocketPool::SocketParams>(
std::vector<SSLConfig::CertAndStatus>());
uint64_t old_traffic = GetTaggedBytes(tag_val1);
int rv = handle.Init(
kGroupId, socket_params, std::nullopt , 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());
EXPECT_GT(GetTaggedBytes(tag_val1), old_traffic);
StreamSocket* socket = handle.socket();
handle.Reset();
old_traffic = GetTaggedBytes(tag_val2);
TestCompletionCallback callback2;
rv = handle.Init(kGroupId, socket_params,
std::nullopt , 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());
EXPECT_EQ(handle.socket(), socket);
const char kRequest[] = "GET / HTTP/1.1\r\n\r\n";
scoped_refptr<IOBuffer> write_buffer =
base::MakeRefCounted<StringIOBuffer>(kRequest);
rv =
handle.socket()->Write(write_buffer.get(), strlen(kRequest),
callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS);
EXPECT_EQ(static_cast<int>(strlen(kRequest)), callback.GetResult(rv));
scoped_refptr<IOBufferWithSize> read_buffer =
base::MakeRefCounted<IOBufferWithSize>(1);
rv = handle.socket()->Read(read_buffer.get(), read_buffer->size(),
callback.callback());
EXPECT_EQ(read_buffer->size(), callback.GetResult(rv));
EXPECT_GT(GetTaggedBytes(tag_val2), old_traffic);
handle.socket()->Disconnect();
handle.Reset();
}
TEST_F(TransportClientSocketPoolTest, TagSSLDirectTwoSockets) {
if (!CanGetTaggedBytes()) {
DVLOG(0) << "Skipping test - GetTaggedBytes unsupported.";
return;
}
EmbeddedTestServer test_server(net::EmbeddedTestServer::TYPE_HTTPS);
test_server.SetSSLConfig(net::EmbeddedTestServer::CERT_OK, SSLServerConfig());
test_server.AddDefaultHandlers(base::FilePath());
ASSERT_TRUE(test_server.Start());
ClientSocketHandle handle;
int32_t tag_val1 = 0x12345678;
SocketTag tag1(SocketTag::UNSET_UID, tag_val1);
int32_t tag_val2 = 0x87654321;
SocketTag tag2(getuid(), tag_val2);
const ClientSocketPool::GroupId kGroupId(
url::SchemeHostPort(test_server.base_url()),
PrivacyMode::PRIVACY_MODE_DISABLED, NetworkAnonymizationKey(),
SecureDnsPolicy::kAllow, false);
scoped_refptr<ClientSocketPool::SocketParams> socket_params =
base::MakeRefCounted<ClientSocketPool::SocketParams>(
std::vector<SSLConfig::CertAndStatus>());
TestCompletionCallback callback;
int rv = handle.Init(
kGroupId, socket_params, std::nullopt , 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;
handle.Reset();
TestCompletionCallback callback2;
rv = handle.Init(kGroupId, socket_params,
std::nullopt , 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());
uint64_t old_traffic = GetTaggedBytes(tag_val2);
const char kRequest[] = "GET / HTTP/1.1\r\n\r\n";
scoped_refptr<IOBuffer> write_buffer =
base::MakeRefCounted<StringIOBuffer>(kRequest);
rv = handle.socket()->Write(write_buffer.get(), strlen(kRequest),
callback2.callback(),
TRAFFIC_ANNOTATION_FOR_TESTS);
EXPECT_EQ(static_cast<int>(strlen(kRequest)), callback2.GetResult(rv));
scoped_refptr<IOBufferWithSize> read_buffer =
base::MakeRefCounted<IOBufferWithSize>(1);
rv = handle.socket()->Read(read_buffer.get(), read_buffer->size(),
callback2.callback());
EXPECT_EQ(read_buffer->size(), callback2.GetResult(rv));
EXPECT_GT(GetTaggedBytes(tag_val2), old_traffic);
}
TEST_F(TransportClientSocketPoolTest, TagSSLDirectTwoSocketsFullPool) {
if (!CanGetTaggedBytes()) {
DVLOG(0) << "Skipping test - GetTaggedBytes unsupported.";
return;
}
EmbeddedTestServer test_server(net::EmbeddedTestServer::TYPE_HTTPS);
test_server.SetSSLConfig(net::EmbeddedTestServer::CERT_OK, SSLServerConfig());
test_server.AddDefaultHandlers(base::FilePath());
ASSERT_TRUE(test_server.Start());
TestCompletionCallback callback;
ClientSocketHandle handle;
int32_t tag_val1 = 0x12345678;
SocketTag tag1(SocketTag::UNSET_UID, tag_val1);
int32_t tag_val2 = 0x87654321;
SocketTag tag2(getuid(), tag_val2);
const ClientSocketPool::GroupId kGroupId(
url::SchemeHostPort(test_server.base_url()),
PrivacyMode::PRIVACY_MODE_DISABLED, NetworkAnonymizationKey(),
SecureDnsPolicy::kAllow, false);
scoped_refptr<ClientSocketPool::SocketParams> socket_params =
base::MakeRefCounted<ClientSocketPool::SocketParams>(
std::vector<SSLConfig::CertAndStatus>());
ClientSocketHandle tcp_handles[kMaxSocketsPerGroup];
int rv;
for (auto& tcp_handle : tcp_handles) {
rv = tcp_handle.Init(
kGroupId, socket_params, std::nullopt , 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());
}
ClientSocketHandle handle_to_be_canceled;
rv = handle_to_be_canceled.Init(
kGroupId, socket_params, std::nullopt , 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, socket_params,
std::nullopt , LOW, tag2,
ClientSocketPool::RespectLimits::ENABLED,
callback.callback(), ClientSocketPool::ProxyAuthCallback(),
pool_for_real_sockets_.get(), NetLogWithSource());
EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
handle_to_be_canceled.Reset();
tcp_handles[0].socket()->Disconnect();
tcp_handles[0].Reset();
EXPECT_THAT(callback.WaitForResult(), IsOk());
EXPECT_TRUE(handle.socket());
EXPECT_TRUE(handle.socket()->IsConnected());
uint64_t old_traffic = GetTaggedBytes(tag_val2);
const char kRequest[] = "GET / HTTP/1.1\r\n\r\n";
scoped_refptr<IOBuffer> write_buffer =
base::MakeRefCounted<StringIOBuffer>(kRequest);
rv =
handle.socket()->Write(write_buffer.get(), strlen(kRequest),
callback.callback(), TRAFFIC_ANNOTATION_FOR_TESTS);
EXPECT_EQ(static_cast<int>(strlen(kRequest)), callback.GetResult(rv));
scoped_refptr<IOBufferWithSize> read_buffer =
base::MakeRefCounted<IOBufferWithSize>(1);
EXPECT_EQ(handle.socket()->Read(read_buffer.get(), read_buffer->size(),
callback.callback()),
ERR_IO_PENDING);
EXPECT_THAT(callback.WaitForResult(), read_buffer->size());
EXPECT_GT(GetTaggedBytes(tag_val2), old_traffic);
}
TEST_F(TransportClientSocketPoolTest, TagHttpProxyNoTunnel) {
SocketTag tag1(SocketTag::UNSET_UID, 0x12345678);
SocketTag tag2(getuid(), 0x87654321);
TransportClientSocketPool proxy_pool(
kMaxSockets, kMaxSocketsPerGroup, kUnusedIdleSocketTimeout,
ProxyUriToProxyChain("http://proxy",
ProxyServer::SCHEME_HTTP),
false, tagging_common_connect_job_params_.get());
session_deps_.host_resolver->set_synchronous_mode(true);
SequencedSocketData socket_data;
socket_data.set_connect_data(MockConnect(SYNCHRONOUS, OK));
tagging_client_socket_factory_.AddSocketDataProvider(&socket_data);
const url::SchemeHostPort kDestination(url::kHttpScheme, "www.google.com",
80);
const ClientSocketPool::GroupId kGroupId(
kDestination, PrivacyMode::PRIVACY_MODE_DISABLED,
NetworkAnonymizationKey(), SecureDnsPolicy::kAllow,
false);
scoped_refptr<ClientSocketPool::SocketParams> socket_params =
ClientSocketPool::SocketParams::CreateForHttpForTesting();
ClientSocketHandle handle;
int rv = handle.Init(
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());
EXPECT_TRUE(handle.socket()->IsConnected());
EXPECT_EQ(tagging_client_socket_factory_.GetLastProducedTCPSocket()->tag(),
tag1);
EXPECT_TRUE(tagging_client_socket_factory_.GetLastProducedTCPSocket()
->tagged_before_connected());
StreamSocket* socket = handle.socket();
handle.Reset();
rv = handle.Init(
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());
EXPECT_EQ(handle.socket(), socket);
EXPECT_EQ(tagging_client_socket_factory_.GetLastProducedTCPSocket()->tag(),
tag2);
handle.socket()->Disconnect();
handle.Reset();
}
TEST_F(TransportClientSocketPoolTest, TagHttpProxyTunnel) {
SocketTag tag1(SocketTag::UNSET_UID, 0x12345678);
SocketTag tag2(getuid(), 0x87654321);
TransportClientSocketPool proxy_pool(
kMaxSockets, kMaxSocketsPerGroup, kUnusedIdleSocketTimeout,
ProxyUriToProxyChain("http://proxy",
ProxyServer::SCHEME_HTTP),
false, tagging_common_connect_job_params_.get());
session_deps_.host_resolver->set_synchronous_mode(true);
std::string request =
"CONNECT www.google.com:443 HTTP/1.1\r\n"
"Host: www.google.com:443\r\n"
"Proxy-Connection: keep-alive\r\n"
"User-Agent: test-ua\r\n\r\n";
MockWrite writes[] = {
MockWrite(SYNCHRONOUS, 0, request.c_str()),
};
MockRead reads[] = {
MockRead(SYNCHRONOUS, 1, "HTTP/1.1 200 Connection Established\r\n\r\n"),
};
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 url::SchemeHostPort kDestination(url::kHttpsScheme, "www.google.com",
443);
const ClientSocketPool::GroupId kGroupId(
kDestination, PrivacyMode::PRIVACY_MODE_DISABLED,
NetworkAnonymizationKey(), SecureDnsPolicy::kAllow,
false);
scoped_refptr<ClientSocketPool::SocketParams> socket_params =
base::MakeRefCounted<ClientSocketPool::SocketParams>(
std::vector<SSLConfig::CertAndStatus>());
ClientSocketHandle handle;
int rv = handle.Init(
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());
EXPECT_TRUE(handle.socket()->IsConnected());
EXPECT_EQ(tagging_client_socket_factory_.GetLastProducedTCPSocket()->tag(),
tag1);
EXPECT_TRUE(tagging_client_socket_factory_.GetLastProducedTCPSocket()
->tagged_before_connected());
StreamSocket* socket = handle.socket();
handle.Reset();
rv = handle.Init(
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());
EXPECT_EQ(handle.socket(), socket);
EXPECT_EQ(tagging_client_socket_factory_.GetLastProducedTCPSocket()->tag(),
tag2);
handle.socket()->Disconnect();
handle.Reset();
}
#endif
class TransportClientSocketPoolMockNowSourceTest
: public TransportClientSocketPoolTest { … };
TEST_F(TransportClientSocketPoolMockNowSourceTest, IdleUnusedSocketTimeout) { … }
}
}