xref: /aosp_15_r20/external/cronet/net/socket/connect_job_params_factory_unittest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1 // Copyright 2024 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 #include "net/socket/connect_job_params_factory.h"
6 
7 #include <ostream>
8 #include <tuple>
9 
10 #include "base/containers/flat_set.h"
11 #include "base/memory/scoped_refptr.h"
12 #include "net/base/host_port_pair.h"
13 #include "net/base/network_anonymization_key.h"
14 #include "net/base/privacy_mode.h"
15 #include "net/base/proxy_chain.h"
16 #include "net/base/proxy_server.h"
17 #include "net/base/schemeful_site.h"
18 #include "net/dns/public/secure_dns_policy.h"
19 #include "net/http/http_proxy_connect_job.h"
20 #include "net/socket/connect_job_factory.h"
21 #include "net/socket/next_proto.h"
22 #include "net/socket/socks_connect_job.h"
23 #include "net/socket/ssl_connect_job.h"
24 #include "net/socket/transport_connect_job.h"
25 #include "net/ssl/ssl_config.h"
26 #include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
27 #include "testing/gtest/include/gtest/gtest.h"
28 #include "third_party/abseil-cpp/absl/types/variant.h"
29 #include "url/gurl.h"
30 #include "url/scheme_host_port.h"
31 
32 namespace net {
33 
34 namespace {
35 
36 struct TestParams {
37   using ParamTuple = std::tuple<bool,
38                                 PrivacyMode,
39                                 SecureDnsPolicy,
40                                 ConnectJobFactory::AlpnMode,
41                                 bool>;
42 
TestParamsnet::__anon6e5dd3000111::TestParams43   explicit TestParams(ParamTuple tup)
44       : disable_cert_network_fetches(std::get<0>(tup)),
45         privacy_mode(std::get<1>(tup)),
46         secure_dns_policy(std::get<2>(tup)),
47         alpn_mode(std::get<3>(tup)),
48         enable_early_data(std::get<4>(tup)) {}
49 
50   bool disable_cert_network_fetches;
51   PrivacyMode privacy_mode;
52   SecureDnsPolicy secure_dns_policy;
53   ConnectJobFactory::AlpnMode alpn_mode;
54   bool enable_early_data;
55 };
56 
operator <<(std::ostream & os,const TestParams & test_params)57 std::ostream& operator<<(std::ostream& os, const TestParams& test_params) {
58   os << "TestParams {.disable_cert_network_fetches="
59      << test_params.disable_cert_network_fetches;
60   os << ", .privacy_mode=" << test_params.privacy_mode;
61   os << ", .secure_dns_policy="
62      << (test_params.secure_dns_policy == SecureDnsPolicy::kAllow ? "kAllow"
63                                                                   : "kDisable");
64   os << ", .alpn_mode="
65      << (test_params.alpn_mode == ConnectJobFactory::AlpnMode::kDisabled
66              ? "kDisabled"
67          : test_params.alpn_mode == ConnectJobFactory::AlpnMode::kHttp11Only
68              ? "kHttp11Only"
69              : "kHttpAll");
70   os << ", .enable_early_data=" << test_params.enable_early_data;
71   os << "}";
72   return os;
73 }
74 
75 // Get a string describing the params variant.
ParamsName(ConnectJobParams & params)76 const char* ParamsName(ConnectJobParams& params) {
77   if (params.is_http_proxy()) {
78     return "HttpProxySocketParams";
79   }
80   if (params.is_socks()) {
81     return "SOCKSSocketParams";
82   }
83   if (params.is_ssl()) {
84     return "SSLSocketParams";
85   }
86   if (params.is_transport()) {
87     return "TransportSocketParams";
88   }
89   return "Unknown";
90 }
91 
ExpectHttpProxySocketParams(ConnectJobParams params)92 scoped_refptr<HttpProxySocketParams> ExpectHttpProxySocketParams(
93     ConnectJobParams params) {
94   EXPECT_TRUE(params.is_http_proxy())
95       << "Expected HttpProxySocketParams, got " << ParamsName(params);
96   return params.take_http_proxy();
97 }
98 
VerifyHttpProxySocketParams(scoped_refptr<HttpProxySocketParams> params,const char * description,std::optional<SSLConfig> quic_ssl_config,const HostPortPair & endpoint,const ProxyChain & proxy_chain,size_t proxy_chain_index,bool tunnel,const NetworkAnonymizationKey & network_anonymization_key,const SecureDnsPolicy secure_dns_policy)99 void VerifyHttpProxySocketParams(
100     scoped_refptr<HttpProxySocketParams> params,
101     const char* description,
102     // Only QUIC proxies have a quic_ssl_config.
103     std::optional<SSLConfig> quic_ssl_config,
104     const HostPortPair& endpoint,
105     const ProxyChain& proxy_chain,
106     size_t proxy_chain_index,
107     bool tunnel,
108     const NetworkAnonymizationKey& network_anonymization_key,
109     const SecureDnsPolicy secure_dns_policy) {
110   SCOPED_TRACE(testing::Message() << "Verifying " << description);
111   if (quic_ssl_config) {
112     // Only examine the values used for QUIC connections.
113     ASSERT_TRUE(params->quic_ssl_config().has_value());
114     EXPECT_EQ(params->quic_ssl_config()->privacy_mode,
115               quic_ssl_config->privacy_mode);
116     EXPECT_EQ(params->quic_ssl_config()->GetCertVerifyFlags(),
117               quic_ssl_config->GetCertVerifyFlags());
118   } else {
119     EXPECT_FALSE(params->quic_ssl_config().has_value());
120   }
121   EXPECT_EQ(params->endpoint(), endpoint);
122   EXPECT_EQ(params->proxy_chain(), proxy_chain);
123   EXPECT_EQ(params->proxy_chain_index(), proxy_chain_index);
124   EXPECT_EQ(params->tunnel(), tunnel);
125   EXPECT_EQ(params->network_anonymization_key(), network_anonymization_key);
126   EXPECT_EQ(params->secure_dns_policy(), secure_dns_policy);
127 }
128 
ExpectSOCKSSocketParams(ConnectJobParams params)129 scoped_refptr<SOCKSSocketParams> ExpectSOCKSSocketParams(
130     ConnectJobParams params) {
131   EXPECT_TRUE(params.is_socks())
132       << "Expected SOCKSSocketParams, got " << ParamsName(params);
133   return params.take_socks();
134 }
135 
136 // Verify the properties of SOCKSSocketParams.
VerifySOCKSSocketParams(scoped_refptr<SOCKSSocketParams> & params,const char * description,bool is_socks_v5,const HostPortPair & destination,const NetworkAnonymizationKey & network_anonymization_key)137 void VerifySOCKSSocketParams(
138     scoped_refptr<SOCKSSocketParams>& params,
139     const char* description,
140     bool is_socks_v5,
141     const HostPortPair& destination,
142     const NetworkAnonymizationKey& network_anonymization_key) {
143   SCOPED_TRACE(testing::Message() << "Verifying " << description);
144   EXPECT_EQ(params->is_socks_v5(), is_socks_v5);
145   EXPECT_EQ(params->destination(), destination);
146   EXPECT_EQ(params->network_anonymization_key(), network_anonymization_key);
147 }
148 
149 // Assert that the params are TransportSocketParams and return them.
ExpectTransportSocketParams(ConnectJobParams params)150 scoped_refptr<TransportSocketParams> ExpectTransportSocketParams(
151     ConnectJobParams params) {
152   EXPECT_TRUE(params.is_transport())
153       << "Expected TransportSocketParams, got " << ParamsName(params);
154   return params.take_transport();
155 }
156 
157 // Verify the properties of TransportSocketParams.
VerifyTransportSocketParams(scoped_refptr<TransportSocketParams> & params,const char * description,const TransportSocketParams::Endpoint destination,const SecureDnsPolicy secure_dns_policy,const NetworkAnonymizationKey & network_anonymization_key,const base::flat_set<std::string> & supported_alpns)158 void VerifyTransportSocketParams(
159     scoped_refptr<TransportSocketParams>& params,
160     const char* description,
161     const TransportSocketParams::Endpoint destination,
162     const SecureDnsPolicy secure_dns_policy,
163     const NetworkAnonymizationKey& network_anonymization_key,
164     const base::flat_set<std::string>& supported_alpns) {
165   SCOPED_TRACE(testing::Message() << "Verifying " << description);
166   EXPECT_EQ(params->destination(), destination);
167   EXPECT_EQ(params->secure_dns_policy(), secure_dns_policy);
168   EXPECT_EQ(params->network_anonymization_key(), network_anonymization_key);
169   EXPECT_EQ(params->supported_alpns(), supported_alpns);
170 }
171 
172 // Assert that the params are SSLSocketParams and return them.
ExpectSSLSocketParams(ConnectJobParams params)173 scoped_refptr<SSLSocketParams> ExpectSSLSocketParams(ConnectJobParams params) {
174   EXPECT_TRUE(params.is_ssl())
175       << "Expected SSLSocketParams, got " << ParamsName(params);
176   return params.take_ssl();
177 }
178 
179 // Verify the properties of SSLSocketParams.
VerifySSLSocketParams(scoped_refptr<SSLSocketParams> & params,const char * description,const HostPortPair & host_and_port,const SSLConfig & ssl_config,PrivacyMode privacy_mode,const NetworkAnonymizationKey & network_anonymization_key)180 void VerifySSLSocketParams(
181     scoped_refptr<SSLSocketParams>& params,
182     const char* description,
183     const HostPortPair& host_and_port,
184     const SSLConfig& ssl_config,
185     PrivacyMode privacy_mode,
186     const NetworkAnonymizationKey& network_anonymization_key) {
187   SCOPED_TRACE(testing::Message() << "Verifying " << description);
188   EXPECT_EQ(params->host_and_port(), host_and_port);
189   // SSLConfig doesn't implement operator==, so just check the properties the
190   // factory uses.
191   EXPECT_EQ(params->ssl_config().disable_cert_verification_network_fetches,
192             ssl_config.disable_cert_verification_network_fetches);
193   EXPECT_EQ(params->ssl_config().alpn_protos, ssl_config.alpn_protos);
194   EXPECT_EQ(params->ssl_config().application_settings,
195             ssl_config.application_settings);
196   EXPECT_EQ(params->ssl_config().renego_allowed_default,
197             ssl_config.renego_allowed_default);
198   EXPECT_EQ(params->ssl_config().renego_allowed_for_protos,
199             ssl_config.renego_allowed_for_protos);
200   EXPECT_EQ(params->ssl_config().privacy_mode, privacy_mode);
201   EXPECT_EQ(params->network_anonymization_key(), network_anonymization_key);
202 }
203 
204 // Calculate the ALPN protocols for the given ALPN mode.
AlpnProtoStringsForMode(ConnectJobFactory::AlpnMode alpn_mode)205 base::flat_set<std::string> AlpnProtoStringsForMode(
206     ConnectJobFactory::AlpnMode alpn_mode) {
207   switch (alpn_mode) {
208     case ConnectJobFactory::AlpnMode::kDisabled:
209       return {};
210     case ConnectJobFactory::AlpnMode::kHttp11Only:
211       return {"http/1.1"};
212     case ConnectJobFactory::AlpnMode::kHttpAll:
213       return {"h2", "http/1.1"};
214   }
215 }
216 
217 class ConnectJobParamsFactoryTest : public testing::TestWithParam<TestParams> {
218  public:
ConnectJobParamsFactoryTest()219   ConnectJobParamsFactoryTest() {
220     early_data_enabled_ = enable_early_data();
221     switch (alpn_mode()) {
222       case ConnectJobFactory::AlpnMode::kDisabled:
223         alpn_protos_ = {};
224         application_settings_ = {};
225         break;
226       case ConnectJobFactory::AlpnMode::kHttp11Only:
227         alpn_protos_ = {kProtoHTTP11};
228         application_settings_ = {};
229         break;
230       case ConnectJobFactory::AlpnMode::kHttpAll:
231         alpn_protos_ = {kProtoHTTP2, kProtoHTTP11};
232         application_settings_ = {{kProtoHTTP2, {}}};
233         break;
234     }
235   }
236 
237  protected:
238   // Parameter accessors.
disable_cert_network_fetches() const239   bool disable_cert_network_fetches() const {
240     return GetParam().disable_cert_network_fetches;
241   }
privacy_mode() const242   PrivacyMode privacy_mode() const { return GetParam().privacy_mode; }
secure_dns_policy() const243   SecureDnsPolicy secure_dns_policy() const {
244     return GetParam().secure_dns_policy;
245   }
alpn_mode() const246   ConnectJobFactory::AlpnMode alpn_mode() const { return GetParam().alpn_mode; }
enable_early_data() const247   bool enable_early_data() const { return GetParam().enable_early_data; }
248 
249   // Create an SSL config for connection to the endpoint, based on the test
250   // parameters.
SSLConfigForEndpoint() const251   SSLConfig SSLConfigForEndpoint() const {
252     SSLConfig endpoint_ssl_config;
253     endpoint_ssl_config.disable_cert_verification_network_fetches =
254         disable_cert_network_fetches();
255     endpoint_ssl_config.early_data_enabled = enable_early_data();
256     switch (alpn_mode()) {
257       case ConnectJobFactory::AlpnMode::kDisabled:
258         endpoint_ssl_config.alpn_protos = {};
259         endpoint_ssl_config.application_settings = {};
260         endpoint_ssl_config.renego_allowed_default = false;
261         endpoint_ssl_config.renego_allowed_for_protos = {};
262         break;
263       case ConnectJobFactory::AlpnMode::kHttp11Only:
264         endpoint_ssl_config.alpn_protos = {kProtoHTTP11};
265         endpoint_ssl_config.application_settings = {};
266         endpoint_ssl_config.renego_allowed_default = true;
267         endpoint_ssl_config.renego_allowed_for_protos = {kProtoHTTP11};
268         break;
269       case ConnectJobFactory::AlpnMode::kHttpAll:
270         endpoint_ssl_config.alpn_protos = {kProtoHTTP2, kProtoHTTP11};
271         endpoint_ssl_config.application_settings = {{kProtoHTTP2, {}}};
272         endpoint_ssl_config.renego_allowed_default = true;
273         endpoint_ssl_config.renego_allowed_for_protos = {kProtoHTTP11};
274         break;
275     }
276     return endpoint_ssl_config;
277   }
278 
279   // Create an SSL config for connection to an HTTPS proxy, based on the test
280   // parameters.
SSLConfigForProxy() const281   SSLConfig SSLConfigForProxy() const {
282     SSLConfig proxy_ssl_config;
283     proxy_ssl_config.disable_cert_verification_network_fetches = true;
284     proxy_ssl_config.early_data_enabled = true;
285     proxy_ssl_config.renego_allowed_default = false;
286     proxy_ssl_config.renego_allowed_for_protos = {};
287     switch (alpn_mode()) {
288       case ConnectJobFactory::AlpnMode::kDisabled:
289         proxy_ssl_config.alpn_protos = {};
290         proxy_ssl_config.application_settings = {};
291         break;
292       case ConnectJobFactory::AlpnMode::kHttp11Only:
293         proxy_ssl_config.alpn_protos = {kProtoHTTP11};
294         proxy_ssl_config.application_settings = {};
295         break;
296       case ConnectJobFactory::AlpnMode::kHttpAll:
297         proxy_ssl_config.alpn_protos = {kProtoHTTP2, kProtoHTTP11};
298         proxy_ssl_config.application_settings = {{kProtoHTTP2, {}}};
299         break;
300     }
301     return proxy_ssl_config;
302   }
303 
304   NextProtoVector alpn_protos_;
305   SSLConfig::ApplicationSettings application_settings_;
306   bool early_data_enabled_;
307   const CommonConnectJobParams common_connect_job_params_{
308       /*client_socket_factory=*/nullptr,
309       /*host_resolver=*/nullptr,
310       /*http_auth_cache=*/nullptr,
311       /*http_auth_handler_factory=*/nullptr,
312       /*spdy_session_pool=*/nullptr,
313       /*quic_supported_versions=*/nullptr,
314       /*quic_session_pool=*/nullptr,
315       /*proxy_delegate=*/nullptr,
316       /*http_user_agent_settings=*/nullptr,
317       /*ssl_client_context=*/nullptr,
318       /*socket_performance_watcher_factory=*/nullptr,
319       /*network_quality_estimator=*/nullptr,
320       /*net_log=*/nullptr,
321       /*websocket_endpoint_lock_manager=*/nullptr,
322       /*http_server_properties=*/nullptr,
323       &alpn_protos_,
324       &application_settings_,
325       /*ignore_certificate_errors=*/nullptr,
326       &early_data_enabled_};
327 
328   const NetworkAnonymizationKey kTestNak =
329       NetworkAnonymizationKey::CreateSameSite(
330           net::SchemefulSite(GURL("http://example.test")));
331   const NetworkAnonymizationKey kProxyDnsNak =
332       NetworkAnonymizationKey::CreateSameSite(
333           net::SchemefulSite(GURL("http://example-dns.test")));
334 };
335 
336 // A connect to a simple HTTP endpoint produces just transport params.
TEST_P(ConnectJobParamsFactoryTest,HttpEndpoint)337 TEST_P(ConnectJobParamsFactoryTest, HttpEndpoint) {
338   const url::SchemeHostPort kEndpoint(url::kHttpScheme, "test", 82);
339   ConnectJobParams params = ConstructConnectJobParams(
340       kEndpoint, ProxyChain::Direct(),
341       /*proxy_annotation_tag=*/std::nullopt,
342       /*allowed_bad_certs=*/{}, alpn_mode(),
343       /*force_tunnel=*/false, privacy_mode(), OnHostResolutionCallback(),
344       kTestNak, secure_dns_policy(), disable_cert_network_fetches(),
345       &common_connect_job_params_, kProxyDnsNak);
346 
347   scoped_refptr<TransportSocketParams> transport_socket_params =
348       ExpectTransportSocketParams(params);
349   VerifyTransportSocketParams(
350       transport_socket_params, "transport_socket_params", kEndpoint,
351       secure_dns_policy(), kTestNak, base::flat_set<std::string>());
352 }
353 
354 // A connect to a endpoint without SSL, specified as a `SchemelessEndpoint`,
355 // produces just transport params.
TEST_P(ConnectJobParamsFactoryTest,UnencryptedEndpointWithoutScheme)356 TEST_P(ConnectJobParamsFactoryTest, UnencryptedEndpointWithoutScheme) {
357   const ConnectJobFactory::SchemelessEndpoint kEndpoint{
358       /*using_ssl=*/false, HostPortPair("test", 82)};
359   ConnectJobParams params = ConstructConnectJobParams(
360       kEndpoint, ProxyChain::Direct(),
361       /*proxy_annotation_tag=*/std::nullopt,
362       /*allowed_bad_certs=*/{}, alpn_mode(),
363       /*force_tunnel=*/false, privacy_mode(), OnHostResolutionCallback(),
364       kTestNak, secure_dns_policy(), disable_cert_network_fetches(),
365       &common_connect_job_params_, kProxyDnsNak);
366 
367   scoped_refptr<TransportSocketParams> transport_socket_params =
368       ExpectTransportSocketParams(params);
369   VerifyTransportSocketParams(transport_socket_params,
370                               "transport_socket_params",
371                               HostPortPair("test", 82), secure_dns_policy(),
372                               kTestNak, base::flat_set<std::string>());
373 }
374 
375 // A connect to a simple HTTPS endpoint produces SSL params wrapping transport
376 // params.
TEST_P(ConnectJobParamsFactoryTest,HttpsEndpoint)377 TEST_P(ConnectJobParamsFactoryTest, HttpsEndpoint) {
378   // HTTPS endpoints are not supported without ALPN.
379   if (alpn_mode() == ConnectJobFactory::AlpnMode::kDisabled) {
380     return;
381   }
382 
383   const url::SchemeHostPort kEndpoint(url::kHttpsScheme, "test", 82);
384   ConnectJobParams params = ConstructConnectJobParams(
385       kEndpoint, ProxyChain::Direct(), TRAFFIC_ANNOTATION_FOR_TESTS,
386       /*allowed_bad_certs=*/{}, alpn_mode(),
387       /*force_tunnel=*/false, privacy_mode(), OnHostResolutionCallback(),
388       kTestNak, secure_dns_policy(), disable_cert_network_fetches(),
389       &common_connect_job_params_, kProxyDnsNak);
390 
391   scoped_refptr<SSLSocketParams> ssl_socket_params =
392       ExpectSSLSocketParams(params);
393   SSLConfig ssl_config = SSLConfigForEndpoint();
394   VerifySSLSocketParams(ssl_socket_params, "ssl_socket_params",
395                         HostPortPair::FromSchemeHostPort(kEndpoint), ssl_config,
396                         privacy_mode(), kTestNak);
397   scoped_refptr<TransportSocketParams> transport_socket_params =
398       ssl_socket_params->GetDirectConnectionParams();
399   VerifyTransportSocketParams(
400       transport_socket_params, "transport_socket_params", kEndpoint,
401       secure_dns_policy(), kTestNak, AlpnProtoStringsForMode(alpn_mode()));
402 }
403 
404 // A connect to a endpoint SSL, specified as a `SchemelessEndpoint`,
405 // produces just transport params.
TEST_P(ConnectJobParamsFactoryTest,EncryptedEndpointWithoutScheme)406 TEST_P(ConnectJobParamsFactoryTest, EncryptedEndpointWithoutScheme) {
407   // Encrypted endpoints without scheme are only supported without ALPN.
408   if (alpn_mode() != ConnectJobFactory::AlpnMode::kDisabled) {
409     return;
410   }
411 
412   const ConnectJobFactory::SchemelessEndpoint kEndpoint{
413       /*using_ssl=*/true, HostPortPair("test", 4433)};
414   ConnectJobParams params = ConstructConnectJobParams(
415       kEndpoint, ProxyChain::Direct(), TRAFFIC_ANNOTATION_FOR_TESTS,
416       /*allowed_bad_certs=*/{}, alpn_mode(),
417       /*force_tunnel=*/false, privacy_mode(), OnHostResolutionCallback(),
418       kTestNak, secure_dns_policy(), disable_cert_network_fetches(),
419       &common_connect_job_params_, kProxyDnsNak);
420 
421   scoped_refptr<SSLSocketParams> ssl_socket_params =
422       ExpectSSLSocketParams(params);
423   SSLConfig ssl_config = SSLConfigForEndpoint();
424   VerifySSLSocketParams(ssl_socket_params, "ssl_socket_params",
425                         HostPortPair("test", 4433), ssl_config, privacy_mode(),
426                         kTestNak);
427   scoped_refptr<TransportSocketParams> transport_socket_params =
428       ssl_socket_params->GetDirectConnectionParams();
429   VerifyTransportSocketParams(transport_socket_params,
430                               "transport_socket_params",
431                               HostPortPair("test", 4433), secure_dns_policy(),
432                               kTestNak, AlpnProtoStringsForMode(alpn_mode()));
433 }
434 
435 // A connection to an HTTP endpoint via an HTTPS proxy, without forcing a
436 // tunnel, sets up an HttpProxySocketParams, wrapping SSLSocketParams wrapping
437 // TransportSocketParams, intending to use GET to the proxy. This is not
438 // tunneled.
TEST_P(ConnectJobParamsFactoryTest,HttpEndpointViaHttpsProxy)439 TEST_P(ConnectJobParamsFactoryTest, HttpEndpointViaHttpsProxy) {
440   const url::SchemeHostPort kEndpoint(url::kHttpScheme, "test", 82);
441   ProxyChain proxy_chain = ProxyChain::FromSchemeHostAndPort(
442       ProxyServer::SCHEME_HTTPS, "proxy", 443);
443   ConnectJobParams params = ConstructConnectJobParams(
444       kEndpoint, proxy_chain, TRAFFIC_ANNOTATION_FOR_TESTS,
445       /*allowed_bad_certs=*/{}, alpn_mode(),
446       /*force_tunnel=*/false, privacy_mode(), OnHostResolutionCallback(),
447       kTestNak, secure_dns_policy(), disable_cert_network_fetches(),
448       &common_connect_job_params_, kProxyDnsNak);
449 
450   scoped_refptr<HttpProxySocketParams> http_proxy_socket_params =
451       ExpectHttpProxySocketParams(params);
452   VerifyHttpProxySocketParams(
453       http_proxy_socket_params, "http_proxy_socket_params",
454       /*quic_ssl_config=*/std::nullopt,
455       HostPortPair::FromSchemeHostPort(kEndpoint), proxy_chain,
456       /*proxy_chain_index=*/0,
457       /*tunnel=*/false, kTestNak, secure_dns_policy());
458 
459   scoped_refptr<SSLSocketParams> ssl_socket_params =
460       http_proxy_socket_params->ssl_params();
461   ASSERT_TRUE(ssl_socket_params);
462   SSLConfig ssl_config = SSLConfigForProxy();
463   VerifySSLSocketParams(ssl_socket_params, "ssl_socket_params",
464                         HostPortPair::FromString("proxy:443"), ssl_config,
465                         PrivacyMode::PRIVACY_MODE_DISABLED, kTestNak);
466 
467   scoped_refptr<TransportSocketParams> transport_socket_params =
468       ssl_socket_params->GetDirectConnectionParams();
469   VerifyTransportSocketParams(
470       transport_socket_params, "transport_socket_params",
471       HostPortPair("proxy", 443), secure_dns_policy(), kProxyDnsNak,
472       AlpnProtoStringsForMode(alpn_mode()));
473 }
474 
475 // A connection to an HTTP endpoint via an QUIC proxy sets up an
476 // HttpProxySocketParams, wrapping almost-unused SSLSocketParams, intending to
477 // use GET to the proxy. This is not tunneled.
TEST_P(ConnectJobParamsFactoryTest,HttpEndpointViaQuicProxy)478 TEST_P(ConnectJobParamsFactoryTest, HttpEndpointViaQuicProxy) {
479   const url::SchemeHostPort kEndpoint(url::kHttpScheme, "test", 82);
480   ProxyChain proxy_chain = ProxyChain::ForIpProtection({
481       ProxyServer::FromSchemeHostAndPort(ProxyServer::SCHEME_QUIC, "proxy",
482                                          443),
483   });
484   ConnectJobParams params = ConstructConnectJobParams(
485       kEndpoint, proxy_chain, TRAFFIC_ANNOTATION_FOR_TESTS,
486       /*allowed_bad_certs=*/{}, alpn_mode(),
487       /*force_tunnel=*/false, privacy_mode(), OnHostResolutionCallback(),
488       kTestNak, secure_dns_policy(), disable_cert_network_fetches(),
489       &common_connect_job_params_, kProxyDnsNak);
490 
491   auto http_proxy_socket_params = ExpectHttpProxySocketParams(params);
492   SSLConfig quic_ssl_config = SSLConfigForProxy();
493   // Traffic always tunnels over QUIC proxies.
494   const bool tunnel = true;
495   VerifyHttpProxySocketParams(
496       http_proxy_socket_params, "http_proxy_socket_params", quic_ssl_config,
497       HostPortPair::FromSchemeHostPort(kEndpoint), proxy_chain,
498       /*proxy_chain_index=*/0, tunnel, kTestNak, secure_dns_policy());
499 }
500 
501 // A connection to an HTTPS endpoint via an HTTPS proxy,
502 // sets up an SSLSocketParams, wrapping HttpProxySocketParams, wrapping
503 // SSLSocketParams, wrapping TransportSocketParams. This is always tunneled.
TEST_P(ConnectJobParamsFactoryTest,HttpsEndpointViaHttpsProxy)504 TEST_P(ConnectJobParamsFactoryTest, HttpsEndpointViaHttpsProxy) {
505   // HTTPS endpoints are not supported without ALPN.
506   if (alpn_mode() == ConnectJobFactory::AlpnMode::kDisabled) {
507     return;
508   }
509 
510   const url::SchemeHostPort kEndpoint(url::kHttpsScheme, "test", 82);
511   ProxyChain proxy_chain = ProxyChain::FromSchemeHostAndPort(
512       ProxyServer::SCHEME_HTTPS, "proxy", 443);
513   ConnectJobParams params = ConstructConnectJobParams(
514       kEndpoint, proxy_chain, TRAFFIC_ANNOTATION_FOR_TESTS,
515       /*allowed_bad_certs=*/{}, alpn_mode(),
516       /*force_tunnel=*/false, privacy_mode(), OnHostResolutionCallback(),
517       kTestNak, secure_dns_policy(), disable_cert_network_fetches(),
518       &common_connect_job_params_, kProxyDnsNak);
519 
520   scoped_refptr<SSLSocketParams> endpoint_ssl_socket_params =
521       ExpectSSLSocketParams(params);
522   SSLConfig endpoint_ssl_config = SSLConfigForEndpoint();
523   VerifySSLSocketParams(endpoint_ssl_socket_params,
524                         "endpoint_ssl_socket_params",
525                         HostPortPair::FromSchemeHostPort(kEndpoint),
526                         endpoint_ssl_config, privacy_mode(), kTestNak);
527 
528   scoped_refptr<HttpProxySocketParams> http_proxy_socket_params =
529       endpoint_ssl_socket_params->GetHttpProxyConnectionParams();
530   VerifyHttpProxySocketParams(
531       http_proxy_socket_params, "http_proxy_socket_params",
532       /*quic_ssl_config=*/std::nullopt,
533       HostPortPair::FromSchemeHostPort(kEndpoint), proxy_chain,
534       /*proxy_chain_index=*/0,
535       /*tunnel=*/true, kTestNak, secure_dns_policy());
536 
537   scoped_refptr<SSLSocketParams> proxy_ssl_socket_params =
538       http_proxy_socket_params->ssl_params();
539   ASSERT_TRUE(proxy_ssl_socket_params);
540   SSLConfig proxy_ssl_config = SSLConfigForProxy();
541   VerifySSLSocketParams(proxy_ssl_socket_params, "proxy_ssl_socket_params",
542                         HostPortPair::FromString("proxy:443"), proxy_ssl_config,
543                         PrivacyMode::PRIVACY_MODE_DISABLED, kTestNak);
544 
545   scoped_refptr<TransportSocketParams> transport_socket_params =
546       proxy_ssl_socket_params->GetDirectConnectionParams();
547   VerifyTransportSocketParams(
548       transport_socket_params, "transport_socket_params",
549       HostPortPair("proxy", 443), secure_dns_policy(), kProxyDnsNak,
550       AlpnProtoStringsForMode(alpn_mode()));
551 }
552 
553 // A connection to an HTTPS endpoint via a QUIC proxy,
554 // sets up an SSLSocketParams, wrapping HttpProxySocketParams, wrapping
555 // SSLSocketParams. This is always tunneled.
TEST_P(ConnectJobParamsFactoryTest,HttpsEndpointViaQuicProxy)556 TEST_P(ConnectJobParamsFactoryTest, HttpsEndpointViaQuicProxy) {
557   // HTTPS endpoints are not supported without ALPN.
558   if (alpn_mode() == ConnectJobFactory::AlpnMode::kDisabled) {
559     return;
560   }
561 
562   const url::SchemeHostPort kEndpoint(url::kHttpsScheme, "test", 82);
563   ProxyChain proxy_chain = ProxyChain::ForIpProtection({
564       ProxyServer::FromSchemeHostAndPort(ProxyServer::SCHEME_QUIC, "proxy",
565                                          443),
566   });
567   ConnectJobParams params = ConstructConnectJobParams(
568       kEndpoint, proxy_chain, TRAFFIC_ANNOTATION_FOR_TESTS,
569       /*allowed_bad_certs=*/{}, alpn_mode(),
570       /*force_tunnel=*/false, privacy_mode(), OnHostResolutionCallback(),
571       kTestNak, secure_dns_policy(), disable_cert_network_fetches(),
572       &common_connect_job_params_, kProxyDnsNak);
573 
574   auto endpoint_ssl_socket_params = ExpectSSLSocketParams(params);
575   SSLConfig endpoint_ssl_config = SSLConfigForEndpoint();
576   VerifySSLSocketParams(endpoint_ssl_socket_params,
577                         "endpoint_ssl_socket_params",
578                         HostPortPair::FromSchemeHostPort(kEndpoint),
579                         endpoint_ssl_config, privacy_mode(), kTestNak);
580 
581   auto http_proxy_socket_params =
582       endpoint_ssl_socket_params->GetHttpProxyConnectionParams();
583   SSLConfig quic_ssl_config = SSLConfigForProxy();
584   VerifyHttpProxySocketParams(
585       http_proxy_socket_params, "http_proxy_socket_params", quic_ssl_config,
586       HostPortPair::FromSchemeHostPort(kEndpoint), proxy_chain,
587       /*proxy_chain_index=*/0,
588       /*tunnel=*/true, kTestNak, secure_dns_policy());
589 }
590 
591 // A connection to an HTTPS endpoint via an HTTP proxy
592 // sets up an SSLSocketParams, wrapping HttpProxySocketParams, wrapping
593 // TransportSocketParams. This is always tunneled.
TEST_P(ConnectJobParamsFactoryTest,HttpsEndpointViaHttpProxy)594 TEST_P(ConnectJobParamsFactoryTest, HttpsEndpointViaHttpProxy) {
595   if (alpn_mode() == ConnectJobFactory::AlpnMode::kDisabled) {
596     return;
597   }
598 
599   const url::SchemeHostPort kEndpoint(url::kHttpsScheme, "test", 82);
600   ProxyChain proxy_chain =
601       ProxyChain::FromSchemeHostAndPort(ProxyServer::SCHEME_HTTP, "proxy", 80);
602   ConnectJobParams params = ConstructConnectJobParams(
603       kEndpoint, proxy_chain, TRAFFIC_ANNOTATION_FOR_TESTS,
604       /*allowed_bad_certs=*/{}, alpn_mode(),
605       /*force_tunnel=*/false, privacy_mode(), OnHostResolutionCallback(),
606       kTestNak, secure_dns_policy(), disable_cert_network_fetches(),
607       &common_connect_job_params_, kProxyDnsNak);
608 
609   scoped_refptr<SSLSocketParams> endpoint_ssl_socket_params =
610       ExpectSSLSocketParams(params);
611   SSLConfig endpoint_ssl_config = SSLConfigForEndpoint();
612   VerifySSLSocketParams(endpoint_ssl_socket_params,
613                         "endpoint_ssl_socket_params",
614                         HostPortPair::FromSchemeHostPort(kEndpoint),
615                         endpoint_ssl_config, privacy_mode(), kTestNak);
616 
617   scoped_refptr<HttpProxySocketParams> http_proxy_socket_params =
618       endpoint_ssl_socket_params->GetHttpProxyConnectionParams();
619   VerifyHttpProxySocketParams(
620       http_proxy_socket_params, "http_proxy_socket_params",
621       /*quic_ssl_config=*/std::nullopt,
622       HostPortPair::FromSchemeHostPort(kEndpoint), proxy_chain,
623       /*proxy_chain_index=*/0,
624       /*tunnel=*/true, kTestNak, secure_dns_policy());
625 
626   scoped_refptr<TransportSocketParams> transport_socket_params =
627       http_proxy_socket_params->transport_params();
628   ASSERT_TRUE(transport_socket_params);
629   VerifyTransportSocketParams(transport_socket_params,
630                               "transport_socket_params",
631                               HostPortPair("proxy", 80), secure_dns_policy(),
632                               kProxyDnsNak, base::flat_set<std::string>({}));
633 }
634 
635 // A connection to an HTTP endpoint via a SOCKS proxy,
636 // sets up an SOCKSSocketParams wrapping TransportSocketParams.
TEST_P(ConnectJobParamsFactoryTest,HttpEndpointViaSOCKSProxy)637 TEST_P(ConnectJobParamsFactoryTest, HttpEndpointViaSOCKSProxy) {
638   const url::SchemeHostPort kEndpoint(url::kHttpScheme, "test", 82);
639   ProxyChain proxy_chain = ProxyChain::FromSchemeHostAndPort(
640       ProxyServer::SCHEME_SOCKS4, "proxy", 999);
641   ConnectJobParams params = ConstructConnectJobParams(
642       kEndpoint, proxy_chain, TRAFFIC_ANNOTATION_FOR_TESTS,
643       /*allowed_bad_certs=*/{}, alpn_mode(),
644       /*force_tunnel=*/false, privacy_mode(), OnHostResolutionCallback(),
645       kTestNak, secure_dns_policy(), disable_cert_network_fetches(),
646       &common_connect_job_params_, kProxyDnsNak);
647 
648   scoped_refptr<SOCKSSocketParams> socks_socket_params =
649       ExpectSOCKSSocketParams(params);
650   VerifySOCKSSocketParams(socks_socket_params, "socks_socket_params",
651                           /*is_socks_v5=*/false,
652                           HostPortPair::FromSchemeHostPort(kEndpoint),
653                           kTestNak);
654 
655   scoped_refptr<TransportSocketParams> transport_socket_params =
656       socks_socket_params->transport_params();
657   VerifyTransportSocketParams(
658       transport_socket_params, "transport_socket_params",
659       HostPortPair("proxy", 999), secure_dns_policy(), kProxyDnsNak, {});
660 }
661 
662 // A connection to an HTTPS endpoint via a SOCKS proxy,
663 // sets up an SSLSocketParams wrapping SOCKSSocketParams wrapping
664 // TransportSocketParams.
TEST_P(ConnectJobParamsFactoryTest,HttpsEndpointViaSOCKSProxy)665 TEST_P(ConnectJobParamsFactoryTest, HttpsEndpointViaSOCKSProxy) {
666   // HTTPS endpoints are not supported without ALPN.
667   if (alpn_mode() == ConnectJobFactory::AlpnMode::kDisabled) {
668     return;
669   }
670 
671   const url::SchemeHostPort kEndpoint(url::kHttpsScheme, "test", 82);
672   ProxyChain proxy_chain = ProxyChain::FromSchemeHostAndPort(
673       ProxyServer::SCHEME_SOCKS5, "proxy", 999);
674   ConnectJobParams params = ConstructConnectJobParams(
675       kEndpoint, proxy_chain, TRAFFIC_ANNOTATION_FOR_TESTS,
676       /*allowed_bad_certs=*/{}, alpn_mode(),
677       /*force_tunnel=*/false, privacy_mode(), OnHostResolutionCallback(),
678       kTestNak, secure_dns_policy(), disable_cert_network_fetches(),
679       &common_connect_job_params_, kProxyDnsNak);
680 
681   scoped_refptr<SSLSocketParams> endpoint_ssl_socket_params =
682       ExpectSSLSocketParams(params);
683   SSLConfig endpoint_ssl_config = SSLConfigForEndpoint();
684   VerifySSLSocketParams(endpoint_ssl_socket_params,
685                         "endpoint_ssl_socket_params",
686                         HostPortPair::FromSchemeHostPort(kEndpoint),
687                         endpoint_ssl_config, privacy_mode(), kTestNak);
688 
689   scoped_refptr<SOCKSSocketParams> socks_socket_params =
690       endpoint_ssl_socket_params->GetSocksProxyConnectionParams();
691   VerifySOCKSSocketParams(socks_socket_params, "socks_socket_params",
692                           /*is_socks_v5=*/true,
693                           HostPortPair::FromSchemeHostPort(kEndpoint),
694                           kTestNak);
695 
696   scoped_refptr<TransportSocketParams> transport_socket_params =
697       socks_socket_params->transport_params();
698   VerifyTransportSocketParams(
699       transport_socket_params, "transport_socket_params",
700       HostPortPair("proxy", 999), secure_dns_policy(), kProxyDnsNak, {});
701 }
702 
703 // A connection to an HTTP endpoint via a two-proxy HTTPS chain
704 // sets up the required parameters.
TEST_P(ConnectJobParamsFactoryTest,HttpEndpointViaHttpsProxyViaHttpsProxy)705 TEST_P(ConnectJobParamsFactoryTest, HttpEndpointViaHttpsProxyViaHttpsProxy) {
706   const url::SchemeHostPort kEndpoint(url::kHttpScheme, "test", 82);
707   ProxyChain proxy_chain = ProxyChain::ForIpProtection({
708       ProxyServer::FromSchemeHostAndPort(ProxyServer::SCHEME_HTTPS, "proxya",
709                                          443),
710       ProxyServer::FromSchemeHostAndPort(ProxyServer::SCHEME_HTTPS, "proxyb",
711                                          443),
712   });
713   ConnectJobParams params = ConstructConnectJobParams(
714       kEndpoint, proxy_chain, TRAFFIC_ANNOTATION_FOR_TESTS,
715       /*allowed_bad_certs=*/{}, alpn_mode(),
716       /*force_tunnel=*/false, privacy_mode(), OnHostResolutionCallback(),
717       kTestNak, secure_dns_policy(), disable_cert_network_fetches(),
718       &common_connect_job_params_, kProxyDnsNak);
719 
720   scoped_refptr<HttpProxySocketParams> http_proxy_socket_params_b =
721       ExpectHttpProxySocketParams(params);
722   VerifyHttpProxySocketParams(
723       http_proxy_socket_params_b, "http_proxy_socket_params_b",
724       /*quic_ssl_config=*/std::nullopt,
725       HostPortPair::FromSchemeHostPort(kEndpoint), proxy_chain,
726       /*proxy_chain_index=*/1,
727       /*tunnel=*/true, kTestNak, secure_dns_policy());
728 
729   scoped_refptr<SSLSocketParams> proxy_ssl_socket_params_b =
730       http_proxy_socket_params_b->ssl_params();
731   ASSERT_TRUE(proxy_ssl_socket_params_b);
732   SSLConfig proxy_ssl_config = SSLConfigForProxy();
733   VerifySSLSocketParams(proxy_ssl_socket_params_b, "proxy_ssl_socket_params_b",
734                         HostPortPair::FromString("proxyb:443"),
735                         proxy_ssl_config, PrivacyMode::PRIVACY_MODE_DISABLED,
736                         kTestNak);
737 
738   scoped_refptr<HttpProxySocketParams> http_proxy_socket_params_a =
739       proxy_ssl_socket_params_b->GetHttpProxyConnectionParams();
740   VerifyHttpProxySocketParams(http_proxy_socket_params_a,
741                               "http_proxy_socket_params_a",
742                               /*quic_ssl_config=*/std::nullopt,
743                               HostPortPair("proxyb", 443), proxy_chain,
744                               /*proxy_chain_index=*/0,
745                               /*tunnel=*/true, kTestNak, secure_dns_policy());
746 
747   scoped_refptr<SSLSocketParams> proxy_ssl_socket_params_a =
748       http_proxy_socket_params_a->ssl_params();
749   ASSERT_TRUE(proxy_ssl_socket_params_a);
750   VerifySSLSocketParams(proxy_ssl_socket_params_a, "proxy_ssl_socket_params_a",
751                         HostPortPair::FromString("proxya:443"),
752                         proxy_ssl_config, PrivacyMode::PRIVACY_MODE_DISABLED,
753                         kTestNak);
754 
755   scoped_refptr<TransportSocketParams> transport_socket_params =
756       proxy_ssl_socket_params_a->GetDirectConnectionParams();
757   VerifyTransportSocketParams(
758       transport_socket_params, "transport_socket_params",
759       HostPortPair("proxya", 443), secure_dns_policy(), kProxyDnsNak,
760       AlpnProtoStringsForMode(alpn_mode()));
761 }
762 
763 // A connection to an HTTPS endpoint via a two-proxy HTTPS chain
764 // sets up the required parameters.
TEST_P(ConnectJobParamsFactoryTest,HttpsEndpointViaHttpsProxyViaHttpsProxy)765 TEST_P(ConnectJobParamsFactoryTest, HttpsEndpointViaHttpsProxyViaHttpsProxy) {
766   // HTTPS endpoints are not supported without ALPN.
767   if (alpn_mode() == ConnectJobFactory::AlpnMode::kDisabled) {
768     return;
769   }
770 
771   const url::SchemeHostPort kEndpoint(url::kHttpsScheme, "test", 82);
772   ProxyChain proxy_chain = ProxyChain::ForIpProtection({
773       ProxyServer::FromSchemeHostAndPort(ProxyServer::SCHEME_HTTPS, "proxya",
774                                          443),
775       ProxyServer::FromSchemeHostAndPort(ProxyServer::SCHEME_HTTPS, "proxyb",
776                                          443),
777   });
778   ConnectJobParams params = ConstructConnectJobParams(
779       kEndpoint, proxy_chain, TRAFFIC_ANNOTATION_FOR_TESTS,
780       /*allowed_bad_certs=*/{}, alpn_mode(),
781       /*force_tunnel=*/false, privacy_mode(), OnHostResolutionCallback(),
782       kTestNak, secure_dns_policy(), disable_cert_network_fetches(),
783       &common_connect_job_params_, kProxyDnsNak);
784 
785   scoped_refptr<SSLSocketParams> endpoint_ssl_socket_params =
786       ExpectSSLSocketParams(params);
787   SSLConfig endpoint_ssl_config = SSLConfigForEndpoint();
788   VerifySSLSocketParams(endpoint_ssl_socket_params,
789                         "endpoint_ssl_socket_params",
790                         HostPortPair::FromSchemeHostPort(kEndpoint),
791                         endpoint_ssl_config, privacy_mode(), kTestNak);
792 
793   scoped_refptr<HttpProxySocketParams> http_proxy_socket_params_b =
794       endpoint_ssl_socket_params->GetHttpProxyConnectionParams();
795   VerifyHttpProxySocketParams(
796       http_proxy_socket_params_b, "http_proxy_socket_params_b",
797       /*quic_ssl_config=*/std::nullopt,
798       HostPortPair::FromSchemeHostPort(kEndpoint), proxy_chain,
799       /*proxy_chain_index=*/1,
800       /*tunnel=*/true, kTestNak, secure_dns_policy());
801 
802   scoped_refptr<SSLSocketParams> proxy_ssl_socket_params_b =
803       http_proxy_socket_params_b->ssl_params();
804   ASSERT_TRUE(proxy_ssl_socket_params_b);
805   SSLConfig proxy_ssl_config = SSLConfigForProxy();
806   VerifySSLSocketParams(proxy_ssl_socket_params_b, "proxy_ssl_socket_params_b",
807                         HostPortPair::FromString("proxyb:443"),
808                         proxy_ssl_config, PrivacyMode::PRIVACY_MODE_DISABLED,
809                         kTestNak);
810 
811   scoped_refptr<HttpProxySocketParams> http_proxy_socket_params_a =
812       proxy_ssl_socket_params_b->GetHttpProxyConnectionParams();
813   VerifyHttpProxySocketParams(http_proxy_socket_params_a,
814                               "http_proxy_socket_params_a",
815                               /*quic_ssl_config=*/std::nullopt,
816                               HostPortPair("proxyb", 443), proxy_chain,
817                               /*proxy_chain_index=*/0,
818                               /*tunnel=*/true, kTestNak, secure_dns_policy());
819 
820   scoped_refptr<SSLSocketParams> proxy_ssl_socket_params_a =
821       http_proxy_socket_params_a->ssl_params();
822   ASSERT_TRUE(proxy_ssl_socket_params_a);
823   VerifySSLSocketParams(proxy_ssl_socket_params_a, "proxy_ssl_socket_params_a",
824                         HostPortPair::FromString("proxya:443"),
825                         proxy_ssl_config, PrivacyMode::PRIVACY_MODE_DISABLED,
826                         kTestNak);
827 
828   scoped_refptr<TransportSocketParams> transport_socket_params =
829       proxy_ssl_socket_params_a->GetDirectConnectionParams();
830   VerifyTransportSocketParams(
831       transport_socket_params, "transport_socket_params",
832       HostPortPair("proxya", 443), secure_dns_policy(), kProxyDnsNak,
833       AlpnProtoStringsForMode(alpn_mode()));
834 }
835 
836 // A connection to an HTTPS endpoint via a two-proxy QUIC chain
837 // sets up the required parameters.
TEST_P(ConnectJobParamsFactoryTest,HttpsEndpointViaQuicProxyViaQuicProxy)838 TEST_P(ConnectJobParamsFactoryTest, HttpsEndpointViaQuicProxyViaQuicProxy) {
839   // HTTPS endpoints are not supported without ALPN.
840   if (alpn_mode() == ConnectJobFactory::AlpnMode::kDisabled) {
841     return;
842   }
843 
844   const url::SchemeHostPort kEndpoint(url::kHttpsScheme, "test", 82);
845   ProxyChain proxy_chain = ProxyChain::ForIpProtection({
846       ProxyServer::FromSchemeHostAndPort(ProxyServer::SCHEME_QUIC, "proxya",
847                                          443),
848       ProxyServer::FromSchemeHostAndPort(ProxyServer::SCHEME_QUIC, "proxyb",
849                                          443),
850   });
851   ConnectJobParams params = ConstructConnectJobParams(
852       kEndpoint, proxy_chain, TRAFFIC_ANNOTATION_FOR_TESTS,
853       /*allowed_bad_certs=*/{}, alpn_mode(),
854       /*force_tunnel=*/false, privacy_mode(), OnHostResolutionCallback(),
855       kTestNak, secure_dns_policy(), disable_cert_network_fetches(),
856       &common_connect_job_params_, kProxyDnsNak);
857 
858   auto endpoint_ssl_socket_params = ExpectSSLSocketParams(params);
859   SSLConfig endpoint_ssl_config = SSLConfigForEndpoint();
860   VerifySSLSocketParams(endpoint_ssl_socket_params,
861                         "endpoint_ssl_socket_params",
862                         HostPortPair::FromSchemeHostPort(kEndpoint),
863                         endpoint_ssl_config, privacy_mode(), kTestNak);
864 
865   auto http_proxy_socket_params_b =
866       endpoint_ssl_socket_params->GetHttpProxyConnectionParams();
867   SSLConfig quic_ssl_config_b = SSLConfigForProxy();
868   VerifyHttpProxySocketParams(http_proxy_socket_params_b,
869                               "http_proxy_socket_params_b", quic_ssl_config_b,
870                               HostPortPair::FromSchemeHostPort(kEndpoint),
871                               proxy_chain,
872                               /*proxy_chain_index=*/1,
873                               /*tunnel=*/true, kTestNak, secure_dns_policy());
874 }
875 
876 // A connection to an HTTPS endpoint via a proxy chain with two HTTPS proxies
877 // and two QUIC proxies.
TEST_P(ConnectJobParamsFactoryTest,HttpsEndpointViaMixedProxyChain)878 TEST_P(ConnectJobParamsFactoryTest, HttpsEndpointViaMixedProxyChain) {
879   // HTTPS endpoints are not supported without ALPN.
880   if (alpn_mode() == ConnectJobFactory::AlpnMode::kDisabled) {
881     return;
882   }
883 
884   const url::SchemeHostPort kEndpoint(url::kHttpsScheme, "test", 82);
885   ProxyChain proxy_chain = ProxyChain::ForIpProtection({
886       ProxyServer::FromSchemeHostAndPort(ProxyServer::SCHEME_QUIC, "proxya",
887                                          443),
888       ProxyServer::FromSchemeHostAndPort(ProxyServer::SCHEME_QUIC, "proxyb",
889                                          443),
890       ProxyServer::FromSchemeHostAndPort(ProxyServer::SCHEME_HTTPS, "proxyc",
891                                          443),
892       ProxyServer::FromSchemeHostAndPort(ProxyServer::SCHEME_HTTPS, "proxyd",
893                                          443),
894   });
895   ConnectJobParams params = ConstructConnectJobParams(
896       kEndpoint, proxy_chain, TRAFFIC_ANNOTATION_FOR_TESTS,
897       /*allowed_bad_certs=*/{}, alpn_mode(),
898       /*force_tunnel=*/false, privacy_mode(), OnHostResolutionCallback(),
899       kTestNak, secure_dns_policy(), disable_cert_network_fetches(),
900       &common_connect_job_params_, kProxyDnsNak);
901 
902   auto endpoint_ssl_socket_params = ExpectSSLSocketParams(params);
903   SSLConfig endpoint_ssl_config = SSLConfigForEndpoint();
904   VerifySSLSocketParams(endpoint_ssl_socket_params,
905                         "endpoint_ssl_socket_params",
906                         HostPortPair::FromSchemeHostPort(kEndpoint),
907                         endpoint_ssl_config, privacy_mode(), kTestNak);
908 
909   scoped_refptr<HttpProxySocketParams> http_proxy_socket_params_d =
910       endpoint_ssl_socket_params->GetHttpProxyConnectionParams();
911   VerifyHttpProxySocketParams(
912       http_proxy_socket_params_d, "http_proxy_socket_params_d",
913       /*quic_ssl_config=*/std::nullopt,
914       HostPortPair::FromSchemeHostPort(kEndpoint), proxy_chain,
915       /*proxy_chain_index=*/3,
916       /*tunnel=*/true, kTestNak, secure_dns_policy());
917 
918   scoped_refptr<SSLSocketParams> proxy_ssl_socket_params_d =
919       http_proxy_socket_params_d->ssl_params();
920   ASSERT_TRUE(proxy_ssl_socket_params_d);
921   SSLConfig proxy_ssl_config = SSLConfigForProxy();
922   VerifySSLSocketParams(proxy_ssl_socket_params_d, "proxy_ssl_socket_params_d",
923                         HostPortPair::FromString("proxyd:443"),
924                         proxy_ssl_config, PrivacyMode::PRIVACY_MODE_DISABLED,
925                         kTestNak);
926 
927   scoped_refptr<HttpProxySocketParams> http_proxy_socket_params_c =
928       proxy_ssl_socket_params_d->GetHttpProxyConnectionParams();
929   VerifyHttpProxySocketParams(http_proxy_socket_params_c,
930                               "http_proxy_socket_params_c",
931                               /*quic_ssl_config=*/std::nullopt,
932                               HostPortPair("proxyd", 443), proxy_chain,
933                               /*proxy_chain_index=*/2,
934                               /*tunnel=*/true, kTestNak, secure_dns_policy());
935 
936   scoped_refptr<SSLSocketParams> proxy_ssl_socket_params_c =
937       http_proxy_socket_params_c->ssl_params();
938   ASSERT_TRUE(proxy_ssl_socket_params_c);
939   VerifySSLSocketParams(proxy_ssl_socket_params_c, "proxy_ssl_socket_params_c",
940                         HostPortPair::FromString("proxyc:443"),
941                         proxy_ssl_config, PrivacyMode::PRIVACY_MODE_DISABLED,
942                         kTestNak);
943 
944   auto http_proxy_socket_params_b =
945       proxy_ssl_socket_params_c->GetHttpProxyConnectionParams();
946   SSLConfig quic_ssl_config_b = SSLConfigForProxy();
947   VerifyHttpProxySocketParams(http_proxy_socket_params_b,
948                               "http_proxy_socket_params_b", quic_ssl_config_b,
949                               HostPortPair("proxyc", 443), proxy_chain,
950                               /*proxy_chain_index=*/1,
951                               /*tunnel=*/true, kTestNak, secure_dns_policy());
952 }
953 
954 INSTANTIATE_TEST_SUITE_P(
955     All,
956     ConnectJobParamsFactoryTest,
957     testing::ConvertGenerator<TestParams::ParamTuple>(testing::Combine(
958         testing::Values(false, true),
959         testing::Values(PrivacyMode::PRIVACY_MODE_ENABLED,
960                         PrivacyMode::PRIVACY_MODE_DISABLED),
961         testing::Values(SecureDnsPolicy::kAllow, SecureDnsPolicy::kDisable),
962         testing::Values(ConnectJobFactory::AlpnMode::kDisabled,
963                         ConnectJobFactory::AlpnMode::kHttp11Only,
964                         ConnectJobFactory::AlpnMode::kHttpAll),
965         testing::Values(false, true))));
966 
967 }  // namespace
968 
969 }  // namespace net
970