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/capturing_net_log.h"
12 #include "net/base/net_log_unittest.h"
13 #include "net/base/test_completion_callback.h"
14 #include "net/cert/mock_cert_verifier.h"
15 #include "net/dns/mock_host_resolver.h"
16 #include "net/http/http_auth_handler_factory.h"
17 #include "net/http/http_network_session.h"
18 #include "net/http/http_network_transaction.h"
19 #include "net/http/http_server_properties_impl.h"
20 #include "net/http/http_stream.h"
21 #include "net/http/http_stream_factory.h"
22 #include "net/http/http_transaction_test_util.h"
23 #include "net/http/transport_security_state.h"
24 #include "net/proxy/proxy_config_service_fixed.h"
25 #include "net/proxy/proxy_resolver.h"
26 #include "net/proxy/proxy_service.h"
27 #include "net/quic/crypto/quic_decrypter.h"
28 #include "net/quic/crypto/quic_encrypter.h"
29 #include "net/quic/quic_framer.h"
30 #include "net/quic/quic_http_utils.h"
31 #include "net/quic/test_tools/crypto_test_utils.h"
32 #include "net/quic/test_tools/mock_clock.h"
33 #include "net/quic/test_tools/mock_crypto_client_stream_factory.h"
34 #include "net/quic/test_tools/mock_random.h"
35 #include "net/quic/test_tools/quic_test_packet_maker.h"
36 #include "net/quic/test_tools/quic_test_utils.h"
37 #include "net/socket/client_socket_factory.h"
38 #include "net/socket/mock_client_socket_pool_manager.h"
39 #include "net/socket/socket_test_util.h"
40 #include "net/socket/ssl_client_socket.h"
41 #include "net/spdy/spdy_frame_builder.h"
42 #include "net/spdy/spdy_framer.h"
43 #include "net/ssl/ssl_config_service_defaults.h"
44 #include "testing/gtest/include/gtest/gtest.h"
45 #include "testing/platform_test.h"
47 //-----------------------------------------------------------------------------
51 // This is the expected return from a current server advertising QUIC.
52 static const char kQuicAlternateProtocolHttpHeader
[] =
53 "Alternate-Protocol: 80:quic\r\n\r\n";
54 static const char kQuicAlternateProtocol50pctHttpHeader
[] =
55 "Alternate-Protocol: 80:quic,p=.5\r\n\r\n";
56 static const char kQuicAlternateProtocolHttpsHeader
[] =
57 "Alternate-Protocol: 443:quic\r\n\r\n";
64 // Helper class to encapsulate MockReads and MockWrites for QUIC.
65 // Simplify ownership issues and the interaction with the MockSocketFactory.
69 STLDeleteElements(&packets_
);
72 void AddRead(scoped_ptr
<QuicEncryptedPacket
> packet
) {
73 reads_
.push_back(MockRead(SYNCHRONOUS
, packet
->data(), packet
->length(),
75 packets_
.push_back(packet
.release());
78 void AddRead(IoMode mode
, int rv
) {
79 reads_
.push_back(MockRead(mode
, rv
));
82 void AddWrite(scoped_ptr
<QuicEncryptedPacket
> packet
) {
83 writes_
.push_back(MockWrite(SYNCHRONOUS
, packet
->data(), packet
->length(),
85 packets_
.push_back(packet
.release());
88 void AddDelayedSocketDataToFactory(MockClientSocketFactory
* factory
,
90 MockRead
* reads
= reads_
.empty() ? nullptr : &reads_
[0];
91 MockWrite
* writes
= writes_
.empty() ? nullptr : &writes_
[0];
92 socket_data_
.reset(new DelayedSocketData(
93 delay
, reads
, reads_
.size(), writes
, writes_
.size()));
94 factory
->AddSocketDataProvider(socket_data_
.get());
98 std::vector
<QuicEncryptedPacket
*> packets_
;
99 std::vector
<MockWrite
> writes_
;
100 std::vector
<MockRead
> reads_
;
101 size_t sequence_number_
;
102 scoped_ptr
<SocketDataProvider
> socket_data_
;
105 class ProxyHeadersHandler
{
107 ProxyHeadersHandler() : was_called_(false) {}
109 bool was_called() { return was_called_
; }
111 void OnBeforeProxyHeadersSent(const ProxyInfo
& proxy_info
,
112 HttpRequestHeaders
* request_headers
) {
120 class QuicNetworkTransactionTest
121 : public PlatformTest
,
122 public ::testing::WithParamInterface
<QuicVersion
> {
124 QuicNetworkTransactionTest()
125 : clock_(new MockClock
),
126 maker_(GetParam(), 0, clock_
),
127 ssl_config_service_(new SSLConfigServiceDefaults
),
128 proxy_service_(ProxyService::CreateDirect()),
129 auth_handler_factory_(
130 HttpAuthHandlerFactory::CreateDefault(&host_resolver_
)),
131 random_generator_(0),
132 hanging_data_(nullptr, 0, nullptr, 0) {
133 request_
.method
= "GET";
134 request_
.url
= GURL("http://www.google.com/");
135 request_
.load_flags
= 0;
136 clock_
->AdvanceTime(QuicTime::Delta::FromMilliseconds(20));
139 void SetUp() override
{
140 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
141 base::MessageLoop::current()->RunUntilIdle();
144 void TearDown() override
{
145 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
146 // Empty the current queue.
147 base::MessageLoop::current()->RunUntilIdle();
148 PlatformTest::TearDown();
149 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
150 base::MessageLoop::current()->RunUntilIdle();
153 scoped_ptr
<QuicEncryptedPacket
> ConstructConnectionClosePacket(
154 QuicPacketSequenceNumber num
) {
155 return maker_
.MakeConnectionClosePacket(num
);
158 scoped_ptr
<QuicEncryptedPacket
> ConstructAckPacket(
159 QuicPacketSequenceNumber largest_received
,
160 QuicPacketSequenceNumber least_unacked
) {
161 return maker_
.MakeAckPacket(2, largest_received
, least_unacked
, true);
164 SpdyHeaderBlock
GetRequestHeaders(const std::string
& method
,
165 const std::string
& scheme
,
166 const std::string
& path
) {
167 return maker_
.GetRequestHeaders(method
, scheme
, path
);
170 SpdyHeaderBlock
GetResponseHeaders(const std::string
& status
) {
171 return maker_
.GetResponseHeaders(status
);
174 scoped_ptr
<QuicEncryptedPacket
> ConstructDataPacket(
175 QuicPacketSequenceNumber sequence_number
,
176 QuicStreamId stream_id
,
177 bool should_include_version
,
179 QuicStreamOffset offset
,
180 base::StringPiece data
) {
181 return maker_
.MakeDataPacket(
182 sequence_number
, stream_id
, should_include_version
, fin
, offset
, data
);
185 scoped_ptr
<QuicEncryptedPacket
> ConstructRequestHeadersPacket(
186 QuicPacketSequenceNumber sequence_number
,
187 QuicStreamId stream_id
,
188 bool should_include_version
,
190 const SpdyHeaderBlock
& headers
) {
191 QuicPriority priority
=
192 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY
);
193 return maker_
.MakeRequestHeadersPacket(sequence_number
, stream_id
,
194 should_include_version
, fin
,
198 scoped_ptr
<QuicEncryptedPacket
> ConstructResponseHeadersPacket(
199 QuicPacketSequenceNumber sequence_number
,
200 QuicStreamId stream_id
,
201 bool should_include_version
,
203 const SpdyHeaderBlock
& headers
) {
204 return maker_
.MakeResponseHeadersPacket(
205 sequence_number
, stream_id
, should_include_version
, fin
, headers
);
208 void CreateSession() {
209 CreateSessionWithFactory(&socket_factory_
, false);
212 void CreateSessionWithNextProtos() {
213 CreateSessionWithFactory(&socket_factory_
, true);
216 // If |use_next_protos| is true, enables SPDY and QUIC.
217 void CreateSessionWithFactory(ClientSocketFactory
* socket_factory
,
218 bool use_next_protos
) {
219 params_
.enable_quic
= true;
220 params_
.quic_clock
= clock_
;
221 params_
.quic_random
= &random_generator_
;
222 params_
.client_socket_factory
= socket_factory
;
223 params_
.quic_crypto_client_stream_factory
= &crypto_client_stream_factory_
;
224 params_
.host_resolver
= &host_resolver_
;
225 params_
.cert_verifier
= &cert_verifier_
;
226 params_
.transport_security_state
= &transport_security_state_
;
227 params_
.proxy_service
= proxy_service_
.get();
228 params_
.ssl_config_service
= ssl_config_service_
.get();
229 params_
.http_auth_handler_factory
= auth_handler_factory_
.get();
230 params_
.http_server_properties
= http_server_properties
.GetWeakPtr();
231 params_
.quic_supported_versions
= SupportedVersions(GetParam());
233 if (use_next_protos
) {
234 params_
.use_alternate_protocols
= true;
235 params_
.next_protos
= NextProtosWithSpdyAndQuic(true, true);
238 session_
= new HttpNetworkSession(params_
);
239 session_
->quic_stream_factory()->set_require_confirmation(false);
242 void CheckWasQuicResponse(const scoped_ptr
<HttpNetworkTransaction
>& trans
) {
243 const HttpResponseInfo
* response
= trans
->GetResponseInfo();
244 ASSERT_TRUE(response
!= nullptr);
245 ASSERT_TRUE(response
->headers
.get() != nullptr);
246 EXPECT_EQ("HTTP/1.1 200 OK", response
->headers
->GetStatusLine());
247 EXPECT_TRUE(response
->was_fetched_via_spdy
);
248 EXPECT_TRUE(response
->was_npn_negotiated
);
249 EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_QUIC1_SPDY3
,
250 response
->connection_info
);
253 void CheckWasHttpResponse(const scoped_ptr
<HttpNetworkTransaction
>& trans
) {
254 const HttpResponseInfo
* response
= trans
->GetResponseInfo();
255 ASSERT_TRUE(response
!= nullptr);
256 ASSERT_TRUE(response
->headers
.get() != nullptr);
257 EXPECT_EQ("HTTP/1.1 200 OK", response
->headers
->GetStatusLine());
258 EXPECT_FALSE(response
->was_fetched_via_spdy
);
259 EXPECT_FALSE(response
->was_npn_negotiated
);
260 EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP1
,
261 response
->connection_info
);
264 void CheckResponseData(HttpNetworkTransaction
* trans
,
265 const std::string
& expected
) {
266 std::string response_data
;
267 ASSERT_EQ(OK
, ReadTransaction(trans
, &response_data
));
268 EXPECT_EQ(expected
, response_data
);
271 void RunTransaction(HttpNetworkTransaction
* trans
) {
272 TestCompletionCallback callback
;
273 int rv
= trans
->Start(&request_
, callback
.callback(), net_log_
.bound());
274 EXPECT_EQ(ERR_IO_PENDING
, rv
);
275 EXPECT_EQ(OK
, callback
.WaitForResult());
278 void SendRequestAndExpectHttpResponse(const std::string
& expected
) {
279 scoped_ptr
<HttpNetworkTransaction
> trans(
280 new HttpNetworkTransaction(DEFAULT_PRIORITY
, session_
.get()));
281 RunTransaction(trans
.get());
282 CheckWasHttpResponse(trans
);
283 CheckResponseData(trans
.get(), expected
);
286 void SendRequestAndExpectQuicResponse(const std::string
& expected
) {
287 SendRequestAndExpectQuicResponseMaybeFromProxy(expected
, false);
290 void SendRequestAndExpectQuicResponseFromProxy(const std::string
& expected
) {
291 SendRequestAndExpectQuicResponseMaybeFromProxy(expected
, true);
294 void AddQuicAlternateProtocolMapping(
295 MockCryptoClientStream::HandshakeMode handshake_mode
) {
296 crypto_client_stream_factory_
.set_handshake_mode(handshake_mode
);
297 HostPortPair host_port_pair
= HostPortPair::FromURL(request_
.url
);
298 AlternativeService
alternative_service(QUIC
, host_port_pair
.host(), 80);
299 session_
->http_server_properties()->SetAlternativeService(
300 host_port_pair
, alternative_service
, 1.0);
303 void ExpectBrokenAlternateProtocolMapping() {
304 const HostPortPair origin
= HostPortPair::FromURL(request_
.url
);
305 const AlternativeService alternative_service
=
306 session_
->http_server_properties()->GetAlternativeService(origin
);
307 EXPECT_NE(UNINITIALIZED_ALTERNATE_PROTOCOL
, alternative_service
.protocol
);
308 EXPECT_TRUE(session_
->http_server_properties()->IsAlternativeServiceBroken(
309 alternative_service
));
312 void ExpectQuicAlternateProtocolMapping() {
313 const AlternativeService alternative_service
=
314 session_
->http_server_properties()->GetAlternativeService(
315 HostPortPair::FromURL(request_
.url
));
316 EXPECT_EQ(QUIC
, alternative_service
.protocol
);
319 void AddHangingNonAlternateProtocolSocketData() {
320 MockConnect
hanging_connect(SYNCHRONOUS
, ERR_IO_PENDING
);
321 hanging_data_
.set_connect_data(hanging_connect
);
322 socket_factory_
.AddSocketDataProvider(&hanging_data_
);
325 MockClock
* clock_
; // Owned by QuicStreamFactory after CreateSession.
326 QuicTestPacketMaker maker_
;
327 scoped_refptr
<HttpNetworkSession
> session_
;
328 MockClientSocketFactory socket_factory_
;
329 MockCryptoClientStreamFactory crypto_client_stream_factory_
;
330 MockHostResolver host_resolver_
;
331 MockCertVerifier cert_verifier_
;
332 TransportSecurityState transport_security_state_
;
333 scoped_refptr
<SSLConfigServiceDefaults
> ssl_config_service_
;
334 scoped_ptr
<ProxyService
> proxy_service_
;
335 scoped_ptr
<HttpAuthHandlerFactory
> auth_handler_factory_
;
336 MockRandom random_generator_
;
337 HttpServerPropertiesImpl http_server_properties
;
338 HttpNetworkSession::Params params_
;
339 HttpRequestInfo request_
;
340 CapturingBoundNetLog net_log_
;
341 StaticSocketDataProvider hanging_data_
;
344 void SendRequestAndExpectQuicResponseMaybeFromProxy(
345 const std::string
& expected
,
347 scoped_ptr
<HttpNetworkTransaction
> trans(
348 new HttpNetworkTransaction(DEFAULT_PRIORITY
, session_
.get()));
349 ProxyHeadersHandler proxy_headers_handler
;
350 trans
->SetBeforeProxyHeadersSentCallback(
351 base::Bind(&ProxyHeadersHandler::OnBeforeProxyHeadersSent
,
352 base::Unretained(&proxy_headers_handler
)));
353 RunTransaction(trans
.get());
354 CheckWasQuicResponse(trans
);
355 CheckResponseData(trans
.get(), expected
);
356 EXPECT_EQ(used_proxy
, proxy_headers_handler
.was_called());
360 INSTANTIATE_TEST_CASE_P(Version
, QuicNetworkTransactionTest
,
361 ::testing::ValuesIn(QuicSupportedVersions()));
363 TEST_P(QuicNetworkTransactionTest
, ForceQuic
) {
364 params_
.origin_to_force_quic_on
=
365 HostPortPair::FromString("www.google.com:80");
367 MockQuicData mock_quic_data
;
368 mock_quic_data
.AddWrite(
369 ConstructRequestHeadersPacket(1, kClientDataStreamId1
, true, true,
370 GetRequestHeaders("GET", "http", "/")));
371 mock_quic_data
.AddRead(
372 ConstructResponseHeadersPacket(1, kClientDataStreamId1
, false, false,
373 GetResponseHeaders("200 OK")));
374 mock_quic_data
.AddRead(
375 ConstructDataPacket(2, kClientDataStreamId1
, false, true, 0, "hello!"));
376 mock_quic_data
.AddWrite(ConstructAckPacket(2, 1));
377 mock_quic_data
.AddRead(SYNCHRONOUS
, 0); // EOF
379 mock_quic_data
.AddDelayedSocketDataToFactory(&socket_factory_
, 1);
381 // The non-alternate protocol job needs to hang in order to guarantee that
382 // the alternate-protocol job will "win".
383 AddHangingNonAlternateProtocolSocketData();
387 SendRequestAndExpectQuicResponse("hello!");
389 // Check that the NetLog was filled reasonably.
390 net::CapturingNetLog::CapturedEntryList entries
;
391 net_log_
.GetEntries(&entries
);
392 EXPECT_LT(0u, entries
.size());
394 // Check that we logged a QUIC_SESSION_PACKET_RECEIVED.
395 int pos
= net::ExpectLogContainsSomewhere(
397 net::NetLog::TYPE_QUIC_SESSION_PACKET_RECEIVED
,
398 net::NetLog::PHASE_NONE
);
401 // ... and also a TYPE_QUIC_SESSION_PACKET_HEADER_RECEIVED.
402 pos
= net::ExpectLogContainsSomewhere(
404 net::NetLog::TYPE_QUIC_SESSION_PACKET_HEADER_RECEIVED
,
405 net::NetLog::PHASE_NONE
);
408 std::string packet_sequence_number
;
409 ASSERT_TRUE(entries
[pos
].GetStringValue(
410 "packet_sequence_number", &packet_sequence_number
));
411 EXPECT_EQ("1", packet_sequence_number
);
413 // ... and also a QUIC_SESSION_STREAM_FRAME_RECEIVED.
414 pos
= net::ExpectLogContainsSomewhere(
416 net::NetLog::TYPE_QUIC_SESSION_STREAM_FRAME_RECEIVED
,
417 net::NetLog::PHASE_NONE
);
421 ASSERT_TRUE(entries
[pos
].GetIntegerValue("stream_id", &log_stream_id
));
422 EXPECT_EQ(3, log_stream_id
);
425 TEST_P(QuicNetworkTransactionTest
, QuicProxy
) {
426 params_
.enable_quic_for_proxies
= true;
427 proxy_service_
.reset(
428 ProxyService::CreateFixedFromPacResult("QUIC myproxy:70"));
430 MockQuicData mock_quic_data
;
431 mock_quic_data
.AddWrite(
432 ConstructRequestHeadersPacket(1, kClientDataStreamId1
, true, true,
433 GetRequestHeaders("GET", "http", "/")));
434 mock_quic_data
.AddRead(
435 ConstructResponseHeadersPacket(1, kClientDataStreamId1
, false, false,
436 GetResponseHeaders("200 OK")));
437 mock_quic_data
.AddRead(
438 ConstructDataPacket(2, kClientDataStreamId1
, false, true, 0, "hello!"));
439 mock_quic_data
.AddWrite(ConstructAckPacket(2, 1));
440 mock_quic_data
.AddRead(SYNCHRONOUS
, 0); // EOF
442 mock_quic_data
.AddDelayedSocketDataToFactory(&socket_factory_
, 1);
444 // There is no need to set up an alternate protocol job, because
445 // no attempt will be made to speak to the proxy over TCP.
449 SendRequestAndExpectQuicResponseFromProxy("hello!");
452 TEST_P(QuicNetworkTransactionTest
, ForceQuicWithErrorConnecting
) {
453 params_
.origin_to_force_quic_on
=
454 HostPortPair::FromString("www.google.com:80");
456 MockQuicData mock_quic_data
;
457 mock_quic_data
.AddRead(ASYNC
, ERR_SOCKET_NOT_CONNECTED
);
459 mock_quic_data
.AddDelayedSocketDataToFactory(&socket_factory_
, 0);
463 scoped_ptr
<HttpNetworkTransaction
> trans(
464 new HttpNetworkTransaction(DEFAULT_PRIORITY
, session_
.get()));
465 TestCompletionCallback callback
;
466 int rv
= trans
->Start(&request_
, callback
.callback(), net_log_
.bound());
467 EXPECT_EQ(ERR_IO_PENDING
, rv
);
468 EXPECT_EQ(ERR_CONNECTION_CLOSED
, callback
.WaitForResult());
471 TEST_P(QuicNetworkTransactionTest
, DoNotForceQuicForHttps
) {
472 // Attempt to "force" quic on 443, which will not be honored.
473 params_
.origin_to_force_quic_on
=
474 HostPortPair::FromString("www.google.com:443");
476 MockRead http_reads
[] = {
477 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
478 MockRead("hello world"),
479 MockRead(SYNCHRONOUS
, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ
),
483 StaticSocketDataProvider
data(http_reads
, arraysize(http_reads
), nullptr, 0);
484 socket_factory_
.AddSocketDataProvider(&data
);
485 SSLSocketDataProvider
ssl(ASYNC
, OK
);
486 socket_factory_
.AddSSLSocketDataProvider(&ssl
);
490 SendRequestAndExpectHttpResponse("hello world");
493 TEST_P(QuicNetworkTransactionTest
, UseAlternateProtocolForQuic
) {
494 MockRead http_reads
[] = {
495 MockRead("HTTP/1.1 200 OK\r\n"),
496 MockRead(kQuicAlternateProtocolHttpHeader
),
497 MockRead("hello world"),
498 MockRead(SYNCHRONOUS
, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ
),
502 StaticSocketDataProvider
http_data(http_reads
, arraysize(http_reads
),
504 socket_factory_
.AddSocketDataProvider(&http_data
);
506 MockQuicData mock_quic_data
;
507 mock_quic_data
.AddWrite(
508 ConstructRequestHeadersPacket(1, kClientDataStreamId1
, true, true,
509 GetRequestHeaders("GET", "http", "/")));
510 mock_quic_data
.AddRead(
511 ConstructResponseHeadersPacket(1, kClientDataStreamId1
, false, false,
512 GetResponseHeaders("200 OK")));
513 mock_quic_data
.AddRead(
514 ConstructDataPacket(2, kClientDataStreamId1
, false, true, 0, "hello!"));
515 mock_quic_data
.AddWrite(ConstructAckPacket(2, 1));
516 mock_quic_data
.AddRead(SYNCHRONOUS
, 0); // EOF
518 mock_quic_data
.AddDelayedSocketDataToFactory(&socket_factory_
, 1);
520 // The non-alternate protocol job needs to hang in order to guarantee that
521 // the alternate-protocol job will "win".
522 AddHangingNonAlternateProtocolSocketData();
524 CreateSessionWithNextProtos();
526 SendRequestAndExpectHttpResponse("hello world");
527 SendRequestAndExpectQuicResponse("hello!");
530 TEST_P(QuicNetworkTransactionTest
, ConfirmAlternativeService
) {
531 MockRead http_reads
[] = {
532 MockRead("HTTP/1.1 200 OK\r\n"),
533 MockRead(kQuicAlternateProtocolHttpHeader
),
534 MockRead("hello world"),
535 MockRead(SYNCHRONOUS
, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ
),
536 MockRead(ASYNC
, OK
)};
538 StaticSocketDataProvider
http_data(http_reads
, arraysize(http_reads
), nullptr,
540 socket_factory_
.AddSocketDataProvider(&http_data
);
542 MockQuicData mock_quic_data
;
543 mock_quic_data
.AddWrite(
544 ConstructRequestHeadersPacket(1, kClientDataStreamId1
, true, true,
545 GetRequestHeaders("GET", "http", "/")));
546 mock_quic_data
.AddRead(ConstructResponseHeadersPacket(
547 1, kClientDataStreamId1
, false, false, GetResponseHeaders("200 OK")));
548 mock_quic_data
.AddRead(
549 ConstructDataPacket(2, kClientDataStreamId1
, false, true, 0, "hello!"));
550 mock_quic_data
.AddWrite(ConstructAckPacket(2, 1));
551 mock_quic_data
.AddRead(SYNCHRONOUS
, 0); // EOF
553 mock_quic_data
.AddDelayedSocketDataToFactory(&socket_factory_
, 1);
555 // The non-alternate protocol job needs to hang in order to guarantee that
556 // the alternate-protocol job will "win".
557 AddHangingNonAlternateProtocolSocketData();
559 CreateSessionWithNextProtos();
561 AlternativeService
alternative_service(QUIC
,
562 HostPortPair::FromURL(request_
.url
));
563 session_
->http_server_properties()->MarkAlternativeServiceRecentlyBroken(
564 alternative_service
);
566 session_
->http_server_properties()->WasAlternativeServiceRecentlyBroken(
567 alternative_service
));
569 SendRequestAndExpectHttpResponse("hello world");
570 SendRequestAndExpectQuicResponse("hello!");
573 session_
->http_server_properties()->WasAlternativeServiceRecentlyBroken(
574 alternative_service
));
577 TEST_P(QuicNetworkTransactionTest
, UseAlternateProtocolProbabilityForQuic
) {
578 MockRead http_reads
[] = {
579 MockRead("HTTP/1.1 200 OK\r\n"),
580 MockRead(kQuicAlternateProtocol50pctHttpHeader
),
581 MockRead("hello world"),
582 MockRead(SYNCHRONOUS
, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ
),
586 StaticSocketDataProvider
http_data(http_reads
, arraysize(http_reads
),
588 socket_factory_
.AddSocketDataProvider(&http_data
);
590 MockQuicData mock_quic_data
;
591 mock_quic_data
.AddWrite(
592 ConstructRequestHeadersPacket(1, kClientDataStreamId1
, true, true,
593 GetRequestHeaders("GET", "http", "/")));
594 mock_quic_data
.AddRead(
595 ConstructResponseHeadersPacket(1, kClientDataStreamId1
, false, false,
596 GetResponseHeaders("200 OK")));
597 mock_quic_data
.AddRead(
598 ConstructDataPacket(2, kClientDataStreamId1
, false, true, 0, "hello!"));
599 mock_quic_data
.AddWrite(ConstructAckPacket(2, 1));
600 mock_quic_data
.AddRead(SYNCHRONOUS
, 0); // EOF
602 mock_quic_data
.AddDelayedSocketDataToFactory(&socket_factory_
, 1);
604 // The non-alternate protocol job needs to hang in order to guarantee that
605 // the alternate-protocol job will "win".
606 AddHangingNonAlternateProtocolSocketData();
608 params_
.alternate_protocol_probability_threshold
= .25;
609 CreateSessionWithNextProtos();
611 SendRequestAndExpectHttpResponse("hello world");
612 SendRequestAndExpectQuicResponse("hello!");
615 TEST_P(QuicNetworkTransactionTest
, DontUseAlternateProtocolProbabilityForQuic
) {
616 MockRead http_reads
[] = {
617 MockRead("HTTP/1.1 200 OK\r\n"),
618 MockRead(kQuicAlternateProtocol50pctHttpHeader
),
619 MockRead("hello world"),
620 MockRead(SYNCHRONOUS
, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ
),
624 StaticSocketDataProvider
http_data(http_reads
, arraysize(http_reads
),
626 socket_factory_
.AddSocketDataProvider(&http_data
);
627 socket_factory_
.AddSocketDataProvider(&http_data
);
629 params_
.alternate_protocol_probability_threshold
= .75;
630 CreateSessionWithNextProtos();
632 SendRequestAndExpectHttpResponse("hello world");
633 SendRequestAndExpectHttpResponse("hello world");
636 TEST_P(QuicNetworkTransactionTest
,
637 DontUseAlternateProtocolWithBadProbabilityForQuic
) {
638 MockRead http_reads
[] = {
639 MockRead("HTTP/1.1 200 OK\r\n"),
640 MockRead("Alternate-Protocol: 443:quic,p=2\r\n\r\n"),
641 MockRead("hello world"),
642 MockRead(SYNCHRONOUS
, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ
),
646 StaticSocketDataProvider
http_data(http_reads
, arraysize(http_reads
),
648 socket_factory_
.AddSocketDataProvider(&http_data
);
649 socket_factory_
.AddSocketDataProvider(&http_data
);
651 params_
.alternate_protocol_probability_threshold
= .75;
652 CreateSessionWithNextProtos();
654 SendRequestAndExpectHttpResponse("hello world");
655 SendRequestAndExpectHttpResponse("hello world");
658 TEST_P(QuicNetworkTransactionTest
, UseAlternateProtocolForQuicForHttps
) {
659 params_
.origin_to_force_quic_on
=
660 HostPortPair::FromString("www.google.com:443");
662 MockRead http_reads
[] = {
663 MockRead("HTTP/1.1 200 OK\r\n"),
664 MockRead(kQuicAlternateProtocolHttpsHeader
),
665 MockRead("hello world"),
666 MockRead(SYNCHRONOUS
, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ
),
670 StaticSocketDataProvider
http_data(http_reads
, arraysize(http_reads
),
672 socket_factory_
.AddSocketDataProvider(&http_data
);
674 MockQuicData mock_quic_data
;
675 mock_quic_data
.AddWrite(
676 ConstructRequestHeadersPacket(1, kClientDataStreamId1
, true, true,
677 GetRequestHeaders("GET", "http", "/")));
678 mock_quic_data
.AddRead(
679 ConstructResponseHeadersPacket(1, kClientDataStreamId1
, false, false,
680 GetResponseHeaders("200 OK")));
681 mock_quic_data
.AddRead(
682 ConstructDataPacket(2, kClientDataStreamId1
, false, true, 0, "hello!"));
683 mock_quic_data
.AddWrite(ConstructAckPacket(2, 1));
684 mock_quic_data
.AddRead(SYNCHRONOUS
, 0); // EOF
686 mock_quic_data
.AddDelayedSocketDataToFactory(&socket_factory_
, 1);
688 // The non-alternate protocol job needs to hang in order to guarantee that
689 // the alternate-protocol job will "win".
690 AddHangingNonAlternateProtocolSocketData();
692 CreateSessionWithNextProtos();
694 // TODO(rtenneti): Test QUIC over HTTPS, GetSSLInfo().
695 SendRequestAndExpectHttpResponse("hello world");
698 TEST_P(QuicNetworkTransactionTest
, HungAlternateProtocol
) {
699 crypto_client_stream_factory_
.set_handshake_mode(
700 MockCryptoClientStream::COLD_START
);
702 MockWrite http_writes
[] = {
703 MockWrite(SYNCHRONOUS
, 0, "GET / HTTP/1.1\r\n"),
704 MockWrite(SYNCHRONOUS
, 1, "Host: www.google.com\r\n"),
705 MockWrite(SYNCHRONOUS
, 2, "Connection: keep-alive\r\n\r\n")
708 MockRead http_reads
[] = {
709 MockRead(SYNCHRONOUS
, 3, "HTTP/1.1 200 OK\r\n"),
710 MockRead(SYNCHRONOUS
, 4, kQuicAlternateProtocolHttpHeader
),
711 MockRead(SYNCHRONOUS
, 5, "hello world"),
712 MockRead(SYNCHRONOUS
, OK
, 6)
715 DeterministicMockClientSocketFactory socket_factory
;
717 DeterministicSocketData
http_data(http_reads
, arraysize(http_reads
),
718 http_writes
, arraysize(http_writes
));
719 socket_factory
.AddSocketDataProvider(&http_data
);
721 // The QUIC transaction will not be allowed to complete.
722 MockWrite quic_writes
[] = {
723 MockWrite(ASYNC
, ERR_IO_PENDING
, 0)
725 MockRead quic_reads
[] = {
726 MockRead(ASYNC
, ERR_IO_PENDING
, 1),
728 DeterministicSocketData
quic_data(quic_reads
, arraysize(quic_reads
),
729 quic_writes
, arraysize(quic_writes
));
730 socket_factory
.AddSocketDataProvider(&quic_data
);
732 // The HTTP transaction will complete.
733 DeterministicSocketData
http_data2(http_reads
, arraysize(http_reads
),
734 http_writes
, arraysize(http_writes
));
735 socket_factory
.AddSocketDataProvider(&http_data2
);
737 CreateSessionWithFactory(&socket_factory
, true);
739 // Run the first request.
740 http_data
.StopAfter(arraysize(http_reads
) + arraysize(http_writes
));
741 SendRequestAndExpectHttpResponse("hello world");
742 ASSERT_TRUE(http_data
.at_read_eof());
743 ASSERT_TRUE(http_data
.at_write_eof());
745 // Now run the second request in which the QUIC socket hangs,
746 // and verify the the transaction continues over HTTP.
747 http_data2
.StopAfter(arraysize(http_reads
) + arraysize(http_writes
));
748 SendRequestAndExpectHttpResponse("hello world");
750 ASSERT_TRUE(http_data2
.at_read_eof());
751 ASSERT_TRUE(http_data2
.at_write_eof());
752 ASSERT_TRUE(!quic_data
.at_read_eof());
753 ASSERT_TRUE(!quic_data
.at_write_eof());
756 TEST_P(QuicNetworkTransactionTest
, ZeroRTTWithHttpRace
) {
757 MockQuicData mock_quic_data
;
758 mock_quic_data
.AddWrite(
759 ConstructRequestHeadersPacket(1, kClientDataStreamId1
, true, true,
760 GetRequestHeaders("GET", "http", "/")));
761 mock_quic_data
.AddRead(
762 ConstructResponseHeadersPacket(1, kClientDataStreamId1
, false, false,
763 GetResponseHeaders("200 OK")));
764 mock_quic_data
.AddRead(
765 ConstructDataPacket(2, kClientDataStreamId1
, false, true, 0, "hello!"));
766 mock_quic_data
.AddWrite(ConstructAckPacket(2, 1));
767 mock_quic_data
.AddRead(SYNCHRONOUS
, 0); // EOF
769 mock_quic_data
.AddDelayedSocketDataToFactory(&socket_factory_
, 1);
771 // The non-alternate protocol job needs to hang in order to guarantee that
772 // the alternate-protocol job will "win".
773 AddHangingNonAlternateProtocolSocketData();
775 CreateSessionWithNextProtos();
776 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT
);
777 SendRequestAndExpectQuicResponse("hello!");
780 TEST_P(QuicNetworkTransactionTest
, ZeroRTTWithNoHttpRace
) {
781 MockQuicData mock_quic_data
;
782 mock_quic_data
.AddWrite(
783 ConstructRequestHeadersPacket(1, kClientDataStreamId1
, true, true,
784 GetRequestHeaders("GET", "http", "/")));
785 mock_quic_data
.AddRead(
786 ConstructResponseHeadersPacket(1, kClientDataStreamId1
, false, false,
787 GetResponseHeaders("200 OK")));
788 mock_quic_data
.AddRead(
789 ConstructDataPacket(2, kClientDataStreamId1
, false, true, 0, "hello!"));
790 mock_quic_data
.AddWrite(ConstructAckPacket(2, 1));
791 mock_quic_data
.AddRead(SYNCHRONOUS
, 0); // EOF
792 mock_quic_data
.AddDelayedSocketDataToFactory(&socket_factory_
, 1);
794 // In order for a new QUIC session to be established via alternate-protocol
795 // without racing an HTTP connection, we need the host resolution to happen
797 host_resolver_
.set_synchronous_mode(true);
798 host_resolver_
.rules()->AddIPLiteralRule("www.google.com", "192.168.0.1", "");
799 HostResolver::RequestInfo
info(HostPortPair("www.google.com", 80));
801 host_resolver_
.Resolve(info
,
804 CompletionCallback(),
808 CreateSessionWithNextProtos();
809 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT
);
810 SendRequestAndExpectQuicResponse("hello!");
813 TEST_P(QuicNetworkTransactionTest
, ZeroRTTWithProxy
) {
814 proxy_service_
.reset(
815 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
817 // Since we are using a proxy, the QUIC job will not succeed.
818 MockWrite http_writes
[] = {
819 MockWrite(SYNCHRONOUS
, 0, "GET http://www.google.com/ HTTP/1.1\r\n"),
820 MockWrite(SYNCHRONOUS
, 1, "Host: www.google.com\r\n"),
821 MockWrite(SYNCHRONOUS
, 2, "Proxy-Connection: keep-alive\r\n\r\n")
824 MockRead http_reads
[] = {
825 MockRead(SYNCHRONOUS
, 3, "HTTP/1.1 200 OK\r\n"),
826 MockRead(SYNCHRONOUS
, 4, kQuicAlternateProtocolHttpHeader
),
827 MockRead(SYNCHRONOUS
, 5, "hello world"),
828 MockRead(SYNCHRONOUS
, OK
, 6)
831 StaticSocketDataProvider
http_data(http_reads
, arraysize(http_reads
),
832 http_writes
, arraysize(http_writes
));
833 socket_factory_
.AddSocketDataProvider(&http_data
);
835 // In order for a new QUIC session to be established via alternate-protocol
836 // without racing an HTTP connection, we need the host resolution to happen
838 host_resolver_
.set_synchronous_mode(true);
839 host_resolver_
.rules()->AddIPLiteralRule("www.google.com", "192.168.0.1", "");
840 HostResolver::RequestInfo
info(HostPortPair("www.google.com", 80));
842 host_resolver_
.Resolve(info
,
845 CompletionCallback(),
849 CreateSessionWithNextProtos();
850 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT
);
851 SendRequestAndExpectHttpResponse("hello world");
854 TEST_P(QuicNetworkTransactionTest
, ZeroRTTWithConfirmationRequired
) {
855 MockQuicData mock_quic_data
;
856 mock_quic_data
.AddWrite(
857 ConstructRequestHeadersPacket(1, kClientDataStreamId1
, true, true,
858 GetRequestHeaders("GET", "http", "/")));
859 mock_quic_data
.AddRead(
860 ConstructResponseHeadersPacket(1, kClientDataStreamId1
, false, false,
861 GetResponseHeaders("200 OK")));
862 mock_quic_data
.AddRead(
863 ConstructDataPacket(2, kClientDataStreamId1
, false, true, 0, "hello!"));
864 mock_quic_data
.AddWrite(ConstructAckPacket(2, 1));
865 mock_quic_data
.AddRead(SYNCHRONOUS
, 0); // EOF
866 mock_quic_data
.AddDelayedSocketDataToFactory(&socket_factory_
, 1);
868 // The non-alternate protocol job needs to hang in order to guarantee that
869 // the alternate-protocol job will "win".
870 AddHangingNonAlternateProtocolSocketData();
872 // In order for a new QUIC session to be established via alternate-protocol
873 // without racing an HTTP connection, we need the host resolution to happen
874 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
875 // connection to the the server, in this test we require confirmation
876 // before encrypting so the HTTP job will still start.
877 host_resolver_
.set_synchronous_mode(true);
878 host_resolver_
.rules()->AddIPLiteralRule("www.google.com", "192.168.0.1", "");
879 HostResolver::RequestInfo
info(HostPortPair("www.google.com", 80));
881 host_resolver_
.Resolve(info
, DEFAULT_PRIORITY
, &address
,
882 CompletionCallback(), nullptr, net_log_
.bound());
884 CreateSessionWithNextProtos();
885 session_
->quic_stream_factory()->set_require_confirmation(true);
886 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT
);
888 scoped_ptr
<HttpNetworkTransaction
> trans(
889 new HttpNetworkTransaction(DEFAULT_PRIORITY
, session_
.get()));
890 TestCompletionCallback callback
;
891 int rv
= trans
->Start(&request_
, callback
.callback(), net_log_
.bound());
892 EXPECT_EQ(ERR_IO_PENDING
, rv
);
894 crypto_client_stream_factory_
.last_stream()->SendOnCryptoHandshakeEvent(
895 QuicSession::HANDSHAKE_CONFIRMED
);
896 EXPECT_EQ(OK
, callback
.WaitForResult());
899 TEST_P(QuicNetworkTransactionTest
, BrokenAlternateProtocol
) {
900 // Alternate-protocol job
901 scoped_ptr
<QuicEncryptedPacket
> close(ConstructConnectionClosePacket(1));
902 MockRead quic_reads
[] = {
903 MockRead(ASYNC
, close
->data(), close
->length()),
904 MockRead(ASYNC
, OK
), // EOF
906 StaticSocketDataProvider
quic_data(quic_reads
, arraysize(quic_reads
),
908 socket_factory_
.AddSocketDataProvider(&quic_data
);
910 // Main job which will succeed even though the alternate job fails.
911 MockRead http_reads
[] = {
912 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
913 MockRead("hello from http"),
914 MockRead(SYNCHRONOUS
, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ
),
918 StaticSocketDataProvider
http_data(http_reads
, arraysize(http_reads
),
920 socket_factory_
.AddSocketDataProvider(&http_data
);
922 CreateSessionWithNextProtos();
923 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START
);
924 SendRequestAndExpectHttpResponse("hello from http");
925 ExpectBrokenAlternateProtocolMapping();
928 TEST_P(QuicNetworkTransactionTest
, BrokenAlternateProtocolReadError
) {
929 // Alternate-protocol job
930 MockRead quic_reads
[] = {
931 MockRead(ASYNC
, ERR_SOCKET_NOT_CONNECTED
),
933 StaticSocketDataProvider
quic_data(quic_reads
, arraysize(quic_reads
),
935 socket_factory_
.AddSocketDataProvider(&quic_data
);
937 // Main job which will succeed even though the alternate job fails.
938 MockRead http_reads
[] = {
939 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
940 MockRead("hello from http"),
941 MockRead(SYNCHRONOUS
, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ
),
945 StaticSocketDataProvider
http_data(http_reads
, arraysize(http_reads
),
947 socket_factory_
.AddSocketDataProvider(&http_data
);
949 CreateSessionWithNextProtos();
951 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START
);
952 SendRequestAndExpectHttpResponse("hello from http");
953 ExpectBrokenAlternateProtocolMapping();
956 TEST_P(QuicNetworkTransactionTest
, NoBrokenAlternateProtocolIfTcpFails
) {
957 // Alternate-protocol job will fail when the session attempts to read.
958 MockRead quic_reads
[] = {
959 MockRead(ASYNC
, ERR_SOCKET_NOT_CONNECTED
),
961 StaticSocketDataProvider
quic_data(quic_reads
, arraysize(quic_reads
),
963 socket_factory_
.AddSocketDataProvider(&quic_data
);
965 // Main job will also fail.
966 MockRead http_reads
[] = {
967 MockRead(ASYNC
, ERR_SOCKET_NOT_CONNECTED
),
970 StaticSocketDataProvider
http_data(http_reads
, arraysize(http_reads
),
972 http_data
.set_connect_data(MockConnect(ASYNC
, ERR_SOCKET_NOT_CONNECTED
));
973 socket_factory_
.AddSocketDataProvider(&http_data
);
975 CreateSessionWithNextProtos();
977 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START
);
978 scoped_ptr
<HttpNetworkTransaction
> trans(
979 new HttpNetworkTransaction(DEFAULT_PRIORITY
, session_
.get()));
980 TestCompletionCallback callback
;
981 int rv
= trans
->Start(&request_
, callback
.callback(), net_log_
.bound());
982 EXPECT_EQ(ERR_IO_PENDING
, rv
);
983 EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED
, callback
.WaitForResult());
984 ExpectQuicAlternateProtocolMapping();
987 TEST_P(QuicNetworkTransactionTest
, FailedZeroRttBrokenAlternateProtocol
) {
988 // Alternate-protocol job
989 MockRead quic_reads
[] = {
990 MockRead(ASYNC
, ERR_SOCKET_NOT_CONNECTED
),
992 StaticSocketDataProvider
quic_data(quic_reads
, arraysize(quic_reads
),
994 socket_factory_
.AddSocketDataProvider(&quic_data
);
996 AddHangingNonAlternateProtocolSocketData();
998 // Second Alternate-protocol job which will race with the TCP job.
999 StaticSocketDataProvider
quic_data2(quic_reads
, arraysize(quic_reads
),
1001 socket_factory_
.AddSocketDataProvider(&quic_data2
);
1003 // Final job that will proceed when the QUIC job fails.
1004 MockRead http_reads
[] = {
1005 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
1006 MockRead("hello from http"),
1007 MockRead(SYNCHRONOUS
, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ
),
1011 StaticSocketDataProvider
http_data(http_reads
, arraysize(http_reads
),
1013 socket_factory_
.AddSocketDataProvider(&http_data
);
1015 CreateSessionWithNextProtos();
1017 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT
);
1019 SendRequestAndExpectHttpResponse("hello from http");
1021 ExpectBrokenAlternateProtocolMapping();
1023 EXPECT_TRUE(quic_data
.at_read_eof());
1024 EXPECT_TRUE(quic_data
.at_write_eof());
1027 TEST_P(QuicNetworkTransactionTest
, DISABLED_HangingZeroRttFallback
) {
1028 // Alternate-protocol job
1029 MockRead quic_reads
[] = {
1030 MockRead(ASYNC
, ERR_IO_PENDING
),
1032 StaticSocketDataProvider
quic_data(quic_reads
, arraysize(quic_reads
),
1034 socket_factory_
.AddSocketDataProvider(&quic_data
);
1036 // Main job that will proceed when the QUIC job fails.
1037 MockRead http_reads
[] = {
1038 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
1039 MockRead("hello from http"),
1040 MockRead(SYNCHRONOUS
, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ
),
1044 StaticSocketDataProvider
http_data(http_reads
, arraysize(http_reads
),
1046 socket_factory_
.AddSocketDataProvider(&http_data
);
1048 CreateSessionWithNextProtos();
1050 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT
);
1052 SendRequestAndExpectHttpResponse("hello from http");
1055 TEST_P(QuicNetworkTransactionTest
, BrokenAlternateProtocolOnConnectFailure
) {
1056 // Alternate-protocol job will fail before creating a QUIC session.
1057 StaticSocketDataProvider
quic_data(nullptr, 0, nullptr, 0);
1058 quic_data
.set_connect_data(MockConnect(SYNCHRONOUS
,
1059 ERR_INTERNET_DISCONNECTED
));
1060 socket_factory_
.AddSocketDataProvider(&quic_data
);
1062 // Main job which will succeed even though the alternate job fails.
1063 MockRead http_reads
[] = {
1064 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
1065 MockRead("hello from http"),
1066 MockRead(SYNCHRONOUS
, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ
),
1070 StaticSocketDataProvider
http_data(http_reads
, arraysize(http_reads
),
1072 socket_factory_
.AddSocketDataProvider(&http_data
);
1074 CreateSessionWithNextProtos();
1075 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START
);
1076 SendRequestAndExpectHttpResponse("hello from http");
1078 ExpectBrokenAlternateProtocolMapping();
1081 TEST_P(QuicNetworkTransactionTest
, ConnectionCloseDuringConnect
) {
1082 MockQuicData mock_quic_data
;
1083 mock_quic_data
.AddRead(ConstructConnectionClosePacket(1));
1084 mock_quic_data
.AddWrite(
1085 ConstructRequestHeadersPacket(1, kClientDataStreamId1
, true, true,
1086 GetRequestHeaders("GET", "http", "/")));
1087 mock_quic_data
.AddWrite(ConstructAckPacket(2, 1));
1088 mock_quic_data
.AddDelayedSocketDataToFactory(&socket_factory_
, 0);
1090 // When the QUIC connection fails, we will try the request again over HTTP.
1091 MockRead http_reads
[] = {
1092 MockRead("HTTP/1.1 200 OK\r\n"),
1093 MockRead(kQuicAlternateProtocolHttpHeader
),
1094 MockRead("hello world"),
1095 MockRead(SYNCHRONOUS
, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ
),
1099 StaticSocketDataProvider
http_data(http_reads
, arraysize(http_reads
),
1101 socket_factory_
.AddSocketDataProvider(&http_data
);
1103 // In order for a new QUIC session to be established via alternate-protocol
1104 // without racing an HTTP connection, we need the host resolution to happen
1106 host_resolver_
.set_synchronous_mode(true);
1107 host_resolver_
.rules()->AddIPLiteralRule("www.google.com", "192.168.0.1", "");
1108 HostResolver::RequestInfo
info(HostPortPair("www.google.com", 80));
1109 AddressList address
;
1110 host_resolver_
.Resolve(info
,
1113 CompletionCallback(),
1117 CreateSessionWithNextProtos();
1118 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT
);
1119 SendRequestAndExpectHttpResponse("hello world");