blob: 96701900d7d0f9219ac1a77a1f25f208d8c36e11 [file] [log] [blame]
// Copyright 2021 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
#include "net/socket/connect_job_factory.h"
#include <memory>
#include <optional>
#include <vector>
#include "base/memory/raw_ptr.h"
#include "base/memory/scoped_refptr.h"
#include "net/base/host_port_pair.h"
#include "net/base/network_isolation_key.h"
#include "net/base/privacy_mode.h"
#include "net/base/proxy_chain.h"
#include "net/base/proxy_server.h"
#include "net/base/request_priority.h"
#include "net/dns/public/secure_dns_policy.h"
#include "net/http/http_proxy_connect_job.h"
#include "net/log/net_log_with_source.h"
#include "net/socket/connect_job.h"
#include "net/socket/connect_job_test_util.h"
#include "net/socket/next_proto.h"
#include "net/socket/socket_tag.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/websocket_endpoint_lock_manager.h"
#include "net/ssl/ssl_config.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/scheme_host_port.h"
#include "url/url_constants.h"
namespace net {
namespace {
// Mock HttpProxyConnectJob::Factory that records the `params` used and then
// passes on to a real factory.
class TestHttpProxyConnectJobFactory : public HttpProxyConnectJob::Factory {
public:
std::unique_ptr<HttpProxyConnectJob> Create(
RequestPriority priority,
const SocketTag& socket_tag,
const CommonConnectJobParams* common_connect_job_params,
scoped_refptr<HttpProxySocketParams> params,
ConnectJob::Delegate* delegate,
const NetLogWithSource* net_log) override {
params_.push_back(params);
return HttpProxyConnectJob::Factory::Create(priority, socket_tag,
common_connect_job_params,
params, delegate, net_log);
}
const std::vector<scoped_refptr<HttpProxySocketParams>>& params() const {
return params_;
}
private:
std::vector<scoped_refptr<HttpProxySocketParams>> params_;
};
// Mock SOCKSConnectJob::Factory that records the `params` used and then passes
// on to a real factory.
class TestSocksConnectJobFactory : public SOCKSConnectJob::Factory {
public:
std::unique_ptr<SOCKSConnectJob> Create(
RequestPriority priority,
const SocketTag& socket_tag,
const CommonConnectJobParams* common_connect_job_params,
scoped_refptr<SOCKSSocketParams> socks_params,
ConnectJob::Delegate* delegate,
const NetLogWithSource* net_log) override {
params_.push_back(socks_params);
return SOCKSConnectJob::Factory::Create(priority, socket_tag,
common_connect_job_params,
socks_params, delegate, net_log);
}
const std::vector<scoped_refptr<SOCKSSocketParams>>& params() const {
return params_;
}
private:
std::vector<scoped_refptr<SOCKSSocketParams>> params_;
};
// Mock SSLConnectJob::Factory that records the `params` used and then passes on
// to a real factory.
class TestSslConnectJobFactory : public SSLConnectJob::Factory {
public:
std::unique_ptr<SSLConnectJob> Create(
RequestPriority priority,
const SocketTag& socket_tag,
const CommonConnectJobParams* common_connect_job_params,
scoped_refptr<SSLSocketParams> params,
ConnectJob::Delegate* delegate,
const NetLogWithSource* net_log) override {
params_.push_back(params);
return SSLConnectJob::Factory::Create(priority, socket_tag,
common_connect_job_params, params,
delegate, net_log);
}
const std::vector<scoped_refptr<SSLSocketParams>>& params() const {
return params_;
}
private:
std::vector<scoped_refptr<SSLSocketParams>> params_;
};
// Mock TransportConnectJob::Factory that records the `params` used and then
// passes on to a real factory.
class TestTransportConnectJobFactory : public TransportConnectJob::Factory {
public:
std::unique_ptr<TransportConnectJob> Create(
RequestPriority priority,
const SocketTag& socket_tag,
const CommonConnectJobParams* common_connect_job_params,
const scoped_refptr<TransportSocketParams>& params,
ConnectJob::Delegate* delegate,
const NetLogWithSource* net_log) override {
params_.push_back(params);
return TransportConnectJob::Factory::Create(priority, socket_tag,
common_connect_job_params,
params, delegate, net_log);
}
const std::vector<scoped_refptr<TransportSocketParams>>& params() const {
return params_;
}
private:
std::vector<scoped_refptr<TransportSocketParams>> params_;
};
class ConnectJobFactoryTest : public TestWithTaskEnvironment {
public:
ConnectJobFactoryTest() {
auto http_proxy_job_factory =
std::make_unique<TestHttpProxyConnectJobFactory>();
http_proxy_job_factory_ = http_proxy_job_factory.get();
auto socks_job_factory = std::make_unique<TestSocksConnectJobFactory>();
socks_job_factory_ = socks_job_factory.get();
auto ssl_job_factory = std::make_unique<TestSslConnectJobFactory>();
ssl_job_factory_ = ssl_job_factory.get();
auto transport_job_factory =
std::make_unique<TestTransportConnectJobFactory>();
transport_job_factory_ = transport_job_factory.get();
factory_ = std::make_unique<ConnectJobFactory>(
std::move(http_proxy_job_factory), std::move(socks_job_factory),
std::move(ssl_job_factory), std::move(transport_job_factory));
}
protected:
// Gets the total number of ConnectJob creations across all types.
size_t GetCreationCount() const {
return http_proxy_job_factory_->params().size() +
socks_job_factory_->params().size() +
ssl_job_factory_->params().size() +
transport_job_factory_->params().size();
}
const NextProtoVector alpn_protos_{kProtoHTTP2, kProtoHTTP11};
const SSLConfig::ApplicationSettings application_settings_{{kProtoHTTP2, {}}};
bool early_data_enabled_ = true;
const CommonConnectJobParams common_connect_job_params_{
/*client_socket_factory=*/nullptr,
/*host_resolver=*/nullptr,
/*http_auth_cache=*/nullptr,
/*http_auth_handler_factory=*/nullptr,
/*spdy_session_pool=*/nullptr,
/*quic_supported_versions=*/nullptr,
/*quic_session_pool=*/nullptr,
/*proxy_delegate=*/nullptr,
/*http_user_agent_settings=*/nullptr,
/*ssl_client_context=*/nullptr,
/*socket_performance_watcher_factory=*/nullptr,
/*network_quality_estimator=*/nullptr,
/*net_log=*/nullptr,
/*websocket_endpoint_lock_manager=*/nullptr,
/*http_server_properties=*/nullptr,
&alpn_protos_,
&application_settings_,
/*ignore_certificate_errors=*/nullptr,
&early_data_enabled_};
TestConnectJobDelegate delegate_;
std::unique_ptr<ConnectJobFactory> factory_;
raw_ptr<TestHttpProxyConnectJobFactory> http_proxy_job_factory_;
raw_ptr<TestSocksConnectJobFactory> socks_job_factory_;
raw_ptr<TestSslConnectJobFactory> ssl_job_factory_;
raw_ptr<TestTransportConnectJobFactory> transport_job_factory_;
};
TEST_F(ConnectJobFactoryTest, CreateConnectJob) {
const url::SchemeHostPort kEndpoint(url::kHttpScheme, "test", 82);
std::unique_ptr<ConnectJob> job = factory_->CreateConnectJob(
kEndpoint, ProxyChain::Direct(), /*proxy_annotation_tag=*/std::nullopt,
/*allowed_bad_certs=*/{}, ConnectJobFactory::AlpnMode::kHttpAll,
/*force_tunnel=*/false, PrivacyMode::PRIVACY_MODE_DISABLED,
OnHostResolutionCallback(), DEFAULT_PRIORITY, SocketTag(),
NetworkAnonymizationKey(), SecureDnsPolicy::kAllow,
/*disable_cert_network_fetches=*/false, &common_connect_job_params_,
&delegate_);
EXPECT_EQ(GetCreationCount(), 1u);
ASSERT_THAT(transport_job_factory_->params(), testing::SizeIs(1));
const TransportSocketParams& params =
*transport_job_factory_->params().front();
EXPECT_THAT(params.destination(),
testing::VariantWith<url::SchemeHostPort>(kEndpoint));
}
TEST_F(ConnectJobFactoryTest, CreateConnectJobWithoutScheme) {
const HostPortPair kEndpoint("test", 82);
std::unique_ptr<ConnectJob> job = factory_->CreateConnectJob(
/*using_ssl=*/false, kEndpoint, ProxyChain::Direct(),
/*proxy_annotation_tag=*/std::nullopt,
/*force_tunnel=*/false, PrivacyMode::PRIVACY_MODE_DISABLED,
OnHostResolutionCallback(), DEFAULT_PRIORITY, SocketTag(),
NetworkAnonymizationKey(), SecureDnsPolicy::kAllow,
&common_connect_job_params_, &delegate_);
EXPECT_EQ(GetCreationCount(), 1u);
ASSERT_THAT(transport_job_factory_->params(), testing::SizeIs(1));
const TransportSocketParams& params =
*transport_job_factory_->params().front();
EXPECT_THAT(params.destination(),
testing::VariantWith<HostPortPair>(kEndpoint));
}
TEST_F(ConnectJobFactoryTest, CreateHttpsConnectJob) {
const url::SchemeHostPort kEndpoint(url::kHttpsScheme, "test", 84);
std::unique_ptr<ConnectJob> job = factory_->CreateConnectJob(
kEndpoint, ProxyChain::Direct(), /*proxy_annotation_tag=*/std::nullopt,
/*allowed_bad_certs=*/{}, ConnectJobFactory::AlpnMode::kHttpAll,
/*force_tunnel=*/false, PrivacyMode::PRIVACY_MODE_DISABLED,
OnHostResolutionCallback(), DEFAULT_PRIORITY, SocketTag(),
NetworkAnonymizationKey(), SecureDnsPolicy::kAllow,
/*disable_cert_network_fetches=*/false, &common_connect_job_params_,
&delegate_);
EXPECT_EQ(GetCreationCount(), 1u);
ASSERT_THAT(ssl_job_factory_->params(), testing::SizeIs(1));
const SSLSocketParams& params = *ssl_job_factory_->params().front();
EXPECT_EQ(params.host_and_port(),
HostPortPair::FromSchemeHostPort(kEndpoint));
EXPECT_FALSE(params.ssl_config().disable_cert_verification_network_fetches);
EXPECT_EQ(0, params.ssl_config().GetCertVerifyFlags());
EXPECT_THAT(params.ssl_config().alpn_protos,
testing::ElementsAreArray(alpn_protos_));
EXPECT_EQ(params.ssl_config().application_settings, application_settings_);
EXPECT_EQ(params.ssl_config().renego_allowed_default, true);
EXPECT_THAT(params.ssl_config().renego_allowed_for_protos,
testing::ElementsAre(kProtoHTTP11));
EXPECT_TRUE(params.ssl_config().early_data_enabled);
ASSERT_EQ(params.GetConnectionType(), SSLSocketParams::DIRECT);
const TransportSocketParams& transport_params =
*params.GetDirectConnectionParams();
EXPECT_THAT(transport_params.destination(),
testing::VariantWith<url::SchemeHostPort>(kEndpoint));
EXPECT_THAT(transport_params.supported_alpns(),
testing::UnorderedElementsAre("h2", "http/1.1"));
}
TEST_F(ConnectJobFactoryTest, CreateHttpsConnectJobForHttp11) {
const url::SchemeHostPort kEndpoint(url::kHttpsScheme, "test", 84);
std::unique_ptr<ConnectJob> job = factory_->CreateConnectJob(
kEndpoint, ProxyChain::Direct(), /*proxy_annotation_tag=*/std::nullopt,
/*allowed_bad_certs=*/{}, ConnectJobFactory::AlpnMode::kHttp11Only,
/*force_tunnel=*/false, PrivacyMode::PRIVACY_MODE_DISABLED,
OnHostResolutionCallback(), DEFAULT_PRIORITY, SocketTag(),
NetworkAnonymizationKey(), SecureDnsPolicy::kAllow,
/*disable_cert_network_fetches=*/false, &common_connect_job_params_,
&delegate_);
EXPECT_EQ(GetCreationCount(), 1u);
ASSERT_THAT(ssl_job_factory_->params(), testing::SizeIs(1));
const SSLSocketParams& params = *ssl_job_factory_->params().front();
EXPECT_EQ(params.host_and_port(),
HostPortPair::FromSchemeHostPort(kEndpoint));
EXPECT_FALSE(params.ssl_config().disable_cert_verification_network_fetches);
EXPECT_EQ(0, params.ssl_config().GetCertVerifyFlags());
EXPECT_THAT(params.ssl_config().alpn_protos,
testing::ElementsAre(kProtoHTTP11));
EXPECT_EQ(params.ssl_config().application_settings, application_settings_);
EXPECT_EQ(params.ssl_config().renego_allowed_default, true);
EXPECT_THAT(params.ssl_config().renego_allowed_for_protos,
testing::ElementsAre(kProtoHTTP11));
EXPECT_TRUE(params.ssl_config().early_data_enabled);
ASSERT_EQ(params.GetConnectionType(), SSLSocketParams::DIRECT);
const TransportSocketParams& transport_params =
*params.GetDirectConnectionParams();
EXPECT_THAT(transport_params.destination(),
testing::VariantWith<url::SchemeHostPort>(kEndpoint));
EXPECT_THAT(transport_params.supported_alpns(),
testing::UnorderedElementsAre("http/1.1"));
}
TEST_F(ConnectJobFactoryTest, CreateHttpsConnectJobWithoutScheme) {
const HostPortPair kEndpoint("test", 84);
std::unique_ptr<ConnectJob> job = factory_->CreateConnectJob(
/*using_ssl=*/true, kEndpoint, ProxyChain::Direct(),
/*proxy_annotation_tag=*/std::nullopt, /*force_tunnel=*/false,
PrivacyMode::PRIVACY_MODE_DISABLED, OnHostResolutionCallback(),
DEFAULT_PRIORITY, SocketTag(), NetworkAnonymizationKey(),
SecureDnsPolicy::kAllow, &common_connect_job_params_, &delegate_);
EXPECT_EQ(GetCreationCount(), 1u);
ASSERT_THAT(ssl_job_factory_->params(), testing::SizeIs(1));
const SSLSocketParams& params = *ssl_job_factory_->params().front();
EXPECT_EQ(params.host_and_port(), kEndpoint);
EXPECT_FALSE(params.ssl_config().disable_cert_verification_network_fetches);
EXPECT_EQ(0, params.ssl_config().GetCertVerifyFlags());
EXPECT_THAT(params.ssl_config().alpn_protos, testing::ElementsAre());
EXPECT_TRUE(params.ssl_config().application_settings.empty());
EXPECT_EQ(params.ssl_config().renego_allowed_default, false);
EXPECT_THAT(params.ssl_config().renego_allowed_for_protos,
testing::ElementsAre());
EXPECT_TRUE(params.ssl_config().early_data_enabled);
ASSERT_EQ(params.GetConnectionType(), SSLSocketParams::DIRECT);
const TransportSocketParams& transport_params =
*params.GetDirectConnectionParams();
EXPECT_THAT(transport_params.destination(),
testing::VariantWith<HostPortPair>(kEndpoint));
}
TEST_F(ConnectJobFactoryTest, CreateHttpProxyConnectJob) {
const url::SchemeHostPort kEndpoint(url::kHttpScheme, "test", 85);
const ProxyChain kProxy(ProxyServer::SCHEME_HTTP,
HostPortPair("proxy.test", 86));
std::unique_ptr<ConnectJob> job = factory_->CreateConnectJob(
kEndpoint, kProxy, TRAFFIC_ANNOTATION_FOR_TESTS, /*allowed_bad_certs=*/{},
ConnectJobFactory::AlpnMode::kHttpAll, /*force_tunnel=*/false,
PrivacyMode::PRIVACY_MODE_DISABLED, OnHostResolutionCallback(),
DEFAULT_PRIORITY, SocketTag(), NetworkAnonymizationKey(),
SecureDnsPolicy::kAllow, /*disable_cert_network_fetches=*/false,
&common_connect_job_params_, &delegate_);
EXPECT_EQ(GetCreationCount(), 1u);
ASSERT_THAT(http_proxy_job_factory_->params(), testing::SizeIs(1));
const HttpProxySocketParams& params =
*http_proxy_job_factory_->params().front();
EXPECT_FALSE(params.proxy_server().is_quic());
EXPECT_EQ(params.endpoint(), HostPortPair::FromSchemeHostPort(kEndpoint));
ASSERT_TRUE(params.transport_params());
const TransportSocketParams& transport_params = *params.transport_params();
EXPECT_THAT(
transport_params.destination(),
testing::VariantWith<HostPortPair>(kProxy.First().host_port_pair()));
}
TEST_F(ConnectJobFactoryTest, CreateHttpProxyConnectJobWithoutScheme) {
const HostPortPair kEndpoint("test", 85);
const ProxyChain kProxy(ProxyServer::SCHEME_HTTP,
HostPortPair("proxy.test", 86));
std::unique_ptr<ConnectJob> job = factory_->CreateConnectJob(
/*using_ssl=*/false, kEndpoint, kProxy, TRAFFIC_ANNOTATION_FOR_TESTS,
/*force_tunnel=*/false, PrivacyMode::PRIVACY_MODE_DISABLED,
OnHostResolutionCallback(), DEFAULT_PRIORITY, SocketTag(),
NetworkAnonymizationKey(), SecureDnsPolicy::kAllow,
&common_connect_job_params_, &delegate_);
EXPECT_EQ(GetCreationCount(), 1u);
ASSERT_THAT(http_proxy_job_factory_->params(), testing::SizeIs(1));
const HttpProxySocketParams& params =
*http_proxy_job_factory_->params().front();
EXPECT_FALSE(params.proxy_server().is_quic());
EXPECT_EQ(params.endpoint(), kEndpoint);
ASSERT_TRUE(params.transport_params());
const TransportSocketParams& transport_params = *params.transport_params();
EXPECT_THAT(
transport_params.destination(),
testing::VariantWith<HostPortPair>(kProxy.First().host_port_pair()));
}
TEST_F(ConnectJobFactoryTest, CreateHttpProxyConnectJobForHttps) {
const url::SchemeHostPort kEndpoint(url::kHttpsScheme, "test", 87);
const ProxyChain kProxy(ProxyServer::SCHEME_HTTP,
HostPortPair("proxy.test", 88));
std::unique_ptr<ConnectJob> job = factory_->CreateConnectJob(
kEndpoint, kProxy, TRAFFIC_ANNOTATION_FOR_TESTS, /*allowed_bad_certs=*/{},
ConnectJobFactory::AlpnMode::kHttpAll, /*force_tunnel=*/false,
PrivacyMode::PRIVACY_MODE_DISABLED, OnHostResolutionCallback(),
DEFAULT_PRIORITY, SocketTag(), NetworkAnonymizationKey(),
SecureDnsPolicy::kAllow, /*disable_cert_network_fetches=*/false,
&common_connect_job_params_, &delegate_);
EXPECT_EQ(GetCreationCount(), 1u);
ASSERT_THAT(ssl_job_factory_->params(), testing::SizeIs(1));
const SSLSocketParams& params = *ssl_job_factory_->params().front();
EXPECT_EQ(params.host_and_port(),
HostPortPair::FromSchemeHostPort(kEndpoint));
EXPECT_FALSE(params.ssl_config().disable_cert_verification_network_fetches);
EXPECT_EQ(0, params.ssl_config().GetCertVerifyFlags());
EXPECT_THAT(params.ssl_config().alpn_protos,
testing::ElementsAreArray(alpn_protos_));
EXPECT_EQ(params.ssl_config().application_settings, application_settings_);
EXPECT_EQ(params.ssl_config().renego_allowed_default, true);
EXPECT_THAT(params.ssl_config().renego_allowed_for_protos,
testing::ElementsAre(kProtoHTTP11));
EXPECT_TRUE(params.ssl_config().early_data_enabled);
ASSERT_EQ(params.GetConnectionType(), SSLSocketParams::HTTP_PROXY);
const HttpProxySocketParams& proxy_params =
*params.GetHttpProxyConnectionParams();
EXPECT_FALSE(proxy_params.proxy_server().is_quic());
EXPECT_EQ(proxy_params.endpoint(),
HostPortPair::FromSchemeHostPort(kEndpoint));
ASSERT_TRUE(proxy_params.transport_params());
const TransportSocketParams& transport_params =
*proxy_params.transport_params();
EXPECT_THAT(
transport_params.destination(),
testing::VariantWith<HostPortPair>(kProxy.First().host_port_pair()));
}
TEST_F(ConnectJobFactoryTest, CreateHttpProxyConnectJobForHttpsWithoutScheme) {
const HostPortPair kEndpoint("test", 87);
const ProxyChain kProxy(ProxyServer::SCHEME_HTTP,
HostPortPair("proxy.test", 88));
std::unique_ptr<ConnectJob> job = factory_->CreateConnectJob(
/*using_ssl=*/true, kEndpoint, kProxy, TRAFFIC_ANNOTATION_FOR_TESTS,
/*force_tunnel=*/false, PrivacyMode::PRIVACY_MODE_DISABLED,
OnHostResolutionCallback(), DEFAULT_PRIORITY, SocketTag(),
NetworkAnonymizationKey(), SecureDnsPolicy::kAllow,
&common_connect_job_params_, &delegate_);
EXPECT_EQ(GetCreationCount(), 1u);
ASSERT_THAT(ssl_job_factory_->params(), testing::SizeIs(1));
const SSLSocketParams& params = *ssl_job_factory_->params().front();
EXPECT_EQ(params.host_and_port(), kEndpoint);
ASSERT_EQ(params.GetConnectionType(), SSLSocketParams::HTTP_PROXY);
const HttpProxySocketParams& proxy_params =
*params.GetHttpProxyConnectionParams();
EXPECT_FALSE(proxy_params.proxy_server().is_quic());
EXPECT_EQ(proxy_params.endpoint(), kEndpoint);
EXPECT_THAT(params.ssl_config().alpn_protos, testing::ElementsAre());
EXPECT_TRUE(params.ssl_config().application_settings.empty());
EXPECT_EQ(params.ssl_config().renego_allowed_default, false);
EXPECT_THAT(params.ssl_config().renego_allowed_for_protos,
testing::ElementsAre());
// While the only production caller of this method disables SSL early data, it
// does so by configuring the HttpNetworkSession, rather than by relying on
// the ConnectJobFactory to disable early data when there's no scheme.
EXPECT_TRUE(params.ssl_config().early_data_enabled);
ASSERT_TRUE(proxy_params.transport_params());
const TransportSocketParams& transport_params =
*proxy_params.transport_params();
EXPECT_THAT(
transport_params.destination(),
testing::VariantWith<HostPortPair>(kProxy.First().host_port_pair()));
}
TEST_F(ConnectJobFactoryTest, CreateHttpsProxyConnectJob) {
const url::SchemeHostPort kEndpoint(url::kHttpScheme, "test", 89);
const ProxyChain kProxy(ProxyServer::SCHEME_HTTPS,
HostPortPair("proxy.test", 90));
std::unique_ptr<ConnectJob> job = factory_->CreateConnectJob(
kEndpoint, kProxy, TRAFFIC_ANNOTATION_FOR_TESTS, /*allowed_bad_certs=*/{},
ConnectJobFactory::AlpnMode::kHttpAll, /*force_tunnel=*/false,
PrivacyMode::PRIVACY_MODE_DISABLED, OnHostResolutionCallback(),
DEFAULT_PRIORITY, SocketTag(), NetworkAnonymizationKey(),
SecureDnsPolicy::kAllow, /*disable_cert_network_fetches=*/false,
&common_connect_job_params_, &delegate_);
EXPECT_EQ(GetCreationCount(), 1u);
ASSERT_THAT(http_proxy_job_factory_->params(), testing::SizeIs(1));
const HttpProxySocketParams& params =
*http_proxy_job_factory_->params().front();
EXPECT_FALSE(params.proxy_server().is_quic());
EXPECT_EQ(params.endpoint(), HostPortPair::FromSchemeHostPort(kEndpoint));
ASSERT_TRUE(params.ssl_params());
const SSLSocketParams& ssl_params = *params.ssl_params();
EXPECT_EQ(ssl_params.host_and_port(), kProxy.First().host_port_pair());
EXPECT_TRUE(
ssl_params.ssl_config().disable_cert_verification_network_fetches);
EXPECT_EQ(CertVerifier::VERIFY_DISABLE_NETWORK_FETCHES,
ssl_params.ssl_config().GetCertVerifyFlags());
EXPECT_THAT(ssl_params.ssl_config().alpn_protos,
testing::ElementsAreArray(alpn_protos_));
EXPECT_EQ(ssl_params.ssl_config().application_settings,
application_settings_);
// Renegotiation is never allowed for proxies.
EXPECT_EQ(ssl_params.ssl_config().renego_allowed_default, false);
EXPECT_THAT(ssl_params.ssl_config().renego_allowed_for_protos,
testing::ElementsAre());
EXPECT_FALSE(ssl_params.ssl_config().early_data_enabled);
ASSERT_EQ(ssl_params.GetConnectionType(), SSLSocketParams::DIRECT);
const TransportSocketParams& transport_params =
*ssl_params.GetDirectConnectionParams();
EXPECT_THAT(
transport_params.destination(),
testing::VariantWith<HostPortPair>(kProxy.First().host_port_pair()));
}
TEST_F(ConnectJobFactoryTest, CreateHttpsProxyConnectJobWithoutScheme) {
const HostPortPair kEndpoint("test", 89);
const ProxyChain kProxy(ProxyServer::SCHEME_HTTPS,
HostPortPair("proxy.test", 90));
std::unique_ptr<ConnectJob> job = factory_->CreateConnectJob(
/*using_ssl=*/false, kEndpoint, kProxy, TRAFFIC_ANNOTATION_FOR_TESTS,
/*force_tunnel=*/false, PrivacyMode::PRIVACY_MODE_DISABLED,
OnHostResolutionCallback(), DEFAULT_PRIORITY, SocketTag(),
NetworkAnonymizationKey(), SecureDnsPolicy::kAllow,
&common_connect_job_params_, &delegate_);
EXPECT_EQ(GetCreationCount(), 1u);
ASSERT_THAT(http_proxy_job_factory_->params(), testing::SizeIs(1));
const HttpProxySocketParams& params =
*http_proxy_job_factory_->params().front();
EXPECT_FALSE(params.proxy_server().is_quic());
EXPECT_EQ(params.endpoint(), kEndpoint);
ASSERT_TRUE(params.ssl_params());
const SSLSocketParams& ssl_params = *params.ssl_params();
EXPECT_EQ(ssl_params.host_and_port(), kProxy.First().host_port_pair());
EXPECT_TRUE(
ssl_params.ssl_config().disable_cert_verification_network_fetches);
EXPECT_EQ(CertVerifier::VERIFY_DISABLE_NETWORK_FETCHES,
ssl_params.ssl_config().GetCertVerifyFlags());
// Alpn should always be used for HTTPS proxies.
EXPECT_THAT(ssl_params.ssl_config().alpn_protos,
testing::ElementsAreArray(alpn_protos_));
EXPECT_EQ(ssl_params.ssl_config().application_settings,
application_settings_);
// Renegotiation is never allowed for proxies.
EXPECT_EQ(ssl_params.ssl_config().renego_allowed_default, false);
EXPECT_THAT(ssl_params.ssl_config().renego_allowed_for_protos,
testing::ElementsAre());
EXPECT_FALSE(ssl_params.ssl_config().early_data_enabled);
ASSERT_EQ(ssl_params.GetConnectionType(), SSLSocketParams::DIRECT);
const TransportSocketParams& transport_params =
*ssl_params.GetDirectConnectionParams();
EXPECT_THAT(
transport_params.destination(),
testing::VariantWith<HostPortPair>(kProxy.First().host_port_pair()));
}
TEST_F(ConnectJobFactoryTest, CreateNestedHttpsProxyConnectJob) {
const url::SchemeHostPort kEndpoint(url::kHttpScheme, "test", 89);
const ProxyServer kProxyServer1{ProxyServer::SCHEME_HTTPS,
HostPortPair("proxy1.test", 443)};
const ProxyServer kProxyServer2{ProxyServer::SCHEME_HTTPS,
HostPortPair("proxy2.test", 443)};
const ProxyChain kNestedProxyChain{{kProxyServer1, kProxyServer2}};
std::unique_ptr<ConnectJob> job = factory_->CreateConnectJob(
kEndpoint, kNestedProxyChain, TRAFFIC_ANNOTATION_FOR_TESTS,
/*allowed_bad_certs=*/{}, ConnectJobFactory::AlpnMode::kHttpAll,
/*force_tunnel=*/false, PrivacyMode::PRIVACY_MODE_DISABLED,
OnHostResolutionCallback(), DEFAULT_PRIORITY, SocketTag(),
NetworkAnonymizationKey(), SecureDnsPolicy::kAllow,
/*disable_cert_network_fetches=*/false, &common_connect_job_params_,
&delegate_);
EXPECT_EQ(GetCreationCount(), 1u);
ASSERT_THAT(http_proxy_job_factory_->params(), testing::SizeIs(1));
// The corresponding HttpProxySocketParams and SSLSocketParams for each hop
// should be present in reverse order.
const HttpProxySocketParams& proxy_server2_http_params =
*http_proxy_job_factory_->params().front();
EXPECT_FALSE(proxy_server2_http_params.proxy_server().is_quic());
// We should to send a CONNECT to `kProxyServer2` for `kEndpoint`.
EXPECT_EQ(proxy_server2_http_params.endpoint(),
HostPortPair::FromSchemeHostPort(kEndpoint));
EXPECT_TRUE(proxy_server2_http_params.tunnel());
const SSLSocketParams& proxy_server2_ssl_params =
*proxy_server2_http_params.ssl_params();
EXPECT_EQ(proxy_server2_ssl_params.host_and_port(),
kProxyServer2.host_port_pair());
EXPECT_THAT(proxy_server2_ssl_params.ssl_config().alpn_protos,
testing::ElementsAreArray(alpn_protos_));
EXPECT_EQ(proxy_server2_ssl_params.ssl_config().application_settings,
application_settings_);
EXPECT_EQ(proxy_server2_ssl_params.ssl_config().renego_allowed_default,
false);
EXPECT_THAT(proxy_server2_ssl_params.ssl_config().renego_allowed_for_protos,
testing::ElementsAre());
EXPECT_FALSE(proxy_server2_ssl_params.ssl_config().early_data_enabled);
const HttpProxySocketParams& proxy_server1_http_params =
*proxy_server2_ssl_params.GetHttpProxyConnectionParams();
EXPECT_FALSE(proxy_server1_http_params.proxy_server().is_quic());
// We should to send a CONNECT to `kProxyServer1` for `kProxyServer2`.
EXPECT_EQ(proxy_server1_http_params.endpoint(),
kProxyServer2.host_port_pair());
ASSERT_TRUE(proxy_server1_http_params.ssl_params());
const SSLSocketParams& proxy_server1_ssl_params =
*proxy_server1_http_params.ssl_params();
EXPECT_EQ(proxy_server1_ssl_params.host_and_port(),
kProxyServer1.host_port_pair());
EXPECT_THAT(proxy_server1_ssl_params.ssl_config().alpn_protos,
testing::ElementsAreArray(alpn_protos_));
EXPECT_EQ(proxy_server1_ssl_params.ssl_config().application_settings,
application_settings_);
EXPECT_EQ(proxy_server1_ssl_params.ssl_config().renego_allowed_default,
false);
EXPECT_THAT(proxy_server1_ssl_params.ssl_config().renego_allowed_for_protos,
testing::ElementsAre());
EXPECT_FALSE(proxy_server1_ssl_params.ssl_config().early_data_enabled);
ASSERT_EQ(proxy_server1_ssl_params.GetConnectionType(),
SSLSocketParams::DIRECT);
ASSERT_EQ(proxy_server2_ssl_params.GetConnectionType(),
SSLSocketParams::HTTP_PROXY);
const TransportSocketParams& transport_params =
*proxy_server1_ssl_params.GetDirectConnectionParams();
EXPECT_THAT(
transport_params.destination(),
testing::VariantWith<HostPortPair>(kProxyServer1.host_port_pair()));
}
TEST_F(ConnectJobFactoryTest, CreateNestedHttpsProxyConnectJobWithoutScheme) {
const HostPortPair kEndpoint("test", 89);
const ProxyServer kProxyServer1{ProxyServer::SCHEME_HTTPS,
HostPortPair("proxy1.test", 443)};
const ProxyServer kProxyServer2{ProxyServer::SCHEME_HTTPS,
HostPortPair("proxy2.test", 443)};
const ProxyChain kNestedProxyChain{{kProxyServer1, kProxyServer2}};
std::unique_ptr<ConnectJob> job = factory_->CreateConnectJob(
/*using_ssl=*/false, kEndpoint, kNestedProxyChain,
TRAFFIC_ANNOTATION_FOR_TESTS, /*force_tunnel=*/false,
PrivacyMode::PRIVACY_MODE_DISABLED, OnHostResolutionCallback(),
DEFAULT_PRIORITY, SocketTag(), NetworkAnonymizationKey(),
SecureDnsPolicy::kAllow, &common_connect_job_params_, &delegate_);
EXPECT_EQ(GetCreationCount(), 1u);
ASSERT_THAT(http_proxy_job_factory_->params(), testing::SizeIs(1));
// The corresponding HttpProxySocketParams and SSLSocketParams for each hop
// should be present in reverse order.
const HttpProxySocketParams& proxy_server2_http_params =
*http_proxy_job_factory_->params().front();
EXPECT_FALSE(proxy_server2_http_params.proxy_server().is_quic());
// We should to send a CONNECT to `kProxyServer2` for `kEndpoint`.
EXPECT_EQ(proxy_server2_http_params.endpoint(), kEndpoint);
const SSLSocketParams& proxy_server2_ssl_params =
*proxy_server2_http_params.ssl_params();
EXPECT_EQ(proxy_server2_ssl_params.host_and_port(),
kProxyServer2.host_port_pair());
const HttpProxySocketParams& proxy_server1_http_params =
*proxy_server2_ssl_params.GetHttpProxyConnectionParams();
EXPECT_FALSE(proxy_server1_http_params.proxy_server().is_quic());
// We should to send a CONNECT to `kProxyServer1` for `kProxyServer2`.
EXPECT_EQ(proxy_server1_http_params.endpoint(),
kProxyServer2.host_port_pair());
EXPECT_THAT(proxy_server2_ssl_params.ssl_config().alpn_protos,
testing::ElementsAreArray(alpn_protos_));
EXPECT_EQ(proxy_server2_ssl_params.ssl_config().application_settings,
application_settings_);
EXPECT_EQ(proxy_server2_ssl_params.ssl_config().renego_allowed_default,
false);
EXPECT_THAT(proxy_server2_ssl_params.ssl_config().renego_allowed_for_protos,
testing::ElementsAre());
EXPECT_FALSE(proxy_server2_ssl_params.ssl_config().early_data_enabled);
ASSERT_TRUE(proxy_server1_http_params.ssl_params());
const SSLSocketParams& proxy_server1_ssl_params =
*proxy_server1_http_params.ssl_params();
EXPECT_EQ(proxy_server1_ssl_params.host_and_port(),
kProxyServer1.host_port_pair());
EXPECT_THAT(proxy_server1_ssl_params.ssl_config().alpn_protos,
testing::ElementsAreArray(alpn_protos_));
EXPECT_EQ(proxy_server1_ssl_params.ssl_config().application_settings,
application_settings_);
EXPECT_EQ(proxy_server1_ssl_params.ssl_config().renego_allowed_default,
false);
EXPECT_THAT(proxy_server1_ssl_params.ssl_config().renego_allowed_for_protos,
testing::ElementsAre());
EXPECT_FALSE(proxy_server1_ssl_params.ssl_config().early_data_enabled);
ASSERT_EQ(proxy_server1_ssl_params.GetConnectionType(),
SSLSocketParams::DIRECT);
ASSERT_EQ(proxy_server2_ssl_params.GetConnectionType(),
SSLSocketParams::HTTP_PROXY);
ASSERT_EQ(proxy_server1_ssl_params.GetConnectionType(),
SSLSocketParams::DIRECT);
const TransportSocketParams& transport_params =
*proxy_server1_ssl_params.GetDirectConnectionParams();
EXPECT_THAT(
transport_params.destination(),
testing::VariantWith<HostPortPair>(kProxyServer1.host_port_pair()));
}
TEST_F(ConnectJobFactoryTest, CreateNestedHttpsProxyConnectJobForHttps) {
const url::SchemeHostPort kEndpoint(url::kHttpsScheme, "test", 443);
const ProxyServer kProxyServer1{ProxyServer::SCHEME_HTTPS,
HostPortPair("proxy1.test", 443)};
const ProxyServer kProxyServer2{ProxyServer::SCHEME_HTTPS,
HostPortPair("proxy2.test", 443)};
const ProxyChain kNestedProxyChain{{kProxyServer1, kProxyServer2}};
std::unique_ptr<ConnectJob> job = factory_->CreateConnectJob(
kEndpoint, kNestedProxyChain, TRAFFIC_ANNOTATION_FOR_TESTS,
/*allowed_bad_certs=*/{}, ConnectJobFactory::AlpnMode::kHttpAll,
/*force_tunnel=*/false, PrivacyMode::PRIVACY_MODE_DISABLED,
OnHostResolutionCallback(), DEFAULT_PRIORITY, SocketTag(),
NetworkAnonymizationKey(), SecureDnsPolicy::kAllow,
/*disable_cert_network_fetches=*/false, &common_connect_job_params_,
&delegate_);
EXPECT_EQ(GetCreationCount(), 1u);
ASSERT_THAT(ssl_job_factory_->params(), testing::SizeIs(1));
const SSLSocketParams& endpoint_ssl_params =
*ssl_job_factory_->params().at(0);
EXPECT_THAT(endpoint_ssl_params.ssl_config().alpn_protos,
testing::ElementsAreArray(alpn_protos_));
EXPECT_EQ(endpoint_ssl_params.ssl_config().application_settings,
application_settings_);
EXPECT_EQ(endpoint_ssl_params.ssl_config().renego_allowed_default, true);
EXPECT_THAT(endpoint_ssl_params.ssl_config().renego_allowed_for_protos,
testing::ElementsAre(kProtoHTTP11));
EXPECT_TRUE(endpoint_ssl_params.ssl_config().early_data_enabled);
// The SSLSocketParams for the destination should be configured to go through
// the chain of proxies, with the corresponding HttpProxySocketParams and
// SSLSocketParams for each hop present in reverse order.
const HttpProxySocketParams& proxy_server2_http_params =
*endpoint_ssl_params.GetHttpProxyConnectionParams();
EXPECT_FALSE(proxy_server2_http_params.proxy_server().is_quic());
// We should to send a CONNECT to `kProxyServer2` for `kEndpoint`.
EXPECT_EQ(proxy_server2_http_params.endpoint(),
HostPortPair::FromSchemeHostPort(kEndpoint));
const SSLSocketParams& proxy_server2_ssl_params =
*proxy_server2_http_params.ssl_params();
EXPECT_EQ(proxy_server2_ssl_params.host_and_port(),
kProxyServer2.host_port_pair());
EXPECT_THAT(proxy_server2_ssl_params.ssl_config().alpn_protos,
testing::ElementsAreArray(alpn_protos_));
EXPECT_EQ(proxy_server2_ssl_params.ssl_config().application_settings,
application_settings_);
EXPECT_EQ(proxy_server2_ssl_params.ssl_config().renego_allowed_default,
false);
EXPECT_THAT(proxy_server2_ssl_params.ssl_config().renego_allowed_for_protos,
testing::ElementsAre());
EXPECT_FALSE(proxy_server2_ssl_params.ssl_config().early_data_enabled);
const HttpProxySocketParams& proxy_server1_http_params =
*proxy_server2_ssl_params.GetHttpProxyConnectionParams();
EXPECT_FALSE(proxy_server1_http_params.proxy_server().is_quic());
// We should to send a CONNECT to `kProxyServer1` for `kProxyServer2`.
EXPECT_EQ(proxy_server1_http_params.endpoint(),
kProxyServer2.host_port_pair());
ASSERT_TRUE(proxy_server1_http_params.ssl_params());
const SSLSocketParams& proxy_server1_ssl_params =
*proxy_server1_http_params.ssl_params();
EXPECT_EQ(proxy_server1_ssl_params.host_and_port(),
kProxyServer1.host_port_pair());
EXPECT_THAT(proxy_server1_ssl_params.ssl_config().alpn_protos,
testing::ElementsAreArray(alpn_protos_));
EXPECT_EQ(proxy_server1_ssl_params.ssl_config().application_settings,
application_settings_);
EXPECT_EQ(proxy_server1_ssl_params.ssl_config().renego_allowed_default,
false);
EXPECT_THAT(proxy_server1_ssl_params.ssl_config().renego_allowed_for_protos,
testing::ElementsAre());
EXPECT_FALSE(proxy_server1_ssl_params.ssl_config().early_data_enabled);
ASSERT_EQ(proxy_server1_ssl_params.GetConnectionType(),
SSLSocketParams::DIRECT);
ASSERT_EQ(proxy_server2_ssl_params.GetConnectionType(),
SSLSocketParams::HTTP_PROXY);
ASSERT_EQ(endpoint_ssl_params.GetConnectionType(),
SSLSocketParams::HTTP_PROXY);
const TransportSocketParams& transport_params =
*proxy_server1_ssl_params.GetDirectConnectionParams();
// We should establish a physical socket / direct connection to
// `kProxyServer1` (and will tunnel all subsequent traffic through
// that).
EXPECT_THAT(
transport_params.destination(),
testing::VariantWith<HostPortPair>(kProxyServer1.host_port_pair()));
}
TEST_F(ConnectJobFactoryTest,
CreateNestedHttpsProxyConnectJobForHttpsWithoutScheme) {
const HostPortPair kEndpoint("test", 443);
const ProxyServer kProxyServer1{ProxyServer::SCHEME_HTTPS,
HostPortPair("proxy1.test", 443)};
const ProxyServer kProxyServer2{ProxyServer::SCHEME_HTTPS,
HostPortPair("proxy2.test", 443)};
const ProxyChain kNestedProxyChain{{kProxyServer1, kProxyServer2}};
std::unique_ptr<ConnectJob> job = factory_->CreateConnectJob(
/*using_ssl=*/true, kEndpoint, kNestedProxyChain,
TRAFFIC_ANNOTATION_FOR_TESTS, /*force_tunnel=*/false,
PrivacyMode::PRIVACY_MODE_DISABLED, OnHostResolutionCallback(),
DEFAULT_PRIORITY, SocketTag(), NetworkAnonymizationKey(),
SecureDnsPolicy::kAllow, &common_connect_job_params_, &delegate_);
EXPECT_EQ(GetCreationCount(), 1u);
ASSERT_THAT(ssl_job_factory_->params(), testing::SizeIs(1));
const SSLSocketParams& endpoint_ssl_params =
*ssl_job_factory_->params().at(0);
EXPECT_THAT(endpoint_ssl_params.ssl_config().alpn_protos,
testing::ElementsAre());
EXPECT_TRUE(endpoint_ssl_params.ssl_config().application_settings.empty());
EXPECT_EQ(endpoint_ssl_params.ssl_config().renego_allowed_default, false);
EXPECT_THAT(endpoint_ssl_params.ssl_config().renego_allowed_for_protos,
testing::ElementsAre());
EXPECT_TRUE(endpoint_ssl_params.ssl_config().early_data_enabled);
// The SSLSocketParams for the destination should be configured to go through
// the chain of proxies, with the corresponding HttpProxySocketParams and
// SSLSocketParams for each hop present in reverse order.
const HttpProxySocketParams& proxy_server2_http_params =
*endpoint_ssl_params.GetHttpProxyConnectionParams();
EXPECT_FALSE(proxy_server2_http_params.proxy_server().is_quic());
// We should to send a CONNECT to `kProxyServer2` for `kEndpoint`.
EXPECT_EQ(proxy_server2_http_params.endpoint(), kEndpoint);
const SSLSocketParams& proxy_server2_ssl_params =
*proxy_server2_http_params.ssl_params();
EXPECT_EQ(proxy_server2_ssl_params.host_and_port(),
kProxyServer2.host_port_pair());
const HttpProxySocketParams& proxy_server1_http_params =
*proxy_server2_ssl_params.GetHttpProxyConnectionParams();
EXPECT_FALSE(proxy_server1_http_params.proxy_server().is_quic());
// We should to send a CONNECT to `kProxyServer1` for `kProxyServer2`.
EXPECT_EQ(proxy_server1_http_params.endpoint(),
kProxyServer2.host_port_pair());
EXPECT_THAT(proxy_server2_ssl_params.ssl_config().alpn_protos,
testing::ElementsAreArray(alpn_protos_));
EXPECT_EQ(proxy_server2_ssl_params.ssl_config().application_settings,
application_settings_);
EXPECT_EQ(proxy_server2_ssl_params.ssl_config().renego_allowed_default,
false);
EXPECT_THAT(proxy_server2_ssl_params.ssl_config().renego_allowed_for_protos,
testing::ElementsAre());
EXPECT_FALSE(proxy_server2_ssl_params.ssl_config().early_data_enabled);
ASSERT_TRUE(proxy_server1_http_params.ssl_params());
const SSLSocketParams& proxy_server1_ssl_params =
*proxy_server1_http_params.ssl_params();
EXPECT_EQ(proxy_server1_ssl_params.host_and_port(),
kProxyServer1.host_port_pair());
EXPECT_THAT(proxy_server1_ssl_params.ssl_config().alpn_protos,
testing::ElementsAreArray(alpn_protos_));
EXPECT_EQ(proxy_server1_ssl_params.ssl_config().application_settings,
application_settings_);
EXPECT_EQ(proxy_server1_ssl_params.ssl_config().renego_allowed_default,
false);
EXPECT_THAT(proxy_server1_ssl_params.ssl_config().renego_allowed_for_protos,
testing::ElementsAre());
EXPECT_FALSE(proxy_server1_ssl_params.ssl_config().early_data_enabled);
ASSERT_EQ(proxy_server1_ssl_params.GetConnectionType(),
SSLSocketParams::DIRECT);
ASSERT_EQ(proxy_server2_ssl_params.GetConnectionType(),
SSLSocketParams::HTTP_PROXY);
ASSERT_EQ(endpoint_ssl_params.GetConnectionType(),
SSLSocketParams::HTTP_PROXY);
const TransportSocketParams& transport_params =
*proxy_server1_ssl_params.GetDirectConnectionParams();
// We should establish a physical socket / direct connection to
// `kProxyServer1` (and will tunnel all subsequent traffic through
// that).
EXPECT_THAT(
transport_params.destination(),
testing::VariantWith<HostPortPair>(kProxyServer1.host_port_pair()));
}
TEST_F(ConnectJobFactoryTest, CreateSocksProxyConnectJob) {
const url::SchemeHostPort kEndpoint(url::kHttpScheme, "test", 91);
const ProxyChain kProxy(ProxyServer::SCHEME_SOCKS5,
HostPortPair("proxy.test", 92));
std::unique_ptr<ConnectJob> job = factory_->CreateConnectJob(
kEndpoint, kProxy, TRAFFIC_ANNOTATION_FOR_TESTS, /*allowed_bad_certs=*/{},
ConnectJobFactory::AlpnMode::kHttpAll, /*force_tunnel=*/false,
PrivacyMode::PRIVACY_MODE_DISABLED, OnHostResolutionCallback(),
DEFAULT_PRIORITY, SocketTag(), NetworkAnonymizationKey(),
SecureDnsPolicy::kAllow, /*disable_cert_network_fetches=*/false,
&common_connect_job_params_, &delegate_);
EXPECT_EQ(GetCreationCount(), 1u);
ASSERT_THAT(socks_job_factory_->params(), testing::SizeIs(1));
const SOCKSSocketParams& params = *socks_job_factory_->params().front();
EXPECT_EQ(params.destination(), HostPortPair::FromSchemeHostPort(kEndpoint));
EXPECT_TRUE(params.is_socks_v5());
const TransportSocketParams& transport_params = *params.transport_params();
EXPECT_THAT(
transport_params.destination(),
testing::VariantWith<HostPortPair>(kProxy.First().host_port_pair()));
}
TEST_F(ConnectJobFactoryTest, CreateSocksProxyConnectJobWithoutScheme) {
const HostPortPair kEndpoint("test", 91);
const ProxyChain kProxy(ProxyServer::SCHEME_SOCKS5,
HostPortPair("proxy.test", 92));
std::unique_ptr<ConnectJob> job = factory_->CreateConnectJob(
/*using_ssl=*/false, kEndpoint, kProxy, TRAFFIC_ANNOTATION_FOR_TESTS,
/*force_tunnel=*/false, PrivacyMode::PRIVACY_MODE_DISABLED,
OnHostResolutionCallback(), DEFAULT_PRIORITY, SocketTag(),
NetworkAnonymizationKey(), SecureDnsPolicy::kAllow,
&common_connect_job_params_, &delegate_);
EXPECT_EQ(GetCreationCount(), 1u);
ASSERT_THAT(socks_job_factory_->params(), testing::SizeIs(1));
const SOCKSSocketParams& params = *socks_job_factory_->params().front();
EXPECT_EQ(params.destination(), kEndpoint);
EXPECT_TRUE(params.is_socks_v5());
const TransportSocketParams& transport_params = *params.transport_params();
EXPECT_THAT(
transport_params.destination(),
testing::VariantWith<HostPortPair>(kProxy.First().host_port_pair()));
}
TEST_F(ConnectJobFactoryTest, CreateWebsocketConnectJob) {
const url::SchemeHostPort kEndpoint(url::kHttpScheme, "test", 93);
WebSocketEndpointLockManager websocket_endpoint_lock_manager;
CommonConnectJobParams common_connect_job_params = common_connect_job_params_;
common_connect_job_params.websocket_endpoint_lock_manager =
&websocket_endpoint_lock_manager;
std::unique_ptr<ConnectJob> job = factory_->CreateConnectJob(
kEndpoint, ProxyChain::Direct(), /*proxy_annotation_tag=*/std::nullopt,
/*allowed_bad_certs=*/{}, ConnectJobFactory::AlpnMode::kHttpAll,
/*force_tunnel=*/false, PrivacyMode::PRIVACY_MODE_DISABLED,
OnHostResolutionCallback(), DEFAULT_PRIORITY, SocketTag(),
NetworkAnonymizationKey(), SecureDnsPolicy::kAllow,
/*disable_cert_network_fetches=*/false, &common_connect_job_params,
&delegate_);
EXPECT_EQ(GetCreationCount(), 1u);
ASSERT_THAT(transport_job_factory_->params(), testing::SizeIs(1));
const TransportSocketParams& params =
*transport_job_factory_->params().front();
EXPECT_THAT(params.destination(),
testing::VariantWith<url::SchemeHostPort>(kEndpoint));
}
TEST_F(ConnectJobFactoryTest, CreateWebsocketConnectJobWithoutScheme) {
const HostPortPair kEndpoint("test", 93);
WebSocketEndpointLockManager websocket_endpoint_lock_manager;
CommonConnectJobParams common_connect_job_params = common_connect_job_params_;
common_connect_job_params.websocket_endpoint_lock_manager =
&websocket_endpoint_lock_manager;
std::unique_ptr<ConnectJob> job = factory_->CreateConnectJob(
/*using_ssl=*/false, kEndpoint, ProxyChain::Direct(),
/*proxy_annotation_tag=*/std::nullopt, /*force_tunnel=*/false,
PrivacyMode::PRIVACY_MODE_DISABLED, OnHostResolutionCallback(),
DEFAULT_PRIORITY, SocketTag(), NetworkAnonymizationKey(),
SecureDnsPolicy::kAllow, &common_connect_job_params, &delegate_);
EXPECT_EQ(GetCreationCount(), 1u);
ASSERT_THAT(transport_job_factory_->params(), testing::SizeIs(1));
const TransportSocketParams& params =
*transport_job_factory_->params().front();
EXPECT_THAT(params.destination(),
testing::VariantWith<HostPortPair>(kEndpoint));
}
} // namespace
} // namespace net