blob: d18586d7d22fe65af0ecc37cfc9b1a40a156b09c [file] [log] [blame]
Matt Menke7b5051072019-01-27 21:22:491// Copyright 2019 The Chromium Authors. All rights reserved.
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/ssl_connect_job.h"
6
7#include <memory>
8#include <string>
9
10#include "base/callback.h"
11#include "base/compiler_specific.h"
12#include "base/stl_util.h"
13#include "base/strings/string_util.h"
14#include "base/strings/utf_string_conversions.h"
David Benjamin07a07d652020-02-26 22:26:5915#include "base/test/metrics/histogram_tester.h"
16#include "base/test/scoped_feature_list.h"
Gabriel Charettec7108742019-08-23 03:31:4017#include "base/test/task_environment.h"
Matt Menke7b5051072019-01-27 21:22:4918#include "base/time/time.h"
19#include "net/base/auth.h"
David Benjamin07a07d652020-02-26 22:26:5920#include "net/base/features.h"
Matt Menke7b5051072019-01-27 21:22:4921#include "net/base/load_timing_info.h"
22#include "net/base/net_errors.h"
Matt Menkeae58eeb2019-05-24 21:09:5023#include "net/base/network_isolation_key.h"
Matt Menke7b5051072019-01-27 21:22:4924#include "net/cert/ct_policy_enforcer.h"
25#include "net/cert/mock_cert_verifier.h"
Matt Menke7b5051072019-01-27 21:22:4926#include "net/dns/mock_host_resolver.h"
Ben Schwartz3ff4dc1e62021-04-27 21:15:2327#include "net/dns/public/secure_dns_policy.h"
Matt Menke7b5051072019-01-27 21:22:4928#include "net/http/http_auth_handler_factory.h"
29#include "net/http/http_network_session.h"
Matt Menke0754b5d02019-02-10 21:46:4330#include "net/http/http_proxy_connect_job.h"
Matt Menke7b5051072019-01-27 21:22:4931#include "net/http/http_request_headers.h"
32#include "net/http/http_response_headers.h"
Matt Menke609160742019-08-02 18:47:2633#include "net/http/http_server_properties.h"
Matt Menke7b5051072019-01-27 21:22:4934#include "net/http/transport_security_state.h"
35#include "net/log/net_log_source.h"
36#include "net/log/net_log_with_source.h"
Nicolas Arciniegad2013f92020-02-07 23:00:5637#include "net/proxy_resolution/configured_proxy_resolution_service.h"
Victor Vasiliev7752898d2019-11-14 21:30:2238#include "net/quic/quic_context.h"
Matt Menke7b5051072019-01-27 21:22:4939#include "net/socket/connect_job_test_util.h"
Matt Menke6030ed9f2019-04-11 20:25:5540#include "net/socket/connection_attempts.h"
Matt Menke7b5051072019-01-27 21:22:4941#include "net/socket/next_proto.h"
42#include "net/socket/socket_tag.h"
43#include "net/socket/socket_test_util.h"
44#include "net/socket/socks_connect_job.h"
Matt Menke7b5051072019-01-27 21:22:4945#include "net/socket/transport_connect_job.h"
46#include "net/ssl/ssl_config_service_defaults.h"
David Benjamin07a07d652020-02-26 22:26:5947#include "net/ssl/ssl_connection_status_flags.h"
48#include "net/ssl/ssl_legacy_crypto_fallback.h"
49#include "net/test/cert_test_util.h"
Matt Menke7b5051072019-01-27 21:22:4950#include "net/test/gtest_util.h"
51#include "net/test/test_certificate_data.h"
David Benjamin07a07d652020-02-26 22:26:5952#include "net/test/test_data_directory.h"
Gabriel Charettec7108742019-08-23 03:31:4053#include "net/test/test_with_task_environment.h"
Matt Menke7b5051072019-01-27 21:22:4954#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
55#include "testing/gtest/include/gtest/gtest.h"
David Benjamin07a07d652020-02-26 22:26:5956#include "third_party/boringssl/src/include/openssl/ssl.h"
Matt Menke7b5051072019-01-27 21:22:4957
58namespace net {
59namespace {
60
Matt Menke7b5051072019-01-27 21:22:4961// Just check that all connect times are set to base::TimeTicks::Now(), for
62// tests that don't update the mocked out time.
63void CheckConnectTimesSet(const LoadTimingInfo::ConnectTiming& connect_timing) {
64 EXPECT_EQ(base::TimeTicks::Now(), connect_timing.dns_start);
65 EXPECT_EQ(base::TimeTicks::Now(), connect_timing.dns_end);
66 EXPECT_EQ(base::TimeTicks::Now(), connect_timing.connect_start);
67 EXPECT_EQ(base::TimeTicks::Now(), connect_timing.ssl_start);
68 EXPECT_EQ(base::TimeTicks::Now(), connect_timing.ssl_end);
69 EXPECT_EQ(base::TimeTicks::Now(), connect_timing.connect_end);
70}
71
72// Just check that all connect times are set to base::TimeTicks::Now(), except
73// for DNS times, for tests that don't update the mocked out time and use a
74// proxy.
75void CheckConnectTimesExceptDnsSet(
76 const LoadTimingInfo::ConnectTiming& connect_timing) {
77 EXPECT_TRUE(connect_timing.dns_start.is_null());
78 EXPECT_TRUE(connect_timing.dns_end.is_null());
79 EXPECT_EQ(base::TimeTicks::Now(), connect_timing.connect_start);
80 EXPECT_EQ(base::TimeTicks::Now(), connect_timing.ssl_start);
81 EXPECT_EQ(base::TimeTicks::Now(), connect_timing.ssl_end);
82 EXPECT_EQ(base::TimeTicks::Now(), connect_timing.connect_end);
83}
84
Gabriel Charette694c3c332019-08-19 14:53:0585class SSLConnectJobTest : public WithTaskEnvironment, public testing::Test {
Matt Menke7b5051072019-01-27 21:22:4986 public:
87 SSLConnectJobTest()
Gabriel Charette694c3c332019-08-19 14:53:0588 : WithTaskEnvironment(base::test::TaskEnvironment::TimeSource::MOCK_TIME),
Nicolas Arciniegad2013f92020-02-07 23:00:5689 proxy_resolution_service_(
90 ConfiguredProxyResolutionService::CreateDirect()),
Matt Menke7b5051072019-01-27 21:22:4991 ssl_config_service_(new SSLConfigServiceDefaults),
Eric Orthbe2efac2019-03-06 01:11:1192 http_auth_handler_factory_(HttpAuthHandlerFactory::CreateDefault()),
Matt Menke7b5051072019-01-27 21:22:4993 session_(CreateNetworkSession()),
Matt Menke7b5051072019-01-27 21:22:4994 direct_transport_socket_params_(
95 new TransportSocketParams(HostPortPair("host", 443),
Matt Menkecd439232019-11-05 15:15:3396 NetworkIsolationKey(),
Ben Schwartz3ff4dc1e62021-04-27 21:15:2397 SecureDnsPolicy::kAllow,
Matt Menke7b5051072019-01-27 21:22:4998 OnHostResolutionCallback())),
Matt Menke7b5051072019-01-27 21:22:4999 proxy_transport_socket_params_(
100 new TransportSocketParams(HostPortPair("proxy", 443),
Matt Menkecd439232019-11-05 15:15:33101 NetworkIsolationKey(),
Ben Schwartz3ff4dc1e62021-04-27 21:15:23102 SecureDnsPolicy::kAllow,
Matt Menke7b5051072019-01-27 21:22:49103 OnHostResolutionCallback())),
104 socks_socket_params_(
105 new SOCKSSocketParams(proxy_transport_socket_params_,
106 true,
107 HostPortPair("sockshost", 443),
Matt Menke166710e2019-11-06 03:35:51108 NetworkIsolationKey(),
Matt Menke7b5051072019-01-27 21:22:49109 TRAFFIC_ANNOTATION_FOR_TESTS)),
110 http_proxy_socket_params_(
111 new HttpProxySocketParams(proxy_transport_socket_params_,
112 nullptr /* ssl_params */,
Matt Menkeb5fb42b2019-03-22 17:26:13113 false /* is_quic */,
Matt Menke7b5051072019-01-27 21:22:49114 HostPortPair("host", 80),
Matt Menke7b5051072019-01-27 21:22:49115 /*is_trusted_proxy=*/false,
116 /*tunnel=*/true,
Matt Menkeae58eeb2019-05-24 21:09:50117 TRAFFIC_ANNOTATION_FOR_TESTS,
118 NetworkIsolationKey())),
Gabriel Charette694c3c332019-08-19 14:53:05119 common_connect_job_params_(session_->CreateCommonConnectJobParams()) {}
Matt Menke7b5051072019-01-27 21:22:49120
121 ~SSLConnectJobTest() override = default;
122
123 std::unique_ptr<ConnectJob> CreateConnectJob(
124 TestConnectJobDelegate* test_delegate,
125 ProxyServer::Scheme proxy_scheme = ProxyServer::SCHEME_DIRECT,
126 RequestPriority priority = DEFAULT_PRIORITY) {
127 return std::make_unique<SSLConnectJob>(
Matt Menkea6f99ad2019-03-08 02:26:43128 priority, SocketTag(), &common_connect_job_params_,
Matt Menke14819512019-03-02 16:59:58129 SSLParams(proxy_scheme), test_delegate, nullptr /* net_log */);
Matt Menke7b5051072019-01-27 21:22:49130 }
131
132 scoped_refptr<SSLSocketParams> SSLParams(ProxyServer::Scheme proxy) {
133 return base::MakeRefCounted<SSLSocketParams>(
134 proxy == ProxyServer::SCHEME_DIRECT ? direct_transport_socket_params_
135 : nullptr,
136 proxy == ProxyServer::SCHEME_SOCKS5 ? socks_socket_params_ : nullptr,
137 proxy == ProxyServer::SCHEME_HTTP ? http_proxy_socket_params_ : nullptr,
David Benjamin151ec6b2019-08-02 19:38:52138 HostPortPair("host", 443), SSLConfig(), PRIVACY_MODE_DISABLED,
David Benjamin6f2da652019-06-26 23:36:35139 NetworkIsolationKey());
Matt Menke7b5051072019-01-27 21:22:49140 }
141
142 void AddAuthToCache() {
Jan Wilken Dörriec92a6d7242021-03-23 17:43:48143 const std::u16string kFoo(u"foo");
144 const std::u16string kBar(u"bar");
Matt Menke7b5051072019-01-27 21:22:49145 session_->http_auth_cache()->Add(
Matt Menke96092e62019-10-18 04:09:33146 GURL("http://proxy:443/"), HttpAuth::AUTH_PROXY, "MyRealm1",
Matt Menkebe090422019-10-18 20:25:26147 HttpAuth::AUTH_SCHEME_BASIC, NetworkIsolationKey(),
148 "Basic realm=MyRealm1", AuthCredentials(kFoo, kBar), "/");
Matt Menke7b5051072019-01-27 21:22:49149 }
150
151 HttpNetworkSession* CreateNetworkSession() {
152 HttpNetworkSession::Context session_context;
153 session_context.host_resolver = &host_resolver_;
154 session_context.cert_verifier = &cert_verifier_;
155 session_context.transport_security_state = &transport_security_state_;
Matt Menke7b5051072019-01-27 21:22:49156 session_context.ct_policy_enforcer = &ct_policy_enforcer_;
157 session_context.proxy_resolution_service = proxy_resolution_service_.get();
158 session_context.client_socket_factory = &socket_factory_;
159 session_context.ssl_config_service = ssl_config_service_.get();
160 session_context.http_auth_handler_factory =
161 http_auth_handler_factory_.get();
162 session_context.http_server_properties = &http_server_properties_;
Victor Vasiliev7752898d2019-11-14 21:30:22163 session_context.quic_context = &quic_context_;
Matt Menke7b5051072019-01-27 21:22:49164 return new HttpNetworkSession(HttpNetworkSession::Params(),
165 session_context);
166 }
167
168 protected:
169 MockClientSocketFactory socket_factory_;
Matt Menkeaade5812019-03-02 13:38:00170 MockHostResolver host_resolver_;
Matt Menke7b5051072019-01-27 21:22:49171 MockCertVerifier cert_verifier_;
172 TransportSecurityState transport_security_state_;
Matt Menke7b5051072019-01-27 21:22:49173 DefaultCTPolicyEnforcer ct_policy_enforcer_;
Nicolas Arciniega8ec5bfa2020-03-20 05:07:26174 const std::unique_ptr<ProxyResolutionService> proxy_resolution_service_;
Matt Menke7b5051072019-01-27 21:22:49175 const std::unique_ptr<SSLConfigService> ssl_config_service_;
176 const std::unique_ptr<HttpAuthHandlerFactory> http_auth_handler_factory_;
Matt Menke609160742019-08-02 18:47:26177 HttpServerProperties http_server_properties_;
Victor Vasiliev7752898d2019-11-14 21:30:22178 QuicContext quic_context_;
Matt Menke7b5051072019-01-27 21:22:49179 const std::unique_ptr<HttpNetworkSession> session_;
Matt Menke7b5051072019-01-27 21:22:49180
181 scoped_refptr<TransportSocketParams> direct_transport_socket_params_;
Matt Menke7b5051072019-01-27 21:22:49182
183 scoped_refptr<TransportSocketParams> proxy_transport_socket_params_;
184 scoped_refptr<SOCKSSocketParams> socks_socket_params_;
185 scoped_refptr<HttpProxySocketParams> http_proxy_socket_params_;
186
Matt Menkea6f99ad2019-03-08 02:26:43187 const CommonConnectJobParams common_connect_job_params_;
Matt Menke7b5051072019-01-27 21:22:49188};
189
190TEST_F(SSLConnectJobTest, TCPFail) {
191 for (IoMode io_mode : {SYNCHRONOUS, ASYNC}) {
192 SCOPED_TRACE(io_mode);
193 host_resolver_.set_synchronous_mode(io_mode == SYNCHRONOUS);
194 StaticSocketDataProvider data;
195 data.set_connect_data(MockConnect(io_mode, ERR_CONNECTION_FAILED));
196 socket_factory_.AddSocketDataProvider(&data);
197
198 TestConnectJobDelegate test_delegate;
199 std::unique_ptr<ConnectJob> ssl_connect_job =
200 CreateConnectJob(&test_delegate);
201 test_delegate.StartJobExpectingResult(
202 ssl_connect_job.get(), ERR_CONNECTION_FAILED, io_mode == SYNCHRONOUS);
203 EXPECT_FALSE(test_delegate.socket());
Matt Menke6f84d1f12019-04-11 19:26:47204 EXPECT_FALSE(ssl_connect_job->IsSSLError());
Matt Menke6030ed9f2019-04-11 20:25:55205 ConnectionAttempts connection_attempts =
206 ssl_connect_job->GetConnectionAttempts();
207 ASSERT_EQ(1u, connection_attempts.size());
208 EXPECT_THAT(connection_attempts[0].result,
Matt Menke7b5051072019-01-27 21:22:49209 test::IsError(ERR_CONNECTION_FAILED));
210 }
211}
212
Matt Menke36eaf5c2019-04-02 16:15:52213TEST_F(SSLConnectJobTest, TCPTimeout) {
214 const base::TimeDelta kTinyTime = base::TimeDelta::FromMicroseconds(1);
215
216 // Make request hang.
217 host_resolver_.set_ondemand_mode(true);
218
219 TestConnectJobDelegate test_delegate;
220 std::unique_ptr<ConnectJob> ssl_connect_job =
221 CreateConnectJob(&test_delegate);
222 ASSERT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
223
224 // Right up until just before the TCP connection timeout, the job does not
225 // time out.
226 FastForwardBy(TransportConnectJob::ConnectionTimeout() - kTinyTime);
227 EXPECT_FALSE(test_delegate.has_result());
228
229 // But at the exact time of TCP connection timeout, the job fails.
230 FastForwardBy(kTinyTime);
231 EXPECT_TRUE(test_delegate.has_result());
232 EXPECT_THAT(test_delegate.WaitForResult(), test::IsError(ERR_TIMED_OUT));
233}
234
235TEST_F(SSLConnectJobTest, SSLTimeoutSyncConnect) {
236 const base::TimeDelta kTinyTime = base::TimeDelta::FromMicroseconds(1);
237
238 // DNS lookup and transport connect complete synchronously, but SSL
239 // negotiation hangs.
240 host_resolver_.set_synchronous_mode(true);
241 StaticSocketDataProvider data;
242 data.set_connect_data(MockConnect(SYNCHRONOUS, OK));
243 socket_factory_.AddSocketDataProvider(&data);
244 SSLSocketDataProvider ssl(SYNCHRONOUS, ERR_IO_PENDING);
245 socket_factory_.AddSSLSocketDataProvider(&ssl);
246
247 // Make request hang.
248 TestConnectJobDelegate test_delegate;
249 std::unique_ptr<ConnectJob> ssl_connect_job =
250 CreateConnectJob(&test_delegate);
251 ASSERT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
252
253 // Right up until just before the SSL handshake timeout, the job does not time
254 // out.
255 FastForwardBy(SSLConnectJob::HandshakeTimeoutForTesting() - kTinyTime);
256 EXPECT_FALSE(test_delegate.has_result());
257
258 // But at the exact SSL handshake timeout time, the job fails.
259 FastForwardBy(kTinyTime);
260 EXPECT_TRUE(test_delegate.has_result());
261 EXPECT_THAT(test_delegate.WaitForResult(), test::IsError(ERR_TIMED_OUT));
262}
263
264TEST_F(SSLConnectJobTest, SSLTimeoutAsyncTcpConnect) {
265 const base::TimeDelta kTinyTime = base::TimeDelta::FromMicroseconds(1);
266
267 // DNS lookup is asynchronous, and later SSL negotiation hangs.
268 host_resolver_.set_ondemand_mode(true);
269 StaticSocketDataProvider data;
270 data.set_connect_data(MockConnect(SYNCHRONOUS, OK));
271 socket_factory_.AddSocketDataProvider(&data);
272 SSLSocketDataProvider ssl(SYNCHRONOUS, ERR_IO_PENDING);
273 socket_factory_.AddSSLSocketDataProvider(&ssl);
274
275 TestConnectJobDelegate test_delegate;
276 std::unique_ptr<ConnectJob> ssl_connect_job =
277 CreateConnectJob(&test_delegate);
278 // Connecting should hand on the TransportConnectJob connect.
279 ASSERT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
280
281 // Right up until just before the TCP connection timeout, the job does not
282 // time out.
283 FastForwardBy(TransportConnectJob::ConnectionTimeout() - kTinyTime);
284 EXPECT_FALSE(test_delegate.has_result());
285
286 // The DNS lookup completes, and a TCP connection is immediately establshed,
287 // which cancels the TCP connection timer. The SSL handshake timer is started,
288 // and the SSL handshake hangs.
289 host_resolver_.ResolveOnlyRequestNow();
290 EXPECT_FALSE(test_delegate.has_result());
291
292 // Right up until just before the SSL handshake timeout, the job does not time
293 // out.
294 FastForwardBy(SSLConnectJob::HandshakeTimeoutForTesting() - kTinyTime);
295 EXPECT_FALSE(test_delegate.has_result());
296
297 // But at the exact SSL handshake timeout time, the job fails.
298 FastForwardBy(kTinyTime);
299 EXPECT_TRUE(test_delegate.has_result());
300 EXPECT_THAT(test_delegate.WaitForResult(), test::IsError(ERR_TIMED_OUT));
301}
302
Matt Menke7b5051072019-01-27 21:22:49303TEST_F(SSLConnectJobTest, BasicDirectSync) {
304 host_resolver_.set_synchronous_mode(true);
305 StaticSocketDataProvider data;
306 data.set_connect_data(MockConnect(SYNCHRONOUS, OK));
307 socket_factory_.AddSocketDataProvider(&data);
308 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
309 socket_factory_.AddSSLSocketDataProvider(&ssl);
310
311 TestConnectJobDelegate test_delegate;
312 std::unique_ptr<ConnectJob> ssl_connect_job =
313 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_DIRECT, MEDIUM);
314
315 test_delegate.StartJobExpectingResult(ssl_connect_job.get(), OK,
316 true /* expect_sync_result */);
317 EXPECT_EQ(MEDIUM, host_resolver_.last_request_priority());
318
Matt Menke6030ed9f2019-04-11 20:25:55319 ConnectionAttempts connection_attempts =
320 ssl_connect_job->GetConnectionAttempts();
321 EXPECT_EQ(0u, connection_attempts.size());
Matt Menke7b5051072019-01-27 21:22:49322 CheckConnectTimesSet(ssl_connect_job->connect_timing());
323}
324
325TEST_F(SSLConnectJobTest, BasicDirectAsync) {
326 host_resolver_.set_ondemand_mode(true);
327 base::TimeTicks start_time = base::TimeTicks::Now();
328 StaticSocketDataProvider data;
329 data.set_connect_data(MockConnect(ASYNC, OK));
330 socket_factory_.AddSocketDataProvider(&data);
331 SSLSocketDataProvider ssl(ASYNC, OK);
332 socket_factory_.AddSSLSocketDataProvider(&ssl);
333
334 TestConnectJobDelegate test_delegate;
335 std::unique_ptr<ConnectJob> ssl_connect_job =
336 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_DIRECT, MEDIUM);
337 EXPECT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
338 EXPECT_TRUE(host_resolver_.has_pending_requests());
339 EXPECT_EQ(MEDIUM, host_resolver_.last_request_priority());
340 FastForwardBy(base::TimeDelta::FromSeconds(5));
341
342 base::TimeTicks resolve_complete_time = base::TimeTicks::Now();
343 host_resolver_.ResolveAllPending();
344 EXPECT_THAT(test_delegate.WaitForResult(), test::IsOk());
345
Matt Menke6030ed9f2019-04-11 20:25:55346 ConnectionAttempts connection_attempts =
347 ssl_connect_job->GetConnectionAttempts();
348 EXPECT_EQ(0u, connection_attempts.size());
Matt Menke7b5051072019-01-27 21:22:49349
350 // Check times. Since time is mocked out, all times will be the same, except
351 // |dns_start|, which is the only one recorded before the FastForwardBy()
352 // call. The test classes don't allow any other phases to be triggered on
353 // demand, or delayed by a set interval.
354 EXPECT_EQ(start_time, ssl_connect_job->connect_timing().dns_start);
355 EXPECT_EQ(resolve_complete_time, ssl_connect_job->connect_timing().dns_end);
356 EXPECT_EQ(resolve_complete_time,
357 ssl_connect_job->connect_timing().connect_start);
358 EXPECT_EQ(resolve_complete_time, ssl_connect_job->connect_timing().ssl_start);
359 EXPECT_EQ(resolve_complete_time, ssl_connect_job->connect_timing().ssl_end);
360 EXPECT_EQ(resolve_complete_time,
361 ssl_connect_job->connect_timing().connect_end);
362}
363
Matt Menke9d5e2c92019-02-05 01:42:23364TEST_F(SSLConnectJobTest, DirectHasEstablishedConnection) {
365 host_resolver_.set_ondemand_mode(true);
366 StaticSocketDataProvider data;
367 data.set_connect_data(MockConnect(ASYNC, OK));
368 socket_factory_.AddSocketDataProvider(&data);
369
370 // SSL negotiation hangs. Value returned after SSL negotiation is complete
371 // doesn't matter, as HasEstablishedConnection() may only be used between job
372 // start and job complete.
373 SSLSocketDataProvider ssl(SYNCHRONOUS, ERR_IO_PENDING);
374 socket_factory_.AddSSLSocketDataProvider(&ssl);
375
376 TestConnectJobDelegate test_delegate;
377 std::unique_ptr<ConnectJob> ssl_connect_job =
378 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_DIRECT, MEDIUM);
379 EXPECT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
380 EXPECT_TRUE(host_resolver_.has_pending_requests());
381 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, ssl_connect_job->GetLoadState());
382 EXPECT_FALSE(ssl_connect_job->HasEstablishedConnection());
383
384 // DNS resolution completes, and then the ConnectJob tries to connect the
385 // socket, which should succeed asynchronously.
386 host_resolver_.ResolveNow(1);
387 EXPECT_EQ(LOAD_STATE_CONNECTING, ssl_connect_job->GetLoadState());
388 EXPECT_FALSE(ssl_connect_job->HasEstablishedConnection());
389
390 // Spinning the message loop causes the socket to finish connecting. The SSL
391 // handshake should start and hang.
392 base::RunLoop().RunUntilIdle();
393 EXPECT_FALSE(test_delegate.has_result());
394 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, ssl_connect_job->GetLoadState());
395 EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
396}
397
Matt Menke7b5051072019-01-27 21:22:49398TEST_F(SSLConnectJobTest, RequestPriority) {
399 host_resolver_.set_ondemand_mode(true);
Matt Menke7b5051072019-01-27 21:22:49400 for (int initial_priority = MINIMUM_PRIORITY;
401 initial_priority <= MAXIMUM_PRIORITY; ++initial_priority) {
402 SCOPED_TRACE(initial_priority);
403 for (int new_priority = MINIMUM_PRIORITY; new_priority <= MAXIMUM_PRIORITY;
404 ++new_priority) {
405 SCOPED_TRACE(new_priority);
406 if (initial_priority == new_priority)
407 continue;
408 TestConnectJobDelegate test_delegate;
409 std::unique_ptr<ConnectJob> ssl_connect_job =
410 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_DIRECT,
411 static_cast<RequestPriority>(initial_priority));
412 EXPECT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
413 EXPECT_TRUE(host_resolver_.has_pending_requests());
414 int request_id = host_resolver_.num_resolve();
415 EXPECT_EQ(initial_priority, host_resolver_.request_priority(request_id));
416
417 ssl_connect_job->ChangePriority(
418 static_cast<RequestPriority>(new_priority));
419 EXPECT_EQ(new_priority, host_resolver_.request_priority(request_id));
420
421 ssl_connect_job->ChangePriority(
422 static_cast<RequestPriority>(initial_priority));
423 EXPECT_EQ(initial_priority, host_resolver_.request_priority(request_id));
Matt Menke7b5051072019-01-27 21:22:49424 }
425 }
426}
427
Ben Schwartz3ff4dc1e62021-04-27 21:15:23428TEST_F(SSLConnectJobTest, SecureDnsPolicy) {
429 for (auto secure_dns_policy :
430 {SecureDnsPolicy::kAllow, SecureDnsPolicy::kDisable}) {
dalyk5f48a132019-10-14 15:20:19431 TestConnectJobDelegate test_delegate;
432 direct_transport_socket_params_ =
Matt Menkecd439232019-11-05 15:15:33433 base::MakeRefCounted<TransportSocketParams>(
Ben Schwartz3ff4dc1e62021-04-27 21:15:23434 HostPortPair("host", 443), NetworkIsolationKey(), secure_dns_policy,
435 OnHostResolutionCallback());
dalyk5f48a132019-10-14 15:20:19436 auto common_connect_job_params = session_->CreateCommonConnectJobParams();
437 std::unique_ptr<ConnectJob> ssl_connect_job =
438 std::make_unique<SSLConnectJob>(DEFAULT_PRIORITY, SocketTag(),
439 &common_connect_job_params,
440 SSLParams(ProxyServer::SCHEME_DIRECT),
441 &test_delegate, nullptr /* net_log */);
442
443 EXPECT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
Ben Schwartz432ce032021-05-05 21:49:24444 EXPECT_EQ(secure_dns_policy, host_resolver_.last_secure_dns_policy());
dalyk5f48a132019-10-14 15:20:19445 }
446}
447
dalykedd30d982019-12-16 15:31:10448TEST_F(SSLConnectJobTest, DirectHostResolutionFailure) {
449 host_resolver_.rules()->AddSimulatedTimeoutFailure("host");
450
451 TestConnectJobDelegate test_delegate;
452 std::unique_ptr<ConnectJob> ssl_connect_job =
453 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_DIRECT);
454 test_delegate.StartJobExpectingResult(ssl_connect_job.get(),
455 ERR_NAME_NOT_RESOLVED,
456 false /* expect_sync_result */);
457 EXPECT_THAT(ssl_connect_job->GetResolveErrorInfo().error,
458 test::IsError(ERR_DNS_TIMED_OUT));
459}
460
Matt Menke7b5051072019-01-27 21:22:49461TEST_F(SSLConnectJobTest, DirectCertError) {
462 StaticSocketDataProvider data;
463 socket_factory_.AddSocketDataProvider(&data);
464 SSLSocketDataProvider ssl(ASYNC, ERR_CERT_COMMON_NAME_INVALID);
465 socket_factory_.AddSSLSocketDataProvider(&ssl);
466
467 TestConnectJobDelegate test_delegate(
468 TestConnectJobDelegate::SocketExpected::ALWAYS);
469 std::unique_ptr<ConnectJob> ssl_connect_job =
470 CreateConnectJob(&test_delegate);
471
472 test_delegate.StartJobExpectingResult(ssl_connect_job.get(),
473 ERR_CERT_COMMON_NAME_INVALID,
474 false /* expect_sync_result */);
Matt Menke6f84d1f12019-04-11 19:26:47475 EXPECT_TRUE(ssl_connect_job->IsSSLError());
Matt Menke6030ed9f2019-04-11 20:25:55476 ConnectionAttempts connection_attempts =
477 ssl_connect_job->GetConnectionAttempts();
478 ASSERT_EQ(1u, connection_attempts.size());
479 EXPECT_THAT(connection_attempts[0].result,
Matt Menke7b5051072019-01-27 21:22:49480 test::IsError(ERR_CERT_COMMON_NAME_INVALID));
481 CheckConnectTimesSet(ssl_connect_job->connect_timing());
482}
483
484TEST_F(SSLConnectJobTest, DirectSSLError) {
485 StaticSocketDataProvider data;
486 socket_factory_.AddSocketDataProvider(&data);
David Benjamin07a07d652020-02-26 22:26:59487 SSLSocketDataProvider ssl(ASYNC, ERR_BAD_SSL_CLIENT_AUTH_CERT);
Matt Menke7b5051072019-01-27 21:22:49488 socket_factory_.AddSSLSocketDataProvider(&ssl);
489
490 TestConnectJobDelegate test_delegate;
491 std::unique_ptr<ConnectJob> ssl_connect_job =
492 CreateConnectJob(&test_delegate);
493
494 test_delegate.StartJobExpectingResult(ssl_connect_job.get(),
David Benjamin07a07d652020-02-26 22:26:59495 ERR_BAD_SSL_CLIENT_AUTH_CERT,
Matt Menke7b5051072019-01-27 21:22:49496 false /* expect_sync_result */);
Matt Menke6030ed9f2019-04-11 20:25:55497 ConnectionAttempts connection_attempts =
498 ssl_connect_job->GetConnectionAttempts();
499 ASSERT_EQ(1u, connection_attempts.size());
500 EXPECT_THAT(connection_attempts[0].result,
David Benjamin07a07d652020-02-26 22:26:59501 test::IsError(ERR_BAD_SSL_CLIENT_AUTH_CERT));
502}
503
504// Test that the legacy crypto fallback is triggered on applicable error codes.
505TEST_F(SSLConnectJobTest, DirectLegacyCryptoFallback) {
506 for (Error error :
507 {ERR_CONNECTION_CLOSED, ERR_CONNECTION_RESET, ERR_SSL_PROTOCOL_ERROR,
508 ERR_SSL_VERSION_OR_CIPHER_MISMATCH}) {
509 SCOPED_TRACE(error);
510
511 for (bool second_attempt_ok : {true, false}) {
512 SCOPED_TRACE(second_attempt_ok);
513
514 StaticSocketDataProvider data;
515 socket_factory_.AddSocketDataProvider(&data);
516 SSLSocketDataProvider ssl(ASYNC, error);
517 socket_factory_.AddSSLSocketDataProvider(&ssl);
518 ssl.expected_disable_legacy_crypto = true;
519
520 Error error2 = second_attempt_ok ? OK : error;
521 StaticSocketDataProvider data2;
522 socket_factory_.AddSocketDataProvider(&data2);
523 SSLSocketDataProvider ssl2(ASYNC, error2);
524 socket_factory_.AddSSLSocketDataProvider(&ssl2);
525 ssl2.expected_disable_legacy_crypto = false;
526
527 TestConnectJobDelegate test_delegate;
528 std::unique_ptr<ConnectJob> ssl_connect_job =
529 CreateConnectJob(&test_delegate);
530
531 test_delegate.StartJobExpectingResult(ssl_connect_job.get(), error2,
532 /*expect_sync_result=*/false);
533 ConnectionAttempts connection_attempts =
534 ssl_connect_job->GetConnectionAttempts();
535 if (second_attempt_ok) {
536 ASSERT_EQ(1u, connection_attempts.size());
537 EXPECT_THAT(connection_attempts[0].result, test::IsError(error));
538 } else {
539 ASSERT_EQ(2u, connection_attempts.size());
540 EXPECT_THAT(connection_attempts[0].result, test::IsError(error));
541 EXPECT_THAT(connection_attempts[1].result, test::IsError(error));
542 }
543 }
544 }
545}
546
547// Test that the feature flag disables the legacy crypto fallback.
548TEST_F(SSLConnectJobTest, LegacyCryptoFallbackDisabled) {
549 base::test::ScopedFeatureList feature_list;
550 feature_list.InitAndDisableFeature(
551 features::kTLSLegacyCryptoFallbackForMetrics);
552 for (Error error :
553 {ERR_CONNECTION_CLOSED, ERR_CONNECTION_RESET, ERR_SSL_PROTOCOL_ERROR,
554 ERR_SSL_VERSION_OR_CIPHER_MISMATCH}) {
555 SCOPED_TRACE(error);
556
557 StaticSocketDataProvider data;
558 socket_factory_.AddSocketDataProvider(&data);
559 SSLSocketDataProvider ssl(ASYNC, error);
560 socket_factory_.AddSSLSocketDataProvider(&ssl);
561 ssl.expected_disable_legacy_crypto = false;
562
563 TestConnectJobDelegate test_delegate;
564 std::unique_ptr<ConnectJob> ssl_connect_job =
565 CreateConnectJob(&test_delegate);
566
567 test_delegate.StartJobExpectingResult(ssl_connect_job.get(), error,
568 /*expect_sync_result=*/false);
569 ConnectionAttempts connection_attempts =
570 ssl_connect_job->GetConnectionAttempts();
571 ASSERT_EQ(1u, connection_attempts.size());
572 EXPECT_THAT(connection_attempts[0].result, test::IsError(error));
573 }
574}
575
576TEST_F(SSLConnectJobTest, LegacyCryptoFallbackHistograms) {
577 base::FilePath certs_dir = GetTestCertsDirectory();
578
579 scoped_refptr<X509Certificate> sha1_leaf =
580 ImportCertFromFile(certs_dir, "sha1_leaf.pem");
581 ASSERT_TRUE(sha1_leaf);
582
583 scoped_refptr<X509Certificate> ok_cert =
584 ImportCertFromFile(certs_dir, "ok_cert.pem");
585 ASSERT_TRUE(ok_cert);
586
587 // Make a copy of |ok_cert| with an unused |sha1_leaf| in the intermediate
588 // list.
589 std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates;
590 for (const auto& cert : ok_cert->intermediate_buffers()) {
591 intermediates.push_back(bssl::UpRef(cert));
592 }
593 intermediates.push_back(bssl::UpRef(sha1_leaf->cert_buffer()));
594 scoped_refptr<X509Certificate> ok_with_unused_sha1 =
595 X509Certificate::CreateFromBuffer(bssl::UpRef(ok_cert->cert_buffer()),
596 std::move(intermediates));
597 ASSERT_TRUE(ok_with_unused_sha1);
598
599 // TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
600 const uint16_t kModernCipher = 0xc02f;
601 // TLS_RSA_WITH_3DES_EDE_CBC_SHA
602 const uint16_t k3DESCipher = 0x000a;
603
604 struct HistogramTest {
605 SSLLegacyCryptoFallback expected;
606 Error first_attempt;
607 uint16_t cipher_suite;
608 uint16_t peer_signature_algorithm;
609 scoped_refptr<X509Certificate> unverified_cert;
610 };
611
612 const HistogramTest kHistogramTests[] = {
613 // Connections not using the fallback map to kNoFallback.
614 {SSLLegacyCryptoFallback::kNoFallback, OK, kModernCipher,
615 SSL_SIGN_RSA_PSS_RSAE_SHA256, ok_cert},
616 {SSLLegacyCryptoFallback::kNoFallback, OK, kModernCipher,
617 SSL_SIGN_RSA_PSS_RSAE_SHA256, sha1_leaf},
618 {SSLLegacyCryptoFallback::kNoFallback, OK, kModernCipher,
619 SSL_SIGN_RSA_PSS_RSAE_SHA256, ok_with_unused_sha1},
620
621 // Connections using 3DES map to kUsed3DES or kSentSHA1CertAndUsed3DES.
622 // Note our only supported 3DES cipher suite does not include a server
623 // signature, so |peer_signature_algorithm| would always be zero.
624 {SSLLegacyCryptoFallback::kUsed3DES, ERR_SSL_PROTOCOL_ERROR, k3DESCipher,
625 0, ok_cert},
626 {SSLLegacyCryptoFallback::kSentSHA1CertAndUsed3DES,
627 ERR_SSL_PROTOCOL_ERROR, k3DESCipher, 0, sha1_leaf},
628 {SSLLegacyCryptoFallback::kSentSHA1CertAndUsed3DES,
629 ERR_SSL_PROTOCOL_ERROR, k3DESCipher, 0, ok_with_unused_sha1},
630
631 // Connections using SHA-1 map to kUsedSHA1 or kSentSHA1CertAndUsedSHA1.
632 {SSLLegacyCryptoFallback::kUsedSHA1, ERR_SSL_PROTOCOL_ERROR,
633 kModernCipher, SSL_SIGN_RSA_PKCS1_SHA1, ok_cert},
634 {SSLLegacyCryptoFallback::kSentSHA1CertAndUsedSHA1,
635 ERR_SSL_PROTOCOL_ERROR, kModernCipher, SSL_SIGN_RSA_PKCS1_SHA1,
636 sha1_leaf},
637 {SSLLegacyCryptoFallback::kSentSHA1CertAndUsedSHA1,
638 ERR_SSL_PROTOCOL_ERROR, kModernCipher, SSL_SIGN_RSA_PKCS1_SHA1,
639 ok_with_unused_sha1},
640
641 // Connections using neither map to kUnknownReason or kSentSHA1Cert.
642 {SSLLegacyCryptoFallback::kUnknownReason, ERR_SSL_PROTOCOL_ERROR,
643 kModernCipher, SSL_SIGN_RSA_PSS_RSAE_SHA256, ok_cert},
644 {SSLLegacyCryptoFallback::kSentSHA1Cert, ERR_SSL_PROTOCOL_ERROR,
645 kModernCipher, SSL_SIGN_RSA_PSS_RSAE_SHA256, sha1_leaf},
646 {SSLLegacyCryptoFallback::kSentSHA1Cert, ERR_SSL_PROTOCOL_ERROR,
647 kModernCipher, SSL_SIGN_RSA_PSS_RSAE_SHA256, ok_with_unused_sha1},
648 };
649 for (size_t i = 0; i < base::size(kHistogramTests); i++) {
650 SCOPED_TRACE(i);
651 const auto& test = kHistogramTests[i];
652
653 base::HistogramTester tester;
654
655 SSLInfo ssl_info;
656 SSLConnectionStatusSetVersion(SSL_CONNECTION_VERSION_TLS1_2,
657 &ssl_info.connection_status);
658 SSLConnectionStatusSetCipherSuite(test.cipher_suite,
659 &ssl_info.connection_status);
660 ssl_info.peer_signature_algorithm = test.peer_signature_algorithm;
661 ssl_info.unverified_cert = test.unverified_cert;
662
663 StaticSocketDataProvider data;
664 socket_factory_.AddSocketDataProvider(&data);
665 SSLSocketDataProvider ssl(ASYNC, test.first_attempt);
666 socket_factory_.AddSSLSocketDataProvider(&ssl);
667 ssl.expected_disable_legacy_crypto = true;
668
669 StaticSocketDataProvider data2;
670 SSLSocketDataProvider ssl2(ASYNC, OK);
671 if (test.first_attempt != OK) {
672 socket_factory_.AddSocketDataProvider(&data2);
673 socket_factory_.AddSSLSocketDataProvider(&ssl2);
674 ssl2.ssl_info = ssl_info;
675 ssl2.expected_disable_legacy_crypto = false;
676 } else {
677 ssl.ssl_info = ssl_info;
678 }
679
680 TestConnectJobDelegate test_delegate;
681 std::unique_ptr<ConnectJob> ssl_connect_job =
682 CreateConnectJob(&test_delegate);
683
684 test_delegate.StartJobExpectingResult(ssl_connect_job.get(), OK,
685 /*expect_sync_result=*/false);
686
687 tester.ExpectUniqueSample("Net.SSLLegacyCryptoFallback", test.expected, 1);
688 }
Matt Menke7b5051072019-01-27 21:22:49689}
690
691TEST_F(SSLConnectJobTest, DirectWithNPN) {
692 StaticSocketDataProvider data;
693 socket_factory_.AddSocketDataProvider(&data);
694 SSLSocketDataProvider ssl(ASYNC, OK);
695 ssl.next_proto = kProtoHTTP11;
696 socket_factory_.AddSSLSocketDataProvider(&ssl);
697
698 TestConnectJobDelegate test_delegate;
699 std::unique_ptr<ConnectJob> ssl_connect_job =
700 CreateConnectJob(&test_delegate);
701
702 test_delegate.StartJobExpectingResult(ssl_connect_job.get(), OK,
703 false /* expect_sync_result */);
704 EXPECT_TRUE(test_delegate.socket()->WasAlpnNegotiated());
705 CheckConnectTimesSet(ssl_connect_job->connect_timing());
706}
707
708TEST_F(SSLConnectJobTest, DirectGotHTTP2) {
709 StaticSocketDataProvider data;
710 socket_factory_.AddSocketDataProvider(&data);
711 SSLSocketDataProvider ssl(ASYNC, OK);
712 ssl.next_proto = kProtoHTTP2;
713 socket_factory_.AddSSLSocketDataProvider(&ssl);
714
715 TestConnectJobDelegate test_delegate;
716 std::unique_ptr<ConnectJob> ssl_connect_job =
717 CreateConnectJob(&test_delegate);
718
719 test_delegate.StartJobExpectingResult(ssl_connect_job.get(), OK,
720 false /* expect_sync_result */);
721 EXPECT_TRUE(test_delegate.socket()->WasAlpnNegotiated());
722 EXPECT_EQ(kProtoHTTP2, test_delegate.socket()->GetNegotiatedProtocol());
723 CheckConnectTimesSet(ssl_connect_job->connect_timing());
724}
725
726TEST_F(SSLConnectJobTest, SOCKSFail) {
727 for (IoMode io_mode : {SYNCHRONOUS, ASYNC}) {
728 SCOPED_TRACE(io_mode);
729 host_resolver_.set_synchronous_mode(io_mode == SYNCHRONOUS);
730 StaticSocketDataProvider data;
731 data.set_connect_data(MockConnect(io_mode, ERR_CONNECTION_FAILED));
732 socket_factory_.AddSocketDataProvider(&data);
733
734 TestConnectJobDelegate test_delegate;
735 std::unique_ptr<ConnectJob> ssl_connect_job =
736 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_SOCKS5);
737 test_delegate.StartJobExpectingResult(ssl_connect_job.get(),
738 ERR_PROXY_CONNECTION_FAILED,
739 io_mode == SYNCHRONOUS);
Matt Menke6f84d1f12019-04-11 19:26:47740 EXPECT_FALSE(ssl_connect_job->IsSSLError());
Matt Menke7b5051072019-01-27 21:22:49741
Matt Menke6030ed9f2019-04-11 20:25:55742 ConnectionAttempts connection_attempts =
743 ssl_connect_job->GetConnectionAttempts();
744 EXPECT_EQ(0u, connection_attempts.size());
Matt Menke7b5051072019-01-27 21:22:49745 }
746}
747
dalykedd30d982019-12-16 15:31:10748TEST_F(SSLConnectJobTest, SOCKSHostResolutionFailure) {
749 host_resolver_.rules()->AddSimulatedTimeoutFailure("proxy");
750
751 TestConnectJobDelegate test_delegate;
752 std::unique_ptr<ConnectJob> ssl_connect_job =
753 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_SOCKS5);
754 test_delegate.StartJobExpectingResult(ssl_connect_job.get(),
755 ERR_PROXY_CONNECTION_FAILED,
756 false /* expect_sync_result */);
757 EXPECT_THAT(ssl_connect_job->GetResolveErrorInfo().error,
758 test::IsError(ERR_DNS_TIMED_OUT));
759}
760
Matt Menke7b5051072019-01-27 21:22:49761TEST_F(SSLConnectJobTest, SOCKSBasic) {
762 for (IoMode io_mode : {SYNCHRONOUS, ASYNC}) {
763 SCOPED_TRACE(io_mode);
764 const char kSOCKS5Request[] = {0x05, 0x01, 0x00, 0x03, 0x09, 's',
765 'o', 'c', 'k', 's', 'h', 'o',
766 's', 't', 0x01, 0xBB};
767
768 MockWrite writes[] = {
769 MockWrite(io_mode, kSOCKS5GreetRequest, kSOCKS5GreetRequestLength),
Matt Menke628d624f2019-02-09 00:40:24770 MockWrite(io_mode, kSOCKS5Request, base::size(kSOCKS5Request)),
771 };
Matt Menke7b5051072019-01-27 21:22:49772
773 MockRead reads[] = {
774 MockRead(io_mode, kSOCKS5GreetResponse, kSOCKS5GreetResponseLength),
Matt Menke628d624f2019-02-09 00:40:24775 MockRead(io_mode, kSOCKS5OkResponse, kSOCKS5OkResponseLength),
776 };
Matt Menke7b5051072019-01-27 21:22:49777
778 host_resolver_.set_synchronous_mode(io_mode == SYNCHRONOUS);
779 StaticSocketDataProvider data(reads, writes);
780 data.set_connect_data(MockConnect(io_mode, OK));
781 socket_factory_.AddSocketDataProvider(&data);
782 SSLSocketDataProvider ssl(io_mode, OK);
783 socket_factory_.AddSSLSocketDataProvider(&ssl);
784
785 TestConnectJobDelegate test_delegate;
786 std::unique_ptr<ConnectJob> ssl_connect_job =
787 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_SOCKS5);
788 test_delegate.StartJobExpectingResult(ssl_connect_job.get(), OK,
789 io_mode == SYNCHRONOUS);
790 CheckConnectTimesExceptDnsSet(ssl_connect_job->connect_timing());
Cammie Smith Barnesaa2a8b52020-12-17 19:33:19791
792 // Proxies should not set any DNS aliases.
793 EXPECT_TRUE(test_delegate.socket()->GetDnsAliases().empty());
Matt Menke7b5051072019-01-27 21:22:49794 }
795}
796
Matt Menke628d624f2019-02-09 00:40:24797TEST_F(SSLConnectJobTest, SOCKSHasEstablishedConnection) {
798 const char kSOCKS5Request[] = {0x05, 0x01, 0x00, 0x03, 0x09, 's', 'o', 'c',
799 'k', 's', 'h', 'o', 's', 't', 0x01, 0xBB};
800
801 MockWrite writes[] = {
802 MockWrite(SYNCHRONOUS, kSOCKS5GreetRequest, kSOCKS5GreetRequestLength, 0),
803 MockWrite(SYNCHRONOUS, kSOCKS5Request, base::size(kSOCKS5Request), 3),
804 };
805
806 MockRead reads[] = {
807 // Pause so can probe current state.
808 MockRead(ASYNC, ERR_IO_PENDING, 1),
809 MockRead(ASYNC, kSOCKS5GreetResponse, kSOCKS5GreetResponseLength, 2),
810 MockRead(SYNCHRONOUS, kSOCKS5OkResponse, kSOCKS5OkResponseLength, 4),
811 };
812
813 host_resolver_.set_ondemand_mode(true);
814 SequencedSocketData data(reads, writes);
815 data.set_connect_data(MockConnect(ASYNC, OK));
816 socket_factory_.AddSocketDataProvider(&data);
817
818 // SSL negotiation hangs. Value returned after SSL negotiation is complete
819 // doesn't matter, as HasEstablishedConnection() may only be used between job
820 // start and job complete.
821 SSLSocketDataProvider ssl(SYNCHRONOUS, ERR_IO_PENDING);
822 socket_factory_.AddSSLSocketDataProvider(&ssl);
823
824 TestConnectJobDelegate test_delegate;
825 std::unique_ptr<ConnectJob> ssl_connect_job =
826 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_SOCKS5);
827 EXPECT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
828 EXPECT_TRUE(host_resolver_.has_pending_requests());
829 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, ssl_connect_job->GetLoadState());
830 EXPECT_FALSE(ssl_connect_job->HasEstablishedConnection());
831
832 // DNS resolution completes, and then the ConnectJob tries to connect the
833 // socket, which should succeed asynchronously.
834 host_resolver_.ResolveNow(1);
835 EXPECT_EQ(LOAD_STATE_CONNECTING, ssl_connect_job->GetLoadState());
836 EXPECT_FALSE(ssl_connect_job->HasEstablishedConnection());
837
838 // Spin the message loop until the first read of the handshake.
839 // HasEstablishedConnection() should return true, as a TCP connection has been
840 // successfully established by this point.
841 data.RunUntilPaused();
842 EXPECT_FALSE(test_delegate.has_result());
843 EXPECT_EQ(LOAD_STATE_CONNECTING, ssl_connect_job->GetLoadState());
844 EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
845
846 // Finish up the handshake, and spin the message loop until the SSL handshake
847 // starts and hang.
848 data.Resume();
849 base::RunLoop().RunUntilIdle();
850 EXPECT_FALSE(test_delegate.has_result());
851 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, ssl_connect_job->GetLoadState());
852 EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
853}
854
Matt Menke7b5051072019-01-27 21:22:49855TEST_F(SSLConnectJobTest, SOCKSRequestPriority) {
856 host_resolver_.set_ondemand_mode(true);
Matt Menke7b5051072019-01-27 21:22:49857 for (int initial_priority = MINIMUM_PRIORITY;
858 initial_priority <= MAXIMUM_PRIORITY; ++initial_priority) {
859 SCOPED_TRACE(initial_priority);
860 for (int new_priority = MINIMUM_PRIORITY; new_priority <= MAXIMUM_PRIORITY;
861 ++new_priority) {
862 SCOPED_TRACE(new_priority);
863 if (initial_priority == new_priority)
864 continue;
865 TestConnectJobDelegate test_delegate;
866 std::unique_ptr<ConnectJob> ssl_connect_job =
867 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_SOCKS5,
868 static_cast<RequestPriority>(initial_priority));
869 EXPECT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
870 EXPECT_TRUE(host_resolver_.has_pending_requests());
871 int request_id = host_resolver_.num_resolve();
872 EXPECT_EQ(initial_priority, host_resolver_.request_priority(request_id));
873
874 ssl_connect_job->ChangePriority(
875 static_cast<RequestPriority>(new_priority));
876 EXPECT_EQ(new_priority, host_resolver_.request_priority(request_id));
877
878 ssl_connect_job->ChangePriority(
879 static_cast<RequestPriority>(initial_priority));
880 EXPECT_EQ(initial_priority, host_resolver_.request_priority(request_id));
Matt Menke7b5051072019-01-27 21:22:49881 }
882 }
883}
884
885TEST_F(SSLConnectJobTest, HttpProxyFail) {
886 for (IoMode io_mode : {SYNCHRONOUS, ASYNC}) {
887 SCOPED_TRACE(io_mode);
888 host_resolver_.set_synchronous_mode(io_mode == SYNCHRONOUS);
889 StaticSocketDataProvider data;
890 data.set_connect_data(MockConnect(io_mode, ERR_CONNECTION_FAILED));
891 socket_factory_.AddSocketDataProvider(&data);
892
893 TestConnectJobDelegate test_delegate;
894 std::unique_ptr<ConnectJob> ssl_connect_job =
895 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_HTTP);
896 test_delegate.StartJobExpectingResult(ssl_connect_job.get(),
897 ERR_PROXY_CONNECTION_FAILED,
898 io_mode == SYNCHRONOUS);
899
Matt Menke6f84d1f12019-04-11 19:26:47900 EXPECT_FALSE(ssl_connect_job->IsSSLError());
Matt Menke6030ed9f2019-04-11 20:25:55901 ConnectionAttempts connection_attempts =
902 ssl_connect_job->GetConnectionAttempts();
903 EXPECT_EQ(0u, connection_attempts.size());
Matt Menke7b5051072019-01-27 21:22:49904 }
905}
906
dalykedd30d982019-12-16 15:31:10907TEST_F(SSLConnectJobTest, HttpProxyHostResolutionFailure) {
908 host_resolver_.rules()->AddSimulatedTimeoutFailure("proxy");
909
910 TestConnectJobDelegate test_delegate;
911 std::unique_ptr<ConnectJob> ssl_connect_job =
912 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_HTTP);
913 test_delegate.StartJobExpectingResult(ssl_connect_job.get(),
914 ERR_PROXY_CONNECTION_FAILED,
915 false /* expect_sync_result */);
916 EXPECT_THAT(ssl_connect_job->GetResolveErrorInfo().error,
917 test::IsError(ERR_DNS_TIMED_OUT));
918}
919
Matt Menkeb57663b32019-03-01 17:17:10920TEST_F(SSLConnectJobTest, HttpProxyAuthChallenge) {
921 MockWrite writes[] = {
922 MockWrite(ASYNC, 0,
923 "CONNECT host:80 HTTP/1.1\r\n"
924 "Host: host:80\r\n"
925 "Proxy-Connection: keep-alive\r\n\r\n"),
926 MockWrite(ASYNC, 5,
927 "CONNECT host:80 HTTP/1.1\r\n"
928 "Host: host:80\r\n"
929 "Proxy-Connection: keep-alive\r\n"
930 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
931 };
932 MockRead reads[] = {
933 MockRead(ASYNC, 1, "HTTP/1.1 407 Proxy Authentication Required\r\n"),
934 MockRead(ASYNC, 2, "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
935 MockRead(ASYNC, 3, "Content-Length: 10\r\n\r\n"),
936 MockRead(ASYNC, 4, "0123456789"),
937 MockRead(ASYNC, 6, "HTTP/1.1 200 Connection Established\r\n\r\n"),
938 };
939 StaticSocketDataProvider data(reads, writes);
940 socket_factory_.AddSocketDataProvider(&data);
941 SSLSocketDataProvider ssl(ASYNC, OK);
942 socket_factory_.AddSSLSocketDataProvider(&ssl);
943
Matt Menkeb57663b32019-03-01 17:17:10944 TestConnectJobDelegate test_delegate;
945 std::unique_ptr<ConnectJob> ssl_connect_job =
946 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_HTTP);
947 ASSERT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
948 test_delegate.WaitForAuthChallenge(1);
949
950 EXPECT_EQ(407, test_delegate.auth_response_info().headers->response_code());
951 std::string proxy_authenticate;
952 ASSERT_TRUE(test_delegate.auth_response_info().headers->EnumerateHeader(
953 nullptr, "Proxy-Authenticate", &proxy_authenticate));
954 EXPECT_EQ(proxy_authenticate, "Basic realm=\"MyRealm1\"");
955
956 // While waiting for auth credentials to be provided, the Job should not time
957 // out.
958 FastForwardBy(base::TimeDelta::FromDays(1));
959 test_delegate.WaitForAuthChallenge(1);
960 EXPECT_FALSE(test_delegate.has_result());
961
962 // Respond to challenge.
Jan Wilken Dörriec92a6d7242021-03-23 17:43:48963 test_delegate.auth_controller()->ResetAuth(AuthCredentials(u"foo", u"bar"));
Matt Menkeb57663b32019-03-01 17:17:10964 test_delegate.RunAuthCallback();
965
966 EXPECT_THAT(test_delegate.WaitForResult(), test::IsOk());
Cammie Smith Barnesaa2a8b52020-12-17 19:33:19967
968 // Proxies should not set any DNS aliases.
969 EXPECT_TRUE(test_delegate.socket()->GetDnsAliases().empty());
Matt Menkeb57663b32019-03-01 17:17:10970}
971
972TEST_F(SSLConnectJobTest, HttpProxyAuthWithCachedCredentials) {
Matt Menke7b5051072019-01-27 21:22:49973 for (IoMode io_mode : {SYNCHRONOUS, ASYNC}) {
974 SCOPED_TRACE(io_mode);
975 host_resolver_.set_synchronous_mode(io_mode == SYNCHRONOUS);
976 MockWrite writes[] = {
977 MockWrite(io_mode,
978 "CONNECT host:80 HTTP/1.1\r\n"
979 "Host: host:80\r\n"
980 "Proxy-Connection: keep-alive\r\n"
981 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
982 };
983 MockRead reads[] = {
984 MockRead(io_mode, "HTTP/1.1 200 Connection Established\r\n\r\n"),
985 };
986 StaticSocketDataProvider data(reads, writes);
987 data.set_connect_data(MockConnect(io_mode, OK));
988 socket_factory_.AddSocketDataProvider(&data);
989 AddAuthToCache();
990 SSLSocketDataProvider ssl(io_mode, OK);
991 socket_factory_.AddSSLSocketDataProvider(&ssl);
992
993 TestConnectJobDelegate test_delegate;
994 std::unique_ptr<ConnectJob> ssl_connect_job =
995 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_HTTP);
996 test_delegate.StartJobExpectingResult(ssl_connect_job.get(), OK,
997 io_mode == SYNCHRONOUS);
998 CheckConnectTimesExceptDnsSet(ssl_connect_job->connect_timing());
Cammie Smith Barnesaa2a8b52020-12-17 19:33:19999 EXPECT_TRUE(test_delegate.socket()->GetDnsAliases().empty());
Matt Menke7b5051072019-01-27 21:22:491000 }
1001}
1002
1003TEST_F(SSLConnectJobTest, HttpProxyRequestPriority) {
1004 host_resolver_.set_ondemand_mode(true);
Matt Menke7b5051072019-01-27 21:22:491005 for (int initial_priority = MINIMUM_PRIORITY;
1006 initial_priority <= MAXIMUM_PRIORITY; ++initial_priority) {
1007 SCOPED_TRACE(initial_priority);
1008 for (int new_priority = MINIMUM_PRIORITY; new_priority <= MAXIMUM_PRIORITY;
1009 ++new_priority) {
1010 SCOPED_TRACE(new_priority);
1011 if (initial_priority == new_priority)
1012 continue;
1013 TestConnectJobDelegate test_delegate;
1014 std::unique_ptr<ConnectJob> ssl_connect_job =
1015 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_HTTP,
1016 static_cast<RequestPriority>(initial_priority));
1017 EXPECT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
1018 EXPECT_TRUE(host_resolver_.has_pending_requests());
1019 int request_id = host_resolver_.num_resolve();
1020 EXPECT_EQ(initial_priority, host_resolver_.request_priority(request_id));
1021
1022 ssl_connect_job->ChangePriority(
1023 static_cast<RequestPriority>(new_priority));
1024 EXPECT_EQ(new_priority, host_resolver_.request_priority(request_id));
1025
1026 ssl_connect_job->ChangePriority(
1027 static_cast<RequestPriority>(initial_priority));
1028 EXPECT_EQ(initial_priority, host_resolver_.request_priority(request_id));
Matt Menke7b5051072019-01-27 21:22:491029 }
1030 }
1031}
1032
Matt Menkeaade5812019-03-02 13:38:001033TEST_F(SSLConnectJobTest, HttpProxyAuthHasEstablishedConnection) {
1034 host_resolver_.set_ondemand_mode(true);
1035 MockWrite writes[] = {
1036 MockWrite(ASYNC, 0,
1037 "CONNECT host:80 HTTP/1.1\r\n"
1038 "Host: host:80\r\n"
1039 "Proxy-Connection: keep-alive\r\n\r\n"),
1040 MockWrite(ASYNC, 3,
1041 "CONNECT host:80 HTTP/1.1\r\n"
1042 "Host: host:80\r\n"
1043 "Proxy-Connection: keep-alive\r\n"
1044 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
1045 };
1046 MockRead reads[] = {
1047 // Pause reading.
1048 MockRead(ASYNC, ERR_IO_PENDING, 1),
1049 MockRead(ASYNC, 2,
1050 "HTTP/1.1 407 Proxy Authentication Required\r\n"
1051 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
1052 "Content-Length: 0\r\n\r\n"),
1053 // Pause reading.
1054 MockRead(ASYNC, ERR_IO_PENDING, 4),
1055 MockRead(ASYNC, 5, "HTTP/1.1 200 Connection Established\r\n\r\n"),
1056 };
1057 SequencedSocketData data(reads, writes);
1058 socket_factory_.AddSocketDataProvider(&data);
1059 SSLSocketDataProvider ssl(ASYNC, OK);
1060 socket_factory_.AddSSLSocketDataProvider(&ssl);
1061
Matt Menkeaade5812019-03-02 13:38:001062 TestConnectJobDelegate test_delegate;
1063 std::unique_ptr<ConnectJob> ssl_connect_job =
1064 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_HTTP);
1065 ASSERT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
1066 EXPECT_TRUE(host_resolver_.has_pending_requests());
1067 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, ssl_connect_job->GetLoadState());
1068 EXPECT_FALSE(ssl_connect_job->HasEstablishedConnection());
1069
1070 // DNS resolution completes, and then the ConnectJob tries to connect the
1071 // socket, which should succeed asynchronously.
1072 host_resolver_.ResolveOnlyRequestNow();
1073 EXPECT_EQ(LOAD_STATE_CONNECTING, ssl_connect_job->GetLoadState());
1074 EXPECT_FALSE(ssl_connect_job->HasEstablishedConnection());
1075
1076 // Spinning the message loop causes the connection to be established and the
1077 // nested HttpProxyConnectJob to start establishing a tunnel.
1078 base::RunLoop().RunUntilIdle();
1079 EXPECT_FALSE(test_delegate.has_result());
1080 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
1081 ssl_connect_job->GetLoadState());
1082 EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
1083
1084 // Receive the auth challenge.
1085 data.Resume();
1086 test_delegate.WaitForAuthChallenge(1);
1087 EXPECT_FALSE(test_delegate.has_result());
1088 EXPECT_EQ(LOAD_STATE_IDLE, ssl_connect_job->GetLoadState());
1089 EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
1090
1091 // Respond to challenge.
Jan Wilken Dörriec92a6d7242021-03-23 17:43:481092 test_delegate.auth_controller()->ResetAuth(AuthCredentials(u"foo", u"bar"));
Matt Menkeaade5812019-03-02 13:38:001093 test_delegate.RunAuthCallback();
1094 EXPECT_FALSE(test_delegate.has_result());
1095 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
1096 ssl_connect_job->GetLoadState());
1097 EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
1098
1099 // Run until the next read pauses.
1100 base::RunLoop().RunUntilIdle();
1101 EXPECT_FALSE(test_delegate.has_result());
1102 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
1103 ssl_connect_job->GetLoadState());
1104 EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
1105
1106 // Receive the connection established response, at which point SSL negotiation
1107 // finally starts.
1108 data.Resume();
1109 EXPECT_FALSE(test_delegate.has_result());
1110 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, ssl_connect_job->GetLoadState());
1111 EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
1112
1113 EXPECT_THAT(test_delegate.WaitForResult(), test::IsOk());
1114}
1115
1116TEST_F(SSLConnectJobTest,
1117 HttpProxyAuthHasEstablishedConnectionWithProxyConnectionClose) {
1118 host_resolver_.set_ondemand_mode(true);
1119 MockWrite writes1[] = {
1120 MockWrite(ASYNC, 0,
1121 "CONNECT host:80 HTTP/1.1\r\n"
1122 "Host: host:80\r\n"
1123 "Proxy-Connection: keep-alive\r\n\r\n"),
1124 };
1125 MockRead reads1[] = {
1126 // Pause reading.
1127 MockRead(ASYNC, ERR_IO_PENDING, 1),
1128 MockRead(ASYNC, 2,
1129 "HTTP/1.1 407 Proxy Authentication Required\r\n"
1130 "Proxy-Connection: Close\r\n"
1131 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
1132 "Content-Length: 0\r\n\r\n"),
1133 };
1134 SequencedSocketData data1(reads1, writes1);
1135 socket_factory_.AddSocketDataProvider(&data1);
1136
1137 MockWrite writes2[] = {
1138 MockWrite(ASYNC, 0,
1139 "CONNECT host:80 HTTP/1.1\r\n"
1140 "Host: host:80\r\n"
1141 "Proxy-Connection: keep-alive\r\n"
1142 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
1143 };
1144 MockRead reads2[] = {
1145 // Pause reading.
1146 MockRead(ASYNC, ERR_IO_PENDING, 1),
1147 MockRead(ASYNC, 2, "HTTP/1.1 200 Connection Established\r\n\r\n"),
1148 };
1149 SequencedSocketData data2(reads2, writes2);
1150 socket_factory_.AddSocketDataProvider(&data2);
1151 SSLSocketDataProvider ssl(ASYNC, OK);
1152 socket_factory_.AddSSLSocketDataProvider(&ssl);
1153
Matt Menkeaade5812019-03-02 13:38:001154 TestConnectJobDelegate test_delegate;
1155 std::unique_ptr<ConnectJob> ssl_connect_job =
1156 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_HTTP);
1157 ASSERT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
1158 EXPECT_TRUE(host_resolver_.has_pending_requests());
1159 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, ssl_connect_job->GetLoadState());
1160 EXPECT_FALSE(ssl_connect_job->HasEstablishedConnection());
1161
1162 // DNS resolution completes, and then the ConnectJob tries to connect the
1163 // socket, which should succeed asynchronously.
1164 host_resolver_.ResolveOnlyRequestNow();
1165 EXPECT_EQ(LOAD_STATE_CONNECTING, ssl_connect_job->GetLoadState());
1166 EXPECT_FALSE(ssl_connect_job->HasEstablishedConnection());
1167
1168 // Spinning the message loop causes the connection to be established and the
1169 // nested HttpProxyConnectJob to start establishing a tunnel.
1170 base::RunLoop().RunUntilIdle();
1171 EXPECT_FALSE(test_delegate.has_result());
1172 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
1173 ssl_connect_job->GetLoadState());
1174 EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
1175
1176 // Receive the auth challenge.
1177 data1.Resume();
1178 test_delegate.WaitForAuthChallenge(1);
1179 EXPECT_FALSE(test_delegate.has_result());
1180 EXPECT_EQ(LOAD_STATE_IDLE, ssl_connect_job->GetLoadState());
1181 EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
1182
1183 // Respond to challenge.
Jan Wilken Dörriec92a6d7242021-03-23 17:43:481184 test_delegate.auth_controller()->ResetAuth(AuthCredentials(u"foo", u"bar"));
Matt Menkeaade5812019-03-02 13:38:001185 test_delegate.RunAuthCallback();
1186 EXPECT_FALSE(test_delegate.has_result());
1187 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
1188 ssl_connect_job->GetLoadState());
1189 EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
1190
1191 // Run until the next DNS lookup.
1192 base::RunLoop().RunUntilIdle();
1193 EXPECT_TRUE(host_resolver_.has_pending_requests());
1194 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, ssl_connect_job->GetLoadState());
1195 EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
1196
1197 // DNS resolution completes, and then the ConnectJob tries to connect the
1198 // socket, which should succeed asynchronously.
1199 host_resolver_.ResolveOnlyRequestNow();
1200 EXPECT_EQ(LOAD_STATE_CONNECTING, ssl_connect_job->GetLoadState());
1201 EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
1202
1203 // Spinning the message loop causes the connection to be established and the
1204 // nested HttpProxyConnectJob to start establishing a tunnel.
1205 base::RunLoop().RunUntilIdle();
1206 EXPECT_FALSE(test_delegate.has_result());
1207 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
1208 ssl_connect_job->GetLoadState());
1209 EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
1210
1211 // Receive the connection established response, at which point SSL negotiation
1212 // finally starts.
1213 data2.Resume();
1214 EXPECT_FALSE(test_delegate.has_result());
1215 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, ssl_connect_job->GetLoadState());
1216 EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
1217
1218 EXPECT_THAT(test_delegate.WaitForResult(), test::IsOk());
1219}
1220
Cammie Smith Barnesaa2a8b52020-12-17 19:33:191221TEST_F(SSLConnectJobTest, DnsAliases) {
1222 host_resolver_.set_synchronous_mode(true);
1223
1224 // Resolve an AddressList with DNS aliases.
1225 std::vector<std::string> aliases({"alias1", "alias2", "host"});
1226 host_resolver_.rules()->AddIPLiteralRuleWithDnsAliases("host", "2.2.2.2",
1227 std::move(aliases));
1228 StaticSocketDataProvider data;
1229 data.set_connect_data(MockConnect(SYNCHRONOUS, OK));
1230 socket_factory_.AddSocketDataProvider(&data);
1231 SSLSocketDataProvider ssl(ASYNC, OK);
1232 socket_factory_.AddSSLSocketDataProvider(&ssl);
1233 TestConnectJobDelegate test_delegate;
1234
1235 std::unique_ptr<ConnectJob> ssl_connect_job =
1236 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_DIRECT, MEDIUM);
1237
1238 EXPECT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
1239
1240 base::RunLoop().RunUntilIdle();
1241
1242 // Verify that the elements of the alias list are those from the
1243 // parameter vector.
1244 EXPECT_THAT(test_delegate.socket()->GetDnsAliases(),
1245 testing::ElementsAre("alias1", "alias2", "host"));
1246}
1247
1248TEST_F(SSLConnectJobTest, NoAdditionalDnsAliases) {
1249 host_resolver_.set_synchronous_mode(true);
1250
1251 // Resolve an AddressList without additional DNS aliases. (The parameter
1252 // is an empty vector.)
1253 std::vector<std::string> aliases;
1254 host_resolver_.rules()->AddIPLiteralRuleWithDnsAliases("host", "2.2.2.2",
1255 std::move(aliases));
1256 StaticSocketDataProvider data;
1257 data.set_connect_data(MockConnect(SYNCHRONOUS, OK));
1258 socket_factory_.AddSocketDataProvider(&data);
1259 SSLSocketDataProvider ssl(ASYNC, OK);
1260 socket_factory_.AddSSLSocketDataProvider(&ssl);
1261 TestConnectJobDelegate test_delegate;
1262
1263 std::unique_ptr<ConnectJob> ssl_connect_job =
1264 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_DIRECT, MEDIUM);
1265
1266 EXPECT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
1267
1268 base::RunLoop().RunUntilIdle();
1269
1270 // Verify that the alias list only contains "host".
1271 EXPECT_THAT(test_delegate.socket()->GetDnsAliases(),
1272 testing::ElementsAre("host"));
1273}
1274
Matt Menke7b5051072019-01-27 21:22:491275} // namespace
1276} // namespace net