1 // Copyright (c) 2012 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.
7 #include "base/basictypes.h"
8 #include "base/compiler_specific.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/stl_util.h"
11 #include "net/base/test_completion_callback.h"
12 #include "net/base/test_data_directory.h"
13 #include "net/cert/mock_cert_verifier.h"
14 #include "net/dns/mock_host_resolver.h"
15 #include "net/http/http_auth_handler_factory.h"
16 #include "net/http/http_network_session.h"
17 #include "net/http/http_network_transaction.h"
18 #include "net/http/http_server_properties_impl.h"
19 #include "net/http/http_stream.h"
20 #include "net/http/http_stream_factory.h"
21 #include "net/http/http_transaction_test_util.h"
22 #include "net/http/transport_security_state.h"
23 #include "net/log/test_net_log.h"
24 #include "net/log/test_net_log_entry.h"
25 #include "net/log/test_net_log_util.h"
26 #include "net/proxy/proxy_config_service_fixed.h"
27 #include "net/proxy/proxy_resolver.h"
28 #include "net/proxy/proxy_service.h"
29 #include "net/quic/crypto/proof_verifier_chromium.h"
30 #include "net/quic/crypto/quic_decrypter.h"
31 #include "net/quic/crypto/quic_encrypter.h"
32 #include "net/quic/quic_framer.h"
33 #include "net/quic/quic_http_utils.h"
34 #include "net/quic/test_tools/crypto_test_utils.h"
35 #include "net/quic/test_tools/mock_clock.h"
36 #include "net/quic/test_tools/mock_crypto_client_stream_factory.h"
37 #include "net/quic/test_tools/mock_random.h"
38 #include "net/quic/test_tools/quic_test_packet_maker.h"
39 #include "net/quic/test_tools/quic_test_utils.h"
40 #include "net/socket/client_socket_factory.h"
41 #include "net/socket/mock_client_socket_pool_manager.h"
42 #include "net/socket/socket_test_util.h"
43 #include "net/socket/ssl_client_socket.h"
44 #include "net/spdy/spdy_frame_builder.h"
45 #include "net/spdy/spdy_framer.h"
46 #include "net/ssl/ssl_config_service_defaults.h"
47 #include "net/test/cert_test_util.h"
48 #include "testing/gtest/include/gtest/gtest.h"
49 #include "testing/platform_test.h"
56 static const char kQuicAlternateProtocolHttpHeader
[] =
57 "Alternate-Protocol: 80:quic\r\n\r\n";
58 static const char kQuicAlternateProtocol50pctHttpHeader
[] =
59 "Alternate-Protocol: 80:quic,p=.5\r\n\r\n";
60 static const char kQuicAlternateProtocolDifferentPortHttpHeader
[] =
61 "Alternate-Protocol: 137:quic\r\n\r\n";
62 static const char kQuicAlternateProtocolHttpsHeader
[] =
63 "Alternate-Protocol: 443:quic\r\n\r\n";
64 static const char kQuicAlternativeServiceHttpHeader
[] =
65 "Alt-Svc: quic=\":80\"\r\n\r\n";
66 static const char kQuicAlternativeService50pctHttpHeader
[] =
67 "Alt-Svc: quic=\":80\";p=.5\r\n\r\n";
68 static const char kQuicAlternativeServiceDifferentPortHttpHeader
[] =
69 "Alt-Svc: quic=\":137\"\r\n\r\n";
70 static const char kQuicAlternativeServiceHttpsHeader
[] =
71 "Alt-Svc: quic=\":443\"\r\n\r\n";
73 const char kDefaultServerHostName
[] = "www.google.com";
77 // Helper class to encapsulate MockReads and MockWrites for QUIC.
78 // Simplify ownership issues and the interaction with the MockSocketFactory.
81 MockQuicData() : sequence_number_(0) {}
84 STLDeleteElements(&packets_
);
87 void AddSynchronousRead(scoped_ptr
<QuicEncryptedPacket
> packet
) {
88 reads_
.push_back(MockRead(SYNCHRONOUS
, packet
->data(), packet
->length(),
90 packets_
.push_back(packet
.release());
93 void AddRead(scoped_ptr
<QuicEncryptedPacket
> packet
) {
95 MockRead(ASYNC
, packet
->data(), packet
->length(), sequence_number_
++));
96 packets_
.push_back(packet
.release());
99 void AddRead(IoMode mode
, int rv
) {
100 reads_
.push_back(MockRead(mode
, rv
, sequence_number_
++));
103 void AddWrite(scoped_ptr
<QuicEncryptedPacket
> packet
) {
104 writes_
.push_back(MockWrite(SYNCHRONOUS
, packet
->data(), packet
->length(),
105 sequence_number_
++));
106 packets_
.push_back(packet
.release());
109 void AddSocketDataToFactory(MockClientSocketFactory
* factory
) {
110 MockRead
* reads
= reads_
.empty() ? nullptr : &reads_
[0];
111 MockWrite
* writes
= writes_
.empty() ? nullptr : &writes_
[0];
113 new SequencedSocketData(reads
, reads_
.size(), writes
, writes_
.size()));
114 factory
->AddSocketDataProvider(socket_data_
.get());
117 void CompleteRead() { socket_data_
->CompleteRead(); }
120 std::vector
<QuicEncryptedPacket
*> packets_
;
121 std::vector
<MockWrite
> writes_
;
122 std::vector
<MockRead
> reads_
;
123 size_t sequence_number_
;
124 scoped_ptr
<SequencedSocketData
> socket_data_
;
127 class ProxyHeadersHandler
{
129 ProxyHeadersHandler() : was_called_(false) {}
131 bool was_called() { return was_called_
; }
133 void OnBeforeProxyHeadersSent(const ProxyInfo
& proxy_info
,
134 HttpRequestHeaders
* request_headers
) {
142 class QuicNetworkTransactionTest
143 : public PlatformTest
,
144 public ::testing::WithParamInterface
<QuicVersion
> {
146 QuicNetworkTransactionTest()
147 : clock_(new MockClock
),
148 maker_(GetParam(), 0, clock_
, kDefaultServerHostName
),
149 ssl_config_service_(new SSLConfigServiceDefaults
),
150 proxy_service_(ProxyService::CreateDirect()),
151 auth_handler_factory_(
152 HttpAuthHandlerFactory::CreateDefault(&host_resolver_
)),
153 random_generator_(0),
154 hanging_data_(nullptr, 0, nullptr, 0) {
155 request_
.method
= "GET";
156 std::string
url("http://");
157 url
.append(kDefaultServerHostName
);
158 request_
.url
= GURL(url
);
159 request_
.load_flags
= 0;
160 clock_
->AdvanceTime(QuicTime::Delta::FromMilliseconds(20));
163 void SetUp() override
{
164 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
165 base::MessageLoop::current()->RunUntilIdle();
168 void TearDown() override
{
169 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
170 // Empty the current queue.
171 base::MessageLoop::current()->RunUntilIdle();
172 PlatformTest::TearDown();
173 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
174 base::MessageLoop::current()->RunUntilIdle();
177 scoped_ptr
<QuicEncryptedPacket
> ConstructConnectionClosePacket(
178 QuicPacketSequenceNumber num
) {
179 return maker_
.MakeConnectionClosePacket(num
);
182 scoped_ptr
<QuicEncryptedPacket
> ConstructAckPacket(
183 QuicPacketSequenceNumber largest_received
,
184 QuicPacketSequenceNumber least_unacked
) {
185 return maker_
.MakeAckPacket(2, largest_received
, least_unacked
, true);
188 SpdyHeaderBlock
GetRequestHeaders(const std::string
& method
,
189 const std::string
& scheme
,
190 const std::string
& path
) {
191 return maker_
.GetRequestHeaders(method
, scheme
, path
);
194 SpdyHeaderBlock
GetResponseHeaders(const std::string
& status
) {
195 return maker_
.GetResponseHeaders(status
);
198 scoped_ptr
<QuicEncryptedPacket
> ConstructDataPacket(
199 QuicPacketSequenceNumber sequence_number
,
200 QuicStreamId stream_id
,
201 bool should_include_version
,
203 QuicStreamOffset offset
,
204 base::StringPiece data
) {
205 return maker_
.MakeDataPacket(
206 sequence_number
, stream_id
, should_include_version
, fin
, offset
, data
);
209 scoped_ptr
<QuicEncryptedPacket
> ConstructRequestHeadersPacket(
210 QuicPacketSequenceNumber sequence_number
,
211 QuicStreamId stream_id
,
212 bool should_include_version
,
214 const SpdyHeaderBlock
& headers
) {
215 QuicPriority priority
=
216 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY
);
217 return maker_
.MakeRequestHeadersPacket(sequence_number
, stream_id
,
218 should_include_version
, fin
,
222 scoped_ptr
<QuicEncryptedPacket
> ConstructResponseHeadersPacket(
223 QuicPacketSequenceNumber sequence_number
,
224 QuicStreamId stream_id
,
225 bool should_include_version
,
227 const SpdyHeaderBlock
& headers
) {
228 return maker_
.MakeResponseHeadersPacket(
229 sequence_number
, stream_id
, should_include_version
, fin
, headers
);
232 void CreateSession() {
233 CreateSessionWithFactory(&socket_factory_
, false);
236 void CreateSessionWithNextProtos() {
237 CreateSessionWithFactory(&socket_factory_
, true);
240 // If |use_next_protos| is true, enables SPDY and QUIC.
241 void CreateSessionWithFactory(ClientSocketFactory
* socket_factory
,
242 bool use_next_protos
) {
243 params_
.enable_quic
= true;
244 params_
.quic_clock
= clock_
;
245 params_
.quic_random
= &random_generator_
;
246 params_
.client_socket_factory
= socket_factory
;
247 params_
.quic_crypto_client_stream_factory
= &crypto_client_stream_factory_
;
248 params_
.host_resolver
= &host_resolver_
;
249 params_
.cert_verifier
= &cert_verifier_
;
250 params_
.transport_security_state
= &transport_security_state_
;
251 params_
.proxy_service
= proxy_service_
.get();
252 params_
.ssl_config_service
= ssl_config_service_
.get();
253 params_
.http_auth_handler_factory
= auth_handler_factory_
.get();
254 params_
.http_server_properties
= http_server_properties_
.GetWeakPtr();
255 params_
.quic_supported_versions
= SupportedVersions(GetParam());
257 if (use_next_protos
) {
258 params_
.use_alternative_services
= true;
259 params_
.next_protos
= NextProtosWithSpdyAndQuic(true, true);
262 session_
= new HttpNetworkSession(params_
);
263 session_
->quic_stream_factory()->set_require_confirmation(false);
264 ASSERT_EQ(params_
.quic_socket_receive_buffer_size
,
265 session_
->quic_stream_factory()->socket_receive_buffer_size());
268 void CheckWasQuicResponse(const scoped_ptr
<HttpNetworkTransaction
>& trans
) {
269 const HttpResponseInfo
* response
= trans
->GetResponseInfo();
270 ASSERT_TRUE(response
!= nullptr);
271 ASSERT_TRUE(response
->headers
.get() != nullptr);
272 EXPECT_EQ("HTTP/1.1 200 OK", response
->headers
->GetStatusLine());
273 EXPECT_TRUE(response
->was_fetched_via_spdy
);
274 EXPECT_TRUE(response
->was_npn_negotiated
);
275 EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_QUIC1_SPDY3
,
276 response
->connection_info
);
279 void CheckResponsePort(const scoped_ptr
<HttpNetworkTransaction
>& trans
,
281 const HttpResponseInfo
* response
= trans
->GetResponseInfo();
282 ASSERT_TRUE(response
!= nullptr);
283 EXPECT_EQ(port
, response
->socket_address
.port());
286 void CheckWasHttpResponse(const scoped_ptr
<HttpNetworkTransaction
>& trans
) {
287 const HttpResponseInfo
* response
= trans
->GetResponseInfo();
288 ASSERT_TRUE(response
!= nullptr);
289 ASSERT_TRUE(response
->headers
.get() != nullptr);
290 EXPECT_EQ("HTTP/1.1 200 OK", response
->headers
->GetStatusLine());
291 EXPECT_FALSE(response
->was_fetched_via_spdy
);
292 EXPECT_FALSE(response
->was_npn_negotiated
);
293 EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP1
,
294 response
->connection_info
);
297 void CheckResponseData(const scoped_ptr
<HttpNetworkTransaction
>& trans
,
298 const std::string
& expected
) {
299 std::string response_data
;
300 ASSERT_EQ(OK
, ReadTransaction(trans
.get(), &response_data
));
301 EXPECT_EQ(expected
, response_data
);
304 void RunTransaction(const scoped_ptr
<HttpNetworkTransaction
>& trans
) {
305 TestCompletionCallback callback
;
306 int rv
= trans
->Start(&request_
, callback
.callback(), net_log_
.bound());
307 EXPECT_EQ(ERR_IO_PENDING
, rv
);
308 EXPECT_EQ(OK
, callback
.WaitForResult());
311 void SendRequestAndExpectHttpResponse(const std::string
& expected
) {
312 scoped_ptr
<HttpNetworkTransaction
> trans(
313 new HttpNetworkTransaction(DEFAULT_PRIORITY
, session_
.get()));
314 RunTransaction(trans
);
315 CheckWasHttpResponse(trans
);
316 CheckResponseData(trans
, expected
);
319 void SendRequestAndExpectQuicResponse(const std::string
& expected
) {
320 SendRequestAndExpectQuicResponseMaybeFromProxy(expected
, false, 80);
323 void SendRequestAndExpectQuicResponseOnPort(const std::string
& expected
,
325 SendRequestAndExpectQuicResponseMaybeFromProxy(expected
, false, port
);
328 void SendRequestAndExpectQuicResponseFromProxyOnPort(
329 const std::string
& expected
,
331 SendRequestAndExpectQuicResponseMaybeFromProxy(expected
, true, port
);
334 void AddQuicAlternateProtocolMapping(
335 MockCryptoClientStream::HandshakeMode handshake_mode
) {
336 crypto_client_stream_factory_
.set_handshake_mode(handshake_mode
);
337 HostPortPair host_port_pair
= HostPortPair::FromURL(request_
.url
);
338 AlternativeService
alternative_service(QUIC
, host_port_pair
.host(), 80);
339 base::Time expiration
= base::Time::Now() + base::TimeDelta::FromDays(1);
340 http_server_properties_
.SetAlternativeService(
341 host_port_pair
, alternative_service
, 1.0, expiration
);
344 void ExpectBrokenAlternateProtocolMapping() {
345 const HostPortPair origin
= HostPortPair::FromURL(request_
.url
);
346 const AlternativeServiceVector alternative_service_vector
=
347 http_server_properties_
.GetAlternativeServices(origin
);
348 EXPECT_EQ(1u, alternative_service_vector
.size());
349 EXPECT_TRUE(http_server_properties_
.IsAlternativeServiceBroken(
350 alternative_service_vector
[0]));
353 void ExpectQuicAlternateProtocolMapping() {
354 const HostPortPair origin
= HostPortPair::FromURL(request_
.url
);
355 const AlternativeServiceVector alternative_service_vector
=
356 http_server_properties_
.GetAlternativeServices(origin
);
357 EXPECT_EQ(1u, alternative_service_vector
.size());
358 EXPECT_EQ(QUIC
, alternative_service_vector
[0].protocol
);
361 void AddHangingNonAlternateProtocolSocketData() {
362 MockConnect
hanging_connect(SYNCHRONOUS
, ERR_IO_PENDING
);
363 hanging_data_
.set_connect_data(hanging_connect
);
364 socket_factory_
.AddSocketDataProvider(&hanging_data_
);
367 MockClock
* clock_
; // Owned by QuicStreamFactory after CreateSession.
368 QuicTestPacketMaker maker_
;
369 scoped_refptr
<HttpNetworkSession
> session_
;
370 MockClientSocketFactory socket_factory_
;
371 MockCryptoClientStreamFactory crypto_client_stream_factory_
;
372 MockHostResolver host_resolver_
;
373 MockCertVerifier cert_verifier_
;
374 TransportSecurityState transport_security_state_
;
375 scoped_refptr
<SSLConfigServiceDefaults
> ssl_config_service_
;
376 scoped_ptr
<ProxyService
> proxy_service_
;
377 scoped_ptr
<HttpAuthHandlerFactory
> auth_handler_factory_
;
378 MockRandom random_generator_
;
379 HttpServerPropertiesImpl http_server_properties_
;
380 HttpNetworkSession::Params params_
;
381 HttpRequestInfo request_
;
382 BoundTestNetLog net_log_
;
383 StaticSocketDataProvider hanging_data_
;
386 void SendRequestAndExpectQuicResponseMaybeFromProxy(
387 const std::string
& expected
,
390 scoped_ptr
<HttpNetworkTransaction
> trans(
391 new HttpNetworkTransaction(DEFAULT_PRIORITY
, session_
.get()));
392 ProxyHeadersHandler proxy_headers_handler
;
393 trans
->SetBeforeProxyHeadersSentCallback(
394 base::Bind(&ProxyHeadersHandler::OnBeforeProxyHeadersSent
,
395 base::Unretained(&proxy_headers_handler
)));
396 RunTransaction(trans
);
397 CheckWasQuicResponse(trans
);
398 CheckResponsePort(trans
, port
);
399 CheckResponseData(trans
, expected
);
400 EXPECT_EQ(used_proxy
, proxy_headers_handler
.was_called());
404 INSTANTIATE_TEST_CASE_P(Version
, QuicNetworkTransactionTest
,
405 ::testing::ValuesIn(QuicSupportedVersions()));
407 TEST_P(QuicNetworkTransactionTest
, ForceQuic
) {
408 // TODO(rch): switch these tests to use secure QUIC.
409 params_
.enable_insecure_quic
= true;
410 params_
.origin_to_force_quic_on
=
411 HostPortPair::FromString("www.google.com:80");
413 MockQuicData mock_quic_data
;
414 mock_quic_data
.AddWrite(
415 ConstructRequestHeadersPacket(1, kClientDataStreamId1
, true, true,
416 GetRequestHeaders("GET", "http", "/")));
417 mock_quic_data
.AddRead(
418 ConstructResponseHeadersPacket(1, kClientDataStreamId1
, false, false,
419 GetResponseHeaders("200 OK")));
420 mock_quic_data
.AddRead(
421 ConstructDataPacket(2, kClientDataStreamId1
, false, true, 0, "hello!"));
422 mock_quic_data
.AddWrite(ConstructAckPacket(2, 1));
423 mock_quic_data
.AddRead(ASYNC
, ERR_IO_PENDING
); // No more data to read
425 mock_quic_data
.AddSocketDataToFactory(&socket_factory_
);
427 // The non-alternate protocol job needs to hang in order to guarantee that
428 // the alternate-protocol job will "win".
429 AddHangingNonAlternateProtocolSocketData();
433 SendRequestAndExpectQuicResponse("hello!");
435 // Check that the NetLog was filled reasonably.
436 TestNetLogEntry::List entries
;
437 net_log_
.GetEntries(&entries
);
438 EXPECT_LT(0u, entries
.size());
440 // Check that we logged a QUIC_SESSION_PACKET_RECEIVED.
441 int pos
= ExpectLogContainsSomewhere(
442 entries
, 0, NetLog::TYPE_QUIC_SESSION_PACKET_RECEIVED
,
446 // ... and also a TYPE_QUIC_SESSION_PACKET_HEADER_RECEIVED.
447 pos
= ExpectLogContainsSomewhere(
448 entries
, 0, NetLog::TYPE_QUIC_SESSION_PACKET_HEADER_RECEIVED
,
452 std::string packet_sequence_number
;
453 ASSERT_TRUE(entries
[pos
].GetStringValue(
454 "packet_sequence_number", &packet_sequence_number
));
455 EXPECT_EQ("1", packet_sequence_number
);
457 // ... and also a QUIC_SESSION_STREAM_FRAME_RECEIVED.
458 pos
= ExpectLogContainsSomewhere(
459 entries
, 0, NetLog::TYPE_QUIC_SESSION_STREAM_FRAME_RECEIVED
,
464 ASSERT_TRUE(entries
[pos
].GetIntegerValue("stream_id", &log_stream_id
));
465 EXPECT_EQ(3, log_stream_id
);
468 TEST_P(QuicNetworkTransactionTest
, QuicProxy
) {
469 params_
.enable_insecure_quic
= true;
470 params_
.enable_quic_for_proxies
= true;
471 proxy_service_
.reset(
472 ProxyService::CreateFixedFromPacResult("QUIC myproxy:70"));
474 MockQuicData mock_quic_data
;
475 mock_quic_data
.AddWrite(
476 ConstructRequestHeadersPacket(1, kClientDataStreamId1
, true, true,
477 GetRequestHeaders("GET", "http", "/")));
478 mock_quic_data
.AddRead(
479 ConstructResponseHeadersPacket(1, kClientDataStreamId1
, false, false,
480 GetResponseHeaders("200 OK")));
481 mock_quic_data
.AddRead(
482 ConstructDataPacket(2, kClientDataStreamId1
, false, true, 0, "hello!"));
483 mock_quic_data
.AddWrite(ConstructAckPacket(2, 1));
484 mock_quic_data
.AddRead(ASYNC
, ERR_IO_PENDING
); // No more data to read
485 mock_quic_data
.AddRead(SYNCHRONOUS
, 0); // EOF
487 mock_quic_data
.AddSocketDataToFactory(&socket_factory_
);
489 // There is no need to set up an alternate protocol job, because
490 // no attempt will be made to speak to the proxy over TCP.
494 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 70);
497 // Regression test for https://crbug.com/492458. Test that for an HTTP
498 // connection through a QUIC proxy, the certificate exhibited by the proxy is
499 // checked against the proxy hostname, not the origin hostname.
500 TEST_P(QuicNetworkTransactionTest
, QuicProxyWithCert
) {
501 const std::string origin_host
= "news.example.com";
502 const std::string proxy_host
= "www.example.org";
504 params_
.enable_insecure_quic
= true;
505 params_
.enable_quic_for_proxies
= true;
506 proxy_service_
.reset(
507 ProxyService::CreateFixedFromPacResult("QUIC " + proxy_host
+ ":70"));
509 maker_
.set_hostname(origin_host
);
510 MockQuicData mock_quic_data
;
511 mock_quic_data
.AddWrite(
512 ConstructRequestHeadersPacket(1, kClientDataStreamId1
, true, true,
513 GetRequestHeaders("GET", "http", "/")));
514 mock_quic_data
.AddRead(ConstructResponseHeadersPacket(
515 1, kClientDataStreamId1
, false, false, GetResponseHeaders("200 OK")));
516 mock_quic_data
.AddRead(
517 ConstructDataPacket(2, kClientDataStreamId1
, false, true, 0, "hello!"));
518 mock_quic_data
.AddWrite(ConstructAckPacket(2, 1));
519 mock_quic_data
.AddRead(ASYNC
, ERR_IO_PENDING
); // No more data to read
520 mock_quic_data
.AddRead(SYNCHRONOUS
, 0);
521 mock_quic_data
.AddSocketDataToFactory(&socket_factory_
);
523 scoped_refptr
<X509Certificate
> cert(
524 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem"));
525 ASSERT_TRUE(cert
.get());
526 // This certificate is valid for the proxy, but not for the origin.
527 bool common_name_fallback_used
;
528 EXPECT_TRUE(cert
->VerifyNameMatch(proxy_host
, &common_name_fallback_used
));
529 EXPECT_FALSE(cert
->VerifyNameMatch(origin_host
, &common_name_fallback_used
));
530 ProofVerifyDetailsChromium verify_details
;
531 verify_details
.cert_verify_result
.verified_cert
= cert
;
532 crypto_client_stream_factory_
.AddProofVerifyDetails(&verify_details
);
534 request_
.url
= GURL("http://" + origin_host
);
535 AddHangingNonAlternateProtocolSocketData();
536 CreateSessionWithNextProtos();
537 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE
);
538 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 70);
541 TEST_P(QuicNetworkTransactionTest
, ForceQuicWithErrorConnecting
) {
542 params_
.enable_insecure_quic
= true;
543 params_
.origin_to_force_quic_on
=
544 HostPortPair::FromString("www.google.com:80");
546 MockQuicData mock_quic_data
;
547 mock_quic_data
.AddRead(ASYNC
, ERR_SOCKET_NOT_CONNECTED
);
549 mock_quic_data
.AddSocketDataToFactory(&socket_factory_
);
553 scoped_ptr
<HttpNetworkTransaction
> trans(
554 new HttpNetworkTransaction(DEFAULT_PRIORITY
, session_
.get()));
555 TestCompletionCallback callback
;
556 int rv
= trans
->Start(&request_
, callback
.callback(), net_log_
.bound());
557 EXPECT_EQ(ERR_IO_PENDING
, rv
);
558 EXPECT_EQ(ERR_CONNECTION_CLOSED
, callback
.WaitForResult());
561 TEST_P(QuicNetworkTransactionTest
, DoNotForceQuicForHttps
) {
562 // Attempt to "force" quic on 443, which will not be honored.
563 params_
.origin_to_force_quic_on
=
564 HostPortPair::FromString("www.google.com:443");
566 MockRead http_reads
[] = {
567 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
568 MockRead("hello world"),
569 MockRead(SYNCHRONOUS
, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ
),
573 StaticSocketDataProvider
data(http_reads
, arraysize(http_reads
), nullptr, 0);
574 socket_factory_
.AddSocketDataProvider(&data
);
575 SSLSocketDataProvider
ssl(ASYNC
, OK
);
576 socket_factory_
.AddSSLSocketDataProvider(&ssl
);
580 SendRequestAndExpectHttpResponse("hello world");
583 TEST_P(QuicNetworkTransactionTest
, UseAlternativeServiceForQuic
) {
584 params_
.enable_insecure_quic
= true;
586 MockRead http_reads
[] = {
587 MockRead("HTTP/1.1 200 OK\r\n"),
588 MockRead(kQuicAlternativeServiceHttpHeader
), MockRead("hello world"),
589 MockRead(SYNCHRONOUS
, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ
),
590 MockRead(ASYNC
, OK
)};
592 StaticSocketDataProvider
http_data(http_reads
, arraysize(http_reads
), nullptr,
594 socket_factory_
.AddSocketDataProvider(&http_data
);
596 MockQuicData mock_quic_data
;
597 mock_quic_data
.AddWrite(
598 ConstructRequestHeadersPacket(1, kClientDataStreamId1
, true, true,
599 GetRequestHeaders("GET", "http", "/")));
600 mock_quic_data
.AddRead(ConstructResponseHeadersPacket(
601 1, kClientDataStreamId1
, false, false, GetResponseHeaders("200 OK")));
602 mock_quic_data
.AddRead(
603 ConstructDataPacket(2, kClientDataStreamId1
, false, true, 0, "hello!"));
604 mock_quic_data
.AddWrite(ConstructAckPacket(2, 1));
605 mock_quic_data
.AddRead(ASYNC
, ERR_IO_PENDING
); // No more data to read
606 mock_quic_data
.AddRead(SYNCHRONOUS
, 0); // EOF
608 mock_quic_data
.AddSocketDataToFactory(&socket_factory_
);
610 AddHangingNonAlternateProtocolSocketData();
611 CreateSessionWithNextProtos();
613 SendRequestAndExpectHttpResponse("hello world");
614 SendRequestAndExpectQuicResponse("hello!");
617 // When multiple alternative services are advertised,
618 // HttpStreamFactoryImpl::RequestStreamInternal() only passes the first one to
619 // Job. This is what the following test verifies.
620 // TODO(bnc): Update this test when multiple alternative services are handled
622 TEST_P(QuicNetworkTransactionTest
, UseFirstAlternativeServiceForQuic
) {
623 params_
.enable_insecure_quic
= true;
625 MockRead http_reads
[] = {
626 MockRead("HTTP/1.1 200 OK\r\n"),
627 MockRead("Alt-Svc: quic=\":443\", quic=\":1234\"\r\n\r\n"),
628 MockRead("hello world"),
629 MockRead(SYNCHRONOUS
, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ
),
630 MockRead(ASYNC
, OK
)};
632 StaticSocketDataProvider
http_data(http_reads
, arraysize(http_reads
), nullptr,
634 socket_factory_
.AddSocketDataProvider(&http_data
);
636 MockQuicData mock_quic_data
;
637 mock_quic_data
.AddWrite(
638 ConstructRequestHeadersPacket(1, kClientDataStreamId1
, true, true,
639 GetRequestHeaders("GET", "http", "/")));
640 mock_quic_data
.AddRead(ConstructResponseHeadersPacket(
641 1, kClientDataStreamId1
, false, false, GetResponseHeaders("200 OK")));
642 mock_quic_data
.AddRead(
643 ConstructDataPacket(2, kClientDataStreamId1
, false, true, 0, "hello!"));
644 mock_quic_data
.AddWrite(ConstructAckPacket(2, 1));
645 mock_quic_data
.AddRead(ASYNC
, ERR_IO_PENDING
); // No more data to read
646 mock_quic_data
.AddRead(SYNCHRONOUS
, 0); // EOF
648 mock_quic_data
.AddSocketDataToFactory(&socket_factory_
);
650 AddHangingNonAlternateProtocolSocketData();
651 CreateSessionWithNextProtos();
653 SendRequestAndExpectHttpResponse("hello world");
654 SendRequestAndExpectQuicResponseOnPort("hello!", 443);
657 TEST_P(QuicNetworkTransactionTest
, AlternativeServiceDifferentPort
) {
658 params_
.enable_insecure_quic
= true;
660 MockRead http_reads
[] = {
661 MockRead("HTTP/1.1 200 OK\r\n"),
662 MockRead(kQuicAlternativeServiceDifferentPortHttpHeader
),
663 MockRead("hello world"),
664 MockRead(SYNCHRONOUS
, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ
),
665 MockRead(ASYNC
, OK
)};
667 StaticSocketDataProvider
http_data(http_reads
, arraysize(http_reads
), nullptr,
669 socket_factory_
.AddSocketDataProvider(&http_data
);
671 MockQuicData mock_quic_data
;
672 mock_quic_data
.AddWrite(
673 ConstructRequestHeadersPacket(1, kClientDataStreamId1
, true, true,
674 GetRequestHeaders("GET", "http", "/")));
675 mock_quic_data
.AddRead(ConstructResponseHeadersPacket(
676 1, kClientDataStreamId1
, false, false, GetResponseHeaders("200 OK")));
677 mock_quic_data
.AddRead(
678 ConstructDataPacket(2, kClientDataStreamId1
, false, true, 0, "hello!"));
679 mock_quic_data
.AddWrite(ConstructAckPacket(2, 1));
680 mock_quic_data
.AddRead(ASYNC
, ERR_IO_PENDING
); // No more data to read
681 mock_quic_data
.AddRead(SYNCHRONOUS
, 0); // EOF
683 mock_quic_data
.AddSocketDataToFactory(&socket_factory_
);
685 AddHangingNonAlternateProtocolSocketData();
686 CreateSessionWithNextProtos();
688 SendRequestAndExpectHttpResponse("hello world");
689 SendRequestAndExpectQuicResponseOnPort("hello!", 137);
692 TEST_P(QuicNetworkTransactionTest
, ConfirmAlternativeService
) {
693 params_
.enable_insecure_quic
= true;
695 MockRead http_reads
[] = {
696 MockRead("HTTP/1.1 200 OK\r\n"),
697 MockRead(kQuicAlternativeServiceHttpHeader
), MockRead("hello world"),
698 MockRead(SYNCHRONOUS
, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ
),
699 MockRead(ASYNC
, OK
)};
701 StaticSocketDataProvider
http_data(http_reads
, arraysize(http_reads
), nullptr,
703 socket_factory_
.AddSocketDataProvider(&http_data
);
705 MockQuicData mock_quic_data
;
706 mock_quic_data
.AddWrite(
707 ConstructRequestHeadersPacket(1, kClientDataStreamId1
, true, true,
708 GetRequestHeaders("GET", "http", "/")));
709 mock_quic_data
.AddRead(ConstructResponseHeadersPacket(
710 1, kClientDataStreamId1
, false, false, GetResponseHeaders("200 OK")));
711 mock_quic_data
.AddRead(
712 ConstructDataPacket(2, kClientDataStreamId1
, false, true, 0, "hello!"));
713 mock_quic_data
.AddWrite(ConstructAckPacket(2, 1));
714 mock_quic_data
.AddRead(ASYNC
, ERR_IO_PENDING
); // No more data to read
715 mock_quic_data
.AddRead(ASYNC
, 0); // EOF
716 mock_quic_data
.AddRead(SYNCHRONOUS
, 0); // EOF
718 mock_quic_data
.AddSocketDataToFactory(&socket_factory_
);
720 AddHangingNonAlternateProtocolSocketData();
721 CreateSessionWithNextProtos();
723 AlternativeService
alternative_service(QUIC
,
724 HostPortPair::FromURL(request_
.url
));
725 http_server_properties_
.MarkAlternativeServiceRecentlyBroken(
726 alternative_service
);
727 EXPECT_TRUE(http_server_properties_
.WasAlternativeServiceRecentlyBroken(
728 alternative_service
));
730 SendRequestAndExpectHttpResponse("hello world");
731 SendRequestAndExpectQuicResponse("hello!");
733 mock_quic_data
.CompleteRead();
735 EXPECT_FALSE(http_server_properties_
.WasAlternativeServiceRecentlyBroken(
736 alternative_service
));
739 TEST_P(QuicNetworkTransactionTest
, UseAlternativeServiceProbabilityForQuic
) {
740 params_
.enable_insecure_quic
= true;
742 MockRead http_reads
[] = {
743 MockRead("HTTP/1.1 200 OK\r\n"),
744 MockRead(kQuicAlternativeService50pctHttpHeader
), MockRead("hello world"),
745 MockRead(SYNCHRONOUS
, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ
),
746 MockRead(ASYNC
, OK
)};
748 StaticSocketDataProvider
http_data(http_reads
, arraysize(http_reads
), nullptr,
750 socket_factory_
.AddSocketDataProvider(&http_data
);
752 MockQuicData mock_quic_data
;
753 mock_quic_data
.AddWrite(
754 ConstructRequestHeadersPacket(1, kClientDataStreamId1
, true, true,
755 GetRequestHeaders("GET", "http", "/")));
756 mock_quic_data
.AddRead(ConstructResponseHeadersPacket(
757 1, kClientDataStreamId1
, false, false, GetResponseHeaders("200 OK")));
758 mock_quic_data
.AddRead(
759 ConstructDataPacket(2, kClientDataStreamId1
, false, true, 0, "hello!"));
760 mock_quic_data
.AddWrite(ConstructAckPacket(2, 1));
761 mock_quic_data
.AddRead(ASYNC
, ERR_IO_PENDING
); // No more data to read
762 mock_quic_data
.AddRead(SYNCHRONOUS
, 0); // EOF
764 mock_quic_data
.AddSocketDataToFactory(&socket_factory_
);
766 AddHangingNonAlternateProtocolSocketData();
767 params_
.alternative_service_probability_threshold
= 0.25;
768 CreateSessionWithNextProtos();
770 SendRequestAndExpectHttpResponse("hello world");
771 SendRequestAndExpectQuicResponse("hello!");
774 TEST_P(QuicNetworkTransactionTest
,
775 DontUseAlternativeServiceProbabilityForQuic
) {
776 params_
.enable_insecure_quic
= true;
778 MockRead http_reads
[] = {
779 MockRead("HTTP/1.1 200 OK\r\n"),
780 MockRead(kQuicAlternativeService50pctHttpHeader
), MockRead("hello world"),
781 MockRead(SYNCHRONOUS
, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ
),
782 MockRead(ASYNC
, OK
)};
784 StaticSocketDataProvider
http_data(http_reads
, arraysize(http_reads
), nullptr,
786 socket_factory_
.AddSocketDataProvider(&http_data
);
787 socket_factory_
.AddSocketDataProvider(&http_data
);
789 params_
.alternative_service_probability_threshold
= 0.75;
790 CreateSessionWithNextProtos();
792 SendRequestAndExpectHttpResponse("hello world");
793 SendRequestAndExpectHttpResponse("hello world");
796 TEST_P(QuicNetworkTransactionTest
, DontUseAlternativeServiceForInsecureQuic
) {
797 params_
.enable_insecure_quic
= true;
799 MockRead http_reads
[] = {MockRead("HTTP/1.1 200 OK\r\n"),
800 MockRead("Content-length: 11\r\n"),
801 MockRead("Alt-Svc: quic=\":443\"\r\n\r\n"),
802 MockRead("hello world"),
803 MockRead("HTTP/1.1 200 OK\r\n"),
804 MockRead("Content-length: 11\r\n"),
805 MockRead("Alt-Svc: quic=\":443\"\r\n\r\n"),
806 MockRead("hello world"),
807 MockRead(ASYNC
, OK
)};
809 StaticSocketDataProvider
http_data(http_reads
, arraysize(http_reads
), nullptr,
811 socket_factory_
.AddSocketDataProvider(&http_data
);
812 socket_factory_
.AddSocketDataProvider(&http_data
);
814 params_
.enable_insecure_quic
= false;
815 CreateSessionWithNextProtos();
817 SendRequestAndExpectHttpResponse("hello world");
818 SendRequestAndExpectHttpResponse("hello world");
821 TEST_P(QuicNetworkTransactionTest
,
822 DontUseAlternativeServiceWithBadProbabilityForQuic
) {
823 params_
.enable_insecure_quic
= true;
825 MockRead http_reads
[] = {
826 MockRead("HTTP/1.1 200 OK\r\n"),
827 MockRead("Alt-Svc: quic=\":443\";p=2\r\n\r\n"), MockRead("hello world"),
828 MockRead(SYNCHRONOUS
, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ
),
829 MockRead(ASYNC
, OK
)};
831 StaticSocketDataProvider
http_data(http_reads
, arraysize(http_reads
), nullptr,
833 socket_factory_
.AddSocketDataProvider(&http_data
);
834 socket_factory_
.AddSocketDataProvider(&http_data
);
836 params_
.alternative_service_probability_threshold
= 0.75;
837 CreateSessionWithNextProtos();
839 SendRequestAndExpectHttpResponse("hello world");
840 SendRequestAndExpectHttpResponse("hello world");
843 TEST_P(QuicNetworkTransactionTest
, UseAlternativeServiceForQuicForHttps
) {
844 params_
.enable_insecure_quic
= true;
845 params_
.origin_to_force_quic_on
=
846 HostPortPair::FromString("www.google.com:443");
848 MockRead http_reads
[] = {
849 MockRead("HTTP/1.1 200 OK\r\n"),
850 MockRead(kQuicAlternativeServiceHttpsHeader
), MockRead("hello world"),
851 MockRead(SYNCHRONOUS
, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ
),
852 MockRead(ASYNC
, OK
)};
854 StaticSocketDataProvider
http_data(http_reads
, arraysize(http_reads
), nullptr,
856 socket_factory_
.AddSocketDataProvider(&http_data
);
858 MockQuicData mock_quic_data
;
859 mock_quic_data
.AddWrite(
860 ConstructRequestHeadersPacket(1, kClientDataStreamId1
, true, true,
861 GetRequestHeaders("GET", "http", "/")));
862 mock_quic_data
.AddRead(ConstructResponseHeadersPacket(
863 1, kClientDataStreamId1
, false, false, GetResponseHeaders("200 OK")));
864 mock_quic_data
.AddRead(
865 ConstructDataPacket(2, kClientDataStreamId1
, false, true, 0, "hello!"));
866 mock_quic_data
.AddWrite(ConstructAckPacket(2, 1));
867 mock_quic_data
.AddRead(SYNCHRONOUS
, 0); // EOF
869 mock_quic_data
.AddSocketDataToFactory(&socket_factory_
);
871 AddHangingNonAlternateProtocolSocketData();
872 CreateSessionWithNextProtos();
874 // TODO(rtenneti): Test QUIC over HTTPS, GetSSLInfo().
875 SendRequestAndExpectHttpResponse("hello world");
878 TEST_P(QuicNetworkTransactionTest
, UseAlternateProtocolForQuic
) {
879 params_
.enable_insecure_quic
= true;
881 MockRead http_reads
[] = {
882 MockRead("HTTP/1.1 200 OK\r\n"),
883 MockRead(kQuicAlternateProtocolHttpHeader
),
884 MockRead("hello world"),
885 MockRead(SYNCHRONOUS
, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ
),
889 StaticSocketDataProvider
http_data(http_reads
, arraysize(http_reads
),
891 socket_factory_
.AddSocketDataProvider(&http_data
);
893 MockQuicData mock_quic_data
;
894 mock_quic_data
.AddWrite(
895 ConstructRequestHeadersPacket(1, kClientDataStreamId1
, true, true,
896 GetRequestHeaders("GET", "http", "/")));
897 mock_quic_data
.AddRead(
898 ConstructResponseHeadersPacket(1, kClientDataStreamId1
, false, false,
899 GetResponseHeaders("200 OK")));
900 mock_quic_data
.AddRead(
901 ConstructDataPacket(2, kClientDataStreamId1
, false, true, 0, "hello!"));
902 mock_quic_data
.AddWrite(ConstructAckPacket(2, 1));
903 mock_quic_data
.AddRead(ASYNC
, ERR_IO_PENDING
); // No more data to read
904 mock_quic_data
.AddRead(SYNCHRONOUS
, 0); // EOF
906 mock_quic_data
.AddSocketDataToFactory(&socket_factory_
);
908 // The non-alternate protocol job needs to hang in order to guarantee that
909 // the alternate-protocol job will "win".
910 AddHangingNonAlternateProtocolSocketData();
912 CreateSessionWithNextProtos();
914 SendRequestAndExpectHttpResponse("hello world");
915 SendRequestAndExpectQuicResponse("hello!");
918 TEST_P(QuicNetworkTransactionTest
, AlternateProtocolDifferentPort
) {
919 params_
.enable_insecure_quic
= true;
921 MockRead http_reads
[] = {
922 MockRead("HTTP/1.1 200 OK\r\n"),
923 MockRead(kQuicAlternateProtocolDifferentPortHttpHeader
),
924 MockRead("hello world"),
925 MockRead(SYNCHRONOUS
, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ
),
926 MockRead(ASYNC
, OK
)};
928 StaticSocketDataProvider
http_data(http_reads
, arraysize(http_reads
), nullptr,
930 socket_factory_
.AddSocketDataProvider(&http_data
);
932 MockQuicData mock_quic_data
;
933 mock_quic_data
.AddWrite(
934 ConstructRequestHeadersPacket(1, kClientDataStreamId1
, true, true,
935 GetRequestHeaders("GET", "http", "/")));
936 mock_quic_data
.AddRead(ConstructResponseHeadersPacket(
937 1, kClientDataStreamId1
, false, false, GetResponseHeaders("200 OK")));
938 mock_quic_data
.AddRead(
939 ConstructDataPacket(2, kClientDataStreamId1
, false, true, 0, "hello!"));
940 mock_quic_data
.AddWrite(ConstructAckPacket(2, 1));
941 mock_quic_data
.AddRead(ASYNC
, ERR_IO_PENDING
); // No more data to read
942 mock_quic_data
.AddRead(SYNCHRONOUS
, 0); // EOF
944 mock_quic_data
.AddSocketDataToFactory(&socket_factory_
);
946 // The non-alternate protocol job needs to hang in order to guarantee that
947 // the alternate-protocol job will "win".
948 AddHangingNonAlternateProtocolSocketData();
950 CreateSessionWithNextProtos();
952 SendRequestAndExpectHttpResponse("hello world");
953 SendRequestAndExpectQuicResponseOnPort("hello!", 137);
956 TEST_P(QuicNetworkTransactionTest
, ConfirmAlternateProtocol
) {
957 params_
.enable_insecure_quic
= true;
959 MockRead http_reads
[] = {
960 MockRead("HTTP/1.1 200 OK\r\n"),
961 MockRead(kQuicAlternateProtocolHttpHeader
),
962 MockRead("hello world"),
963 MockRead(SYNCHRONOUS
, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ
),
964 MockRead(ASYNC
, OK
)};
966 StaticSocketDataProvider
http_data(http_reads
, arraysize(http_reads
), nullptr,
968 socket_factory_
.AddSocketDataProvider(&http_data
);
970 MockQuicData mock_quic_data
;
971 mock_quic_data
.AddWrite(
972 ConstructRequestHeadersPacket(1, kClientDataStreamId1
, true, true,
973 GetRequestHeaders("GET", "http", "/")));
974 mock_quic_data
.AddRead(ConstructResponseHeadersPacket(
975 1, kClientDataStreamId1
, false, false, GetResponseHeaders("200 OK")));
976 mock_quic_data
.AddRead(
977 ConstructDataPacket(2, kClientDataStreamId1
, false, true, 0, "hello!"));
978 mock_quic_data
.AddWrite(ConstructAckPacket(2, 1));
979 mock_quic_data
.AddRead(ASYNC
, ERR_IO_PENDING
); // No more data to read
980 mock_quic_data
.AddRead(ASYNC
, 0); // EOF
981 mock_quic_data
.AddRead(SYNCHRONOUS
, 0); // EOF
983 mock_quic_data
.AddSocketDataToFactory(&socket_factory_
);
985 // The non-alternate protocol job needs to hang in order to guarantee that
986 // the alternate-protocol job will "win".
987 AddHangingNonAlternateProtocolSocketData();
989 CreateSessionWithNextProtos();
991 AlternativeService
alternative_service(QUIC
,
992 HostPortPair::FromURL(request_
.url
));
993 http_server_properties_
.MarkAlternativeServiceRecentlyBroken(
994 alternative_service
);
995 EXPECT_TRUE(http_server_properties_
.WasAlternativeServiceRecentlyBroken(
996 alternative_service
));
998 SendRequestAndExpectHttpResponse("hello world");
999 SendRequestAndExpectQuicResponse("hello!");
1001 mock_quic_data
.CompleteRead();
1003 EXPECT_FALSE(http_server_properties_
.WasAlternativeServiceRecentlyBroken(
1004 alternative_service
));
1007 TEST_P(QuicNetworkTransactionTest
, UseAlternateProtocolProbabilityForQuic
) {
1008 params_
.enable_insecure_quic
= true;
1010 MockRead http_reads
[] = {
1011 MockRead("HTTP/1.1 200 OK\r\n"),
1012 MockRead(kQuicAlternateProtocol50pctHttpHeader
),
1013 MockRead("hello world"),
1014 MockRead(SYNCHRONOUS
, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ
),
1018 StaticSocketDataProvider
http_data(http_reads
, arraysize(http_reads
),
1020 socket_factory_
.AddSocketDataProvider(&http_data
);
1022 MockQuicData mock_quic_data
;
1023 mock_quic_data
.AddWrite(
1024 ConstructRequestHeadersPacket(1, kClientDataStreamId1
, true, true,
1025 GetRequestHeaders("GET", "http", "/")));
1026 mock_quic_data
.AddRead(
1027 ConstructResponseHeadersPacket(1, kClientDataStreamId1
, false, false,
1028 GetResponseHeaders("200 OK")));
1029 mock_quic_data
.AddRead(
1030 ConstructDataPacket(2, kClientDataStreamId1
, false, true, 0, "hello!"));
1031 mock_quic_data
.AddWrite(ConstructAckPacket(2, 1));
1032 mock_quic_data
.AddRead(ASYNC
, ERR_IO_PENDING
); // No more data to read
1033 mock_quic_data
.AddRead(SYNCHRONOUS
, 0); // EOF
1035 mock_quic_data
.AddSocketDataToFactory(&socket_factory_
);
1037 // The non-alternate protocol job needs to hang in order to guarantee that
1038 // the alternate-protocol job will "win".
1039 AddHangingNonAlternateProtocolSocketData();
1041 params_
.alternative_service_probability_threshold
= .25;
1042 CreateSessionWithNextProtos();
1044 SendRequestAndExpectHttpResponse("hello world");
1045 SendRequestAndExpectQuicResponse("hello!");
1048 TEST_P(QuicNetworkTransactionTest
, DontUseAlternateProtocolProbabilityForQuic
) {
1049 params_
.enable_insecure_quic
= true;
1051 MockRead http_reads
[] = {
1052 MockRead("HTTP/1.1 200 OK\r\n"),
1053 MockRead(kQuicAlternateProtocol50pctHttpHeader
),
1054 MockRead("hello world"),
1055 MockRead(SYNCHRONOUS
, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ
),
1059 StaticSocketDataProvider
http_data(http_reads
, arraysize(http_reads
),
1061 socket_factory_
.AddSocketDataProvider(&http_data
);
1062 socket_factory_
.AddSocketDataProvider(&http_data
);
1064 params_
.alternative_service_probability_threshold
= .75;
1065 CreateSessionWithNextProtos();
1067 SendRequestAndExpectHttpResponse("hello world");
1068 SendRequestAndExpectHttpResponse("hello world");
1071 TEST_P(QuicNetworkTransactionTest
, DontUseAlternateProtocolForInsecureQuic
) {
1072 params_
.enable_insecure_quic
= true;
1074 MockRead http_reads
[] = {MockRead("HTTP/1.1 200 OK\r\n"),
1075 MockRead("Content-length: 11\r\n"),
1076 MockRead("Alternate-Protocol: 443:quic\r\n\r\n"),
1077 MockRead("hello world"),
1078 MockRead("HTTP/1.1 200 OK\r\n"),
1079 MockRead("Content-length: 11\r\n"),
1080 MockRead("Alternate-Protocol: 443:quic\r\n\r\n"),
1081 MockRead("hello world"),
1082 MockRead(ASYNC
, OK
)};
1084 StaticSocketDataProvider
http_data(http_reads
, arraysize(http_reads
), nullptr,
1086 socket_factory_
.AddSocketDataProvider(&http_data
);
1087 socket_factory_
.AddSocketDataProvider(&http_data
);
1089 params_
.enable_insecure_quic
= false;
1090 CreateSessionWithNextProtos();
1092 SendRequestAndExpectHttpResponse("hello world");
1093 SendRequestAndExpectHttpResponse("hello world");
1096 TEST_P(QuicNetworkTransactionTest
,
1097 DontUseAlternateProtocolWithBadProbabilityForQuic
) {
1098 params_
.enable_insecure_quic
= true;
1100 MockRead http_reads
[] = {
1101 MockRead("HTTP/1.1 200 OK\r\n"),
1102 MockRead("Alternate-Protocol: 443:quic,p=2\r\n\r\n"),
1103 MockRead("hello world"),
1104 MockRead(SYNCHRONOUS
, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ
),
1108 StaticSocketDataProvider
http_data(http_reads
, arraysize(http_reads
),
1110 socket_factory_
.AddSocketDataProvider(&http_data
);
1111 socket_factory_
.AddSocketDataProvider(&http_data
);
1113 params_
.alternative_service_probability_threshold
= .75;
1114 CreateSessionWithNextProtos();
1116 SendRequestAndExpectHttpResponse("hello world");
1117 SendRequestAndExpectHttpResponse("hello world");
1120 TEST_P(QuicNetworkTransactionTest
, UseAlternateProtocolForQuicForHttps
) {
1121 params_
.enable_insecure_quic
= true;
1122 params_
.origin_to_force_quic_on
=
1123 HostPortPair::FromString("www.google.com:443");
1125 MockRead http_reads
[] = {
1126 MockRead("HTTP/1.1 200 OK\r\n"),
1127 MockRead(kQuicAlternateProtocolHttpsHeader
),
1128 MockRead("hello world"),
1129 MockRead(SYNCHRONOUS
, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ
),
1133 StaticSocketDataProvider
http_data(http_reads
, arraysize(http_reads
),
1135 socket_factory_
.AddSocketDataProvider(&http_data
);
1137 MockQuicData mock_quic_data
;
1138 mock_quic_data
.AddWrite(
1139 ConstructRequestHeadersPacket(1, kClientDataStreamId1
, true, true,
1140 GetRequestHeaders("GET", "http", "/")));
1141 mock_quic_data
.AddRead(
1142 ConstructResponseHeadersPacket(1, kClientDataStreamId1
, false, false,
1143 GetResponseHeaders("200 OK")));
1144 mock_quic_data
.AddRead(
1145 ConstructDataPacket(2, kClientDataStreamId1
, false, true, 0, "hello!"));
1146 mock_quic_data
.AddWrite(ConstructAckPacket(2, 1));
1147 mock_quic_data
.AddRead(ASYNC
, ERR_IO_PENDING
); // No more data to read
1148 mock_quic_data
.AddRead(SYNCHRONOUS
, 0); // EOF
1150 mock_quic_data
.AddSocketDataToFactory(&socket_factory_
);
1152 // The non-alternate protocol job needs to hang in order to guarantee that
1153 // the alternate-protocol job will "win".
1154 AddHangingNonAlternateProtocolSocketData();
1156 CreateSessionWithNextProtos();
1158 // TODO(rtenneti): Test QUIC over HTTPS, GetSSLInfo().
1159 SendRequestAndExpectHttpResponse("hello world");
1162 class QuicAltSvcCertificateVerificationTest
1163 : public QuicNetworkTransactionTest
{
1165 void Run(bool valid
) {
1166 HostPortPair
origin(valid
? "mail.example.org" : "invalid.example.org",
1168 HostPortPair
alternative("www.example.org", 443);
1169 std::string
url("https://");
1170 url
.append(origin
.host());
1172 request_
.url
= GURL(url
);
1174 maker_
.set_hostname(origin
.host());
1175 MockQuicData mock_quic_data
;
1176 mock_quic_data
.AddWrite(
1177 ConstructRequestHeadersPacket(1, kClientDataStreamId1
, true, true,
1178 GetRequestHeaders("GET", "https", "/")));
1179 mock_quic_data
.AddRead(ConstructResponseHeadersPacket(
1180 1, kClientDataStreamId1
, false, false, GetResponseHeaders("200 OK")));
1181 mock_quic_data
.AddRead(
1182 ConstructDataPacket(2, kClientDataStreamId1
, false, true, 0, "hello!"));
1183 mock_quic_data
.AddWrite(ConstructAckPacket(2, 1));
1184 mock_quic_data
.AddRead(ASYNC
, ERR_IO_PENDING
);
1185 mock_quic_data
.AddSocketDataToFactory(&socket_factory_
);
1187 scoped_refptr
<X509Certificate
> cert(
1188 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem"));
1189 ASSERT_TRUE(cert
.get());
1190 bool common_name_fallback_used
;
1192 cert
->VerifyNameMatch(origin
.host(), &common_name_fallback_used
));
1194 cert
->VerifyNameMatch(alternative
.host(), &common_name_fallback_used
));
1195 ProofVerifyDetailsChromium verify_details
;
1196 verify_details
.cert_verify_result
.verified_cert
= cert
;
1197 verify_details
.cert_verify_result
.is_issued_by_known_root
= true;
1198 crypto_client_stream_factory_
.AddProofVerifyDetails(&verify_details
);
1199 crypto_client_stream_factory_
.set_handshake_mode(
1200 MockCryptoClientStream::CONFIRM_HANDSHAKE
);
1202 // Connection to |origin| fails, so that success of |request| depends on
1203 // connection to |alternate| only.
1204 MockConnect
refused_connect(ASYNC
, ERR_CONNECTION_REFUSED
);
1205 StaticSocketDataProvider refused_data
;
1206 refused_data
.set_connect_data(refused_connect
);
1207 socket_factory_
.AddSocketDataProvider(&refused_data
);
1209 CreateSessionWithNextProtos();
1210 AlternativeService
alternative_service(QUIC
, alternative
);
1211 base::Time expiration
= base::Time::Now() + base::TimeDelta::FromDays(1);
1212 session_
->http_server_properties()->SetAlternativeService(
1213 origin
, alternative_service
, 1.0, expiration
);
1214 scoped_ptr
<HttpNetworkTransaction
> trans(
1215 new HttpNetworkTransaction(DEFAULT_PRIORITY
, session_
.get()));
1216 TestCompletionCallback callback
;
1217 int rv
= trans
->Start(&request_
, callback
.callback(), net_log_
.bound());
1218 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1219 rv
= callback
.WaitForResult();
1222 CheckWasQuicResponse(trans
);
1223 CheckResponsePort(trans
, 443);
1224 CheckResponseData(trans
, "hello!");
1226 EXPECT_EQ(ERR_CONNECTION_REFUSED
, rv
);
1231 INSTANTIATE_TEST_CASE_P(Version
,
1232 QuicAltSvcCertificateVerificationTest
,
1233 ::testing::ValuesIn(QuicSupportedVersions()));
1235 TEST_P(QuicAltSvcCertificateVerificationTest
,
1236 RequestSucceedsWithValidCertificate
) {
1240 TEST_P(QuicAltSvcCertificateVerificationTest
,
1241 RequestFailsWithInvalidCertificate
) {
1245 TEST_P(QuicNetworkTransactionTest
, HungAlternateProtocol
) {
1246 params_
.enable_insecure_quic
= true;
1247 crypto_client_stream_factory_
.set_handshake_mode(
1248 MockCryptoClientStream::COLD_START
);
1250 MockWrite http_writes
[] = {
1251 MockWrite(SYNCHRONOUS
, 0, "GET / HTTP/1.1\r\n"),
1252 MockWrite(SYNCHRONOUS
, 1, "Host: www.google.com\r\n"),
1253 MockWrite(SYNCHRONOUS
, 2, "Connection: keep-alive\r\n\r\n")
1256 MockRead http_reads
[] = {
1257 MockRead(SYNCHRONOUS
, 3, "HTTP/1.1 200 OK\r\n"),
1258 MockRead(SYNCHRONOUS
, 4, kQuicAlternateProtocolHttpHeader
),
1259 MockRead(SYNCHRONOUS
, 5, "hello world"),
1260 MockRead(SYNCHRONOUS
, OK
, 6)
1263 DeterministicMockClientSocketFactory socket_factory
;
1265 DeterministicSocketData
http_data(http_reads
, arraysize(http_reads
),
1266 http_writes
, arraysize(http_writes
));
1267 socket_factory
.AddSocketDataProvider(&http_data
);
1269 // The QUIC transaction will not be allowed to complete.
1270 MockWrite quic_writes
[] = {
1271 MockWrite(ASYNC
, ERR_IO_PENDING
, 0)
1273 MockRead quic_reads
[] = {
1274 MockRead(ASYNC
, ERR_IO_PENDING
, 1),
1276 DeterministicSocketData
quic_data(quic_reads
, arraysize(quic_reads
),
1277 quic_writes
, arraysize(quic_writes
));
1278 socket_factory
.AddSocketDataProvider(&quic_data
);
1280 // The HTTP transaction will complete.
1281 DeterministicSocketData
http_data2(http_reads
, arraysize(http_reads
),
1282 http_writes
, arraysize(http_writes
));
1283 socket_factory
.AddSocketDataProvider(&http_data2
);
1285 CreateSessionWithFactory(&socket_factory
, true);
1287 // Run the first request.
1288 http_data
.StopAfter(arraysize(http_reads
) + arraysize(http_writes
));
1289 SendRequestAndExpectHttpResponse("hello world");
1290 ASSERT_TRUE(http_data
.AllReadDataConsumed());
1291 ASSERT_TRUE(http_data
.AllWriteDataConsumed());
1293 // Now run the second request in which the QUIC socket hangs,
1294 // and verify the the transaction continues over HTTP.
1295 http_data2
.StopAfter(arraysize(http_reads
) + arraysize(http_writes
));
1296 SendRequestAndExpectHttpResponse("hello world");
1298 ASSERT_TRUE(http_data2
.AllReadDataConsumed());
1299 ASSERT_TRUE(http_data2
.AllWriteDataConsumed());
1300 ASSERT_TRUE(!quic_data
.AllReadDataConsumed());
1301 ASSERT_TRUE(!quic_data
.AllWriteDataConsumed());
1304 TEST_P(QuicNetworkTransactionTest
, ZeroRTTWithHttpRace
) {
1305 params_
.enable_insecure_quic
= true;
1306 MockQuicData mock_quic_data
;
1307 mock_quic_data
.AddWrite(
1308 ConstructRequestHeadersPacket(1, kClientDataStreamId1
, true, true,
1309 GetRequestHeaders("GET", "http", "/")));
1310 mock_quic_data
.AddRead(
1311 ConstructResponseHeadersPacket(1, kClientDataStreamId1
, false, false,
1312 GetResponseHeaders("200 OK")));
1313 mock_quic_data
.AddRead(
1314 ConstructDataPacket(2, kClientDataStreamId1
, false, true, 0, "hello!"));
1315 mock_quic_data
.AddWrite(ConstructAckPacket(2, 1));
1316 mock_quic_data
.AddRead(ASYNC
, ERR_IO_PENDING
); // No more data to read
1317 mock_quic_data
.AddRead(SYNCHRONOUS
, 0); // EOF
1319 mock_quic_data
.AddSocketDataToFactory(&socket_factory_
);
1321 // The non-alternate protocol job needs to hang in order to guarantee that
1322 // the alternate-protocol job will "win".
1323 AddHangingNonAlternateProtocolSocketData();
1325 CreateSessionWithNextProtos();
1326 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT
);
1327 SendRequestAndExpectQuicResponse("hello!");
1330 TEST_P(QuicNetworkTransactionTest
, ZeroRTTWithNoHttpRace
) {
1331 params_
.enable_insecure_quic
= true;
1332 MockQuicData mock_quic_data
;
1333 mock_quic_data
.AddWrite(
1334 ConstructRequestHeadersPacket(1, kClientDataStreamId1
, true, true,
1335 GetRequestHeaders("GET", "http", "/")));
1336 mock_quic_data
.AddRead(
1337 ConstructResponseHeadersPacket(1, kClientDataStreamId1
, false, false,
1338 GetResponseHeaders("200 OK")));
1339 mock_quic_data
.AddRead(
1340 ConstructDataPacket(2, kClientDataStreamId1
, false, true, 0, "hello!"));
1341 mock_quic_data
.AddWrite(ConstructAckPacket(2, 1));
1342 mock_quic_data
.AddRead(ASYNC
, ERR_IO_PENDING
); // No more data to read
1343 mock_quic_data
.AddRead(SYNCHRONOUS
, 0); // EOF
1344 mock_quic_data
.AddSocketDataToFactory(&socket_factory_
);
1346 // In order for a new QUIC session to be established via alternate-protocol
1347 // without racing an HTTP connection, we need the host resolution to happen
1349 host_resolver_
.set_synchronous_mode(true);
1350 host_resolver_
.rules()->AddIPLiteralRule("www.google.com", "192.168.0.1", "");
1351 HostResolver::RequestInfo
info(HostPortPair("www.google.com", 80));
1352 AddressList address
;
1353 host_resolver_
.Resolve(info
,
1356 CompletionCallback(),
1360 CreateSessionWithNextProtos();
1361 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT
);
1362 SendRequestAndExpectQuicResponse("hello!");
1365 TEST_P(QuicNetworkTransactionTest
, ZeroRTTWithProxy
) {
1366 params_
.enable_insecure_quic
= true;
1367 proxy_service_
.reset(
1368 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
1370 // Since we are using a proxy, the QUIC job will not succeed.
1371 MockWrite http_writes
[] = {
1372 MockWrite(SYNCHRONOUS
, 0, "GET http://www.google.com/ HTTP/1.1\r\n"),
1373 MockWrite(SYNCHRONOUS
, 1, "Host: www.google.com\r\n"),
1374 MockWrite(SYNCHRONOUS
, 2, "Proxy-Connection: keep-alive\r\n\r\n")
1377 MockRead http_reads
[] = {
1378 MockRead(SYNCHRONOUS
, 3, "HTTP/1.1 200 OK\r\n"),
1379 MockRead(SYNCHRONOUS
, 4, kQuicAlternateProtocolHttpHeader
),
1380 MockRead(SYNCHRONOUS
, 5, "hello world"),
1381 MockRead(SYNCHRONOUS
, OK
, 6)
1384 StaticSocketDataProvider
http_data(http_reads
, arraysize(http_reads
),
1385 http_writes
, arraysize(http_writes
));
1386 socket_factory_
.AddSocketDataProvider(&http_data
);
1388 // In order for a new QUIC session to be established via alternate-protocol
1389 // without racing an HTTP connection, we need the host resolution to happen
1391 host_resolver_
.set_synchronous_mode(true);
1392 host_resolver_
.rules()->AddIPLiteralRule("www.google.com", "192.168.0.1", "");
1393 HostResolver::RequestInfo
info(HostPortPair("www.google.com", 80));
1394 AddressList address
;
1395 host_resolver_
.Resolve(info
,
1398 CompletionCallback(),
1402 CreateSessionWithNextProtos();
1403 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT
);
1404 SendRequestAndExpectHttpResponse("hello world");
1407 TEST_P(QuicNetworkTransactionTest
, ZeroRTTWithConfirmationRequired
) {
1408 params_
.enable_insecure_quic
= true;
1409 MockQuicData mock_quic_data
;
1410 mock_quic_data
.AddWrite(
1411 ConstructRequestHeadersPacket(1, kClientDataStreamId1
, true, true,
1412 GetRequestHeaders("GET", "http", "/")));
1413 mock_quic_data
.AddRead(
1414 ConstructResponseHeadersPacket(1, kClientDataStreamId1
, false, false,
1415 GetResponseHeaders("200 OK")));
1416 mock_quic_data
.AddRead(
1417 ConstructDataPacket(2, kClientDataStreamId1
, false, true, 0, "hello!"));
1418 mock_quic_data
.AddWrite(ConstructAckPacket(2, 1));
1419 mock_quic_data
.AddRead(ASYNC
, ERR_IO_PENDING
); // No more data to read
1420 mock_quic_data
.AddSocketDataToFactory(&socket_factory_
);
1422 // The non-alternate protocol job needs to hang in order to guarantee that
1423 // the alternate-protocol job will "win".
1424 AddHangingNonAlternateProtocolSocketData();
1426 // In order for a new QUIC session to be established via alternate-protocol
1427 // without racing an HTTP connection, we need the host resolution to happen
1428 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
1429 // connection to the the server, in this test we require confirmation
1430 // before encrypting so the HTTP job will still start.
1431 host_resolver_
.set_synchronous_mode(true);
1432 host_resolver_
.rules()->AddIPLiteralRule("www.google.com", "192.168.0.1", "");
1433 HostResolver::RequestInfo
info(HostPortPair("www.google.com", 80));
1434 AddressList address
;
1435 host_resolver_
.Resolve(info
, DEFAULT_PRIORITY
, &address
,
1436 CompletionCallback(), nullptr, net_log_
.bound());
1438 CreateSessionWithNextProtos();
1439 session_
->quic_stream_factory()->set_require_confirmation(true);
1440 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT
);
1442 scoped_ptr
<HttpNetworkTransaction
> trans(
1443 new HttpNetworkTransaction(DEFAULT_PRIORITY
, session_
.get()));
1444 TestCompletionCallback callback
;
1445 int rv
= trans
->Start(&request_
, callback
.callback(), net_log_
.bound());
1446 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1448 crypto_client_stream_factory_
.last_stream()->SendOnCryptoHandshakeEvent(
1449 QuicSession::HANDSHAKE_CONFIRMED
);
1450 EXPECT_EQ(OK
, callback
.WaitForResult());
1452 CheckWasQuicResponse(trans
);
1453 CheckResponseData(trans
, "hello!");
1456 TEST_P(QuicNetworkTransactionTest
, BrokenAlternateProtocol
) {
1457 params_
.enable_insecure_quic
= true;
1458 // Alternate-protocol job
1459 scoped_ptr
<QuicEncryptedPacket
> close(ConstructConnectionClosePacket(1));
1460 MockRead quic_reads
[] = {
1461 MockRead(ASYNC
, close
->data(), close
->length()),
1462 MockRead(ASYNC
, ERR_IO_PENDING
), // No more data to read
1463 MockRead(ASYNC
, OK
), // EOF
1465 StaticSocketDataProvider
quic_data(quic_reads
, arraysize(quic_reads
),
1467 socket_factory_
.AddSocketDataProvider(&quic_data
);
1469 // Main job which will succeed even though the alternate job fails.
1470 MockRead http_reads
[] = {
1471 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
1472 MockRead("hello from http"),
1473 MockRead(SYNCHRONOUS
, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ
),
1477 StaticSocketDataProvider
http_data(http_reads
, arraysize(http_reads
),
1479 socket_factory_
.AddSocketDataProvider(&http_data
);
1481 CreateSessionWithNextProtos();
1482 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START
);
1483 SendRequestAndExpectHttpResponse("hello from http");
1484 ExpectBrokenAlternateProtocolMapping();
1487 TEST_P(QuicNetworkTransactionTest
, BrokenAlternateProtocolReadError
) {
1488 params_
.enable_insecure_quic
= true;
1489 // Alternate-protocol job
1490 MockRead quic_reads
[] = {
1491 MockRead(ASYNC
, ERR_SOCKET_NOT_CONNECTED
),
1493 StaticSocketDataProvider
quic_data(quic_reads
, arraysize(quic_reads
),
1495 socket_factory_
.AddSocketDataProvider(&quic_data
);
1497 // Main job which will succeed even though the alternate job fails.
1498 MockRead http_reads
[] = {
1499 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
1500 MockRead("hello from http"),
1501 MockRead(SYNCHRONOUS
, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ
),
1505 StaticSocketDataProvider
http_data(http_reads
, arraysize(http_reads
),
1507 socket_factory_
.AddSocketDataProvider(&http_data
);
1509 CreateSessionWithNextProtos();
1511 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START
);
1512 SendRequestAndExpectHttpResponse("hello from http");
1513 ExpectBrokenAlternateProtocolMapping();
1516 TEST_P(QuicNetworkTransactionTest
, NoBrokenAlternateProtocolIfTcpFails
) {
1517 params_
.enable_insecure_quic
= true;
1518 // Alternate-protocol job will fail when the session attempts to read.
1519 MockRead quic_reads
[] = {
1520 MockRead(ASYNC
, ERR_SOCKET_NOT_CONNECTED
),
1522 StaticSocketDataProvider
quic_data(quic_reads
, arraysize(quic_reads
),
1524 socket_factory_
.AddSocketDataProvider(&quic_data
);
1526 // Main job will also fail.
1527 MockRead http_reads
[] = {
1528 MockRead(ASYNC
, ERR_SOCKET_NOT_CONNECTED
),
1531 StaticSocketDataProvider
http_data(http_reads
, arraysize(http_reads
),
1533 http_data
.set_connect_data(MockConnect(ASYNC
, ERR_SOCKET_NOT_CONNECTED
));
1534 socket_factory_
.AddSocketDataProvider(&http_data
);
1536 CreateSessionWithNextProtos();
1538 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START
);
1539 scoped_ptr
<HttpNetworkTransaction
> trans(
1540 new HttpNetworkTransaction(DEFAULT_PRIORITY
, session_
.get()));
1541 TestCompletionCallback callback
;
1542 int rv
= trans
->Start(&request_
, callback
.callback(), net_log_
.bound());
1543 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1544 EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED
, callback
.WaitForResult());
1545 ExpectQuicAlternateProtocolMapping();
1548 TEST_P(QuicNetworkTransactionTest
, FailedZeroRttBrokenAlternateProtocol
) {
1549 params_
.enable_insecure_quic
= true;
1550 // Alternate-protocol job
1551 MockRead quic_reads
[] = {
1552 MockRead(ASYNC
, ERR_SOCKET_NOT_CONNECTED
),
1554 StaticSocketDataProvider
quic_data(quic_reads
, arraysize(quic_reads
),
1556 socket_factory_
.AddSocketDataProvider(&quic_data
);
1558 AddHangingNonAlternateProtocolSocketData();
1560 // Second Alternate-protocol job which will race with the TCP job.
1561 StaticSocketDataProvider
quic_data2(quic_reads
, arraysize(quic_reads
),
1563 socket_factory_
.AddSocketDataProvider(&quic_data2
);
1565 // Final job that will proceed when the QUIC job fails.
1566 MockRead http_reads
[] = {
1567 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
1568 MockRead("hello from http"),
1569 MockRead(SYNCHRONOUS
, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ
),
1573 StaticSocketDataProvider
http_data(http_reads
, arraysize(http_reads
),
1575 socket_factory_
.AddSocketDataProvider(&http_data
);
1577 CreateSessionWithNextProtos();
1579 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT
);
1581 SendRequestAndExpectHttpResponse("hello from http");
1583 ExpectBrokenAlternateProtocolMapping();
1585 EXPECT_TRUE(quic_data
.AllReadDataConsumed());
1586 EXPECT_TRUE(quic_data
.AllWriteDataConsumed());
1589 TEST_P(QuicNetworkTransactionTest
, DISABLED_HangingZeroRttFallback
) {
1590 params_
.enable_insecure_quic
= true;
1591 // Alternate-protocol job
1592 MockRead quic_reads
[] = {
1593 MockRead(ASYNC
, ERR_IO_PENDING
),
1595 StaticSocketDataProvider
quic_data(quic_reads
, arraysize(quic_reads
),
1597 socket_factory_
.AddSocketDataProvider(&quic_data
);
1599 // Main job that will proceed when the QUIC job fails.
1600 MockRead http_reads
[] = {
1601 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
1602 MockRead("hello from http"),
1603 MockRead(SYNCHRONOUS
, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ
),
1607 StaticSocketDataProvider
http_data(http_reads
, arraysize(http_reads
),
1609 socket_factory_
.AddSocketDataProvider(&http_data
);
1611 CreateSessionWithNextProtos();
1613 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT
);
1615 SendRequestAndExpectHttpResponse("hello from http");
1618 TEST_P(QuicNetworkTransactionTest
, BrokenAlternateProtocolOnConnectFailure
) {
1619 params_
.enable_insecure_quic
= true;
1620 // Alternate-protocol job will fail before creating a QUIC session.
1621 StaticSocketDataProvider
quic_data(nullptr, 0, nullptr, 0);
1622 quic_data
.set_connect_data(MockConnect(SYNCHRONOUS
,
1623 ERR_INTERNET_DISCONNECTED
));
1624 socket_factory_
.AddSocketDataProvider(&quic_data
);
1626 // Main job which will succeed even though the alternate job fails.
1627 MockRead http_reads
[] = {
1628 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
1629 MockRead("hello from http"),
1630 MockRead(SYNCHRONOUS
, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ
),
1634 StaticSocketDataProvider
http_data(http_reads
, arraysize(http_reads
),
1636 socket_factory_
.AddSocketDataProvider(&http_data
);
1638 CreateSessionWithNextProtos();
1639 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START
);
1640 SendRequestAndExpectHttpResponse("hello from http");
1642 ExpectBrokenAlternateProtocolMapping();
1645 TEST_P(QuicNetworkTransactionTest
, ConnectionCloseDuringConnect
) {
1646 params_
.enable_insecure_quic
= true;
1647 MockQuicData mock_quic_data
;
1648 mock_quic_data
.AddSynchronousRead(ConstructConnectionClosePacket(1));
1649 mock_quic_data
.AddWrite(
1650 ConstructRequestHeadersPacket(1, kClientDataStreamId1
, true, true,
1651 GetRequestHeaders("GET", "http", "/")));
1652 mock_quic_data
.AddWrite(ConstructAckPacket(2, 1));
1653 mock_quic_data
.AddSocketDataToFactory(&socket_factory_
);
1655 // When the QUIC connection fails, we will try the request again over HTTP.
1656 MockRead http_reads
[] = {
1657 MockRead("HTTP/1.1 200 OK\r\n"),
1658 MockRead(kQuicAlternateProtocolHttpHeader
),
1659 MockRead("hello world"),
1660 MockRead(SYNCHRONOUS
, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ
),
1664 StaticSocketDataProvider
http_data(http_reads
, arraysize(http_reads
),
1666 socket_factory_
.AddSocketDataProvider(&http_data
);
1668 // In order for a new QUIC session to be established via alternate-protocol
1669 // without racing an HTTP connection, we need the host resolution to happen
1671 host_resolver_
.set_synchronous_mode(true);
1672 host_resolver_
.rules()->AddIPLiteralRule("www.google.com", "192.168.0.1", "");
1673 HostResolver::RequestInfo
info(HostPortPair("www.google.com", 80));
1674 AddressList address
;
1675 host_resolver_
.Resolve(info
,
1678 CompletionCallback(),
1682 CreateSessionWithNextProtos();
1683 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT
);
1684 SendRequestAndExpectHttpResponse("hello world");
1687 // Test that a secure request over an insecure QUIC connection fails with
1688 // the appropriate error code. Note that this never happens in production,
1689 // because the handshake (which this test mocks) would fail in this scenario.
1690 TEST_P(QuicNetworkTransactionTest
, SecureResourceOverInsecureQuic
) {
1691 params_
.enable_insecure_quic
= true;
1692 maker_
.set_hostname("www.example.org");
1693 MockQuicData mock_quic_data
;
1694 mock_quic_data
.AddWrite(
1695 ConstructRequestHeadersPacket(1, kClientDataStreamId1
, true, true,
1696 GetRequestHeaders("GET", "https", "/")));
1697 mock_quic_data
.AddRead(ConstructResponseHeadersPacket(
1698 1, kClientDataStreamId1
, false, false, GetResponseHeaders("200 OK")));
1699 mock_quic_data
.AddRead(
1700 ConstructDataPacket(2, kClientDataStreamId1
, false, true, 0, "hello!"));
1701 mock_quic_data
.AddWrite(ConstructAckPacket(2, 1));
1702 mock_quic_data
.AddRead(SYNCHRONOUS
, 0);
1703 mock_quic_data
.AddSocketDataToFactory(&socket_factory_
);
1705 request_
.url
= GURL("https://www.example.org:443");
1706 AddHangingNonAlternateProtocolSocketData();
1707 CreateSessionWithNextProtos();
1708 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE
);
1709 scoped_ptr
<HttpNetworkTransaction
> trans(
1710 new HttpNetworkTransaction(DEFAULT_PRIORITY
, session_
.get()));
1711 TestCompletionCallback callback
;
1712 int rv
= trans
->Start(&request_
, callback
.callback(), net_log_
.bound());
1713 EXPECT_EQ(ERR_REQUEST_FOR_SECURE_RESOURCE_OVER_INSECURE_QUIC
,
1714 callback
.GetResult(rv
));
1717 TEST_P(QuicNetworkTransactionTest
, SecureResourceOverSecureQuic
) {
1718 params_
.enable_insecure_quic
= true;
1719 maker_
.set_hostname("www.example.org");
1720 MockQuicData mock_quic_data
;
1721 mock_quic_data
.AddWrite(
1722 ConstructRequestHeadersPacket(1, kClientDataStreamId1
, true, true,
1723 GetRequestHeaders("GET", "https", "/")));
1724 mock_quic_data
.AddRead(ConstructResponseHeadersPacket(
1725 1, kClientDataStreamId1
, false, false, GetResponseHeaders("200 OK")));
1726 mock_quic_data
.AddRead(
1727 ConstructDataPacket(2, kClientDataStreamId1
, false, true, 0, "hello!"));
1728 mock_quic_data
.AddWrite(ConstructAckPacket(2, 1));
1729 mock_quic_data
.AddRead(SYNCHRONOUS
, ERR_IO_PENDING
); // No more read data.
1730 mock_quic_data
.AddSocketDataToFactory(&socket_factory_
);
1732 scoped_refptr
<X509Certificate
> cert(
1733 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem"));
1734 ASSERT_TRUE(cert
.get());
1735 bool common_name_fallback_used
;
1737 cert
->VerifyNameMatch("www.example.org", &common_name_fallback_used
));
1738 ProofVerifyDetailsChromium verify_details
;
1739 verify_details
.cert_verify_result
.verified_cert
= cert
;
1740 crypto_client_stream_factory_
.AddProofVerifyDetails(&verify_details
);
1742 request_
.url
= GURL("https://www.example.org:443");
1743 AddHangingNonAlternateProtocolSocketData();
1744 CreateSessionWithNextProtos();
1745 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE
);
1746 SendRequestAndExpectQuicResponse("hello!");