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