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/cert/mock_cert_verifier.h"
13 #include "net/dns/mock_host_resolver.h"
14 #include "net/http/http_auth_handler_factory.h"
15 #include "net/http/http_network_session.h"
16 #include "net/http/http_network_transaction.h"
17 #include "net/http/http_server_properties_impl.h"
18 #include "net/http/http_stream.h"
19 #include "net/http/http_stream_factory.h"
20 #include "net/http/http_transaction_test_util.h"
21 #include "net/http/transport_security_state.h"
22 #include "net/log/net_log_unittest.h"
23 #include "net/log/test_net_log.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 kQuicAlternateProtocolDifferentPortHttpHeader
[] =
57 "Alternate-Protocol: 137:quic\r\n\r\n";
58 static const char kQuicAlternateProtocolHttpsHeader
[] =
59 "Alternate-Protocol: 443:quic\r\n\r\n";
66 // Helper class to encapsulate MockReads and MockWrites for QUIC.
67 // Simplify ownership issues and the interaction with the MockSocketFactory.
70 MockQuicData() : sequence_number_(0) {}
73 STLDeleteElements(&packets_
);
76 void AddSynchronousRead(scoped_ptr
<QuicEncryptedPacket
> packet
) {
77 reads_
.push_back(MockRead(SYNCHRONOUS
, packet
->data(), packet
->length(),
79 packets_
.push_back(packet
.release());
82 void AddRead(scoped_ptr
<QuicEncryptedPacket
> packet
) {
84 MockRead(ASYNC
, packet
->data(), packet
->length(), sequence_number_
++));
85 packets_
.push_back(packet
.release());
88 void AddRead(IoMode mode
, int rv
) {
89 reads_
.push_back(MockRead(mode
, rv
, sequence_number_
++));
92 void AddWrite(scoped_ptr
<QuicEncryptedPacket
> packet
) {
93 writes_
.push_back(MockWrite(SYNCHRONOUS
, packet
->data(), packet
->length(),
95 packets_
.push_back(packet
.release());
98 void AddSocketDataToFactory(MockClientSocketFactory
* factory
) {
99 MockRead
* reads
= reads_
.empty() ? nullptr : &reads_
[0];
100 MockWrite
* writes
= writes_
.empty() ? nullptr : &writes_
[0];
102 new SequencedSocketData(reads
, reads_
.size(), writes
, writes_
.size()));
103 factory
->AddSocketDataProvider(socket_data_
.get());
107 std::vector
<QuicEncryptedPacket
*> packets_
;
108 std::vector
<MockWrite
> writes_
;
109 std::vector
<MockRead
> reads_
;
110 size_t sequence_number_
;
111 scoped_ptr
<SocketDataProvider
> socket_data_
;
114 class ProxyHeadersHandler
{
116 ProxyHeadersHandler() : was_called_(false) {}
118 bool was_called() { return was_called_
; }
120 void OnBeforeProxyHeadersSent(const ProxyInfo
& proxy_info
,
121 HttpRequestHeaders
* request_headers
) {
129 class QuicNetworkTransactionTest
130 : public PlatformTest
,
131 public ::testing::WithParamInterface
<QuicVersion
> {
133 QuicNetworkTransactionTest()
134 : clock_(new MockClock
),
135 maker_(GetParam(), 0, clock_
),
136 ssl_config_service_(new SSLConfigServiceDefaults
),
137 proxy_service_(ProxyService::CreateDirect()),
138 auth_handler_factory_(
139 HttpAuthHandlerFactory::CreateDefault(&host_resolver_
)),
140 random_generator_(0),
141 hanging_data_(nullptr, 0, nullptr, 0) {
142 request_
.method
= "GET";
143 request_
.url
= GURL("http://www.google.com/");
144 request_
.load_flags
= 0;
145 clock_
->AdvanceTime(QuicTime::Delta::FromMilliseconds(20));
148 void SetUp() override
{
149 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
150 base::MessageLoop::current()->RunUntilIdle();
153 void TearDown() override
{
154 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
155 // Empty the current queue.
156 base::MessageLoop::current()->RunUntilIdle();
157 PlatformTest::TearDown();
158 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
159 base::MessageLoop::current()->RunUntilIdle();
162 scoped_ptr
<QuicEncryptedPacket
> ConstructConnectionClosePacket(
163 QuicPacketSequenceNumber num
) {
164 return maker_
.MakeConnectionClosePacket(num
);
167 scoped_ptr
<QuicEncryptedPacket
> ConstructAckPacket(
168 QuicPacketSequenceNumber largest_received
,
169 QuicPacketSequenceNumber least_unacked
) {
170 return maker_
.MakeAckPacket(2, largest_received
, least_unacked
, true);
173 SpdyHeaderBlock
GetRequestHeaders(const std::string
& method
,
174 const std::string
& scheme
,
175 const std::string
& path
) {
176 return maker_
.GetRequestHeaders(method
, scheme
, path
);
179 SpdyHeaderBlock
GetResponseHeaders(const std::string
& status
) {
180 return maker_
.GetResponseHeaders(status
);
183 scoped_ptr
<QuicEncryptedPacket
> ConstructDataPacket(
184 QuicPacketSequenceNumber sequence_number
,
185 QuicStreamId stream_id
,
186 bool should_include_version
,
188 QuicStreamOffset offset
,
189 base::StringPiece data
) {
190 return maker_
.MakeDataPacket(
191 sequence_number
, stream_id
, should_include_version
, fin
, offset
, data
);
194 scoped_ptr
<QuicEncryptedPacket
> ConstructRequestHeadersPacket(
195 QuicPacketSequenceNumber sequence_number
,
196 QuicStreamId stream_id
,
197 bool should_include_version
,
199 const SpdyHeaderBlock
& headers
) {
200 QuicPriority priority
=
201 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY
);
202 return maker_
.MakeRequestHeadersPacket(sequence_number
, stream_id
,
203 should_include_version
, fin
,
207 scoped_ptr
<QuicEncryptedPacket
> ConstructResponseHeadersPacket(
208 QuicPacketSequenceNumber sequence_number
,
209 QuicStreamId stream_id
,
210 bool should_include_version
,
212 const SpdyHeaderBlock
& headers
) {
213 return maker_
.MakeResponseHeadersPacket(
214 sequence_number
, stream_id
, should_include_version
, fin
, headers
);
217 void CreateSession() {
218 CreateSessionWithFactory(&socket_factory_
, false);
221 void CreateSessionWithNextProtos() {
222 CreateSessionWithFactory(&socket_factory_
, true);
225 // If |use_next_protos| is true, enables SPDY and QUIC.
226 void CreateSessionWithFactory(ClientSocketFactory
* socket_factory
,
227 bool use_next_protos
) {
228 params_
.enable_quic
= true;
229 params_
.quic_clock
= clock_
;
230 params_
.quic_random
= &random_generator_
;
231 params_
.client_socket_factory
= socket_factory
;
232 params_
.quic_crypto_client_stream_factory
= &crypto_client_stream_factory_
;
233 params_
.host_resolver
= &host_resolver_
;
234 params_
.cert_verifier
= &cert_verifier_
;
235 params_
.transport_security_state
= &transport_security_state_
;
236 params_
.proxy_service
= proxy_service_
.get();
237 params_
.ssl_config_service
= ssl_config_service_
.get();
238 params_
.http_auth_handler_factory
= auth_handler_factory_
.get();
239 params_
.http_server_properties
= http_server_properties
.GetWeakPtr();
240 params_
.quic_supported_versions
= SupportedVersions(GetParam());
242 if (use_next_protos
) {
243 params_
.use_alternate_protocols
= true;
244 params_
.next_protos
= NextProtosWithSpdyAndQuic(true, true);
247 session_
= new HttpNetworkSession(params_
);
248 session_
->quic_stream_factory()->set_require_confirmation(false);
251 void CheckWasQuicResponse(const scoped_ptr
<HttpNetworkTransaction
>& trans
) {
252 const HttpResponseInfo
* response
= trans
->GetResponseInfo();
253 ASSERT_TRUE(response
!= nullptr);
254 ASSERT_TRUE(response
->headers
.get() != nullptr);
255 EXPECT_EQ("HTTP/1.1 200 OK", response
->headers
->GetStatusLine());
256 EXPECT_TRUE(response
->was_fetched_via_spdy
);
257 EXPECT_TRUE(response
->was_npn_negotiated
);
258 EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_QUIC1_SPDY3
,
259 response
->connection_info
);
262 void CheckResponsePort(const scoped_ptr
<HttpNetworkTransaction
>& trans
,
264 const HttpResponseInfo
* response
= trans
->GetResponseInfo();
265 ASSERT_TRUE(response
!= nullptr);
266 EXPECT_EQ(port
, response
->socket_address
.port());
269 void CheckWasHttpResponse(const scoped_ptr
<HttpNetworkTransaction
>& trans
) {
270 const HttpResponseInfo
* response
= trans
->GetResponseInfo();
271 ASSERT_TRUE(response
!= nullptr);
272 ASSERT_TRUE(response
->headers
.get() != nullptr);
273 EXPECT_EQ("HTTP/1.1 200 OK", response
->headers
->GetStatusLine());
274 EXPECT_FALSE(response
->was_fetched_via_spdy
);
275 EXPECT_FALSE(response
->was_npn_negotiated
);
276 EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP1
,
277 response
->connection_info
);
280 void CheckResponseData(HttpNetworkTransaction
* trans
,
281 const std::string
& expected
) {
282 std::string response_data
;
283 ASSERT_EQ(OK
, ReadTransaction(trans
, &response_data
));
284 EXPECT_EQ(expected
, response_data
);
287 void RunTransaction(HttpNetworkTransaction
* trans
) {
288 TestCompletionCallback callback
;
289 int rv
= trans
->Start(&request_
, callback
.callback(), net_log_
.bound());
290 EXPECT_EQ(ERR_IO_PENDING
, rv
);
291 EXPECT_EQ(OK
, callback
.WaitForResult());
294 void SendRequestAndExpectHttpResponse(const std::string
& expected
) {
295 scoped_ptr
<HttpNetworkTransaction
> trans(
296 new HttpNetworkTransaction(DEFAULT_PRIORITY
, session_
.get()));
297 RunTransaction(trans
.get());
298 CheckWasHttpResponse(trans
);
299 CheckResponseData(trans
.get(), expected
);
302 void SendRequestAndExpectQuicResponse(const std::string
& expected
) {
303 SendRequestAndExpectQuicResponseMaybeFromProxy(expected
, false, 80);
306 void SendRequestAndExpectQuicResponseOnPort(const std::string
& expected
,
308 SendRequestAndExpectQuicResponseMaybeFromProxy(expected
, false, port
);
311 void SendRequestAndExpectQuicResponseFromProxyOnPort(
312 const std::string
& expected
,
314 SendRequestAndExpectQuicResponseMaybeFromProxy(expected
, true, port
);
317 void AddQuicAlternateProtocolMapping(
318 MockCryptoClientStream::HandshakeMode handshake_mode
) {
319 crypto_client_stream_factory_
.set_handshake_mode(handshake_mode
);
320 HostPortPair host_port_pair
= HostPortPair::FromURL(request_
.url
);
321 AlternativeService
alternative_service(QUIC
, host_port_pair
.host(), 80);
322 session_
->http_server_properties()->SetAlternativeService(
323 host_port_pair
, alternative_service
, 1.0);
326 void ExpectBrokenAlternateProtocolMapping() {
327 const HostPortPair origin
= HostPortPair::FromURL(request_
.url
);
328 const AlternativeService alternative_service
=
329 session_
->http_server_properties()->GetAlternativeService(origin
);
330 EXPECT_NE(UNINITIALIZED_ALTERNATE_PROTOCOL
, alternative_service
.protocol
);
331 EXPECT_TRUE(session_
->http_server_properties()->IsAlternativeServiceBroken(
332 alternative_service
));
335 void ExpectQuicAlternateProtocolMapping() {
336 const AlternativeService alternative_service
=
337 session_
->http_server_properties()->GetAlternativeService(
338 HostPortPair::FromURL(request_
.url
));
339 EXPECT_EQ(QUIC
, alternative_service
.protocol
);
342 void AddHangingNonAlternateProtocolSocketData() {
343 MockConnect
hanging_connect(SYNCHRONOUS
, ERR_IO_PENDING
);
344 hanging_data_
.set_connect_data(hanging_connect
);
345 socket_factory_
.AddSocketDataProvider(&hanging_data_
);
348 MockClock
* clock_
; // Owned by QuicStreamFactory after CreateSession.
349 QuicTestPacketMaker maker_
;
350 scoped_refptr
<HttpNetworkSession
> session_
;
351 MockClientSocketFactory socket_factory_
;
352 MockCryptoClientStreamFactory crypto_client_stream_factory_
;
353 MockHostResolver host_resolver_
;
354 MockCertVerifier cert_verifier_
;
355 TransportSecurityState transport_security_state_
;
356 scoped_refptr
<SSLConfigServiceDefaults
> ssl_config_service_
;
357 scoped_ptr
<ProxyService
> proxy_service_
;
358 scoped_ptr
<HttpAuthHandlerFactory
> auth_handler_factory_
;
359 MockRandom random_generator_
;
360 HttpServerPropertiesImpl http_server_properties
;
361 HttpNetworkSession::Params params_
;
362 HttpRequestInfo request_
;
363 BoundTestNetLog net_log_
;
364 StaticSocketDataProvider hanging_data_
;
367 void SendRequestAndExpectQuicResponseMaybeFromProxy(
368 const std::string
& expected
,
371 scoped_ptr
<HttpNetworkTransaction
> trans(
372 new HttpNetworkTransaction(DEFAULT_PRIORITY
, session_
.get()));
373 ProxyHeadersHandler proxy_headers_handler
;
374 trans
->SetBeforeProxyHeadersSentCallback(
375 base::Bind(&ProxyHeadersHandler::OnBeforeProxyHeadersSent
,
376 base::Unretained(&proxy_headers_handler
)));
377 RunTransaction(trans
.get());
378 CheckWasQuicResponse(trans
);
379 CheckResponsePort(trans
, port
);
380 CheckResponseData(trans
.get(), expected
);
381 EXPECT_EQ(used_proxy
, proxy_headers_handler
.was_called());
385 INSTANTIATE_TEST_CASE_P(Version
, QuicNetworkTransactionTest
,
386 ::testing::ValuesIn(QuicSupportedVersions()));
388 TEST_P(QuicNetworkTransactionTest
, ForceQuic
) {
389 params_
.origin_to_force_quic_on
=
390 HostPortPair::FromString("www.google.com:80");
392 MockQuicData mock_quic_data
;
393 mock_quic_data
.AddWrite(
394 ConstructRequestHeadersPacket(1, kClientDataStreamId1
, true, true,
395 GetRequestHeaders("GET", "http", "/")));
396 mock_quic_data
.AddRead(
397 ConstructResponseHeadersPacket(1, kClientDataStreamId1
, false, false,
398 GetResponseHeaders("200 OK")));
399 mock_quic_data
.AddRead(
400 ConstructDataPacket(2, kClientDataStreamId1
, false, true, 0, "hello!"));
401 mock_quic_data
.AddWrite(ConstructAckPacket(2, 1));
402 mock_quic_data
.AddRead(SYNCHRONOUS
, 0); // EOF
404 mock_quic_data
.AddSocketDataToFactory(&socket_factory_
);
406 // The non-alternate protocol job needs to hang in order to guarantee that
407 // the alternate-protocol job will "win".
408 AddHangingNonAlternateProtocolSocketData();
412 SendRequestAndExpectQuicResponse("hello!");
414 // Check that the NetLog was filled reasonably.
415 TestNetLog::CapturedEntryList entries
;
416 net_log_
.GetEntries(&entries
);
417 EXPECT_LT(0u, entries
.size());
419 // Check that we logged a QUIC_SESSION_PACKET_RECEIVED.
420 int pos
= ExpectLogContainsSomewhere(
421 entries
, 0, NetLog::TYPE_QUIC_SESSION_PACKET_RECEIVED
,
425 // ... and also a TYPE_QUIC_SESSION_PACKET_HEADER_RECEIVED.
426 pos
= ExpectLogContainsSomewhere(
427 entries
, 0, NetLog::TYPE_QUIC_SESSION_PACKET_HEADER_RECEIVED
,
431 std::string packet_sequence_number
;
432 ASSERT_TRUE(entries
[pos
].GetStringValue(
433 "packet_sequence_number", &packet_sequence_number
));
434 EXPECT_EQ("1", packet_sequence_number
);
436 // ... and also a QUIC_SESSION_STREAM_FRAME_RECEIVED.
437 pos
= ExpectLogContainsSomewhere(
438 entries
, 0, NetLog::TYPE_QUIC_SESSION_STREAM_FRAME_RECEIVED
,
443 ASSERT_TRUE(entries
[pos
].GetIntegerValue("stream_id", &log_stream_id
));
444 EXPECT_EQ(3, log_stream_id
);
447 TEST_P(QuicNetworkTransactionTest
, QuicProxy
) {
448 params_
.enable_quic_for_proxies
= true;
449 proxy_service_
.reset(
450 ProxyService::CreateFixedFromPacResult("QUIC myproxy:70"));
452 MockQuicData mock_quic_data
;
453 mock_quic_data
.AddWrite(
454 ConstructRequestHeadersPacket(1, kClientDataStreamId1
, true, true,
455 GetRequestHeaders("GET", "http", "/")));
456 mock_quic_data
.AddRead(
457 ConstructResponseHeadersPacket(1, kClientDataStreamId1
, false, false,
458 GetResponseHeaders("200 OK")));
459 mock_quic_data
.AddRead(
460 ConstructDataPacket(2, kClientDataStreamId1
, false, true, 0, "hello!"));
461 mock_quic_data
.AddWrite(ConstructAckPacket(2, 1));
462 mock_quic_data
.AddRead(SYNCHRONOUS
, 0); // EOF
464 mock_quic_data
.AddSocketDataToFactory(&socket_factory_
);
466 // There is no need to set up an alternate protocol job, because
467 // no attempt will be made to speak to the proxy over TCP.
471 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 70);
474 TEST_P(QuicNetworkTransactionTest
, ForceQuicWithErrorConnecting
) {
475 params_
.origin_to_force_quic_on
=
476 HostPortPair::FromString("www.google.com:80");
478 MockQuicData mock_quic_data
;
479 mock_quic_data
.AddRead(ASYNC
, ERR_SOCKET_NOT_CONNECTED
);
481 mock_quic_data
.AddSocketDataToFactory(&socket_factory_
);
485 scoped_ptr
<HttpNetworkTransaction
> trans(
486 new HttpNetworkTransaction(DEFAULT_PRIORITY
, session_
.get()));
487 TestCompletionCallback callback
;
488 int rv
= trans
->Start(&request_
, callback
.callback(), net_log_
.bound());
489 EXPECT_EQ(ERR_IO_PENDING
, rv
);
490 EXPECT_EQ(ERR_CONNECTION_CLOSED
, callback
.WaitForResult());
493 TEST_P(QuicNetworkTransactionTest
, DoNotForceQuicForHttps
) {
494 // Attempt to "force" quic on 443, which will not be honored.
495 params_
.origin_to_force_quic_on
=
496 HostPortPair::FromString("www.google.com:443");
498 MockRead http_reads
[] = {
499 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
500 MockRead("hello world"),
501 MockRead(SYNCHRONOUS
, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ
),
505 StaticSocketDataProvider
data(http_reads
, arraysize(http_reads
), nullptr, 0);
506 socket_factory_
.AddSocketDataProvider(&data
);
507 SSLSocketDataProvider
ssl(ASYNC
, OK
);
508 socket_factory_
.AddSSLSocketDataProvider(&ssl
);
512 SendRequestAndExpectHttpResponse("hello world");
515 TEST_P(QuicNetworkTransactionTest
, UseAlternateProtocolForQuic
) {
516 MockRead http_reads
[] = {
517 MockRead("HTTP/1.1 200 OK\r\n"),
518 MockRead(kQuicAlternateProtocolHttpHeader
),
519 MockRead("hello world"),
520 MockRead(SYNCHRONOUS
, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ
),
524 StaticSocketDataProvider
http_data(http_reads
, arraysize(http_reads
),
526 socket_factory_
.AddSocketDataProvider(&http_data
);
528 MockQuicData mock_quic_data
;
529 mock_quic_data
.AddWrite(
530 ConstructRequestHeadersPacket(1, kClientDataStreamId1
, true, true,
531 GetRequestHeaders("GET", "http", "/")));
532 mock_quic_data
.AddRead(
533 ConstructResponseHeadersPacket(1, kClientDataStreamId1
, false, false,
534 GetResponseHeaders("200 OK")));
535 mock_quic_data
.AddRead(
536 ConstructDataPacket(2, kClientDataStreamId1
, false, true, 0, "hello!"));
537 mock_quic_data
.AddWrite(ConstructAckPacket(2, 1));
538 mock_quic_data
.AddRead(SYNCHRONOUS
, 0); // EOF
540 mock_quic_data
.AddSocketDataToFactory(&socket_factory_
);
542 // The non-alternate protocol job needs to hang in order to guarantee that
543 // the alternate-protocol job will "win".
544 AddHangingNonAlternateProtocolSocketData();
546 CreateSessionWithNextProtos();
548 SendRequestAndExpectHttpResponse("hello world");
549 SendRequestAndExpectQuicResponse("hello!");
552 TEST_P(QuicNetworkTransactionTest
, AlternateProtocolDifferentPort
) {
553 MockRead http_reads
[] = {
554 MockRead("HTTP/1.1 200 OK\r\n"),
555 MockRead(kQuicAlternateProtocolDifferentPortHttpHeader
),
556 MockRead("hello world"),
557 MockRead(SYNCHRONOUS
, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ
),
558 MockRead(ASYNC
, OK
)};
560 StaticSocketDataProvider
http_data(http_reads
, arraysize(http_reads
), nullptr,
562 socket_factory_
.AddSocketDataProvider(&http_data
);
564 MockQuicData mock_quic_data
;
565 mock_quic_data
.AddWrite(
566 ConstructRequestHeadersPacket(1, kClientDataStreamId1
, true, true,
567 GetRequestHeaders("GET", "http", "/")));
568 mock_quic_data
.AddRead(ConstructResponseHeadersPacket(
569 1, kClientDataStreamId1
, false, false, GetResponseHeaders("200 OK")));
570 mock_quic_data
.AddRead(
571 ConstructDataPacket(2, kClientDataStreamId1
, false, true, 0, "hello!"));
572 mock_quic_data
.AddWrite(ConstructAckPacket(2, 1));
573 mock_quic_data
.AddRead(SYNCHRONOUS
, 0); // EOF
575 mock_quic_data
.AddSocketDataToFactory(&socket_factory_
);
577 // The non-alternate protocol job needs to hang in order to guarantee that
578 // the alternate-protocol job will "win".
579 AddHangingNonAlternateProtocolSocketData();
581 CreateSessionWithNextProtos();
583 SendRequestAndExpectHttpResponse("hello world");
584 SendRequestAndExpectQuicResponseOnPort("hello!", 137);
587 TEST_P(QuicNetworkTransactionTest
, ConfirmAlternativeService
) {
588 MockRead http_reads
[] = {
589 MockRead("HTTP/1.1 200 OK\r\n"),
590 MockRead(kQuicAlternateProtocolHttpHeader
),
591 MockRead("hello world"),
592 MockRead(SYNCHRONOUS
, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ
),
593 MockRead(ASYNC
, OK
)};
595 StaticSocketDataProvider
http_data(http_reads
, arraysize(http_reads
), nullptr,
597 socket_factory_
.AddSocketDataProvider(&http_data
);
599 MockQuicData mock_quic_data
;
600 mock_quic_data
.AddWrite(
601 ConstructRequestHeadersPacket(1, kClientDataStreamId1
, true, true,
602 GetRequestHeaders("GET", "http", "/")));
603 mock_quic_data
.AddRead(ConstructResponseHeadersPacket(
604 1, kClientDataStreamId1
, false, false, GetResponseHeaders("200 OK")));
605 mock_quic_data
.AddRead(
606 ConstructDataPacket(2, kClientDataStreamId1
, false, true, 0, "hello!"));
607 mock_quic_data
.AddWrite(ConstructAckPacket(2, 1));
608 mock_quic_data
.AddRead(SYNCHRONOUS
, 0); // EOF
610 mock_quic_data
.AddSocketDataToFactory(&socket_factory_
);
612 // The non-alternate protocol job needs to hang in order to guarantee that
613 // the alternate-protocol job will "win".
614 AddHangingNonAlternateProtocolSocketData();
616 CreateSessionWithNextProtos();
618 AlternativeService
alternative_service(QUIC
,
619 HostPortPair::FromURL(request_
.url
));
620 session_
->http_server_properties()->MarkAlternativeServiceRecentlyBroken(
621 alternative_service
);
623 session_
->http_server_properties()->WasAlternativeServiceRecentlyBroken(
624 alternative_service
));
626 SendRequestAndExpectHttpResponse("hello world");
627 SendRequestAndExpectQuicResponse("hello!");
630 session_
->http_server_properties()->WasAlternativeServiceRecentlyBroken(
631 alternative_service
));
634 TEST_P(QuicNetworkTransactionTest
, UseAlternateProtocolProbabilityForQuic
) {
635 MockRead http_reads
[] = {
636 MockRead("HTTP/1.1 200 OK\r\n"),
637 MockRead(kQuicAlternateProtocol50pctHttpHeader
),
638 MockRead("hello world"),
639 MockRead(SYNCHRONOUS
, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ
),
643 StaticSocketDataProvider
http_data(http_reads
, arraysize(http_reads
),
645 socket_factory_
.AddSocketDataProvider(&http_data
);
647 MockQuicData mock_quic_data
;
648 mock_quic_data
.AddWrite(
649 ConstructRequestHeadersPacket(1, kClientDataStreamId1
, true, true,
650 GetRequestHeaders("GET", "http", "/")));
651 mock_quic_data
.AddRead(
652 ConstructResponseHeadersPacket(1, kClientDataStreamId1
, false, false,
653 GetResponseHeaders("200 OK")));
654 mock_quic_data
.AddRead(
655 ConstructDataPacket(2, kClientDataStreamId1
, false, true, 0, "hello!"));
656 mock_quic_data
.AddWrite(ConstructAckPacket(2, 1));
657 mock_quic_data
.AddRead(SYNCHRONOUS
, 0); // EOF
659 mock_quic_data
.AddSocketDataToFactory(&socket_factory_
);
661 // The non-alternate protocol job needs to hang in order to guarantee that
662 // the alternate-protocol job will "win".
663 AddHangingNonAlternateProtocolSocketData();
665 params_
.alternate_protocol_probability_threshold
= .25;
666 CreateSessionWithNextProtos();
668 SendRequestAndExpectHttpResponse("hello world");
669 SendRequestAndExpectQuicResponse("hello!");
672 TEST_P(QuicNetworkTransactionTest
, DontUseAlternateProtocolProbabilityForQuic
) {
673 MockRead http_reads
[] = {
674 MockRead("HTTP/1.1 200 OK\r\n"),
675 MockRead(kQuicAlternateProtocol50pctHttpHeader
),
676 MockRead("hello world"),
677 MockRead(SYNCHRONOUS
, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ
),
681 StaticSocketDataProvider
http_data(http_reads
, arraysize(http_reads
),
683 socket_factory_
.AddSocketDataProvider(&http_data
);
684 socket_factory_
.AddSocketDataProvider(&http_data
);
686 params_
.alternate_protocol_probability_threshold
= .75;
687 CreateSessionWithNextProtos();
689 SendRequestAndExpectHttpResponse("hello world");
690 SendRequestAndExpectHttpResponse("hello world");
693 TEST_P(QuicNetworkTransactionTest
,
694 DontUseAlternateProtocolWithBadProbabilityForQuic
) {
695 MockRead http_reads
[] = {
696 MockRead("HTTP/1.1 200 OK\r\n"),
697 MockRead("Alternate-Protocol: 443:quic,p=2\r\n\r\n"),
698 MockRead("hello world"),
699 MockRead(SYNCHRONOUS
, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ
),
703 StaticSocketDataProvider
http_data(http_reads
, arraysize(http_reads
),
705 socket_factory_
.AddSocketDataProvider(&http_data
);
706 socket_factory_
.AddSocketDataProvider(&http_data
);
708 params_
.alternate_protocol_probability_threshold
= .75;
709 CreateSessionWithNextProtos();
711 SendRequestAndExpectHttpResponse("hello world");
712 SendRequestAndExpectHttpResponse("hello world");
715 TEST_P(QuicNetworkTransactionTest
, UseAlternateProtocolForQuicForHttps
) {
716 params_
.origin_to_force_quic_on
=
717 HostPortPair::FromString("www.google.com:443");
719 MockRead http_reads
[] = {
720 MockRead("HTTP/1.1 200 OK\r\n"),
721 MockRead(kQuicAlternateProtocolHttpsHeader
),
722 MockRead("hello world"),
723 MockRead(SYNCHRONOUS
, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ
),
727 StaticSocketDataProvider
http_data(http_reads
, arraysize(http_reads
),
729 socket_factory_
.AddSocketDataProvider(&http_data
);
731 MockQuicData mock_quic_data
;
732 mock_quic_data
.AddWrite(
733 ConstructRequestHeadersPacket(1, kClientDataStreamId1
, true, true,
734 GetRequestHeaders("GET", "http", "/")));
735 mock_quic_data
.AddRead(
736 ConstructResponseHeadersPacket(1, kClientDataStreamId1
, false, false,
737 GetResponseHeaders("200 OK")));
738 mock_quic_data
.AddRead(
739 ConstructDataPacket(2, kClientDataStreamId1
, false, true, 0, "hello!"));
740 mock_quic_data
.AddWrite(ConstructAckPacket(2, 1));
741 mock_quic_data
.AddRead(SYNCHRONOUS
, 0); // EOF
743 mock_quic_data
.AddSocketDataToFactory(&socket_factory_
);
745 // The non-alternate protocol job needs to hang in order to guarantee that
746 // the alternate-protocol job will "win".
747 AddHangingNonAlternateProtocolSocketData();
749 CreateSessionWithNextProtos();
751 // TODO(rtenneti): Test QUIC over HTTPS, GetSSLInfo().
752 SendRequestAndExpectHttpResponse("hello world");
755 TEST_P(QuicNetworkTransactionTest
, HungAlternateProtocol
) {
756 crypto_client_stream_factory_
.set_handshake_mode(
757 MockCryptoClientStream::COLD_START
);
759 MockWrite http_writes
[] = {
760 MockWrite(SYNCHRONOUS
, 0, "GET / HTTP/1.1\r\n"),
761 MockWrite(SYNCHRONOUS
, 1, "Host: www.google.com\r\n"),
762 MockWrite(SYNCHRONOUS
, 2, "Connection: keep-alive\r\n\r\n")
765 MockRead http_reads
[] = {
766 MockRead(SYNCHRONOUS
, 3, "HTTP/1.1 200 OK\r\n"),
767 MockRead(SYNCHRONOUS
, 4, kQuicAlternateProtocolHttpHeader
),
768 MockRead(SYNCHRONOUS
, 5, "hello world"),
769 MockRead(SYNCHRONOUS
, OK
, 6)
772 DeterministicMockClientSocketFactory socket_factory
;
774 DeterministicSocketData
http_data(http_reads
, arraysize(http_reads
),
775 http_writes
, arraysize(http_writes
));
776 socket_factory
.AddSocketDataProvider(&http_data
);
778 // The QUIC transaction will not be allowed to complete.
779 MockWrite quic_writes
[] = {
780 MockWrite(ASYNC
, ERR_IO_PENDING
, 0)
782 MockRead quic_reads
[] = {
783 MockRead(ASYNC
, ERR_IO_PENDING
, 1),
785 DeterministicSocketData
quic_data(quic_reads
, arraysize(quic_reads
),
786 quic_writes
, arraysize(quic_writes
));
787 socket_factory
.AddSocketDataProvider(&quic_data
);
789 // The HTTP transaction will complete.
790 DeterministicSocketData
http_data2(http_reads
, arraysize(http_reads
),
791 http_writes
, arraysize(http_writes
));
792 socket_factory
.AddSocketDataProvider(&http_data2
);
794 CreateSessionWithFactory(&socket_factory
, true);
796 // Run the first request.
797 http_data
.StopAfter(arraysize(http_reads
) + arraysize(http_writes
));
798 SendRequestAndExpectHttpResponse("hello world");
799 ASSERT_TRUE(http_data
.at_read_eof());
800 ASSERT_TRUE(http_data
.at_write_eof());
802 // Now run the second request in which the QUIC socket hangs,
803 // and verify the the transaction continues over HTTP.
804 http_data2
.StopAfter(arraysize(http_reads
) + arraysize(http_writes
));
805 SendRequestAndExpectHttpResponse("hello world");
807 ASSERT_TRUE(http_data2
.at_read_eof());
808 ASSERT_TRUE(http_data2
.at_write_eof());
809 ASSERT_TRUE(!quic_data
.at_read_eof());
810 ASSERT_TRUE(!quic_data
.at_write_eof());
813 TEST_P(QuicNetworkTransactionTest
, ZeroRTTWithHttpRace
) {
814 MockQuicData mock_quic_data
;
815 mock_quic_data
.AddWrite(
816 ConstructRequestHeadersPacket(1, kClientDataStreamId1
, true, true,
817 GetRequestHeaders("GET", "http", "/")));
818 mock_quic_data
.AddRead(
819 ConstructResponseHeadersPacket(1, kClientDataStreamId1
, false, false,
820 GetResponseHeaders("200 OK")));
821 mock_quic_data
.AddRead(
822 ConstructDataPacket(2, kClientDataStreamId1
, false, true, 0, "hello!"));
823 mock_quic_data
.AddWrite(ConstructAckPacket(2, 1));
824 mock_quic_data
.AddRead(SYNCHRONOUS
, 0); // EOF
826 mock_quic_data
.AddSocketDataToFactory(&socket_factory_
);
828 // The non-alternate protocol job needs to hang in order to guarantee that
829 // the alternate-protocol job will "win".
830 AddHangingNonAlternateProtocolSocketData();
832 CreateSessionWithNextProtos();
833 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT
);
834 SendRequestAndExpectQuicResponse("hello!");
837 TEST_P(QuicNetworkTransactionTest
, ZeroRTTWithNoHttpRace
) {
838 MockQuicData mock_quic_data
;
839 mock_quic_data
.AddWrite(
840 ConstructRequestHeadersPacket(1, kClientDataStreamId1
, true, true,
841 GetRequestHeaders("GET", "http", "/")));
842 mock_quic_data
.AddRead(
843 ConstructResponseHeadersPacket(1, kClientDataStreamId1
, false, false,
844 GetResponseHeaders("200 OK")));
845 mock_quic_data
.AddRead(
846 ConstructDataPacket(2, kClientDataStreamId1
, false, true, 0, "hello!"));
847 mock_quic_data
.AddWrite(ConstructAckPacket(2, 1));
848 mock_quic_data
.AddRead(SYNCHRONOUS
, 0); // EOF
849 mock_quic_data
.AddSocketDataToFactory(&socket_factory_
);
851 // In order for a new QUIC session to be established via alternate-protocol
852 // without racing an HTTP connection, we need the host resolution to happen
854 host_resolver_
.set_synchronous_mode(true);
855 host_resolver_
.rules()->AddIPLiteralRule("www.google.com", "192.168.0.1", "");
856 HostResolver::RequestInfo
info(HostPortPair("www.google.com", 80));
858 host_resolver_
.Resolve(info
,
861 CompletionCallback(),
865 CreateSessionWithNextProtos();
866 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT
);
867 SendRequestAndExpectQuicResponse("hello!");
870 TEST_P(QuicNetworkTransactionTest
, ZeroRTTWithProxy
) {
871 proxy_service_
.reset(
872 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
874 // Since we are using a proxy, the QUIC job will not succeed.
875 MockWrite http_writes
[] = {
876 MockWrite(SYNCHRONOUS
, 0, "GET http://www.google.com/ HTTP/1.1\r\n"),
877 MockWrite(SYNCHRONOUS
, 1, "Host: www.google.com\r\n"),
878 MockWrite(SYNCHRONOUS
, 2, "Proxy-Connection: keep-alive\r\n\r\n")
881 MockRead http_reads
[] = {
882 MockRead(SYNCHRONOUS
, 3, "HTTP/1.1 200 OK\r\n"),
883 MockRead(SYNCHRONOUS
, 4, kQuicAlternateProtocolHttpHeader
),
884 MockRead(SYNCHRONOUS
, 5, "hello world"),
885 MockRead(SYNCHRONOUS
, OK
, 6)
888 StaticSocketDataProvider
http_data(http_reads
, arraysize(http_reads
),
889 http_writes
, arraysize(http_writes
));
890 socket_factory_
.AddSocketDataProvider(&http_data
);
892 // In order for a new QUIC session to be established via alternate-protocol
893 // without racing an HTTP connection, we need the host resolution to happen
895 host_resolver_
.set_synchronous_mode(true);
896 host_resolver_
.rules()->AddIPLiteralRule("www.google.com", "192.168.0.1", "");
897 HostResolver::RequestInfo
info(HostPortPair("www.google.com", 80));
899 host_resolver_
.Resolve(info
,
902 CompletionCallback(),
906 CreateSessionWithNextProtos();
907 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT
);
908 SendRequestAndExpectHttpResponse("hello world");
911 TEST_P(QuicNetworkTransactionTest
, ZeroRTTWithConfirmationRequired
) {
912 MockQuicData mock_quic_data
;
913 mock_quic_data
.AddWrite(
914 ConstructRequestHeadersPacket(1, kClientDataStreamId1
, true, true,
915 GetRequestHeaders("GET", "http", "/")));
916 mock_quic_data
.AddRead(
917 ConstructResponseHeadersPacket(1, kClientDataStreamId1
, false, false,
918 GetResponseHeaders("200 OK")));
919 mock_quic_data
.AddRead(
920 ConstructDataPacket(2, kClientDataStreamId1
, false, true, 0, "hello!"));
921 mock_quic_data
.AddWrite(ConstructAckPacket(2, 1));
922 mock_quic_data
.AddRead(SYNCHRONOUS
, 0); // EOF
923 mock_quic_data
.AddSocketDataToFactory(&socket_factory_
);
925 // The non-alternate protocol job needs to hang in order to guarantee that
926 // the alternate-protocol job will "win".
927 AddHangingNonAlternateProtocolSocketData();
929 // In order for a new QUIC session to be established via alternate-protocol
930 // without racing an HTTP connection, we need the host resolution to happen
931 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
932 // connection to the the server, in this test we require confirmation
933 // before encrypting so the HTTP job will still start.
934 host_resolver_
.set_synchronous_mode(true);
935 host_resolver_
.rules()->AddIPLiteralRule("www.google.com", "192.168.0.1", "");
936 HostResolver::RequestInfo
info(HostPortPair("www.google.com", 80));
938 host_resolver_
.Resolve(info
, DEFAULT_PRIORITY
, &address
,
939 CompletionCallback(), nullptr, net_log_
.bound());
941 CreateSessionWithNextProtos();
942 session_
->quic_stream_factory()->set_require_confirmation(true);
943 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT
);
945 scoped_ptr
<HttpNetworkTransaction
> trans(
946 new HttpNetworkTransaction(DEFAULT_PRIORITY
, session_
.get()));
947 TestCompletionCallback callback
;
948 int rv
= trans
->Start(&request_
, callback
.callback(), net_log_
.bound());
949 EXPECT_EQ(ERR_IO_PENDING
, rv
);
951 crypto_client_stream_factory_
.last_stream()->SendOnCryptoHandshakeEvent(
952 QuicSession::HANDSHAKE_CONFIRMED
);
953 EXPECT_EQ(OK
, callback
.WaitForResult());
956 TEST_P(QuicNetworkTransactionTest
, BrokenAlternateProtocol
) {
957 // Alternate-protocol job
958 scoped_ptr
<QuicEncryptedPacket
> close(ConstructConnectionClosePacket(1));
959 MockRead quic_reads
[] = {
960 MockRead(ASYNC
, close
->data(), close
->length()),
961 MockRead(ASYNC
, OK
), // EOF
963 StaticSocketDataProvider
quic_data(quic_reads
, arraysize(quic_reads
),
965 socket_factory_
.AddSocketDataProvider(&quic_data
);
967 // Main job which will succeed even though the alternate job fails.
968 MockRead http_reads
[] = {
969 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
970 MockRead("hello from http"),
971 MockRead(SYNCHRONOUS
, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ
),
975 StaticSocketDataProvider
http_data(http_reads
, arraysize(http_reads
),
977 socket_factory_
.AddSocketDataProvider(&http_data
);
979 CreateSessionWithNextProtos();
980 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START
);
981 SendRequestAndExpectHttpResponse("hello from http");
982 ExpectBrokenAlternateProtocolMapping();
985 TEST_P(QuicNetworkTransactionTest
, BrokenAlternateProtocolReadError
) {
986 // Alternate-protocol job
987 MockRead quic_reads
[] = {
988 MockRead(ASYNC
, ERR_SOCKET_NOT_CONNECTED
),
990 StaticSocketDataProvider
quic_data(quic_reads
, arraysize(quic_reads
),
992 socket_factory_
.AddSocketDataProvider(&quic_data
);
994 // Main job which will succeed even though the alternate job fails.
995 MockRead http_reads
[] = {
996 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
997 MockRead("hello from http"),
998 MockRead(SYNCHRONOUS
, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ
),
1002 StaticSocketDataProvider
http_data(http_reads
, arraysize(http_reads
),
1004 socket_factory_
.AddSocketDataProvider(&http_data
);
1006 CreateSessionWithNextProtos();
1008 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START
);
1009 SendRequestAndExpectHttpResponse("hello from http");
1010 ExpectBrokenAlternateProtocolMapping();
1013 TEST_P(QuicNetworkTransactionTest
, NoBrokenAlternateProtocolIfTcpFails
) {
1014 // Alternate-protocol job will fail when the session attempts to read.
1015 MockRead quic_reads
[] = {
1016 MockRead(ASYNC
, ERR_SOCKET_NOT_CONNECTED
),
1018 StaticSocketDataProvider
quic_data(quic_reads
, arraysize(quic_reads
),
1020 socket_factory_
.AddSocketDataProvider(&quic_data
);
1022 // Main job will also fail.
1023 MockRead http_reads
[] = {
1024 MockRead(ASYNC
, ERR_SOCKET_NOT_CONNECTED
),
1027 StaticSocketDataProvider
http_data(http_reads
, arraysize(http_reads
),
1029 http_data
.set_connect_data(MockConnect(ASYNC
, ERR_SOCKET_NOT_CONNECTED
));
1030 socket_factory_
.AddSocketDataProvider(&http_data
);
1032 CreateSessionWithNextProtos();
1034 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START
);
1035 scoped_ptr
<HttpNetworkTransaction
> trans(
1036 new HttpNetworkTransaction(DEFAULT_PRIORITY
, session_
.get()));
1037 TestCompletionCallback callback
;
1038 int rv
= trans
->Start(&request_
, callback
.callback(), net_log_
.bound());
1039 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1040 EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED
, callback
.WaitForResult());
1041 ExpectQuicAlternateProtocolMapping();
1044 TEST_P(QuicNetworkTransactionTest
, FailedZeroRttBrokenAlternateProtocol
) {
1045 // Alternate-protocol job
1046 MockRead quic_reads
[] = {
1047 MockRead(ASYNC
, ERR_SOCKET_NOT_CONNECTED
),
1049 StaticSocketDataProvider
quic_data(quic_reads
, arraysize(quic_reads
),
1051 socket_factory_
.AddSocketDataProvider(&quic_data
);
1053 AddHangingNonAlternateProtocolSocketData();
1055 // Second Alternate-protocol job which will race with the TCP job.
1056 StaticSocketDataProvider
quic_data2(quic_reads
, arraysize(quic_reads
),
1058 socket_factory_
.AddSocketDataProvider(&quic_data2
);
1060 // Final job that will proceed when the QUIC job fails.
1061 MockRead http_reads
[] = {
1062 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
1063 MockRead("hello from http"),
1064 MockRead(SYNCHRONOUS
, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ
),
1068 StaticSocketDataProvider
http_data(http_reads
, arraysize(http_reads
),
1070 socket_factory_
.AddSocketDataProvider(&http_data
);
1072 CreateSessionWithNextProtos();
1074 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT
);
1076 SendRequestAndExpectHttpResponse("hello from http");
1078 ExpectBrokenAlternateProtocolMapping();
1080 EXPECT_TRUE(quic_data
.at_read_eof());
1081 EXPECT_TRUE(quic_data
.at_write_eof());
1084 TEST_P(QuicNetworkTransactionTest
, DISABLED_HangingZeroRttFallback
) {
1085 // Alternate-protocol job
1086 MockRead quic_reads
[] = {
1087 MockRead(ASYNC
, ERR_IO_PENDING
),
1089 StaticSocketDataProvider
quic_data(quic_reads
, arraysize(quic_reads
),
1091 socket_factory_
.AddSocketDataProvider(&quic_data
);
1093 // Main job that will proceed when the QUIC job fails.
1094 MockRead http_reads
[] = {
1095 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
1096 MockRead("hello from http"),
1097 MockRead(SYNCHRONOUS
, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ
),
1101 StaticSocketDataProvider
http_data(http_reads
, arraysize(http_reads
),
1103 socket_factory_
.AddSocketDataProvider(&http_data
);
1105 CreateSessionWithNextProtos();
1107 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT
);
1109 SendRequestAndExpectHttpResponse("hello from http");
1112 TEST_P(QuicNetworkTransactionTest
, BrokenAlternateProtocolOnConnectFailure
) {
1113 // Alternate-protocol job will fail before creating a QUIC session.
1114 StaticSocketDataProvider
quic_data(nullptr, 0, nullptr, 0);
1115 quic_data
.set_connect_data(MockConnect(SYNCHRONOUS
,
1116 ERR_INTERNET_DISCONNECTED
));
1117 socket_factory_
.AddSocketDataProvider(&quic_data
);
1119 // Main job which will succeed even though the alternate job fails.
1120 MockRead http_reads
[] = {
1121 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
1122 MockRead("hello from http"),
1123 MockRead(SYNCHRONOUS
, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ
),
1127 StaticSocketDataProvider
http_data(http_reads
, arraysize(http_reads
),
1129 socket_factory_
.AddSocketDataProvider(&http_data
);
1131 CreateSessionWithNextProtos();
1132 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START
);
1133 SendRequestAndExpectHttpResponse("hello from http");
1135 ExpectBrokenAlternateProtocolMapping();
1138 TEST_P(QuicNetworkTransactionTest
, ConnectionCloseDuringConnect
) {
1139 MockQuicData mock_quic_data
;
1140 mock_quic_data
.AddSynchronousRead(ConstructConnectionClosePacket(1));
1141 mock_quic_data
.AddWrite(
1142 ConstructRequestHeadersPacket(1, kClientDataStreamId1
, true, true,
1143 GetRequestHeaders("GET", "http", "/")));
1144 mock_quic_data
.AddWrite(ConstructAckPacket(2, 1));
1145 mock_quic_data
.AddSocketDataToFactory(&socket_factory_
);
1147 // When the QUIC connection fails, we will try the request again over HTTP.
1148 MockRead http_reads
[] = {
1149 MockRead("HTTP/1.1 200 OK\r\n"),
1150 MockRead(kQuicAlternateProtocolHttpHeader
),
1151 MockRead("hello world"),
1152 MockRead(SYNCHRONOUS
, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ
),
1156 StaticSocketDataProvider
http_data(http_reads
, arraysize(http_reads
),
1158 socket_factory_
.AddSocketDataProvider(&http_data
);
1160 // In order for a new QUIC session to be established via alternate-protocol
1161 // without racing an HTTP connection, we need the host resolution to happen
1163 host_resolver_
.set_synchronous_mode(true);
1164 host_resolver_
.rules()->AddIPLiteralRule("www.google.com", "192.168.0.1", "");
1165 HostResolver::RequestInfo
info(HostPortPair("www.google.com", 80));
1166 AddressList address
;
1167 host_resolver_
.Resolve(info
,
1170 CompletionCallback(),
1174 CreateSessionWithNextProtos();
1175 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT
);
1176 SendRequestAndExpectHttpResponse("hello world");