blob: 7d346ba4284e789b03c57586401f8e13dcc34a91 [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"
15#include "base/test/scoped_task_environment.h"
16#include "base/time/time.h"
17#include "net/base/auth.h"
18#include "net/base/load_timing_info.h"
19#include "net/base/net_errors.h"
20#include "net/cert/ct_policy_enforcer.h"
21#include "net/cert/mock_cert_verifier.h"
22#include "net/cert/multi_log_ct_verifier.h"
23#include "net/dns/mock_host_resolver.h"
24#include "net/http/http_auth_handler_factory.h"
25#include "net/http/http_network_session.h"
Matt Menke0754b5d02019-02-10 21:46:4326#include "net/http/http_proxy_connect_job.h"
Matt Menke7b5051072019-01-27 21:22:4927#include "net/http/http_request_headers.h"
28#include "net/http/http_response_headers.h"
29#include "net/http/http_server_properties_impl.h"
30#include "net/http/transport_security_state.h"
31#include "net/log/net_log_source.h"
32#include "net/log/net_log_with_source.h"
33#include "net/proxy_resolution/proxy_resolution_service.h"
34#include "net/socket/client_socket_handle.h"
35#include "net/socket/connect_job_test_util.h"
36#include "net/socket/next_proto.h"
37#include "net/socket/socket_tag.h"
38#include "net/socket/socket_test_util.h"
39#include "net/socket/socks_connect_job.h"
Matt Menke7b5051072019-01-27 21:22:4940#include "net/socket/transport_connect_job.h"
41#include "net/ssl/ssl_config_service_defaults.h"
42#include "net/test/gtest_util.h"
43#include "net/test/test_certificate_data.h"
44#include "net/test/test_with_scoped_task_environment.h"
45#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
46#include "testing/gtest/include/gtest/gtest.h"
47
48namespace net {
49namespace {
50
Matt Menke7b5051072019-01-27 21:22:4951// Just check that all connect times are set to base::TimeTicks::Now(), for
52// tests that don't update the mocked out time.
53void CheckConnectTimesSet(const LoadTimingInfo::ConnectTiming& connect_timing) {
54 EXPECT_EQ(base::TimeTicks::Now(), connect_timing.dns_start);
55 EXPECT_EQ(base::TimeTicks::Now(), connect_timing.dns_end);
56 EXPECT_EQ(base::TimeTicks::Now(), connect_timing.connect_start);
57 EXPECT_EQ(base::TimeTicks::Now(), connect_timing.ssl_start);
58 EXPECT_EQ(base::TimeTicks::Now(), connect_timing.ssl_end);
59 EXPECT_EQ(base::TimeTicks::Now(), connect_timing.connect_end);
60}
61
62// Just check that all connect times are set to base::TimeTicks::Now(), except
63// for DNS times, for tests that don't update the mocked out time and use a
64// proxy.
65void CheckConnectTimesExceptDnsSet(
66 const LoadTimingInfo::ConnectTiming& connect_timing) {
67 EXPECT_TRUE(connect_timing.dns_start.is_null());
68 EXPECT_TRUE(connect_timing.dns_end.is_null());
69 EXPECT_EQ(base::TimeTicks::Now(), connect_timing.connect_start);
70 EXPECT_EQ(base::TimeTicks::Now(), connect_timing.ssl_start);
71 EXPECT_EQ(base::TimeTicks::Now(), connect_timing.ssl_end);
72 EXPECT_EQ(base::TimeTicks::Now(), connect_timing.connect_end);
73}
74
75class SSLConnectJobTest : public WithScopedTaskEnvironment,
76 public testing::Test {
77 public:
78 SSLConnectJobTest()
79 : WithScopedTaskEnvironment(
80 base::test::ScopedTaskEnvironment::MainThreadType::MOCK_TIME,
81 base::test::ScopedTaskEnvironment::NowSource::
82 MAIN_THREAD_MOCK_TIME),
83 proxy_resolution_service_(ProxyResolutionService::CreateDirect()),
84 ssl_config_service_(new SSLConfigServiceDefaults),
Eric Orthbe2efac2019-03-06 01:11:1185 http_auth_handler_factory_(HttpAuthHandlerFactory::CreateDefault()),
Matt Menke7b5051072019-01-27 21:22:4986 session_(CreateNetworkSession()),
87 ssl_client_socket_context_(&cert_verifier_,
Matt Menke7b5051072019-01-27 21:22:4988 &transport_security_state_,
89 &ct_verifier_,
90 &ct_policy_enforcer_,
Daniel McArdleda3fa942019-02-15 16:41:2191 nullptr /* ssl_client_session_cache */),
Matt Menke7b5051072019-01-27 21:22:4992 direct_transport_socket_params_(
93 new TransportSocketParams(HostPortPair("host", 443),
Matt Menke7b5051072019-01-27 21:22:4994 OnHostResolutionCallback())),
Matt Menke7b5051072019-01-27 21:22:4995 proxy_transport_socket_params_(
96 new TransportSocketParams(HostPortPair("proxy", 443),
Matt Menke7b5051072019-01-27 21:22:4997 OnHostResolutionCallback())),
98 socks_socket_params_(
99 new SOCKSSocketParams(proxy_transport_socket_params_,
100 true,
101 HostPortPair("sockshost", 443),
102 TRAFFIC_ANNOTATION_FOR_TESTS)),
103 http_proxy_socket_params_(
104 new HttpProxySocketParams(proxy_transport_socket_params_,
105 nullptr /* ssl_params */,
Matt Menkeb5fb42b2019-03-22 17:26:13106 false /* is_quic */,
Matt Menke7b5051072019-01-27 21:22:49107 HostPortPair("host", 80),
Matt Menke7b5051072019-01-27 21:22:49108 /*is_trusted_proxy=*/false,
109 /*tunnel=*/true,
110 TRAFFIC_ANNOTATION_FOR_TESTS)),
Matt Menkeb88837e2019-03-20 11:50:40111 common_connect_job_params_(session_->CreateCommonConnectJobParams()) {
Matt Menke7b5051072019-01-27 21:22:49112 ssl_config_service_->GetSSLConfig(&ssl_config_);
113
114 // Set an initial delay to ensure that the first call to TimeTicks::Now()
115 // before incrementing the counter does not return a null value.
116 FastForwardBy(base::TimeDelta::FromSeconds(1));
117 }
118
119 ~SSLConnectJobTest() override = default;
120
121 std::unique_ptr<ConnectJob> CreateConnectJob(
122 TestConnectJobDelegate* test_delegate,
123 ProxyServer::Scheme proxy_scheme = ProxyServer::SCHEME_DIRECT,
124 RequestPriority priority = DEFAULT_PRIORITY) {
125 return std::make_unique<SSLConnectJob>(
Matt Menkea6f99ad2019-03-08 02:26:43126 priority, SocketTag(), &common_connect_job_params_,
Matt Menke14819512019-03-02 16:59:58127 SSLParams(proxy_scheme), test_delegate, nullptr /* net_log */);
Matt Menke7b5051072019-01-27 21:22:49128 }
129
130 scoped_refptr<SSLSocketParams> SSLParams(ProxyServer::Scheme proxy) {
131 return base::MakeRefCounted<SSLSocketParams>(
132 proxy == ProxyServer::SCHEME_DIRECT ? direct_transport_socket_params_
133 : nullptr,
134 proxy == ProxyServer::SCHEME_SOCKS5 ? socks_socket_params_ : nullptr,
135 proxy == ProxyServer::SCHEME_HTTP ? http_proxy_socket_params_ : nullptr,
136 HostPortPair("host", 443), ssl_config_, PRIVACY_MODE_DISABLED);
137 }
138
139 void AddAuthToCache() {
140 const base::string16 kFoo(base::ASCIIToUTF16("foo"));
141 const base::string16 kBar(base::ASCIIToUTF16("bar"));
142 session_->http_auth_cache()->Add(
143 GURL("http://proxy:443/"), "MyRealm1", HttpAuth::AUTH_SCHEME_BASIC,
144 "Basic realm=MyRealm1", AuthCredentials(kFoo, kBar), "/");
145 }
146
147 HttpNetworkSession* CreateNetworkSession() {
148 HttpNetworkSession::Context session_context;
149 session_context.host_resolver = &host_resolver_;
150 session_context.cert_verifier = &cert_verifier_;
151 session_context.transport_security_state = &transport_security_state_;
152 session_context.cert_transparency_verifier = &ct_verifier_;
153 session_context.ct_policy_enforcer = &ct_policy_enforcer_;
154 session_context.proxy_resolution_service = proxy_resolution_service_.get();
155 session_context.client_socket_factory = &socket_factory_;
156 session_context.ssl_config_service = ssl_config_service_.get();
157 session_context.http_auth_handler_factory =
158 http_auth_handler_factory_.get();
159 session_context.http_server_properties = &http_server_properties_;
160 return new HttpNetworkSession(HttpNetworkSession::Params(),
161 session_context);
162 }
163
164 protected:
165 MockClientSocketFactory socket_factory_;
Matt Menkeaade5812019-03-02 13:38:00166 MockHostResolver host_resolver_;
Matt Menke7b5051072019-01-27 21:22:49167 MockCertVerifier cert_verifier_;
168 TransportSecurityState transport_security_state_;
169 MultiLogCTVerifier ct_verifier_;
170 DefaultCTPolicyEnforcer ct_policy_enforcer_;
171 const std::unique_ptr<ProxyResolutionService> proxy_resolution_service_;
172 const std::unique_ptr<SSLConfigService> ssl_config_service_;
173 const std::unique_ptr<HttpAuthHandlerFactory> http_auth_handler_factory_;
174 HttpServerPropertiesImpl http_server_properties_;
175 const std::unique_ptr<HttpNetworkSession> session_;
176 SSLClientSocketContext ssl_client_socket_context_;
177
178 scoped_refptr<TransportSocketParams> direct_transport_socket_params_;
Matt Menke7b5051072019-01-27 21:22:49179
180 scoped_refptr<TransportSocketParams> proxy_transport_socket_params_;
181 scoped_refptr<SOCKSSocketParams> socks_socket_params_;
182 scoped_refptr<HttpProxySocketParams> http_proxy_socket_params_;
183
Matt Menke7b5051072019-01-27 21:22:49184 SSLConfig ssl_config_;
Matt Menkea6f99ad2019-03-08 02:26:43185 const CommonConnectJobParams common_connect_job_params_;
Matt Menke7b5051072019-01-27 21:22:49186};
187
188TEST_F(SSLConnectJobTest, TCPFail) {
189 for (IoMode io_mode : {SYNCHRONOUS, ASYNC}) {
190 SCOPED_TRACE(io_mode);
191 host_resolver_.set_synchronous_mode(io_mode == SYNCHRONOUS);
192 StaticSocketDataProvider data;
193 data.set_connect_data(MockConnect(io_mode, ERR_CONNECTION_FAILED));
194 socket_factory_.AddSocketDataProvider(&data);
195
196 TestConnectJobDelegate test_delegate;
197 std::unique_ptr<ConnectJob> ssl_connect_job =
198 CreateConnectJob(&test_delegate);
199 test_delegate.StartJobExpectingResult(
200 ssl_connect_job.get(), ERR_CONNECTION_FAILED, io_mode == SYNCHRONOUS);
201 EXPECT_FALSE(test_delegate.socket());
202 ClientSocketHandle handle;
203 ssl_connect_job->GetAdditionalErrorState(&handle);
204 EXPECT_FALSE(handle.is_ssl_error());
205 ASSERT_EQ(1u, handle.connection_attempts().size());
206 EXPECT_THAT(handle.connection_attempts()[0].result,
207 test::IsError(ERR_CONNECTION_FAILED));
208 }
209}
210
Matt Menke36eaf5c2019-04-02 16:15:52211TEST_F(SSLConnectJobTest, TCPTimeout) {
212 const base::TimeDelta kTinyTime = base::TimeDelta::FromMicroseconds(1);
213
214 // Make request hang.
215 host_resolver_.set_ondemand_mode(true);
216
217 TestConnectJobDelegate test_delegate;
218 std::unique_ptr<ConnectJob> ssl_connect_job =
219 CreateConnectJob(&test_delegate);
220 ASSERT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
221
222 // Right up until just before the TCP connection timeout, the job does not
223 // time out.
224 FastForwardBy(TransportConnectJob::ConnectionTimeout() - kTinyTime);
225 EXPECT_FALSE(test_delegate.has_result());
226
227 // But at the exact time of TCP connection timeout, the job fails.
228 FastForwardBy(kTinyTime);
229 EXPECT_TRUE(test_delegate.has_result());
230 EXPECT_THAT(test_delegate.WaitForResult(), test::IsError(ERR_TIMED_OUT));
231}
232
233TEST_F(SSLConnectJobTest, SSLTimeoutSyncConnect) {
234 const base::TimeDelta kTinyTime = base::TimeDelta::FromMicroseconds(1);
235
236 // DNS lookup and transport connect complete synchronously, but SSL
237 // negotiation hangs.
238 host_resolver_.set_synchronous_mode(true);
239 StaticSocketDataProvider data;
240 data.set_connect_data(MockConnect(SYNCHRONOUS, OK));
241 socket_factory_.AddSocketDataProvider(&data);
242 SSLSocketDataProvider ssl(SYNCHRONOUS, ERR_IO_PENDING);
243 socket_factory_.AddSSLSocketDataProvider(&ssl);
244
245 // Make request hang.
246 TestConnectJobDelegate test_delegate;
247 std::unique_ptr<ConnectJob> ssl_connect_job =
248 CreateConnectJob(&test_delegate);
249 ASSERT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
250
251 // Right up until just before the SSL handshake timeout, the job does not time
252 // out.
253 FastForwardBy(SSLConnectJob::HandshakeTimeoutForTesting() - kTinyTime);
254 EXPECT_FALSE(test_delegate.has_result());
255
256 // But at the exact SSL handshake timeout time, the job fails.
257 FastForwardBy(kTinyTime);
258 EXPECT_TRUE(test_delegate.has_result());
259 EXPECT_THAT(test_delegate.WaitForResult(), test::IsError(ERR_TIMED_OUT));
260}
261
262TEST_F(SSLConnectJobTest, SSLTimeoutAsyncTcpConnect) {
263 const base::TimeDelta kTinyTime = base::TimeDelta::FromMicroseconds(1);
264
265 // DNS lookup is asynchronous, and later SSL negotiation hangs.
266 host_resolver_.set_ondemand_mode(true);
267 StaticSocketDataProvider data;
268 data.set_connect_data(MockConnect(SYNCHRONOUS, OK));
269 socket_factory_.AddSocketDataProvider(&data);
270 SSLSocketDataProvider ssl(SYNCHRONOUS, ERR_IO_PENDING);
271 socket_factory_.AddSSLSocketDataProvider(&ssl);
272
273 TestConnectJobDelegate test_delegate;
274 std::unique_ptr<ConnectJob> ssl_connect_job =
275 CreateConnectJob(&test_delegate);
276 // Connecting should hand on the TransportConnectJob connect.
277 ASSERT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
278
279 // Right up until just before the TCP connection timeout, the job does not
280 // time out.
281 FastForwardBy(TransportConnectJob::ConnectionTimeout() - kTinyTime);
282 EXPECT_FALSE(test_delegate.has_result());
283
284 // The DNS lookup completes, and a TCP connection is immediately establshed,
285 // which cancels the TCP connection timer. The SSL handshake timer is started,
286 // and the SSL handshake hangs.
287 host_resolver_.ResolveOnlyRequestNow();
288 EXPECT_FALSE(test_delegate.has_result());
289
290 // Right up until just before the SSL handshake timeout, the job does not time
291 // out.
292 FastForwardBy(SSLConnectJob::HandshakeTimeoutForTesting() - kTinyTime);
293 EXPECT_FALSE(test_delegate.has_result());
294
295 // But at the exact SSL handshake timeout time, the job fails.
296 FastForwardBy(kTinyTime);
297 EXPECT_TRUE(test_delegate.has_result());
298 EXPECT_THAT(test_delegate.WaitForResult(), test::IsError(ERR_TIMED_OUT));
299}
300
Matt Menke7b5051072019-01-27 21:22:49301TEST_F(SSLConnectJobTest, BasicDirectSync) {
302 host_resolver_.set_synchronous_mode(true);
303 StaticSocketDataProvider data;
304 data.set_connect_data(MockConnect(SYNCHRONOUS, OK));
305 socket_factory_.AddSocketDataProvider(&data);
306 SSLSocketDataProvider ssl(SYNCHRONOUS, OK);
307 socket_factory_.AddSSLSocketDataProvider(&ssl);
308
309 TestConnectJobDelegate test_delegate;
310 std::unique_ptr<ConnectJob> ssl_connect_job =
311 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_DIRECT, MEDIUM);
312
313 test_delegate.StartJobExpectingResult(ssl_connect_job.get(), OK,
314 true /* expect_sync_result */);
315 EXPECT_EQ(MEDIUM, host_resolver_.last_request_priority());
316
317 ClientSocketHandle handle;
318 ssl_connect_job->GetAdditionalErrorState(&handle);
319 EXPECT_EQ(0u, handle.connection_attempts().size());
320 CheckConnectTimesSet(ssl_connect_job->connect_timing());
321}
322
323TEST_F(SSLConnectJobTest, BasicDirectAsync) {
324 host_resolver_.set_ondemand_mode(true);
325 base::TimeTicks start_time = base::TimeTicks::Now();
326 StaticSocketDataProvider data;
327 data.set_connect_data(MockConnect(ASYNC, OK));
328 socket_factory_.AddSocketDataProvider(&data);
329 SSLSocketDataProvider ssl(ASYNC, OK);
330 socket_factory_.AddSSLSocketDataProvider(&ssl);
331
332 TestConnectJobDelegate test_delegate;
333 std::unique_ptr<ConnectJob> ssl_connect_job =
334 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_DIRECT, MEDIUM);
335 EXPECT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
336 EXPECT_TRUE(host_resolver_.has_pending_requests());
337 EXPECT_EQ(MEDIUM, host_resolver_.last_request_priority());
338 FastForwardBy(base::TimeDelta::FromSeconds(5));
339
340 base::TimeTicks resolve_complete_time = base::TimeTicks::Now();
341 host_resolver_.ResolveAllPending();
342 EXPECT_THAT(test_delegate.WaitForResult(), test::IsOk());
343
344 ClientSocketHandle handle;
345 ssl_connect_job->GetAdditionalErrorState(&handle);
346 EXPECT_EQ(0u, handle.connection_attempts().size());
347
348 // Check times. Since time is mocked out, all times will be the same, except
349 // |dns_start|, which is the only one recorded before the FastForwardBy()
350 // call. The test classes don't allow any other phases to be triggered on
351 // demand, or delayed by a set interval.
352 EXPECT_EQ(start_time, ssl_connect_job->connect_timing().dns_start);
353 EXPECT_EQ(resolve_complete_time, ssl_connect_job->connect_timing().dns_end);
354 EXPECT_EQ(resolve_complete_time,
355 ssl_connect_job->connect_timing().connect_start);
356 EXPECT_EQ(resolve_complete_time, ssl_connect_job->connect_timing().ssl_start);
357 EXPECT_EQ(resolve_complete_time, ssl_connect_job->connect_timing().ssl_end);
358 EXPECT_EQ(resolve_complete_time,
359 ssl_connect_job->connect_timing().connect_end);
360}
361
Matt Menke9d5e2c92019-02-05 01:42:23362TEST_F(SSLConnectJobTest, DirectHasEstablishedConnection) {
363 host_resolver_.set_ondemand_mode(true);
364 StaticSocketDataProvider data;
365 data.set_connect_data(MockConnect(ASYNC, OK));
366 socket_factory_.AddSocketDataProvider(&data);
367
368 // SSL negotiation hangs. Value returned after SSL negotiation is complete
369 // doesn't matter, as HasEstablishedConnection() may only be used between job
370 // start and job complete.
371 SSLSocketDataProvider ssl(SYNCHRONOUS, ERR_IO_PENDING);
372 socket_factory_.AddSSLSocketDataProvider(&ssl);
373
374 TestConnectJobDelegate test_delegate;
375 std::unique_ptr<ConnectJob> ssl_connect_job =
376 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_DIRECT, MEDIUM);
377 EXPECT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
378 EXPECT_TRUE(host_resolver_.has_pending_requests());
379 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, ssl_connect_job->GetLoadState());
380 EXPECT_FALSE(ssl_connect_job->HasEstablishedConnection());
381
382 // DNS resolution completes, and then the ConnectJob tries to connect the
383 // socket, which should succeed asynchronously.
384 host_resolver_.ResolveNow(1);
385 EXPECT_EQ(LOAD_STATE_CONNECTING, ssl_connect_job->GetLoadState());
386 EXPECT_FALSE(ssl_connect_job->HasEstablishedConnection());
387
388 // Spinning the message loop causes the socket to finish connecting. The SSL
389 // handshake should start and hang.
390 base::RunLoop().RunUntilIdle();
391 EXPECT_FALSE(test_delegate.has_result());
392 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, ssl_connect_job->GetLoadState());
393 EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
394}
395
Matt Menke7b5051072019-01-27 21:22:49396TEST_F(SSLConnectJobTest, RequestPriority) {
397 host_resolver_.set_ondemand_mode(true);
Matt Menke7b5051072019-01-27 21:22:49398 for (int initial_priority = MINIMUM_PRIORITY;
399 initial_priority <= MAXIMUM_PRIORITY; ++initial_priority) {
400 SCOPED_TRACE(initial_priority);
401 for (int new_priority = MINIMUM_PRIORITY; new_priority <= MAXIMUM_PRIORITY;
402 ++new_priority) {
403 SCOPED_TRACE(new_priority);
404 if (initial_priority == new_priority)
405 continue;
406 TestConnectJobDelegate test_delegate;
407 std::unique_ptr<ConnectJob> ssl_connect_job =
408 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_DIRECT,
409 static_cast<RequestPriority>(initial_priority));
410 EXPECT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
411 EXPECT_TRUE(host_resolver_.has_pending_requests());
412 int request_id = host_resolver_.num_resolve();
413 EXPECT_EQ(initial_priority, host_resolver_.request_priority(request_id));
414
415 ssl_connect_job->ChangePriority(
416 static_cast<RequestPriority>(new_priority));
417 EXPECT_EQ(new_priority, host_resolver_.request_priority(request_id));
418
419 ssl_connect_job->ChangePriority(
420 static_cast<RequestPriority>(initial_priority));
421 EXPECT_EQ(initial_priority, host_resolver_.request_priority(request_id));
Matt Menke7b5051072019-01-27 21:22:49422 }
423 }
424}
425
426TEST_F(SSLConnectJobTest, DirectCertError) {
427 StaticSocketDataProvider data;
428 socket_factory_.AddSocketDataProvider(&data);
429 SSLSocketDataProvider ssl(ASYNC, ERR_CERT_COMMON_NAME_INVALID);
430 socket_factory_.AddSSLSocketDataProvider(&ssl);
431
432 TestConnectJobDelegate test_delegate(
433 TestConnectJobDelegate::SocketExpected::ALWAYS);
434 std::unique_ptr<ConnectJob> ssl_connect_job =
435 CreateConnectJob(&test_delegate);
436
437 test_delegate.StartJobExpectingResult(ssl_connect_job.get(),
438 ERR_CERT_COMMON_NAME_INVALID,
439 false /* expect_sync_result */);
440 ClientSocketHandle handle;
441 ssl_connect_job->GetAdditionalErrorState(&handle);
442 EXPECT_TRUE(handle.is_ssl_error());
443 ASSERT_EQ(1u, handle.connection_attempts().size());
444 EXPECT_THAT(handle.connection_attempts()[0].result,
445 test::IsError(ERR_CERT_COMMON_NAME_INVALID));
446 CheckConnectTimesSet(ssl_connect_job->connect_timing());
447}
448
449TEST_F(SSLConnectJobTest, DirectSSLError) {
450 StaticSocketDataProvider data;
451 socket_factory_.AddSocketDataProvider(&data);
452 SSLSocketDataProvider ssl(ASYNC, ERR_SSL_PROTOCOL_ERROR);
453 socket_factory_.AddSSLSocketDataProvider(&ssl);
454
455 TestConnectJobDelegate test_delegate;
456 std::unique_ptr<ConnectJob> ssl_connect_job =
457 CreateConnectJob(&test_delegate);
458
459 test_delegate.StartJobExpectingResult(ssl_connect_job.get(),
460 ERR_SSL_PROTOCOL_ERROR,
461 false /* expect_sync_result */);
462 ClientSocketHandle handle;
463 ssl_connect_job->GetAdditionalErrorState(&handle);
464 EXPECT_TRUE(handle.is_ssl_error());
465 ASSERT_EQ(1u, handle.connection_attempts().size());
466 EXPECT_THAT(handle.connection_attempts()[0].result,
467 test::IsError(ERR_SSL_PROTOCOL_ERROR));
468}
469
470TEST_F(SSLConnectJobTest, DirectWithNPN) {
471 StaticSocketDataProvider data;
472 socket_factory_.AddSocketDataProvider(&data);
473 SSLSocketDataProvider ssl(ASYNC, OK);
474 ssl.next_proto = kProtoHTTP11;
475 socket_factory_.AddSSLSocketDataProvider(&ssl);
476
477 TestConnectJobDelegate test_delegate;
478 std::unique_ptr<ConnectJob> ssl_connect_job =
479 CreateConnectJob(&test_delegate);
480
481 test_delegate.StartJobExpectingResult(ssl_connect_job.get(), OK,
482 false /* expect_sync_result */);
483 EXPECT_TRUE(test_delegate.socket()->WasAlpnNegotiated());
484 CheckConnectTimesSet(ssl_connect_job->connect_timing());
485}
486
487TEST_F(SSLConnectJobTest, DirectGotHTTP2) {
488 StaticSocketDataProvider data;
489 socket_factory_.AddSocketDataProvider(&data);
490 SSLSocketDataProvider ssl(ASYNC, OK);
491 ssl.next_proto = kProtoHTTP2;
492 socket_factory_.AddSSLSocketDataProvider(&ssl);
493
494 TestConnectJobDelegate test_delegate;
495 std::unique_ptr<ConnectJob> ssl_connect_job =
496 CreateConnectJob(&test_delegate);
497
498 test_delegate.StartJobExpectingResult(ssl_connect_job.get(), OK,
499 false /* expect_sync_result */);
500 EXPECT_TRUE(test_delegate.socket()->WasAlpnNegotiated());
501 EXPECT_EQ(kProtoHTTP2, test_delegate.socket()->GetNegotiatedProtocol());
502 CheckConnectTimesSet(ssl_connect_job->connect_timing());
503}
504
505TEST_F(SSLConnectJobTest, SOCKSFail) {
506 for (IoMode io_mode : {SYNCHRONOUS, ASYNC}) {
507 SCOPED_TRACE(io_mode);
508 host_resolver_.set_synchronous_mode(io_mode == SYNCHRONOUS);
509 StaticSocketDataProvider data;
510 data.set_connect_data(MockConnect(io_mode, ERR_CONNECTION_FAILED));
511 socket_factory_.AddSocketDataProvider(&data);
512
513 TestConnectJobDelegate test_delegate;
514 std::unique_ptr<ConnectJob> ssl_connect_job =
515 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_SOCKS5);
516 test_delegate.StartJobExpectingResult(ssl_connect_job.get(),
517 ERR_PROXY_CONNECTION_FAILED,
518 io_mode == SYNCHRONOUS);
519
520 ClientSocketHandle handle;
521 ssl_connect_job->GetAdditionalErrorState(&handle);
522 EXPECT_FALSE(handle.is_ssl_error());
523 EXPECT_EQ(0u, handle.connection_attempts().size());
524 }
525}
526
527TEST_F(SSLConnectJobTest, SOCKSBasic) {
528 for (IoMode io_mode : {SYNCHRONOUS, ASYNC}) {
529 SCOPED_TRACE(io_mode);
530 const char kSOCKS5Request[] = {0x05, 0x01, 0x00, 0x03, 0x09, 's',
531 'o', 'c', 'k', 's', 'h', 'o',
532 's', 't', 0x01, 0xBB};
533
534 MockWrite writes[] = {
535 MockWrite(io_mode, kSOCKS5GreetRequest, kSOCKS5GreetRequestLength),
Matt Menke628d624f2019-02-09 00:40:24536 MockWrite(io_mode, kSOCKS5Request, base::size(kSOCKS5Request)),
537 };
Matt Menke7b5051072019-01-27 21:22:49538
539 MockRead reads[] = {
540 MockRead(io_mode, kSOCKS5GreetResponse, kSOCKS5GreetResponseLength),
Matt Menke628d624f2019-02-09 00:40:24541 MockRead(io_mode, kSOCKS5OkResponse, kSOCKS5OkResponseLength),
542 };
Matt Menke7b5051072019-01-27 21:22:49543
544 host_resolver_.set_synchronous_mode(io_mode == SYNCHRONOUS);
545 StaticSocketDataProvider data(reads, writes);
546 data.set_connect_data(MockConnect(io_mode, OK));
547 socket_factory_.AddSocketDataProvider(&data);
548 SSLSocketDataProvider ssl(io_mode, OK);
549 socket_factory_.AddSSLSocketDataProvider(&ssl);
550
551 TestConnectJobDelegate test_delegate;
552 std::unique_ptr<ConnectJob> ssl_connect_job =
553 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_SOCKS5);
554 test_delegate.StartJobExpectingResult(ssl_connect_job.get(), OK,
555 io_mode == SYNCHRONOUS);
556 CheckConnectTimesExceptDnsSet(ssl_connect_job->connect_timing());
557 }
558}
559
Matt Menke628d624f2019-02-09 00:40:24560TEST_F(SSLConnectJobTest, SOCKSHasEstablishedConnection) {
561 const char kSOCKS5Request[] = {0x05, 0x01, 0x00, 0x03, 0x09, 's', 'o', 'c',
562 'k', 's', 'h', 'o', 's', 't', 0x01, 0xBB};
563
564 MockWrite writes[] = {
565 MockWrite(SYNCHRONOUS, kSOCKS5GreetRequest, kSOCKS5GreetRequestLength, 0),
566 MockWrite(SYNCHRONOUS, kSOCKS5Request, base::size(kSOCKS5Request), 3),
567 };
568
569 MockRead reads[] = {
570 // Pause so can probe current state.
571 MockRead(ASYNC, ERR_IO_PENDING, 1),
572 MockRead(ASYNC, kSOCKS5GreetResponse, kSOCKS5GreetResponseLength, 2),
573 MockRead(SYNCHRONOUS, kSOCKS5OkResponse, kSOCKS5OkResponseLength, 4),
574 };
575
576 host_resolver_.set_ondemand_mode(true);
577 SequencedSocketData data(reads, writes);
578 data.set_connect_data(MockConnect(ASYNC, OK));
579 socket_factory_.AddSocketDataProvider(&data);
580
581 // SSL negotiation hangs. Value returned after SSL negotiation is complete
582 // doesn't matter, as HasEstablishedConnection() may only be used between job
583 // start and job complete.
584 SSLSocketDataProvider ssl(SYNCHRONOUS, ERR_IO_PENDING);
585 socket_factory_.AddSSLSocketDataProvider(&ssl);
586
587 TestConnectJobDelegate test_delegate;
588 std::unique_ptr<ConnectJob> ssl_connect_job =
589 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_SOCKS5);
590 EXPECT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
591 EXPECT_TRUE(host_resolver_.has_pending_requests());
592 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, ssl_connect_job->GetLoadState());
593 EXPECT_FALSE(ssl_connect_job->HasEstablishedConnection());
594
595 // DNS resolution completes, and then the ConnectJob tries to connect the
596 // socket, which should succeed asynchronously.
597 host_resolver_.ResolveNow(1);
598 EXPECT_EQ(LOAD_STATE_CONNECTING, ssl_connect_job->GetLoadState());
599 EXPECT_FALSE(ssl_connect_job->HasEstablishedConnection());
600
601 // Spin the message loop until the first read of the handshake.
602 // HasEstablishedConnection() should return true, as a TCP connection has been
603 // successfully established by this point.
604 data.RunUntilPaused();
605 EXPECT_FALSE(test_delegate.has_result());
606 EXPECT_EQ(LOAD_STATE_CONNECTING, ssl_connect_job->GetLoadState());
607 EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
608
609 // Finish up the handshake, and spin the message loop until the SSL handshake
610 // starts and hang.
611 data.Resume();
612 base::RunLoop().RunUntilIdle();
613 EXPECT_FALSE(test_delegate.has_result());
614 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, ssl_connect_job->GetLoadState());
615 EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
616}
617
Matt Menke7b5051072019-01-27 21:22:49618TEST_F(SSLConnectJobTest, SOCKSRequestPriority) {
619 host_resolver_.set_ondemand_mode(true);
Matt Menke7b5051072019-01-27 21:22:49620 for (int initial_priority = MINIMUM_PRIORITY;
621 initial_priority <= MAXIMUM_PRIORITY; ++initial_priority) {
622 SCOPED_TRACE(initial_priority);
623 for (int new_priority = MINIMUM_PRIORITY; new_priority <= MAXIMUM_PRIORITY;
624 ++new_priority) {
625 SCOPED_TRACE(new_priority);
626 if (initial_priority == new_priority)
627 continue;
628 TestConnectJobDelegate test_delegate;
629 std::unique_ptr<ConnectJob> ssl_connect_job =
630 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_SOCKS5,
631 static_cast<RequestPriority>(initial_priority));
632 EXPECT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
633 EXPECT_TRUE(host_resolver_.has_pending_requests());
634 int request_id = host_resolver_.num_resolve();
635 EXPECT_EQ(initial_priority, host_resolver_.request_priority(request_id));
636
637 ssl_connect_job->ChangePriority(
638 static_cast<RequestPriority>(new_priority));
639 EXPECT_EQ(new_priority, host_resolver_.request_priority(request_id));
640
641 ssl_connect_job->ChangePriority(
642 static_cast<RequestPriority>(initial_priority));
643 EXPECT_EQ(initial_priority, host_resolver_.request_priority(request_id));
Matt Menke7b5051072019-01-27 21:22:49644 }
645 }
646}
647
648TEST_F(SSLConnectJobTest, HttpProxyFail) {
649 for (IoMode io_mode : {SYNCHRONOUS, ASYNC}) {
650 SCOPED_TRACE(io_mode);
651 host_resolver_.set_synchronous_mode(io_mode == SYNCHRONOUS);
652 StaticSocketDataProvider data;
653 data.set_connect_data(MockConnect(io_mode, ERR_CONNECTION_FAILED));
654 socket_factory_.AddSocketDataProvider(&data);
655
656 TestConnectJobDelegate test_delegate;
657 std::unique_ptr<ConnectJob> ssl_connect_job =
658 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_HTTP);
659 test_delegate.StartJobExpectingResult(ssl_connect_job.get(),
660 ERR_PROXY_CONNECTION_FAILED,
661 io_mode == SYNCHRONOUS);
662
663 ClientSocketHandle handle;
664 ssl_connect_job->GetAdditionalErrorState(&handle);
665 EXPECT_FALSE(handle.is_ssl_error());
666 EXPECT_EQ(0u, handle.connection_attempts().size());
667 }
668}
669
Matt Menkeb57663b32019-03-01 17:17:10670TEST_F(SSLConnectJobTest, HttpProxyAuthChallenge) {
671 MockWrite writes[] = {
672 MockWrite(ASYNC, 0,
673 "CONNECT host:80 HTTP/1.1\r\n"
674 "Host: host:80\r\n"
675 "Proxy-Connection: keep-alive\r\n\r\n"),
676 MockWrite(ASYNC, 5,
677 "CONNECT host:80 HTTP/1.1\r\n"
678 "Host: host:80\r\n"
679 "Proxy-Connection: keep-alive\r\n"
680 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
681 };
682 MockRead reads[] = {
683 MockRead(ASYNC, 1, "HTTP/1.1 407 Proxy Authentication Required\r\n"),
684 MockRead(ASYNC, 2, "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"),
685 MockRead(ASYNC, 3, "Content-Length: 10\r\n\r\n"),
686 MockRead(ASYNC, 4, "0123456789"),
687 MockRead(ASYNC, 6, "HTTP/1.1 200 Connection Established\r\n\r\n"),
688 };
689 StaticSocketDataProvider data(reads, writes);
690 socket_factory_.AddSocketDataProvider(&data);
691 SSLSocketDataProvider ssl(ASYNC, OK);
692 socket_factory_.AddSSLSocketDataProvider(&ssl);
693
694 ClientSocketHandle handle;
695 TestCompletionCallback callback;
696
697 TestConnectJobDelegate test_delegate;
698 std::unique_ptr<ConnectJob> ssl_connect_job =
699 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_HTTP);
700 ASSERT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
701 test_delegate.WaitForAuthChallenge(1);
702
703 EXPECT_EQ(407, test_delegate.auth_response_info().headers->response_code());
704 std::string proxy_authenticate;
705 ASSERT_TRUE(test_delegate.auth_response_info().headers->EnumerateHeader(
706 nullptr, "Proxy-Authenticate", &proxy_authenticate));
707 EXPECT_EQ(proxy_authenticate, "Basic realm=\"MyRealm1\"");
708
709 // While waiting for auth credentials to be provided, the Job should not time
710 // out.
711 FastForwardBy(base::TimeDelta::FromDays(1));
712 test_delegate.WaitForAuthChallenge(1);
713 EXPECT_FALSE(test_delegate.has_result());
714
715 // Respond to challenge.
716 test_delegate.auth_controller()->ResetAuth(
717 AuthCredentials(base::ASCIIToUTF16("foo"), base::ASCIIToUTF16("bar")));
718 test_delegate.RunAuthCallback();
719
720 EXPECT_THAT(test_delegate.WaitForResult(), test::IsOk());
721}
722
723TEST_F(SSLConnectJobTest, HttpProxyAuthWithCachedCredentials) {
Matt Menke7b5051072019-01-27 21:22:49724 for (IoMode io_mode : {SYNCHRONOUS, ASYNC}) {
725 SCOPED_TRACE(io_mode);
726 host_resolver_.set_synchronous_mode(io_mode == SYNCHRONOUS);
727 MockWrite writes[] = {
728 MockWrite(io_mode,
729 "CONNECT host:80 HTTP/1.1\r\n"
730 "Host: host:80\r\n"
731 "Proxy-Connection: keep-alive\r\n"
732 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
733 };
734 MockRead reads[] = {
735 MockRead(io_mode, "HTTP/1.1 200 Connection Established\r\n\r\n"),
736 };
737 StaticSocketDataProvider data(reads, writes);
738 data.set_connect_data(MockConnect(io_mode, OK));
739 socket_factory_.AddSocketDataProvider(&data);
740 AddAuthToCache();
741 SSLSocketDataProvider ssl(io_mode, OK);
742 socket_factory_.AddSSLSocketDataProvider(&ssl);
743
744 TestConnectJobDelegate test_delegate;
745 std::unique_ptr<ConnectJob> ssl_connect_job =
746 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_HTTP);
747 test_delegate.StartJobExpectingResult(ssl_connect_job.get(), OK,
748 io_mode == SYNCHRONOUS);
749 CheckConnectTimesExceptDnsSet(ssl_connect_job->connect_timing());
750 }
751}
752
753TEST_F(SSLConnectJobTest, HttpProxyRequestPriority) {
754 host_resolver_.set_ondemand_mode(true);
Matt Menke7b5051072019-01-27 21:22:49755 for (int initial_priority = MINIMUM_PRIORITY;
756 initial_priority <= MAXIMUM_PRIORITY; ++initial_priority) {
757 SCOPED_TRACE(initial_priority);
758 for (int new_priority = MINIMUM_PRIORITY; new_priority <= MAXIMUM_PRIORITY;
759 ++new_priority) {
760 SCOPED_TRACE(new_priority);
761 if (initial_priority == new_priority)
762 continue;
763 TestConnectJobDelegate test_delegate;
764 std::unique_ptr<ConnectJob> ssl_connect_job =
765 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_HTTP,
766 static_cast<RequestPriority>(initial_priority));
767 EXPECT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
768 EXPECT_TRUE(host_resolver_.has_pending_requests());
769 int request_id = host_resolver_.num_resolve();
770 EXPECT_EQ(initial_priority, host_resolver_.request_priority(request_id));
771
772 ssl_connect_job->ChangePriority(
773 static_cast<RequestPriority>(new_priority));
774 EXPECT_EQ(new_priority, host_resolver_.request_priority(request_id));
775
776 ssl_connect_job->ChangePriority(
777 static_cast<RequestPriority>(initial_priority));
778 EXPECT_EQ(initial_priority, host_resolver_.request_priority(request_id));
Matt Menke7b5051072019-01-27 21:22:49779 }
780 }
781}
782
Matt Menkeaade5812019-03-02 13:38:00783TEST_F(SSLConnectJobTest, HttpProxyAuthHasEstablishedConnection) {
784 host_resolver_.set_ondemand_mode(true);
785 MockWrite writes[] = {
786 MockWrite(ASYNC, 0,
787 "CONNECT host:80 HTTP/1.1\r\n"
788 "Host: host:80\r\n"
789 "Proxy-Connection: keep-alive\r\n\r\n"),
790 MockWrite(ASYNC, 3,
791 "CONNECT host:80 HTTP/1.1\r\n"
792 "Host: host:80\r\n"
793 "Proxy-Connection: keep-alive\r\n"
794 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
795 };
796 MockRead reads[] = {
797 // Pause reading.
798 MockRead(ASYNC, ERR_IO_PENDING, 1),
799 MockRead(ASYNC, 2,
800 "HTTP/1.1 407 Proxy Authentication Required\r\n"
801 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
802 "Content-Length: 0\r\n\r\n"),
803 // Pause reading.
804 MockRead(ASYNC, ERR_IO_PENDING, 4),
805 MockRead(ASYNC, 5, "HTTP/1.1 200 Connection Established\r\n\r\n"),
806 };
807 SequencedSocketData data(reads, writes);
808 socket_factory_.AddSocketDataProvider(&data);
809 SSLSocketDataProvider ssl(ASYNC, OK);
810 socket_factory_.AddSSLSocketDataProvider(&ssl);
811
812 ClientSocketHandle handle;
813 TestCompletionCallback callback;
814
815 TestConnectJobDelegate test_delegate;
816 std::unique_ptr<ConnectJob> ssl_connect_job =
817 CreateConnectJob(&test_delegate, ProxyServer::SCHEME_HTTP);
818 ASSERT_THAT(ssl_connect_job->Connect(), test::IsError(ERR_IO_PENDING));
819 EXPECT_TRUE(host_resolver_.has_pending_requests());
820 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, ssl_connect_job->GetLoadState());
821 EXPECT_FALSE(ssl_connect_job->HasEstablishedConnection());
822
823 // DNS resolution completes, and then the ConnectJob tries to connect the
824 // socket, which should succeed asynchronously.
825 host_resolver_.ResolveOnlyRequestNow();
826 EXPECT_EQ(LOAD_STATE_CONNECTING, ssl_connect_job->GetLoadState());
827 EXPECT_FALSE(ssl_connect_job->HasEstablishedConnection());
828
829 // Spinning the message loop causes the connection to be established and the
830 // nested HttpProxyConnectJob to start establishing a tunnel.
831 base::RunLoop().RunUntilIdle();
832 EXPECT_FALSE(test_delegate.has_result());
833 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
834 ssl_connect_job->GetLoadState());
835 EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
836
837 // Receive the auth challenge.
838 data.Resume();
839 test_delegate.WaitForAuthChallenge(1);
840 EXPECT_FALSE(test_delegate.has_result());
841 EXPECT_EQ(LOAD_STATE_IDLE, ssl_connect_job->GetLoadState());
842 EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
843
844 // Respond to challenge.
845 test_delegate.auth_controller()->ResetAuth(
846 AuthCredentials(base::ASCIIToUTF16("foo"), base::ASCIIToUTF16("bar")));
847 test_delegate.RunAuthCallback();
848 EXPECT_FALSE(test_delegate.has_result());
849 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
850 ssl_connect_job->GetLoadState());
851 EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
852
853 // Run until the next read pauses.
854 base::RunLoop().RunUntilIdle();
855 EXPECT_FALSE(test_delegate.has_result());
856 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
857 ssl_connect_job->GetLoadState());
858 EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
859
860 // Receive the connection established response, at which point SSL negotiation
861 // finally starts.
862 data.Resume();
863 EXPECT_FALSE(test_delegate.has_result());
864 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, ssl_connect_job->GetLoadState());
865 EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
866
867 EXPECT_THAT(test_delegate.WaitForResult(), test::IsOk());
868}
869
870TEST_F(SSLConnectJobTest,
871 HttpProxyAuthHasEstablishedConnectionWithProxyConnectionClose) {
872 host_resolver_.set_ondemand_mode(true);
873 MockWrite writes1[] = {
874 MockWrite(ASYNC, 0,
875 "CONNECT host:80 HTTP/1.1\r\n"
876 "Host: host:80\r\n"
877 "Proxy-Connection: keep-alive\r\n\r\n"),
878 };
879 MockRead reads1[] = {
880 // Pause reading.
881 MockRead(ASYNC, ERR_IO_PENDING, 1),
882 MockRead(ASYNC, 2,
883 "HTTP/1.1 407 Proxy Authentication Required\r\n"
884 "Proxy-Connection: Close\r\n"
885 "Proxy-Authenticate: Basic realm=\"MyRealm1\"\r\n"
886 "Content-Length: 0\r\n\r\n"),
887 };
888 SequencedSocketData data1(reads1, writes1);
889 socket_factory_.AddSocketDataProvider(&data1);
890
891 MockWrite writes2[] = {
892 MockWrite(ASYNC, 0,
893 "CONNECT host:80 HTTP/1.1\r\n"
894 "Host: host:80\r\n"
895 "Proxy-Connection: keep-alive\r\n"
896 "Proxy-Authorization: Basic Zm9vOmJhcg==\r\n\r\n"),
897 };
898 MockRead reads2[] = {
899 // Pause reading.
900 MockRead(ASYNC, ERR_IO_PENDING, 1),
901 MockRead(ASYNC, 2, "HTTP/1.1 200 Connection Established\r\n\r\n"),
902 };
903 SequencedSocketData data2(reads2, writes2);
904 socket_factory_.AddSocketDataProvider(&data2);
905 SSLSocketDataProvider ssl(ASYNC, OK);
906 socket_factory_.AddSSLSocketDataProvider(&ssl);
907
908 ClientSocketHandle handle;
909 TestCompletionCallback callback;
910
911 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 EXPECT_TRUE(host_resolver_.has_pending_requests());
916 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, ssl_connect_job->GetLoadState());
917 EXPECT_FALSE(ssl_connect_job->HasEstablishedConnection());
918
919 // DNS resolution completes, and then the ConnectJob tries to connect the
920 // socket, which should succeed asynchronously.
921 host_resolver_.ResolveOnlyRequestNow();
922 EXPECT_EQ(LOAD_STATE_CONNECTING, ssl_connect_job->GetLoadState());
923 EXPECT_FALSE(ssl_connect_job->HasEstablishedConnection());
924
925 // Spinning the message loop causes the connection to be established and the
926 // nested HttpProxyConnectJob to start establishing a tunnel.
927 base::RunLoop().RunUntilIdle();
928 EXPECT_FALSE(test_delegate.has_result());
929 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
930 ssl_connect_job->GetLoadState());
931 EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
932
933 // Receive the auth challenge.
934 data1.Resume();
935 test_delegate.WaitForAuthChallenge(1);
936 EXPECT_FALSE(test_delegate.has_result());
937 EXPECT_EQ(LOAD_STATE_IDLE, ssl_connect_job->GetLoadState());
938 EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
939
940 // Respond to challenge.
941 test_delegate.auth_controller()->ResetAuth(
942 AuthCredentials(base::ASCIIToUTF16("foo"), base::ASCIIToUTF16("bar")));
943 test_delegate.RunAuthCallback();
944 EXPECT_FALSE(test_delegate.has_result());
945 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
946 ssl_connect_job->GetLoadState());
947 EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
948
949 // Run until the next DNS lookup.
950 base::RunLoop().RunUntilIdle();
951 EXPECT_TRUE(host_resolver_.has_pending_requests());
952 EXPECT_EQ(LOAD_STATE_RESOLVING_HOST, ssl_connect_job->GetLoadState());
953 EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
954
955 // DNS resolution completes, and then the ConnectJob tries to connect the
956 // socket, which should succeed asynchronously.
957 host_resolver_.ResolveOnlyRequestNow();
958 EXPECT_EQ(LOAD_STATE_CONNECTING, ssl_connect_job->GetLoadState());
959 EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
960
961 // Spinning the message loop causes the connection to be established and the
962 // nested HttpProxyConnectJob to start establishing a tunnel.
963 base::RunLoop().RunUntilIdle();
964 EXPECT_FALSE(test_delegate.has_result());
965 EXPECT_EQ(LOAD_STATE_ESTABLISHING_PROXY_TUNNEL,
966 ssl_connect_job->GetLoadState());
967 EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
968
969 // Receive the connection established response, at which point SSL negotiation
970 // finally starts.
971 data2.Resume();
972 EXPECT_FALSE(test_delegate.has_result());
973 EXPECT_EQ(LOAD_STATE_SSL_HANDSHAKE, ssl_connect_job->GetLoadState());
974 EXPECT_TRUE(ssl_connect_job->HasEstablishedConnection());
975
976 EXPECT_THAT(test_delegate.WaitForResult(), test::IsOk());
977}
978
Matt Menke7b5051072019-01-27 21:22:49979} // namespace
980} // namespace net