blob: 6b908b3aa2d0cb25854b5ff2dca604ff17654d4c [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"
Matt Menke7b5051072019-01-27 21:22:4912#include "base/strings/string_util.h"
13#include "base/strings/utf_string_conversions.h"
David Benjamin07a07d652020-02-26 22:26:5914#include "base/test/metrics/histogram_tester.h"
15#include "base/test/scoped_feature_list.h"
Gabriel Charettec7108742019-08-23 03:31:4016#include "base/test/task_environment.h"
Matt Menke7b5051072019-01-27 21:22:4917#include "base/time/time.h"
18#include "net/base/auth.h"
David Benjamin07a07d652020-02-26 22:26:5919#include "net/base/features.h"
Matt Menke7b5051072019-01-27 21:22:4920#include "net/base/load_timing_info.h"
21#include "net/base/net_errors.h"
Matt Menkeae58eeb2019-05-24 21:09:5022#include "net/base/network_isolation_key.h"
Matt Menke7b5051072019-01-27 21:22:4923#include "net/cert/ct_policy_enforcer.h"
24#include "net/cert/mock_cert_verifier.h"
Matt Menke7b5051072019-01-27 21:22:4925#include "net/dns/mock_host_resolver.h"
Ben Schwartz3ff4dc1e62021-04-27 21:15:2326#include "net/dns/public/secure_dns_policy.h"
Matt Menke7b5051072019-01-27 21:22:4927#include "net/http/http_auth_handler_factory.h"
28#include "net/http/http_network_session.h"
Matt Menke0754b5d02019-02-10 21:46:4329#include "net/http/http_proxy_connect_job.h"
Matt Menke7b5051072019-01-27 21:22:4930#include "net/http/http_request_headers.h"
31#include "net/http/http_response_headers.h"
Matt Menke609160742019-08-02 18:47:2632#include "net/http/http_server_properties.h"
Matt Menke7b5051072019-01-27 21:22:4933#include "net/http/transport_security_state.h"
34#include "net/log/net_log_source.h"
35#include "net/log/net_log_with_source.h"
Nicolas Arciniegad2013f92020-02-07 23:00:5636#include "net/proxy_resolution/configured_proxy_resolution_service.h"
Victor Vasiliev7752898d2019-11-14 21:30:2237#include "net/quic/quic_context.h"
Matt Menke7b5051072019-01-27 21:22:4938#include "net/socket/connect_job_test_util.h"
Matt Menke6030ed9f2019-04-11 20:25:5539#include "net/socket/connection_attempts.h"
Matt Menke7b5051072019-01-27 21:22:4940#include "net/socket/next_proto.h"
41#include "net/socket/socket_tag.h"
42#include "net/socket/socket_test_util.h"
43#include "net/socket/socks_connect_job.h"
Matt Menke7b5051072019-01-27 21:22:4944#include "net/socket/transport_connect_job.h"
45#include "net/ssl/ssl_config_service_defaults.h"
David Benjamin07a07d652020-02-26 22:26:5946#include "net/ssl/ssl_connection_status_flags.h"
47#include "net/ssl/ssl_legacy_crypto_fallback.h"
48#include "net/test/cert_test_util.h"
Matt Menke7b5051072019-01-27 21:22:4949#include "net/test/gtest_util.h"
50#include "net/test/test_certificate_data.h"
David Benjamin07a07d652020-02-26 22:26:5951#include "net/test/test_data_directory.h"
Gabriel Charettec7108742019-08-23 03:31:4052#include "net/test/test_with_task_environment.h"
Matt Menke7b5051072019-01-27 21:22:4953#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
54#include "testing/gtest/include/gtest/gtest.h"
David Benjamin07a07d652020-02-26 22:26:5955#include "third_party/boringssl/src/include/openssl/ssl.h"
Matt Menke8db2ff52021-11-23 20:17:4656#include "url/gurl.h"
Eric Orthc98a3e62021-07-02 17:46:3757#include "url/scheme_host_port.h"
58#include "url/url_constants.h"
Matt Menke7b5051072019-01-27 21:22:4959
60namespace net {
61namespace {
62
Matt Menke7b5051072019-01-27 21:22:4963// Just check that all connect times are set to base::TimeTicks::Now(), for
64// tests that don't update the mocked out time.
65void CheckConnectTimesSet(const LoadTimingInfo::ConnectTiming& connect_timing) {
66 EXPECT_EQ(base::TimeTicks::Now(), connect_timing.dns_start);
67 EXPECT_EQ(base::TimeTicks::Now(), connect_timing.dns_end);
68 EXPECT_EQ(base::TimeTicks::Now(), connect_timing.connect_start);
69 EXPECT_EQ(base::TimeTicks::Now(), connect_timing.ssl_start);
70 EXPECT_EQ(base::TimeTicks::Now(), connect_timing.ssl_end);
71 EXPECT_EQ(base::TimeTicks::Now(), connect_timing.connect_end);
72}
73
74// Just check that all connect times are set to base::TimeTicks::Now(), except
75// for DNS times, for tests that don't update the mocked out time and use a
76// proxy.
77void CheckConnectTimesExceptDnsSet(
78 const LoadTimingInfo::ConnectTiming& connect_timing) {
79 EXPECT_TRUE(connect_timing.dns_start.is_null());
80 EXPECT_TRUE(connect_timing.dns_end.is_null());
81 EXPECT_EQ(base::TimeTicks::Now(), connect_timing.connect_start);
82 EXPECT_EQ(base::TimeTicks::Now(), connect_timing.ssl_start);
83 EXPECT_EQ(base::TimeTicks::Now(), connect_timing.ssl_end);
84 EXPECT_EQ(base::TimeTicks::Now(), connect_timing.connect_end);
85}
86
Gabriel Charette694c3c332019-08-19 14:53:0587class SSLConnectJobTest : public WithTaskEnvironment, public testing::Test {
Matt Menke7b5051072019-01-27 21:22:4988 public:
89 SSLConnectJobTest()
Gabriel Charette694c3c332019-08-19 14:53:0590 : WithTaskEnvironment(base::test::TaskEnvironment::TimeSource::MOCK_TIME),
Nicolas Arciniegad2013f92020-02-07 23:00:5691 proxy_resolution_service_(
92 ConfiguredProxyResolutionService::CreateDirect()),
Matt Menke7b5051072019-01-27 21:22:4993 ssl_config_service_(new SSLConfigServiceDefaults),
Eric Orthbe2efac2019-03-06 01:11:1194 http_auth_handler_factory_(HttpAuthHandlerFactory::CreateDefault()),
Matt Menke7b5051072019-01-27 21:22:4995 session_(CreateNetworkSession()),
Eric Orthc98a3e62021-07-02 17:46:3796 direct_transport_socket_params_(new TransportSocketParams(
97 url::SchemeHostPort(url::kHttpsScheme, "host", 443),
98 NetworkIsolationKey(),
99 SecureDnsPolicy::kAllow,
David Benjamin13072a42022-02-10 22:23:21100 OnHostResolutionCallback(),
101 /*supported_alpns=*/{"h2", "http/1.1"})),
Matt Menke7b5051072019-01-27 21:22:49102 proxy_transport_socket_params_(
103 new TransportSocketParams(HostPortPair("proxy", 443),
Matt Menkecd439232019-11-05 15:15:33104 NetworkIsolationKey(),
Ben Schwartz3ff4dc1e62021-04-27 21:15:23105 SecureDnsPolicy::kAllow,
David Benjamin13072a42022-02-10 22:23:21106 OnHostResolutionCallback(),
107 /*supported_alpns=*/{})),
Matt Menke7b5051072019-01-27 21:22:49108 socks_socket_params_(
109 new SOCKSSocketParams(proxy_transport_socket_params_,
110 true,
111 HostPortPair("sockshost", 443),
Matt Menke166710e2019-11-06 03:35:51112 NetworkIsolationKey(),
Matt Menke7b5051072019-01-27 21:22:49113 TRAFFIC_ANNOTATION_FOR_TESTS)),
114 http_proxy_socket_params_(
115 new HttpProxySocketParams(proxy_transport_socket_params_,
116 nullptr /* ssl_params */,
Matt Menkeb5fb42b2019-03-22 17:26:13117 false /* is_quic */,
Matt Menke7b5051072019-01-27 21:22:49118 HostPortPair("host", 80),
Matt Menke7b5051072019-01-27 21:22:49119 /*tunnel=*/true,
Matt Menkeae58eeb2019-05-24 21:09:50120 TRAFFIC_ANNOTATION_FOR_TESTS,
121 NetworkIsolationKey())),
Gabriel Charette694c3c332019-08-19 14:53:05122 common_connect_job_params_(session_->CreateCommonConnectJobParams()) {}
Matt Menke7b5051072019-01-27 21:22:49123
124 ~SSLConnectJobTest() override = default;
125
126 std::unique_ptr<ConnectJob> CreateConnectJob(
127 TestConnectJobDelegate* test_delegate,
128 ProxyServer::Scheme proxy_scheme = ProxyServer::SCHEME_DIRECT,
129 RequestPriority priority = DEFAULT_PRIORITY) {
130 return std::make_unique<SSLConnectJob>(
Matt Menkea6f99ad2019-03-08 02:26:43131 priority, SocketTag(), &common_connect_job_params_,
Matt Menke14819512019-03-02 16:59:58132 SSLParams(proxy_scheme), test_delegate, nullptr /* net_log */);
Matt Menke7b5051072019-01-27 21:22:49133 }
134
135 scoped_refptr<SSLSocketParams> SSLParams(ProxyServer::Scheme proxy) {
136 return base::MakeRefCounted<SSLSocketParams>(
137 proxy == ProxyServer::SCHEME_DIRECT ? direct_transport_socket_params_
138 : nullptr,
139 proxy == ProxyServer::SCHEME_SOCKS5 ? socks_socket_params_ : nullptr,
140 proxy == ProxyServer::SCHEME_HTTP ? http_proxy_socket_params_ : nullptr,
David Benjamin151ec6b2019-08-02 19:38:52141 HostPortPair("host", 443), SSLConfig(), PRIVACY_MODE_DISABLED,
David Benjamin6f2da652019-06-26 23:36:35142 NetworkIsolationKey());
Matt Menke7b5051072019-01-27 21:22:49143 }
144
145 void AddAuthToCache() {
Jan Wilken Dörriec92a6d7242021-03-23 17:43:48146 const std::u16string kFoo(u"foo");
147 const std::u16string kBar(u"bar");
Matt Menke7b5051072019-01-27 21:22:49148 session_->http_auth_cache()->Add(
Matt Menke8db2ff52021-11-23 20:17:46149 url::SchemeHostPort(GURL("http://proxy:443/")), HttpAuth::AUTH_PROXY,
150 "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC, NetworkIsolationKey(),
Matt Menkebe090422019-10-18 20:25:26151 "Basic realm=MyRealm1", AuthCredentials(kFoo, kBar), "/");
Matt Menke7b5051072019-01-27 21:22:49152 }
153
154 HttpNetworkSession* CreateNetworkSession() {
Matt Menke30a878c2021-07-20 22:25:09155 HttpNetworkSessionContext session_context;
Matt Menke7b5051072019-01-27 21:22:49156 session_context.host_resolver = &host_resolver_;
157 session_context.cert_verifier = &cert_verifier_;
158 session_context.transport_security_state = &transport_security_state_;
Matt Menke7b5051072019-01-27 21:22:49159 session_context.ct_policy_enforcer = &ct_policy_enforcer_;
160 session_context.proxy_resolution_service = proxy_resolution_service_.get();
161 session_context.client_socket_factory = &socket_factory_;
162 session_context.ssl_config_service = ssl_config_service_.get();
163 session_context.http_auth_handler_factory =
164 http_auth_handler_factory_.get();
165 session_context.http_server_properties = &http_server_properties_;
Victor Vasiliev7752898d2019-11-14 21:30:22166 session_context.quic_context = &quic_context_;
Matt Menke30a878c2021-07-20 22:25:09167 return new HttpNetworkSession(HttpNetworkSessionParams(), session_context);
Matt Menke7b5051072019-01-27 21:22:49168 }
169
170 protected:
171 MockClientSocketFactory socket_factory_;
Eric Orthbe86fee2021-10-28 22:31:11172 MockHostResolver host_resolver_{/*default_result=*/MockHostResolverBase::
173 RuleResolver::GetLocalhostResult()};
Matt Menke7b5051072019-01-27 21:22:49174 MockCertVerifier cert_verifier_;
175 TransportSecurityState transport_security_state_;
Matt Menke7b5051072019-01-27 21:22:49176 DefaultCTPolicyEnforcer ct_policy_enforcer_;
Nicolas Arciniega8ec5bfa2020-03-20 05:07:26177 const std::unique_ptr<ProxyResolutionService> proxy_resolution_service_;
Matt Menke7b5051072019-01-27 21:22:49178 const std::unique_ptr<SSLConfigService> ssl_config_service_;
179 const std::unique_ptr<HttpAuthHandlerFactory> http_auth_handler_factory_;
Matt Menke609160742019-08-02 18:47:26180 HttpServerProperties http_server_properties_;
Victor Vasiliev7752898d2019-11-14 21:30:22181 QuicContext quic_context_;
Matt Menke7b5051072019-01-27 21:22:49182 const std::unique_ptr<HttpNetworkSession> session_;
Matt Menke7b5051072019-01-27 21:22:49183
184 scoped_refptr<TransportSocketParams> direct_transport_socket_params_;
Matt Menke7b5051072019-01-27 21:22:49185
186 scoped_refptr<TransportSocketParams> proxy_transport_socket_params_;
187 scoped_refptr<SOCKSSocketParams> socks_socket_params_;
188 scoped_refptr<HttpProxySocketParams> http_proxy_socket_params_;
189
Matt Menkea6f99ad2019-03-08 02:26:43190 const CommonConnectJobParams common_connect_job_params_;
Matt Menke7b5051072019-01-27 21:22:49191};
192
193TEST_F(SSLConnectJobTest, TCPFail) {
194 for (IoMode io_mode : {SYNCHRONOUS, ASYNC}) {
195 SCOPED_TRACE(io_mode);
196 host_resolver_.set_synchronous_mode(io_mode == SYNCHRONOUS);
197 StaticSocketDataProvider data;
198 data.set_connect_data(MockConnect(io_mode, ERR_CONNECTION_FAILED));
199 socket_factory_.AddSocketDataProvider(&data);
200
201 TestConnectJobDelegate test_delegate;
202 std::unique_ptr<ConnectJob> ssl_connect_job =
203 CreateConnectJob(&test_delegate);
204 test_delegate.StartJobExpectingResult(
205 ssl_connect_job.get(), ERR_CONNECTION_FAILED, io_mode == SYNCHRONOUS);
206 EXPECT_FALSE(test_delegate.socket());
Matt Menke6f84d1f12019-04-11 19:26:47207 EXPECT_FALSE(ssl_connect_job->IsSSLError());
Matt Menke6030ed9f2019-04-11 20:25:55208 ConnectionAttempts connection_attempts =
209 ssl_connect_job->GetConnectionAttempts();
210 ASSERT_EQ(1u, connection_attempts.size());
211 EXPECT_THAT(connection_attempts[0].result,
Matt Menke7b5051072019-01-27 21:22:49212 test::IsError(ERR_CONNECTION_FAILED));
213 }
214}
215
Matt Menke36eaf5c2019-04-02 16:15:52216TEST_F(SSLConnectJobTest, TCPTimeout) {
Peter Kastinge5a38ed2021-10-02 03:06:35217 const base::TimeDelta kTinyTime = base::Microseconds(1);
Matt Menke36eaf5c2019-04-02 16:15:52218
219 // Make request hang.
220 host_resolver_.set_ondemand_mode(true);
221
222 TestConnectJobDelegate test_delegate;
223 std::unique_ptr<ConnectJob> ssl_connect_job =
224 CreateConnectJob(&test_delegate);
225 ASSERT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
226
227 // Right up until just before the TCP connection timeout, the job does not
228 // time out.
229 FastForwardBy(TransportConnectJob::ConnectionTimeout() - kTinyTime);
230 EXPECT_FALSE(test_delegate.has_result());
231
232 // But at the exact time of TCP connection timeout, the job fails.
233 FastForwardBy(kTinyTime);
234 EXPECT_TRUE(test_delegate.has_result());
235 EXPECT_THAT(test_delegate.WaitForResult(), test::IsError(ERR_TIMED_OUT));
236}
237
238TEST_F(SSLConnectJobTest, SSLTimeoutSyncConnect) {
Peter Kastinge5a38ed2021-10-02 03:06:35239 const base::TimeDelta kTinyTime = base::Microseconds(1);
Matt Menke36eaf5c2019-04-02 16:15:52240
241 // DNS lookup and transport connect complete synchronously, but SSL
242 // negotiation hangs.
243 host_resolver_.set_synchronous_mode(true);
244 StaticSocketDataProvider data;
245 data.set_connect_data(MockConnect(SYNCHRONOUS, OK));
246 socket_factory_.AddSocketDataProvider(&data);
247 SSLSocketDataProvider ssl(SYNCHRONOUS, ERR_IO_PENDING);
248 socket_factory_.AddSSLSocketDataProvider(&ssl);
249
250 // Make request hang.
251 TestConnectJobDelegate test_delegate;
252 std::unique_ptr<ConnectJob> ssl_connect_job =
253 CreateConnectJob(&test_delegate);
254 ASSERT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
255
256 // Right up until just before the SSL handshake timeout, the job does not time
257 // out.
258 FastForwardBy(SSLConnectJob::HandshakeTimeoutForTesting() - kTinyTime);
259 EXPECT_FALSE(test_delegate.has_result());
260
261 // But at the exact SSL handshake timeout time, the job fails.
262 FastForwardBy(kTinyTime);
263 EXPECT_TRUE(test_delegate.has_result());
264 EXPECT_THAT(test_delegate.WaitForResult(), test::IsError(ERR_TIMED_OUT));
265}
266
267TEST_F(SSLConnectJobTest, SSLTimeoutAsyncTcpConnect) {
Peter Kastinge5a38ed2021-10-02 03:06:35268 const base::TimeDelta kTinyTime = base::Microseconds(1);
Matt Menke36eaf5c2019-04-02 16:15:52269
270 // DNS lookup is asynchronous, and later SSL negotiation hangs.
271 host_resolver_.set_ondemand_mode(true);
272 StaticSocketDataProvider data;
273 data.set_connect_data(MockConnect(SYNCHRONOUS, OK));
274 socket_factory_.AddSocketDataProvider(&data);
275 SSLSocketDataProvider ssl(SYNCHRONOUS, ERR_IO_PENDING);
276 socket_factory_.AddSSLSocketDataProvider(&ssl);
277
278 TestConnectJobDelegate test_delegate;
279 std::unique_ptr<ConnectJob> ssl_connect_job =
280 CreateConnectJob(&test_delegate);
281 // Connecting should hand on the TransportConnectJob connect.
282 ASSERT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
283
284 // Right up until just before the TCP connection timeout, the job does not
285 // time out.
286 FastForwardBy(TransportConnectJob::ConnectionTimeout() - kTinyTime);
287 EXPECT_FALSE(test_delegate.has_result());
288
289 // The DNS lookup completes, and a TCP connection is immediately establshed,
290 // which cancels the TCP connection timer. The SSL handshake timer is started,
291 // and the SSL handshake hangs.
292 host_resolver_.ResolveOnlyRequestNow();
293 EXPECT_FALSE(test_delegate.has_result());
294
295 // Right up until just before the SSL handshake timeout, the job does not time
296 // out.
297 FastForwardBy(SSLConnectJob::HandshakeTimeoutForTesting() - kTinyTime);
298 EXPECT_FALSE(test_delegate.has_result());
299
300 // But at the exact SSL handshake timeout time, the job fails.
301 FastForwardBy(kTinyTime);
302 EXPECT_TRUE(test_delegate.has_result());
303 EXPECT_THAT(test_delegate.WaitForResult(), test::IsError(ERR_TIMED_OUT));
304}
305
Matt Menke7b5051072019-01-27 21:22:49306TEST_F(SSLConnectJobTest, BasicDirectSync) {
307 host_resolver_.set_synchronous_mode(true);
308 StaticSocketDataProvider data;
309 data.set_connect_data(MockConnect(SYNCHRONOUS, OK));
310 socket_factory_.AddSocketDataProvider(&data);
311 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
312 socket_factory_.AddSSLSocketDataProvider(&ssl);
313
314 TestConnectJobDelegate test_delegate;
315 std::unique_ptr<ConnectJob> ssl_connect_job =
316 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_DIRECT, MEDIUM);
317
318 test_delegate.StartJobExpectingResult(ssl_connect_job.get(), OK,
319 true /* expect_sync_result */);
320 EXPECT_EQ(MEDIUM, host_resolver_.last_request_priority());
321
Matt Menke6030ed9f2019-04-11 20:25:55322 ConnectionAttempts connection_attempts =
323 ssl_connect_job->GetConnectionAttempts();
324 EXPECT_EQ(0u, connection_attempts.size());
Matt Menke7b5051072019-01-27 21:22:49325 CheckConnectTimesSet(ssl_connect_job->connect_timing());
326}
327
328TEST_F(SSLConnectJobTest, BasicDirectAsync) {
329 host_resolver_.set_ondemand_mode(true);
330 base::TimeTicks start_time = base::TimeTicks::Now();
331 StaticSocketDataProvider data;
332 data.set_connect_data(MockConnect(ASYNC, OK));
333 socket_factory_.AddSocketDataProvider(&data);
334 SSLSocketDataProvider ssl(ASYNC, OK);
335 socket_factory_.AddSSLSocketDataProvider(&ssl);
336
337 TestConnectJobDelegate test_delegate;
338 std::unique_ptr<ConnectJob> ssl_connect_job =
339 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_DIRECT, MEDIUM);
340 EXPECT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
341 EXPECT_TRUE(host_resolver_.has_pending_requests());
342 EXPECT_EQ(MEDIUM, host_resolver_.last_request_priority());
Peter Kastinge5a38ed2021-10-02 03:06:35343 FastForwardBy(base::Seconds(5));
Matt Menke7b5051072019-01-27 21:22:49344
345 base::TimeTicks resolve_complete_time = base::TimeTicks::Now();
346 host_resolver_.ResolveAllPending();
347 EXPECT_THAT(test_delegate.WaitForResult(), test::IsOk());
348
Matt Menke6030ed9f2019-04-11 20:25:55349 ConnectionAttempts connection_attempts =
350 ssl_connect_job->GetConnectionAttempts();
351 EXPECT_EQ(0u, connection_attempts.size());
Matt Menke7b5051072019-01-27 21:22:49352
353 // Check times. Since time is mocked out, all times will be the same, except
354 // |dns_start|, which is the only one recorded before the FastForwardBy()
355 // call. The test classes don't allow any other phases to be triggered on
356 // demand, or delayed by a set interval.
357 EXPECT_EQ(start_time, ssl_connect_job->connect_timing().dns_start);
358 EXPECT_EQ(resolve_complete_time, ssl_connect_job->connect_timing().dns_end);
359 EXPECT_EQ(resolve_complete_time,
360 ssl_connect_job->connect_timing().connect_start);
361 EXPECT_EQ(resolve_complete_time, ssl_connect_job->connect_timing().ssl_start);
362 EXPECT_EQ(resolve_complete_time, ssl_connect_job->connect_timing().ssl_end);
363 EXPECT_EQ(resolve_complete_time,
364 ssl_connect_job->connect_timing().connect_end);
365}
366
Matt Menke9d5e2c92019-02-05 01:42:23367TEST_F(SSLConnectJobTest, DirectHasEstablishedConnection) {
368 host_resolver_.set_ondemand_mode(true);
369 StaticSocketDataProvider data;
370 data.set_connect_data(MockConnect(ASYNC, OK));
371 socket_factory_.AddSocketDataProvider(&data);
372
373 // SSL negotiation hangs. Value returned after SSL negotiation is complete
374 // doesn't matter, as HasEstablishedConnection() may only be used between job
375 // start and job complete.
376 SSLSocketDataProvider ssl(SYNCHRONOUS, ERR_IO_PENDING);
377 socket_factory_.AddSSLSocketDataProvider(&ssl);
378
379 TestConnectJobDelegate test_delegate;
380 std::unique_ptr<ConnectJob> ssl_connect_job =
381 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_DIRECT, MEDIUM);
382 EXPECT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
383 EXPECT_TRUE(host_resolver_.has_pending_requests());
384 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, ssl_connect_job->GetLoadState());
385 EXPECT_FALSE(ssl_connect_job->HasEstablishedConnection());
386
387 // DNS resolution completes, and then the ConnectJob tries to connect the
388 // socket, which should succeed asynchronously.
389 host_resolver_.ResolveNow(1);
390 EXPECT_EQ(LOAD_STATE_CONNECTING, ssl_connect_job->GetLoadState());
391 EXPECT_FALSE(ssl_connect_job->HasEstablishedConnection());
392
393 // Spinning the message loop causes the socket to finish connecting. The SSL
394 // handshake should start and hang.
395 base::RunLoop().RunUntilIdle();
396 EXPECT_FALSE(test_delegate.has_result());
397 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, ssl_connect_job->GetLoadState());
398 EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
399}
400
Matt Menke7b5051072019-01-27 21:22:49401TEST_F(SSLConnectJobTest, RequestPriority) {
402 host_resolver_.set_ondemand_mode(true);
Matt Menke7b5051072019-01-27 21:22:49403 for (int initial_priority = MINIMUM_PRIORITY;
404 initial_priority <= MAXIMUM_PRIORITY; ++initial_priority) {
405 SCOPED_TRACE(initial_priority);
406 for (int new_priority = MINIMUM_PRIORITY; new_priority <= MAXIMUM_PRIORITY;
407 ++new_priority) {
408 SCOPED_TRACE(new_priority);
409 if (initial_priority == new_priority)
410 continue;
411 TestConnectJobDelegate test_delegate;
412 std::unique_ptr<ConnectJob> ssl_connect_job =
413 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_DIRECT,
414 static_cast<RequestPriority>(initial_priority));
415 EXPECT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
416 EXPECT_TRUE(host_resolver_.has_pending_requests());
417 int request_id = host_resolver_.num_resolve();
418 EXPECT_EQ(initial_priority, host_resolver_.request_priority(request_id));
419
420 ssl_connect_job->ChangePriority(
421 static_cast<RequestPriority>(new_priority));
422 EXPECT_EQ(new_priority, host_resolver_.request_priority(request_id));
423
424 ssl_connect_job->ChangePriority(
425 static_cast<RequestPriority>(initial_priority));
426 EXPECT_EQ(initial_priority, host_resolver_.request_priority(request_id));
Matt Menke7b5051072019-01-27 21:22:49427 }
428 }
429}
430
Ben Schwartz3ff4dc1e62021-04-27 21:15:23431TEST_F(SSLConnectJobTest, SecureDnsPolicy) {
432 for (auto secure_dns_policy :
433 {SecureDnsPolicy::kAllow, SecureDnsPolicy::kDisable}) {
dalyk5f48a132019-10-14 15:20:19434 TestConnectJobDelegate test_delegate;
435 direct_transport_socket_params_ =
Matt Menkecd439232019-11-05 15:15:33436 base::MakeRefCounted<TransportSocketParams>(
Eric Orthc98a3e62021-07-02 17:46:37437 url::SchemeHostPort(url::kHttpsScheme, "host", 443),
438 NetworkIsolationKey(), secure_dns_policy,
David Benjamin13072a42022-02-10 22:23:21439 OnHostResolutionCallback(),
440 /*supported_alpns=*/base::flat_set<std::string>{"h2", "http/1.1"});
dalyk5f48a132019-10-14 15:20:19441 auto common_connect_job_params = session_->CreateCommonConnectJobParams();
442 std::unique_ptr<ConnectJob> ssl_connect_job =
443 std::make_unique<SSLConnectJob>(DEFAULT_PRIORITY, SocketTag(),
444 &common_connect_job_params,
445 SSLParams(ProxyServer::SCHEME_DIRECT),
446 &test_delegate, nullptr /* net_log */);
447
448 EXPECT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
Ben Schwartz432ce032021-05-05 21:49:24449 EXPECT_EQ(secure_dns_policy, host_resolver_.last_secure_dns_policy());
dalyk5f48a132019-10-14 15:20:19450 }
451}
452
dalykedd30d982019-12-16 15:31:10453TEST_F(SSLConnectJobTest, DirectHostResolutionFailure) {
454 host_resolver_.rules()->AddSimulatedTimeoutFailure("host");
455
456 TestConnectJobDelegate test_delegate;
457 std::unique_ptr<ConnectJob> ssl_connect_job =
458 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_DIRECT);
459 test_delegate.StartJobExpectingResult(ssl_connect_job.get(),
460 ERR_NAME_NOT_RESOLVED,
461 false /* expect_sync_result */);
462 EXPECT_THAT(ssl_connect_job->GetResolveErrorInfo().error,
463 test::IsError(ERR_DNS_TIMED_OUT));
464}
465
Matt Menke7b5051072019-01-27 21:22:49466TEST_F(SSLConnectJobTest, DirectCertError) {
467 StaticSocketDataProvider data;
468 socket_factory_.AddSocketDataProvider(&data);
469 SSLSocketDataProvider ssl(ASYNC, ERR_CERT_COMMON_NAME_INVALID);
470 socket_factory_.AddSSLSocketDataProvider(&ssl);
471
472 TestConnectJobDelegate test_delegate(
473 TestConnectJobDelegate::SocketExpected::ALWAYS);
474 std::unique_ptr<ConnectJob> ssl_connect_job =
475 CreateConnectJob(&test_delegate);
476
477 test_delegate.StartJobExpectingResult(ssl_connect_job.get(),
478 ERR_CERT_COMMON_NAME_INVALID,
479 false /* expect_sync_result */);
Matt Menke6f84d1f12019-04-11 19:26:47480 EXPECT_TRUE(ssl_connect_job->IsSSLError());
Matt Menke6030ed9f2019-04-11 20:25:55481 ConnectionAttempts connection_attempts =
482 ssl_connect_job->GetConnectionAttempts();
483 ASSERT_EQ(1u, connection_attempts.size());
484 EXPECT_THAT(connection_attempts[0].result,
Matt Menke7b5051072019-01-27 21:22:49485 test::IsError(ERR_CERT_COMMON_NAME_INVALID));
486 CheckConnectTimesSet(ssl_connect_job->connect_timing());
487}
488
489TEST_F(SSLConnectJobTest, DirectSSLError) {
490 StaticSocketDataProvider data;
491 socket_factory_.AddSocketDataProvider(&data);
David Benjamin07a07d652020-02-26 22:26:59492 SSLSocketDataProvider ssl(ASYNC, ERR_BAD_SSL_CLIENT_AUTH_CERT);
Matt Menke7b5051072019-01-27 21:22:49493 socket_factory_.AddSSLSocketDataProvider(&ssl);
494
495 TestConnectJobDelegate test_delegate;
496 std::unique_ptr<ConnectJob> ssl_connect_job =
497 CreateConnectJob(&test_delegate);
498
499 test_delegate.StartJobExpectingResult(ssl_connect_job.get(),
David Benjamin07a07d652020-02-26 22:26:59500 ERR_BAD_SSL_CLIENT_AUTH_CERT,
Matt Menke7b5051072019-01-27 21:22:49501 false /* expect_sync_result */);
Matt Menke6030ed9f2019-04-11 20:25:55502 ConnectionAttempts connection_attempts =
503 ssl_connect_job->GetConnectionAttempts();
504 ASSERT_EQ(1u, connection_attempts.size());
505 EXPECT_THAT(connection_attempts[0].result,
David Benjamin07a07d652020-02-26 22:26:59506 test::IsError(ERR_BAD_SSL_CLIENT_AUTH_CERT));
507}
508
509// Test that the legacy crypto fallback is triggered on applicable error codes.
510TEST_F(SSLConnectJobTest, DirectLegacyCryptoFallback) {
511 for (Error error :
512 {ERR_CONNECTION_CLOSED, ERR_CONNECTION_RESET, ERR_SSL_PROTOCOL_ERROR,
513 ERR_SSL_VERSION_OR_CIPHER_MISMATCH}) {
514 SCOPED_TRACE(error);
515
516 for (bool second_attempt_ok : {true, false}) {
517 SCOPED_TRACE(second_attempt_ok);
518
519 StaticSocketDataProvider data;
520 socket_factory_.AddSocketDataProvider(&data);
521 SSLSocketDataProvider ssl(ASYNC, error);
522 socket_factory_.AddSSLSocketDataProvider(&ssl);
523 ssl.expected_disable_legacy_crypto = true;
524
525 Error error2 = second_attempt_ok ? OK : error;
526 StaticSocketDataProvider data2;
527 socket_factory_.AddSocketDataProvider(&data2);
528 SSLSocketDataProvider ssl2(ASYNC, error2);
529 socket_factory_.AddSSLSocketDataProvider(&ssl2);
530 ssl2.expected_disable_legacy_crypto = false;
531
532 TestConnectJobDelegate test_delegate;
533 std::unique_ptr<ConnectJob> ssl_connect_job =
534 CreateConnectJob(&test_delegate);
535
536 test_delegate.StartJobExpectingResult(ssl_connect_job.get(), error2,
537 /*expect_sync_result=*/false);
538 ConnectionAttempts connection_attempts =
539 ssl_connect_job->GetConnectionAttempts();
540 if (second_attempt_ok) {
541 ASSERT_EQ(1u, connection_attempts.size());
542 EXPECT_THAT(connection_attempts[0].result, test::IsError(error));
543 } else {
544 ASSERT_EQ(2u, connection_attempts.size());
545 EXPECT_THAT(connection_attempts[0].result, test::IsError(error));
546 EXPECT_THAT(connection_attempts[1].result, test::IsError(error));
547 }
548 }
549 }
550}
551
David Benjamin07a07d652020-02-26 22:26:59552TEST_F(SSLConnectJobTest, LegacyCryptoFallbackHistograms) {
553 base::FilePath certs_dir = GetTestCertsDirectory();
554
555 scoped_refptr<X509Certificate> sha1_leaf =
556 ImportCertFromFile(certs_dir, "sha1_leaf.pem");
557 ASSERT_TRUE(sha1_leaf);
558
559 scoped_refptr<X509Certificate> ok_cert =
560 ImportCertFromFile(certs_dir, "ok_cert.pem");
561 ASSERT_TRUE(ok_cert);
562
563 // Make a copy of |ok_cert| with an unused |sha1_leaf| in the intermediate
564 // list.
565 std::vector<bssl::UniquePtr<CRYPTO_BUFFER>> intermediates;
566 for (const auto& cert : ok_cert->intermediate_buffers()) {
567 intermediates.push_back(bssl::UpRef(cert));
568 }
569 intermediates.push_back(bssl::UpRef(sha1_leaf->cert_buffer()));
570 scoped_refptr<X509Certificate> ok_with_unused_sha1 =
571 X509Certificate::CreateFromBuffer(bssl::UpRef(ok_cert->cert_buffer()),
572 std::move(intermediates));
573 ASSERT_TRUE(ok_with_unused_sha1);
574
575 // TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
576 const uint16_t kModernCipher = 0xc02f;
David Benjamin07a07d652020-02-26 22:26:59577
578 struct HistogramTest {
579 SSLLegacyCryptoFallback expected;
580 Error first_attempt;
581 uint16_t cipher_suite;
582 uint16_t peer_signature_algorithm;
583 scoped_refptr<X509Certificate> unverified_cert;
584 };
585
586 const HistogramTest kHistogramTests[] = {
587 // Connections not using the fallback map to kNoFallback.
588 {SSLLegacyCryptoFallback::kNoFallback, OK, kModernCipher,
589 SSL_SIGN_RSA_PSS_RSAE_SHA256, ok_cert},
590 {SSLLegacyCryptoFallback::kNoFallback, OK, kModernCipher,
591 SSL_SIGN_RSA_PSS_RSAE_SHA256, sha1_leaf},
592 {SSLLegacyCryptoFallback::kNoFallback, OK, kModernCipher,
593 SSL_SIGN_RSA_PSS_RSAE_SHA256, ok_with_unused_sha1},
594
David Benjamin07a07d652020-02-26 22:26:59595 // Connections using SHA-1 map to kUsedSHA1 or kSentSHA1CertAndUsedSHA1.
596 {SSLLegacyCryptoFallback::kUsedSHA1, ERR_SSL_PROTOCOL_ERROR,
597 kModernCipher, SSL_SIGN_RSA_PKCS1_SHA1, ok_cert},
598 {SSLLegacyCryptoFallback::kSentSHA1CertAndUsedSHA1,
599 ERR_SSL_PROTOCOL_ERROR, kModernCipher, SSL_SIGN_RSA_PKCS1_SHA1,
600 sha1_leaf},
601 {SSLLegacyCryptoFallback::kSentSHA1CertAndUsedSHA1,
602 ERR_SSL_PROTOCOL_ERROR, kModernCipher, SSL_SIGN_RSA_PKCS1_SHA1,
603 ok_with_unused_sha1},
604
605 // Connections using neither map to kUnknownReason or kSentSHA1Cert.
606 {SSLLegacyCryptoFallback::kUnknownReason, ERR_SSL_PROTOCOL_ERROR,
607 kModernCipher, SSL_SIGN_RSA_PSS_RSAE_SHA256, ok_cert},
608 {SSLLegacyCryptoFallback::kSentSHA1Cert, ERR_SSL_PROTOCOL_ERROR,
609 kModernCipher, SSL_SIGN_RSA_PSS_RSAE_SHA256, sha1_leaf},
610 {SSLLegacyCryptoFallback::kSentSHA1Cert, ERR_SSL_PROTOCOL_ERROR,
611 kModernCipher, SSL_SIGN_RSA_PSS_RSAE_SHA256, ok_with_unused_sha1},
612 };
Daniel Cheng5feb16f2022-02-28 06:52:07613 for (size_t i = 0; i < std::size(kHistogramTests); i++) {
David Benjamin07a07d652020-02-26 22:26:59614 SCOPED_TRACE(i);
615 const auto& test = kHistogramTests[i];
616
617 base::HistogramTester tester;
618
619 SSLInfo ssl_info;
620 SSLConnectionStatusSetVersion(SSL_CONNECTION_VERSION_TLS1_2,
621 &ssl_info.connection_status);
622 SSLConnectionStatusSetCipherSuite(test.cipher_suite,
623 &ssl_info.connection_status);
624 ssl_info.peer_signature_algorithm = test.peer_signature_algorithm;
625 ssl_info.unverified_cert = test.unverified_cert;
626
627 StaticSocketDataProvider data;
628 socket_factory_.AddSocketDataProvider(&data);
629 SSLSocketDataProvider ssl(ASYNC, test.first_attempt);
630 socket_factory_.AddSSLSocketDataProvider(&ssl);
631 ssl.expected_disable_legacy_crypto = true;
632
633 StaticSocketDataProvider data2;
634 SSLSocketDataProvider ssl2(ASYNC, OK);
635 if (test.first_attempt != OK) {
636 socket_factory_.AddSocketDataProvider(&data2);
637 socket_factory_.AddSSLSocketDataProvider(&ssl2);
638 ssl2.ssl_info = ssl_info;
639 ssl2.expected_disable_legacy_crypto = false;
640 } else {
641 ssl.ssl_info = ssl_info;
642 }
643
644 TestConnectJobDelegate test_delegate;
645 std::unique_ptr<ConnectJob> ssl_connect_job =
646 CreateConnectJob(&test_delegate);
647
648 test_delegate.StartJobExpectingResult(ssl_connect_job.get(), OK,
649 /*expect_sync_result=*/false);
650
651 tester.ExpectUniqueSample("Net.SSLLegacyCryptoFallback", test.expected, 1);
652 }
Matt Menke7b5051072019-01-27 21:22:49653}
654
655TEST_F(SSLConnectJobTest, DirectWithNPN) {
656 StaticSocketDataProvider data;
657 socket_factory_.AddSocketDataProvider(&data);
658 SSLSocketDataProvider ssl(ASYNC, OK);
659 ssl.next_proto = kProtoHTTP11;
660 socket_factory_.AddSSLSocketDataProvider(&ssl);
661
662 TestConnectJobDelegate test_delegate;
663 std::unique_ptr<ConnectJob> ssl_connect_job =
664 CreateConnectJob(&test_delegate);
665
666 test_delegate.StartJobExpectingResult(ssl_connect_job.get(), OK,
667 false /* expect_sync_result */);
668 EXPECT_TRUE(test_delegate.socket()->WasAlpnNegotiated());
669 CheckConnectTimesSet(ssl_connect_job->connect_timing());
670}
671
672TEST_F(SSLConnectJobTest, DirectGotHTTP2) {
673 StaticSocketDataProvider data;
674 socket_factory_.AddSocketDataProvider(&data);
675 SSLSocketDataProvider ssl(ASYNC, OK);
676 ssl.next_proto = kProtoHTTP2;
677 socket_factory_.AddSSLSocketDataProvider(&ssl);
678
679 TestConnectJobDelegate test_delegate;
680 std::unique_ptr<ConnectJob> ssl_connect_job =
681 CreateConnectJob(&test_delegate);
682
683 test_delegate.StartJobExpectingResult(ssl_connect_job.get(), OK,
684 false /* expect_sync_result */);
685 EXPECT_TRUE(test_delegate.socket()->WasAlpnNegotiated());
686 EXPECT_EQ(kProtoHTTP2, test_delegate.socket()->GetNegotiatedProtocol());
687 CheckConnectTimesSet(ssl_connect_job->connect_timing());
688}
689
690TEST_F(SSLConnectJobTest, SOCKSFail) {
691 for (IoMode io_mode : {SYNCHRONOUS, ASYNC}) {
692 SCOPED_TRACE(io_mode);
693 host_resolver_.set_synchronous_mode(io_mode == SYNCHRONOUS);
694 StaticSocketDataProvider data;
695 data.set_connect_data(MockConnect(io_mode, ERR_CONNECTION_FAILED));
696 socket_factory_.AddSocketDataProvider(&data);
697
698 TestConnectJobDelegate test_delegate;
699 std::unique_ptr<ConnectJob> ssl_connect_job =
700 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_SOCKS5);
701 test_delegate.StartJobExpectingResult(ssl_connect_job.get(),
702 ERR_PROXY_CONNECTION_FAILED,
703 io_mode == SYNCHRONOUS);
Matt Menke6f84d1f12019-04-11 19:26:47704 EXPECT_FALSE(ssl_connect_job->IsSSLError());
Matt Menke7b5051072019-01-27 21:22:49705
Matt Menke6030ed9f2019-04-11 20:25:55706 ConnectionAttempts connection_attempts =
707 ssl_connect_job->GetConnectionAttempts();
708 EXPECT_EQ(0u, connection_attempts.size());
Matt Menke7b5051072019-01-27 21:22:49709 }
710}
711
dalykedd30d982019-12-16 15:31:10712TEST_F(SSLConnectJobTest, SOCKSHostResolutionFailure) {
713 host_resolver_.rules()->AddSimulatedTimeoutFailure("proxy");
714
715 TestConnectJobDelegate test_delegate;
716 std::unique_ptr<ConnectJob> ssl_connect_job =
717 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_SOCKS5);
718 test_delegate.StartJobExpectingResult(ssl_connect_job.get(),
719 ERR_PROXY_CONNECTION_FAILED,
720 false /* expect_sync_result */);
721 EXPECT_THAT(ssl_connect_job->GetResolveErrorInfo().error,
722 test::IsError(ERR_DNS_TIMED_OUT));
723}
724
Matt Menke7b5051072019-01-27 21:22:49725TEST_F(SSLConnectJobTest, SOCKSBasic) {
726 for (IoMode io_mode : {SYNCHRONOUS, ASYNC}) {
727 SCOPED_TRACE(io_mode);
Peter Kasting0ff39d42021-06-14 13:26:06728 const uint8_t kSOCKS5Request[] = {0x05, 0x01, 0x00, 0x03, 0x09, 's',
729 'o', 'c', 'k', 's', 'h', 'o',
730 's', 't', 0x01, 0xBB};
Matt Menke7b5051072019-01-27 21:22:49731
732 MockWrite writes[] = {
733 MockWrite(io_mode, kSOCKS5GreetRequest, kSOCKS5GreetRequestLength),
Peter Kasting0ff39d42021-06-14 13:26:06734 MockWrite(io_mode, reinterpret_cast<const char*>(kSOCKS5Request),
Daniel Cheng5feb16f2022-02-28 06:52:07735 std::size(kSOCKS5Request)),
Matt Menke628d624f2019-02-09 00:40:24736 };
Matt Menke7b5051072019-01-27 21:22:49737
738 MockRead reads[] = {
739 MockRead(io_mode, kSOCKS5GreetResponse, kSOCKS5GreetResponseLength),
Matt Menke628d624f2019-02-09 00:40:24740 MockRead(io_mode, kSOCKS5OkResponse, kSOCKS5OkResponseLength),
741 };
Matt Menke7b5051072019-01-27 21:22:49742
743 host_resolver_.set_synchronous_mode(io_mode == SYNCHRONOUS);
744 StaticSocketDataProvider data(reads, writes);
745 data.set_connect_data(MockConnect(io_mode, OK));
746 socket_factory_.AddSocketDataProvider(&data);
747 SSLSocketDataProvider ssl(io_mode, OK);
748 socket_factory_.AddSSLSocketDataProvider(&ssl);
749
750 TestConnectJobDelegate test_delegate;
751 std::unique_ptr<ConnectJob> ssl_connect_job =
752 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_SOCKS5);
753 test_delegate.StartJobExpectingResult(ssl_connect_job.get(), OK,
754 io_mode == SYNCHRONOUS);
755 CheckConnectTimesExceptDnsSet(ssl_connect_job->connect_timing());
Cammie Smith Barnesaa2a8b52020-12-17 19:33:19756
757 // Proxies should not set any DNS aliases.
758 EXPECT_TRUE(test_delegate.socket()->GetDnsAliases().empty());
Matt Menke7b5051072019-01-27 21:22:49759 }
760}
761
Matt Menke628d624f2019-02-09 00:40:24762TEST_F(SSLConnectJobTest, SOCKSHasEstablishedConnection) {
Peter Kasting0ff39d42021-06-14 13:26:06763 const uint8_t kSOCKS5Request[] = {0x05, 0x01, 0x00, 0x03, 0x09, 's',
764 'o', 'c', 'k', 's', 'h', 'o',
765 's', 't', 0x01, 0xBB};
Matt Menke628d624f2019-02-09 00:40:24766
767 MockWrite writes[] = {
768 MockWrite(SYNCHRONOUS, kSOCKS5GreetRequest, kSOCKS5GreetRequestLength, 0),
Peter Kasting0ff39d42021-06-14 13:26:06769 MockWrite(SYNCHRONOUS, reinterpret_cast<const char*>(kSOCKS5Request),
Daniel Cheng5feb16f2022-02-28 06:52:07770 std::size(kSOCKS5Request), 3),
Matt Menke628d624f2019-02-09 00:40:24771 };
772
773 MockRead reads[] = {
774 // Pause so can probe current state.
775 MockRead(ASYNC, ERR_IO_PENDING, 1),
776 MockRead(ASYNC, kSOCKS5GreetResponse, kSOCKS5GreetResponseLength, 2),
777 MockRead(SYNCHRONOUS, kSOCKS5OkResponse, kSOCKS5OkResponseLength, 4),
778 };
779
780 host_resolver_.set_ondemand_mode(true);
781 SequencedSocketData data(reads, writes);
782 data.set_connect_data(MockConnect(ASYNC, OK));
783 socket_factory_.AddSocketDataProvider(&data);
784
785 // SSL negotiation hangs. Value returned after SSL negotiation is complete
786 // doesn't matter, as HasEstablishedConnection() may only be used between job
787 // start and job complete.
788 SSLSocketDataProvider ssl(SYNCHRONOUS, ERR_IO_PENDING);
789 socket_factory_.AddSSLSocketDataProvider(&ssl);
790
791 TestConnectJobDelegate test_delegate;
792 std::unique_ptr<ConnectJob> ssl_connect_job =
793 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_SOCKS5);
794 EXPECT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
795 EXPECT_TRUE(host_resolver_.has_pending_requests());
796 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, ssl_connect_job->GetLoadState());
797 EXPECT_FALSE(ssl_connect_job->HasEstablishedConnection());
798
799 // DNS resolution completes, and then the ConnectJob tries to connect the
800 // socket, which should succeed asynchronously.
801 host_resolver_.ResolveNow(1);
802 EXPECT_EQ(LOAD_STATE_CONNECTING, ssl_connect_job->GetLoadState());
803 EXPECT_FALSE(ssl_connect_job->HasEstablishedConnection());
804
805 // Spin the message loop until the first read of the handshake.
806 // HasEstablishedConnection() should return true, as a TCP connection has been
807 // successfully established by this point.
808 data.RunUntilPaused();
809 EXPECT_FALSE(test_delegate.has_result());
810 EXPECT_EQ(LOAD_STATE_CONNECTING, ssl_connect_job->GetLoadState());
811 EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
812
813 // Finish up the handshake, and spin the message loop until the SSL handshake
814 // starts and hang.
815 data.Resume();
816 base::RunLoop().RunUntilIdle();
817 EXPECT_FALSE(test_delegate.has_result());
818 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, ssl_connect_job->GetLoadState());
819 EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
820}
821
Matt Menke7b5051072019-01-27 21:22:49822TEST_F(SSLConnectJobTest, SOCKSRequestPriority) {
823 host_resolver_.set_ondemand_mode(true);
Matt Menke7b5051072019-01-27 21:22:49824 for (int initial_priority = MINIMUM_PRIORITY;
825 initial_priority <= MAXIMUM_PRIORITY; ++initial_priority) {
826 SCOPED_TRACE(initial_priority);
827 for (int new_priority = MINIMUM_PRIORITY; new_priority <= MAXIMUM_PRIORITY;
828 ++new_priority) {
829 SCOPED_TRACE(new_priority);
830 if (initial_priority == new_priority)
831 continue;
832 TestConnectJobDelegate test_delegate;
833 std::unique_ptr<ConnectJob> ssl_connect_job =
834 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_SOCKS5,
835 static_cast<RequestPriority>(initial_priority));
836 EXPECT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
837 EXPECT_TRUE(host_resolver_.has_pending_requests());
838 int request_id = host_resolver_.num_resolve();
839 EXPECT_EQ(initial_priority, host_resolver_.request_priority(request_id));
840
841 ssl_connect_job->ChangePriority(
842 static_cast<RequestPriority>(new_priority));
843 EXPECT_EQ(new_priority, host_resolver_.request_priority(request_id));
844
845 ssl_connect_job->ChangePriority(
846 static_cast<RequestPriority>(initial_priority));
847 EXPECT_EQ(initial_priority, host_resolver_.request_priority(request_id));
Matt Menke7b5051072019-01-27 21:22:49848 }
849 }
850}
851
852TEST_F(SSLConnectJobTest, HttpProxyFail) {
853 for (IoMode io_mode : {SYNCHRONOUS, ASYNC}) {
854 SCOPED_TRACE(io_mode);
855 host_resolver_.set_synchronous_mode(io_mode == SYNCHRONOUS);
856 StaticSocketDataProvider data;
857 data.set_connect_data(MockConnect(io_mode, ERR_CONNECTION_FAILED));
858 socket_factory_.AddSocketDataProvider(&data);
859
860 TestConnectJobDelegate test_delegate;
861 std::unique_ptr<ConnectJob> ssl_connect_job =
862 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_HTTP);
863 test_delegate.StartJobExpectingResult(ssl_connect_job.get(),
864 ERR_PROXY_CONNECTION_FAILED,
865 io_mode == SYNCHRONOUS);
866
Matt Menke6f84d1f12019-04-11 19:26:47867 EXPECT_FALSE(ssl_connect_job->IsSSLError());
Matt Menke6030ed9f2019-04-11 20:25:55868 ConnectionAttempts connection_attempts =
869 ssl_connect_job->GetConnectionAttempts();
870 EXPECT_EQ(0u, connection_attempts.size());
Matt Menke7b5051072019-01-27 21:22:49871 }
872}
873
dalykedd30d982019-12-16 15:31:10874TEST_F(SSLConnectJobTest, HttpProxyHostResolutionFailure) {
875 host_resolver_.rules()->AddSimulatedTimeoutFailure("proxy");
876
877 TestConnectJobDelegate test_delegate;
878 std::unique_ptr<ConnectJob> ssl_connect_job =
879 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_HTTP);
880 test_delegate.StartJobExpectingResult(ssl_connect_job.get(),
881 ERR_PROXY_CONNECTION_FAILED,
882 false /* expect_sync_result */);
883 EXPECT_THAT(ssl_connect_job->GetResolveErrorInfo().error,
884 test::IsError(ERR_DNS_TIMED_OUT));
885}
886
Matt Menkeb57663b32019-03-01 17:17:10887TEST_F(SSLConnectJobTest, HttpProxyAuthChallenge) {
888 MockWrite writes[] = {
889 MockWrite(ASYNC, 0,
890 "CONNECT host:80 HTTP/1.1\r\n"
891 "Host: host:80\r\n"
892 "Proxy-Connection: keep-alive\r\n\r\n"),
893 MockWrite(ASYNC, 5,
894 "CONNECT host:80 HTTP/1.1\r\n"
895 "Host: host:80\r\n"
896 "Proxy-Connection: keep-alive\r\n"
897 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
898 };
899 MockRead reads[] = {
900 MockRead(ASYNC, 1, "HTTP/1.1 407 Proxy Authentication Required\r\n"),
901 MockRead(ASYNC, 2, "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
902 MockRead(ASYNC, 3, "Content-Length: 10\r\n\r\n"),
903 MockRead(ASYNC, 4, "0123456789"),
904 MockRead(ASYNC, 6, "HTTP/1.1 200 Connection Established\r\n\r\n"),
905 };
906 StaticSocketDataProvider data(reads, writes);
907 socket_factory_.AddSocketDataProvider(&data);
908 SSLSocketDataProvider ssl(ASYNC, OK);
909 socket_factory_.AddSSLSocketDataProvider(&ssl);
910
Matt Menkeb57663b32019-03-01 17:17:10911 TestConnectJobDelegate test_delegate;
912 std::unique_ptr<ConnectJob> ssl_connect_job =
913 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_HTTP);
914 ASSERT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
915 test_delegate.WaitForAuthChallenge(1);
916
917 EXPECT_EQ(407, test_delegate.auth_response_info().headers->response_code());
918 std::string proxy_authenticate;
919 ASSERT_TRUE(test_delegate.auth_response_info().headers->EnumerateHeader(
920 nullptr, "Proxy-Authenticate", &proxy_authenticate));
921 EXPECT_EQ(proxy_authenticate, "Basic realm=\"MyRealm1\"");
922
923 // While waiting for auth credentials to be provided, the Job should not time
924 // out.
Peter Kastinge5a38ed2021-10-02 03:06:35925 FastForwardBy(base::Days(1));
Matt Menkeb57663b32019-03-01 17:17:10926 test_delegate.WaitForAuthChallenge(1);
927 EXPECT_FALSE(test_delegate.has_result());
928
929 // Respond to challenge.
Jan Wilken Dörriec92a6d7242021-03-23 17:43:48930 test_delegate.auth_controller()->ResetAuth(AuthCredentials(u"foo", u"bar"));
Matt Menkeb57663b32019-03-01 17:17:10931 test_delegate.RunAuthCallback();
932
933 EXPECT_THAT(test_delegate.WaitForResult(), test::IsOk());
Cammie Smith Barnesaa2a8b52020-12-17 19:33:19934
935 // Proxies should not set any DNS aliases.
936 EXPECT_TRUE(test_delegate.socket()->GetDnsAliases().empty());
Matt Menkeb57663b32019-03-01 17:17:10937}
938
939TEST_F(SSLConnectJobTest, HttpProxyAuthWithCachedCredentials) {
Matt Menke7b5051072019-01-27 21:22:49940 for (IoMode io_mode : {SYNCHRONOUS, ASYNC}) {
941 SCOPED_TRACE(io_mode);
942 host_resolver_.set_synchronous_mode(io_mode == SYNCHRONOUS);
943 MockWrite writes[] = {
944 MockWrite(io_mode,
945 "CONNECT host:80 HTTP/1.1\r\n"
946 "Host: host:80\r\n"
947 "Proxy-Connection: keep-alive\r\n"
948 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
949 };
950 MockRead reads[] = {
951 MockRead(io_mode, "HTTP/1.1 200 Connection Established\r\n\r\n"),
952 };
953 StaticSocketDataProvider data(reads, writes);
954 data.set_connect_data(MockConnect(io_mode, OK));
955 socket_factory_.AddSocketDataProvider(&data);
956 AddAuthToCache();
957 SSLSocketDataProvider ssl(io_mode, OK);
958 socket_factory_.AddSSLSocketDataProvider(&ssl);
959
960 TestConnectJobDelegate test_delegate;
961 std::unique_ptr<ConnectJob> ssl_connect_job =
962 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_HTTP);
963 test_delegate.StartJobExpectingResult(ssl_connect_job.get(), OK,
964 io_mode == SYNCHRONOUS);
965 CheckConnectTimesExceptDnsSet(ssl_connect_job->connect_timing());
Cammie Smith Barnesaa2a8b52020-12-17 19:33:19966 EXPECT_TRUE(test_delegate.socket()->GetDnsAliases().empty());
Matt Menke7b5051072019-01-27 21:22:49967 }
968}
969
970TEST_F(SSLConnectJobTest, HttpProxyRequestPriority) {
971 host_resolver_.set_ondemand_mode(true);
Matt Menke7b5051072019-01-27 21:22:49972 for (int initial_priority = MINIMUM_PRIORITY;
973 initial_priority <= MAXIMUM_PRIORITY; ++initial_priority) {
974 SCOPED_TRACE(initial_priority);
975 for (int new_priority = MINIMUM_PRIORITY; new_priority <= MAXIMUM_PRIORITY;
976 ++new_priority) {
977 SCOPED_TRACE(new_priority);
978 if (initial_priority == new_priority)
979 continue;
980 TestConnectJobDelegate test_delegate;
981 std::unique_ptr<ConnectJob> ssl_connect_job =
982 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_HTTP,
983 static_cast<RequestPriority>(initial_priority));
984 EXPECT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
985 EXPECT_TRUE(host_resolver_.has_pending_requests());
986 int request_id = host_resolver_.num_resolve();
987 EXPECT_EQ(initial_priority, host_resolver_.request_priority(request_id));
988
989 ssl_connect_job->ChangePriority(
990 static_cast<RequestPriority>(new_priority));
991 EXPECT_EQ(new_priority, host_resolver_.request_priority(request_id));
992
993 ssl_connect_job->ChangePriority(
994 static_cast<RequestPriority>(initial_priority));
995 EXPECT_EQ(initial_priority, host_resolver_.request_priority(request_id));
Matt Menke7b5051072019-01-27 21:22:49996 }
997 }
998}
999
Matt Menkeaade5812019-03-02 13:38:001000TEST_F(SSLConnectJobTest, HttpProxyAuthHasEstablishedConnection) {
1001 host_resolver_.set_ondemand_mode(true);
1002 MockWrite writes[] = {
1003 MockWrite(ASYNC, 0,
1004 "CONNECT host:80 HTTP/1.1\r\n"
1005 "Host: host:80\r\n"
1006 "Proxy-Connection: keep-alive\r\n\r\n"),
1007 MockWrite(ASYNC, 3,
1008 "CONNECT host:80 HTTP/1.1\r\n"
1009 "Host: host:80\r\n"
1010 "Proxy-Connection: keep-alive\r\n"
1011 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
1012 };
1013 MockRead reads[] = {
1014 // Pause reading.
1015 MockRead(ASYNC, ERR_IO_PENDING, 1),
1016 MockRead(ASYNC, 2,
1017 "HTTP/1.1 407 Proxy Authentication Required\r\n"
1018 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
1019 "Content-Length: 0\r\n\r\n"),
1020 // Pause reading.
1021 MockRead(ASYNC, ERR_IO_PENDING, 4),
1022 MockRead(ASYNC, 5, "HTTP/1.1 200 Connection Established\r\n\r\n"),
1023 };
1024 SequencedSocketData data(reads, writes);
1025 socket_factory_.AddSocketDataProvider(&data);
1026 SSLSocketDataProvider ssl(ASYNC, OK);
1027 socket_factory_.AddSSLSocketDataProvider(&ssl);
1028
Matt Menkeaade5812019-03-02 13:38:001029 TestConnectJobDelegate test_delegate;
1030 std::unique_ptr<ConnectJob> ssl_connect_job =
1031 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_HTTP);
1032 ASSERT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
1033 EXPECT_TRUE(host_resolver_.has_pending_requests());
1034 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, ssl_connect_job->GetLoadState());
1035 EXPECT_FALSE(ssl_connect_job->HasEstablishedConnection());
1036
1037 // DNS resolution completes, and then the ConnectJob tries to connect the
1038 // socket, which should succeed asynchronously.
1039 host_resolver_.ResolveOnlyRequestNow();
1040 EXPECT_EQ(LOAD_STATE_CONNECTING, ssl_connect_job->GetLoadState());
1041 EXPECT_FALSE(ssl_connect_job->HasEstablishedConnection());
1042
1043 // Spinning the message loop causes the connection to be established and the
1044 // nested HttpProxyConnectJob to start establishing a tunnel.
1045 base::RunLoop().RunUntilIdle();
1046 EXPECT_FALSE(test_delegate.has_result());
1047 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
1048 ssl_connect_job->GetLoadState());
1049 EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
1050
1051 // Receive the auth challenge.
1052 data.Resume();
1053 test_delegate.WaitForAuthChallenge(1);
1054 EXPECT_FALSE(test_delegate.has_result());
1055 EXPECT_EQ(LOAD_STATE_IDLE, ssl_connect_job->GetLoadState());
1056 EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
1057
1058 // Respond to challenge.
Jan Wilken Dörriec92a6d7242021-03-23 17:43:481059 test_delegate.auth_controller()->ResetAuth(AuthCredentials(u"foo", u"bar"));
Matt Menkeaade5812019-03-02 13:38:001060 test_delegate.RunAuthCallback();
1061 EXPECT_FALSE(test_delegate.has_result());
1062 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
1063 ssl_connect_job->GetLoadState());
1064 EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
1065
1066 // Run until the next read pauses.
1067 base::RunLoop().RunUntilIdle();
1068 EXPECT_FALSE(test_delegate.has_result());
1069 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
1070 ssl_connect_job->GetLoadState());
1071 EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
1072
1073 // Receive the connection established response, at which point SSL negotiation
1074 // finally starts.
1075 data.Resume();
1076 EXPECT_FALSE(test_delegate.has_result());
1077 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, ssl_connect_job->GetLoadState());
1078 EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
1079
1080 EXPECT_THAT(test_delegate.WaitForResult(), test::IsOk());
1081}
1082
1083TEST_F(SSLConnectJobTest,
1084 HttpProxyAuthHasEstablishedConnectionWithProxyConnectionClose) {
1085 host_resolver_.set_ondemand_mode(true);
1086 MockWrite writes1[] = {
1087 MockWrite(ASYNC, 0,
1088 "CONNECT host:80 HTTP/1.1\r\n"
1089 "Host: host:80\r\n"
1090 "Proxy-Connection: keep-alive\r\n\r\n"),
1091 };
1092 MockRead reads1[] = {
1093 // Pause reading.
1094 MockRead(ASYNC, ERR_IO_PENDING, 1),
1095 MockRead(ASYNC, 2,
1096 "HTTP/1.1 407 Proxy Authentication Required\r\n"
1097 "Proxy-Connection: Close\r\n"
1098 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
1099 "Content-Length: 0\r\n\r\n"),
1100 };
1101 SequencedSocketData data1(reads1, writes1);
1102 socket_factory_.AddSocketDataProvider(&data1);
1103
1104 MockWrite writes2[] = {
1105 MockWrite(ASYNC, 0,
1106 "CONNECT host:80 HTTP/1.1\r\n"
1107 "Host: host:80\r\n"
1108 "Proxy-Connection: keep-alive\r\n"
1109 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
1110 };
1111 MockRead reads2[] = {
1112 // Pause reading.
1113 MockRead(ASYNC, ERR_IO_PENDING, 1),
1114 MockRead(ASYNC, 2, "HTTP/1.1 200 Connection Established\r\n\r\n"),
1115 };
1116 SequencedSocketData data2(reads2, writes2);
1117 socket_factory_.AddSocketDataProvider(&data2);
1118 SSLSocketDataProvider ssl(ASYNC, OK);
1119 socket_factory_.AddSSLSocketDataProvider(&ssl);
1120
Matt Menkeaade5812019-03-02 13:38:001121 TestConnectJobDelegate test_delegate;
1122 std::unique_ptr<ConnectJob> ssl_connect_job =
1123 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_HTTP);
1124 ASSERT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
1125 EXPECT_TRUE(host_resolver_.has_pending_requests());
1126 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, ssl_connect_job->GetLoadState());
1127 EXPECT_FALSE(ssl_connect_job->HasEstablishedConnection());
1128
1129 // DNS resolution completes, and then the ConnectJob tries to connect the
1130 // socket, which should succeed asynchronously.
1131 host_resolver_.ResolveOnlyRequestNow();
1132 EXPECT_EQ(LOAD_STATE_CONNECTING, ssl_connect_job->GetLoadState());
1133 EXPECT_FALSE(ssl_connect_job->HasEstablishedConnection());
1134
1135 // Spinning the message loop causes the connection to be established and the
1136 // nested HttpProxyConnectJob to start establishing a tunnel.
1137 base::RunLoop().RunUntilIdle();
1138 EXPECT_FALSE(test_delegate.has_result());
1139 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
1140 ssl_connect_job->GetLoadState());
1141 EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
1142
1143 // Receive the auth challenge.
1144 data1.Resume();
1145 test_delegate.WaitForAuthChallenge(1);
1146 EXPECT_FALSE(test_delegate.has_result());
1147 EXPECT_EQ(LOAD_STATE_IDLE, ssl_connect_job->GetLoadState());
1148 EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
1149
1150 // Respond to challenge.
Jan Wilken Dörriec92a6d7242021-03-23 17:43:481151 test_delegate.auth_controller()->ResetAuth(AuthCredentials(u"foo", u"bar"));
Matt Menkeaade5812019-03-02 13:38:001152 test_delegate.RunAuthCallback();
1153 EXPECT_FALSE(test_delegate.has_result());
1154 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
1155 ssl_connect_job->GetLoadState());
1156 EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
1157
1158 // Run until the next DNS lookup.
1159 base::RunLoop().RunUntilIdle();
1160 EXPECT_TRUE(host_resolver_.has_pending_requests());
1161 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, ssl_connect_job->GetLoadState());
1162 EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
1163
1164 // DNS resolution completes, and then the ConnectJob tries to connect the
1165 // socket, which should succeed asynchronously.
1166 host_resolver_.ResolveOnlyRequestNow();
1167 EXPECT_EQ(LOAD_STATE_CONNECTING, ssl_connect_job->GetLoadState());
1168 EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
1169
1170 // Spinning the message loop causes the connection to be established and the
1171 // nested HttpProxyConnectJob to start establishing a tunnel.
1172 base::RunLoop().RunUntilIdle();
1173 EXPECT_FALSE(test_delegate.has_result());
1174 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
1175 ssl_connect_job->GetLoadState());
1176 EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
1177
1178 // Receive the connection established response, at which point SSL negotiation
1179 // finally starts.
1180 data2.Resume();
1181 EXPECT_FALSE(test_delegate.has_result());
1182 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, ssl_connect_job->GetLoadState());
1183 EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
1184
1185 EXPECT_THAT(test_delegate.WaitForResult(), test::IsOk());
1186}
1187
Cammie Smith Barnesaa2a8b52020-12-17 19:33:191188TEST_F(SSLConnectJobTest, DnsAliases) {
1189 host_resolver_.set_synchronous_mode(true);
1190
1191 // Resolve an AddressList with DNS aliases.
1192 std::vector<std::string> aliases({"alias1", "alias2", "host"});
1193 host_resolver_.rules()->AddIPLiteralRuleWithDnsAliases("host", "2.2.2.2",
1194 std::move(aliases));
1195 StaticSocketDataProvider data;
1196 data.set_connect_data(MockConnect(SYNCHRONOUS, OK));
1197 socket_factory_.AddSocketDataProvider(&data);
1198 SSLSocketDataProvider ssl(ASYNC, OK);
1199 socket_factory_.AddSSLSocketDataProvider(&ssl);
1200 TestConnectJobDelegate test_delegate;
1201
1202 std::unique_ptr<ConnectJob> ssl_connect_job =
1203 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_DIRECT, MEDIUM);
1204
1205 EXPECT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
1206
1207 base::RunLoop().RunUntilIdle();
1208
1209 // Verify that the elements of the alias list are those from the
1210 // parameter vector.
1211 EXPECT_THAT(test_delegate.socket()->GetDnsAliases(),
1212 testing::ElementsAre("alias1", "alias2", "host"));
1213}
1214
1215TEST_F(SSLConnectJobTest, NoAdditionalDnsAliases) {
1216 host_resolver_.set_synchronous_mode(true);
1217
1218 // Resolve an AddressList without additional DNS aliases. (The parameter
1219 // is an empty vector.)
1220 std::vector<std::string> aliases;
1221 host_resolver_.rules()->AddIPLiteralRuleWithDnsAliases("host", "2.2.2.2",
1222 std::move(aliases));
1223 StaticSocketDataProvider data;
1224 data.set_connect_data(MockConnect(SYNCHRONOUS, OK));
1225 socket_factory_.AddSocketDataProvider(&data);
1226 SSLSocketDataProvider ssl(ASYNC, OK);
1227 socket_factory_.AddSSLSocketDataProvider(&ssl);
1228 TestConnectJobDelegate test_delegate;
1229
1230 std::unique_ptr<ConnectJob> ssl_connect_job =
1231 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_DIRECT, MEDIUM);
1232
1233 EXPECT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
1234
1235 base::RunLoop().RunUntilIdle();
1236
1237 // Verify that the alias list only contains "host".
1238 EXPECT_THAT(test_delegate.socket()->GetDnsAliases(),
1239 testing::ElementsAre("host"));
1240}
1241
Matt Menke7b5051072019-01-27 21:22:491242} // namespace
1243} // namespace net