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 // This is the expected return from a current server advertising QUIC.
57 static const char kQuicAlternateProtocolHttpHeader
[] =
58 "Alternate-Protocol: 80:quic\r\n\r\n";
59 static const char kQuicAlternateProtocol50pctHttpHeader
[] =
60 "Alternate-Protocol: 80:quic,p=.5\r\n\r\n";
61 static const char kQuicAlternateProtocolDifferentPortHttpHeader
[] =
62 "Alternate-Protocol: 137:quic\r\n\r\n";
63 static const char kQuicAlternateProtocolHttpsHeader
[] =
64 "Alternate-Protocol: 443:quic\r\n\r\n";
66 const char kDefaultServerHostName
[] = "www.google.com";
70 // Helper class to encapsulate MockReads and MockWrites for QUIC.
71 // Simplify ownership issues and the interaction with the MockSocketFactory.
74 MockQuicData() : sequence_number_(0) {}
77 STLDeleteElements(&packets_
);
80 void AddSynchronousRead(scoped_ptr
<QuicEncryptedPacket
> packet
) {
81 reads_
.push_back(MockRead(SYNCHRONOUS
, packet
->data(), packet
->length(),
83 packets_
.push_back(packet
.release());
86 void AddRead(scoped_ptr
<QuicEncryptedPacket
> packet
) {
88 MockRead(ASYNC
, packet
->data(), packet
->length(), sequence_number_
++));
89 packets_
.push_back(packet
.release());
92 void AddRead(IoMode mode
, int rv
) {
93 reads_
.push_back(MockRead(mode
, rv
, sequence_number_
++));
96 void AddWrite(scoped_ptr
<QuicEncryptedPacket
> packet
) {
97 writes_
.push_back(MockWrite(SYNCHRONOUS
, packet
->data(), packet
->length(),
99 packets_
.push_back(packet
.release());
102 void AddSocketDataToFactory(MockClientSocketFactory
* factory
) {
103 MockRead
* reads
= reads_
.empty() ? nullptr : &reads_
[0];
104 MockWrite
* writes
= writes_
.empty() ? nullptr : &writes_
[0];
106 new SequencedSocketData(reads
, reads_
.size(), writes
, writes_
.size()));
107 factory
->AddSocketDataProvider(socket_data_
.get());
111 std::vector
<QuicEncryptedPacket
*> packets_
;
112 std::vector
<MockWrite
> writes_
;
113 std::vector
<MockRead
> reads_
;
114 size_t sequence_number_
;
115 scoped_ptr
<SocketDataProvider
> socket_data_
;
118 class ProxyHeadersHandler
{
120 ProxyHeadersHandler() : was_called_(false) {}
122 bool was_called() { return was_called_
; }
124 void OnBeforeProxyHeadersSent(const ProxyInfo
& proxy_info
,
125 HttpRequestHeaders
* request_headers
) {
133 class QuicNetworkTransactionTest
134 : public PlatformTest
,
135 public ::testing::WithParamInterface
<QuicVersion
> {
137 QuicNetworkTransactionTest()
138 : clock_(new MockClock
),
139 maker_(GetParam(), 0, clock_
, kDefaultServerHostName
),
140 ssl_config_service_(new SSLConfigServiceDefaults
),
141 proxy_service_(ProxyService::CreateDirect()),
142 auth_handler_factory_(
143 HttpAuthHandlerFactory::CreateDefault(&host_resolver_
)),
144 random_generator_(0),
145 hanging_data_(nullptr, 0, nullptr, 0) {
146 request_
.method
= "GET";
147 std::string
url("http://");
148 url
.append(kDefaultServerHostName
);
149 request_
.url
= GURL(url
);
150 request_
.load_flags
= 0;
151 clock_
->AdvanceTime(QuicTime::Delta::FromMilliseconds(20));
154 void SetUp() override
{
155 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
156 base::MessageLoop::current()->RunUntilIdle();
159 void TearDown() override
{
160 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
161 // Empty the current queue.
162 base::MessageLoop::current()->RunUntilIdle();
163 PlatformTest::TearDown();
164 NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
165 base::MessageLoop::current()->RunUntilIdle();
168 scoped_ptr
<QuicEncryptedPacket
> ConstructConnectionClosePacket(
169 QuicPacketSequenceNumber num
) {
170 return maker_
.MakeConnectionClosePacket(num
);
173 scoped_ptr
<QuicEncryptedPacket
> ConstructAckPacket(
174 QuicPacketSequenceNumber largest_received
,
175 QuicPacketSequenceNumber least_unacked
) {
176 return maker_
.MakeAckPacket(2, largest_received
, least_unacked
, true);
179 SpdyHeaderBlock
GetRequestHeaders(const std::string
& method
,
180 const std::string
& scheme
,
181 const std::string
& path
) {
182 return maker_
.GetRequestHeaders(method
, scheme
, path
);
185 SpdyHeaderBlock
GetResponseHeaders(const std::string
& status
) {
186 return maker_
.GetResponseHeaders(status
);
189 scoped_ptr
<QuicEncryptedPacket
> ConstructDataPacket(
190 QuicPacketSequenceNumber sequence_number
,
191 QuicStreamId stream_id
,
192 bool should_include_version
,
194 QuicStreamOffset offset
,
195 base::StringPiece data
) {
196 return maker_
.MakeDataPacket(
197 sequence_number
, stream_id
, should_include_version
, fin
, offset
, data
);
200 scoped_ptr
<QuicEncryptedPacket
> ConstructRequestHeadersPacket(
201 QuicPacketSequenceNumber sequence_number
,
202 QuicStreamId stream_id
,
203 bool should_include_version
,
205 const SpdyHeaderBlock
& headers
) {
206 QuicPriority priority
=
207 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY
);
208 return maker_
.MakeRequestHeadersPacket(sequence_number
, stream_id
,
209 should_include_version
, fin
,
213 scoped_ptr
<QuicEncryptedPacket
> ConstructResponseHeadersPacket(
214 QuicPacketSequenceNumber sequence_number
,
215 QuicStreamId stream_id
,
216 bool should_include_version
,
218 const SpdyHeaderBlock
& headers
) {
219 return maker_
.MakeResponseHeadersPacket(
220 sequence_number
, stream_id
, should_include_version
, fin
, headers
);
223 void CreateSession() {
224 CreateSessionWithFactory(&socket_factory_
, false);
227 void CreateSessionWithNextProtos() {
228 CreateSessionWithFactory(&socket_factory_
, true);
231 // If |use_next_protos| is true, enables SPDY and QUIC.
232 void CreateSessionWithFactory(ClientSocketFactory
* socket_factory
,
233 bool use_next_protos
) {
234 params_
.enable_quic
= true;
235 params_
.quic_clock
= clock_
;
236 params_
.quic_random
= &random_generator_
;
237 params_
.client_socket_factory
= socket_factory
;
238 params_
.quic_crypto_client_stream_factory
= &crypto_client_stream_factory_
;
239 params_
.host_resolver
= &host_resolver_
;
240 params_
.cert_verifier
= &cert_verifier_
;
241 params_
.transport_security_state
= &transport_security_state_
;
242 params_
.proxy_service
= proxy_service_
.get();
243 params_
.ssl_config_service
= ssl_config_service_
.get();
244 params_
.http_auth_handler_factory
= auth_handler_factory_
.get();
245 params_
.http_server_properties
= http_server_properties_
.GetWeakPtr();
246 params_
.quic_supported_versions
= SupportedVersions(GetParam());
248 if (use_next_protos
) {
249 params_
.use_alternate_protocols
= true;
250 params_
.next_protos
= NextProtosWithSpdyAndQuic(true, true);
253 session_
= new HttpNetworkSession(params_
);
254 session_
->quic_stream_factory()->set_require_confirmation(false);
255 ASSERT_EQ(params_
.quic_socket_receive_buffer_size
,
256 session_
->quic_stream_factory()->socket_receive_buffer_size());
259 void CheckWasQuicResponse(const scoped_ptr
<HttpNetworkTransaction
>& trans
) {
260 const HttpResponseInfo
* response
= trans
->GetResponseInfo();
261 ASSERT_TRUE(response
!= nullptr);
262 ASSERT_TRUE(response
->headers
.get() != nullptr);
263 EXPECT_EQ("HTTP/1.1 200 OK", response
->headers
->GetStatusLine());
264 EXPECT_TRUE(response
->was_fetched_via_spdy
);
265 EXPECT_TRUE(response
->was_npn_negotiated
);
266 EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_QUIC1_SPDY3
,
267 response
->connection_info
);
270 void CheckResponsePort(const scoped_ptr
<HttpNetworkTransaction
>& trans
,
272 const HttpResponseInfo
* response
= trans
->GetResponseInfo();
273 ASSERT_TRUE(response
!= nullptr);
274 EXPECT_EQ(port
, response
->socket_address
.port());
277 void CheckWasHttpResponse(const scoped_ptr
<HttpNetworkTransaction
>& trans
) {
278 const HttpResponseInfo
* response
= trans
->GetResponseInfo();
279 ASSERT_TRUE(response
!= nullptr);
280 ASSERT_TRUE(response
->headers
.get() != nullptr);
281 EXPECT_EQ("HTTP/1.1 200 OK", response
->headers
->GetStatusLine());
282 EXPECT_FALSE(response
->was_fetched_via_spdy
);
283 EXPECT_FALSE(response
->was_npn_negotiated
);
284 EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP1
,
285 response
->connection_info
);
288 void CheckResponseData(const scoped_ptr
<HttpNetworkTransaction
>& trans
,
289 const std::string
& expected
) {
290 std::string response_data
;
291 ASSERT_EQ(OK
, ReadTransaction(trans
.get(), &response_data
));
292 EXPECT_EQ(expected
, response_data
);
295 void RunTransaction(const scoped_ptr
<HttpNetworkTransaction
>& trans
) {
296 TestCompletionCallback callback
;
297 int rv
= trans
->Start(&request_
, callback
.callback(), net_log_
.bound());
298 EXPECT_EQ(ERR_IO_PENDING
, rv
);
299 EXPECT_EQ(OK
, callback
.WaitForResult());
302 void SendRequestAndExpectHttpResponse(const std::string
& expected
) {
303 scoped_ptr
<HttpNetworkTransaction
> trans(
304 new HttpNetworkTransaction(DEFAULT_PRIORITY
, session_
.get()));
305 RunTransaction(trans
);
306 CheckWasHttpResponse(trans
);
307 CheckResponseData(trans
, expected
);
310 void SendRequestAndExpectQuicResponse(const std::string
& expected
) {
311 SendRequestAndExpectQuicResponseMaybeFromProxy(expected
, false, 80);
314 void SendRequestAndExpectQuicResponseOnPort(const std::string
& expected
,
316 SendRequestAndExpectQuicResponseMaybeFromProxy(expected
, false, port
);
319 void SendRequestAndExpectQuicResponseFromProxyOnPort(
320 const std::string
& expected
,
322 SendRequestAndExpectQuicResponseMaybeFromProxy(expected
, true, port
);
325 void AddQuicAlternateProtocolMapping(
326 MockCryptoClientStream::HandshakeMode handshake_mode
) {
327 crypto_client_stream_factory_
.set_handshake_mode(handshake_mode
);
328 HostPortPair host_port_pair
= HostPortPair::FromURL(request_
.url
);
329 AlternativeService
alternative_service(QUIC
, host_port_pair
.host(), 80);
330 http_server_properties_
.SetAlternativeService(host_port_pair
,
331 alternative_service
, 1.0);
334 void ExpectBrokenAlternateProtocolMapping() {
335 const HostPortPair origin
= HostPortPair::FromURL(request_
.url
);
336 const AlternativeServiceVector alternative_service_vector
=
337 http_server_properties_
.GetAlternativeServices(origin
);
338 EXPECT_EQ(1u, alternative_service_vector
.size());
339 EXPECT_TRUE(http_server_properties_
.IsAlternativeServiceBroken(
340 alternative_service_vector
[0]));
343 void ExpectQuicAlternateProtocolMapping() {
344 const HostPortPair origin
= HostPortPair::FromURL(request_
.url
);
345 const AlternativeServiceVector alternative_service_vector
=
346 http_server_properties_
.GetAlternativeServices(origin
);
347 EXPECT_EQ(1u, alternative_service_vector
.size());
348 EXPECT_EQ(QUIC
, alternative_service_vector
[0].protocol
);
351 void AddHangingNonAlternateProtocolSocketData() {
352 MockConnect
hanging_connect(SYNCHRONOUS
, ERR_IO_PENDING
);
353 hanging_data_
.set_connect_data(hanging_connect
);
354 socket_factory_
.AddSocketDataProvider(&hanging_data_
);
357 MockClock
* clock_
; // Owned by QuicStreamFactory after CreateSession.
358 QuicTestPacketMaker maker_
;
359 scoped_refptr
<HttpNetworkSession
> session_
;
360 MockClientSocketFactory socket_factory_
;
361 MockCryptoClientStreamFactory crypto_client_stream_factory_
;
362 MockHostResolver host_resolver_
;
363 MockCertVerifier cert_verifier_
;
364 TransportSecurityState transport_security_state_
;
365 scoped_refptr
<SSLConfigServiceDefaults
> ssl_config_service_
;
366 scoped_ptr
<ProxyService
> proxy_service_
;
367 scoped_ptr
<HttpAuthHandlerFactory
> auth_handler_factory_
;
368 MockRandom random_generator_
;
369 HttpServerPropertiesImpl http_server_properties_
;
370 HttpNetworkSession::Params params_
;
371 HttpRequestInfo request_
;
372 BoundTestNetLog net_log_
;
373 StaticSocketDataProvider hanging_data_
;
376 void SendRequestAndExpectQuicResponseMaybeFromProxy(
377 const std::string
& expected
,
380 scoped_ptr
<HttpNetworkTransaction
> trans(
381 new HttpNetworkTransaction(DEFAULT_PRIORITY
, session_
.get()));
382 ProxyHeadersHandler proxy_headers_handler
;
383 trans
->SetBeforeProxyHeadersSentCallback(
384 base::Bind(&ProxyHeadersHandler::OnBeforeProxyHeadersSent
,
385 base::Unretained(&proxy_headers_handler
)));
386 RunTransaction(trans
);
387 CheckWasQuicResponse(trans
);
388 CheckResponsePort(trans
, port
);
389 CheckResponseData(trans
, expected
);
390 EXPECT_EQ(used_proxy
, proxy_headers_handler
.was_called());
394 INSTANTIATE_TEST_CASE_P(Version
, QuicNetworkTransactionTest
,
395 ::testing::ValuesIn(QuicSupportedVersions()));
397 TEST_P(QuicNetworkTransactionTest
, ForceQuic
) {
398 params_
.origin_to_force_quic_on
=
399 HostPortPair::FromString("www.google.com:80");
401 MockQuicData mock_quic_data
;
402 mock_quic_data
.AddWrite(
403 ConstructRequestHeadersPacket(1, kClientDataStreamId1
, true, true,
404 GetRequestHeaders("GET", "http", "/")));
405 mock_quic_data
.AddRead(
406 ConstructResponseHeadersPacket(1, kClientDataStreamId1
, false, false,
407 GetResponseHeaders("200 OK")));
408 mock_quic_data
.AddRead(
409 ConstructDataPacket(2, kClientDataStreamId1
, false, true, 0, "hello!"));
410 mock_quic_data
.AddWrite(ConstructAckPacket(2, 1));
411 mock_quic_data
.AddRead(SYNCHRONOUS
, 0); // EOF
413 mock_quic_data
.AddSocketDataToFactory(&socket_factory_
);
415 // The non-alternate protocol job needs to hang in order to guarantee that
416 // the alternate-protocol job will "win".
417 AddHangingNonAlternateProtocolSocketData();
421 SendRequestAndExpectQuicResponse("hello!");
423 // Check that the NetLog was filled reasonably.
424 TestNetLogEntry::List entries
;
425 net_log_
.GetEntries(&entries
);
426 EXPECT_LT(0u, entries
.size());
428 // Check that we logged a QUIC_SESSION_PACKET_RECEIVED.
429 int pos
= ExpectLogContainsSomewhere(
430 entries
, 0, NetLog::TYPE_QUIC_SESSION_PACKET_RECEIVED
,
434 // ... and also a TYPE_QUIC_SESSION_PACKET_HEADER_RECEIVED.
435 pos
= ExpectLogContainsSomewhere(
436 entries
, 0, NetLog::TYPE_QUIC_SESSION_PACKET_HEADER_RECEIVED
,
440 std::string packet_sequence_number
;
441 ASSERT_TRUE(entries
[pos
].GetStringValue(
442 "packet_sequence_number", &packet_sequence_number
));
443 EXPECT_EQ("1", packet_sequence_number
);
445 // ... and also a QUIC_SESSION_STREAM_FRAME_RECEIVED.
446 pos
= ExpectLogContainsSomewhere(
447 entries
, 0, NetLog::TYPE_QUIC_SESSION_STREAM_FRAME_RECEIVED
,
452 ASSERT_TRUE(entries
[pos
].GetIntegerValue("stream_id", &log_stream_id
));
453 EXPECT_EQ(3, log_stream_id
);
456 TEST_P(QuicNetworkTransactionTest
, QuicProxy
) {
457 params_
.enable_quic_for_proxies
= true;
458 proxy_service_
.reset(
459 ProxyService::CreateFixedFromPacResult("QUIC myproxy:70"));
461 MockQuicData mock_quic_data
;
462 mock_quic_data
.AddWrite(
463 ConstructRequestHeadersPacket(1, kClientDataStreamId1
, true, true,
464 GetRequestHeaders("GET", "http", "/")));
465 mock_quic_data
.AddRead(
466 ConstructResponseHeadersPacket(1, kClientDataStreamId1
, false, false,
467 GetResponseHeaders("200 OK")));
468 mock_quic_data
.AddRead(
469 ConstructDataPacket(2, kClientDataStreamId1
, false, true, 0, "hello!"));
470 mock_quic_data
.AddWrite(ConstructAckPacket(2, 1));
471 mock_quic_data
.AddRead(SYNCHRONOUS
, 0); // EOF
473 mock_quic_data
.AddSocketDataToFactory(&socket_factory_
);
475 // There is no need to set up an alternate protocol job, because
476 // no attempt will be made to speak to the proxy over TCP.
480 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 70);
483 // Regression test for https://crbug.com/492458. Test that for an HTTP
484 // connection through a QUIC proxy, the certificate exhibited by the proxy is
485 // checked against the proxy hostname, not the origin hostname.
486 TEST_P(QuicNetworkTransactionTest
, QuicProxyWithCert
) {
487 const std::string origin_host
= "news.example.com";
488 const std::string proxy_host
= "www.example.org";
490 params_
.enable_quic_for_proxies
= true;
491 proxy_service_
.reset(
492 ProxyService::CreateFixedFromPacResult("QUIC " + proxy_host
+ ":70"));
494 maker_
.set_hostname(origin_host
);
495 MockQuicData mock_quic_data
;
496 mock_quic_data
.AddWrite(
497 ConstructRequestHeadersPacket(1, kClientDataStreamId1
, true, true,
498 GetRequestHeaders("GET", "http", "/")));
499 mock_quic_data
.AddRead(ConstructResponseHeadersPacket(
500 1, kClientDataStreamId1
, false, false, GetResponseHeaders("200 OK")));
501 mock_quic_data
.AddRead(
502 ConstructDataPacket(2, kClientDataStreamId1
, false, true, 0, "hello!"));
503 mock_quic_data
.AddWrite(ConstructAckPacket(2, 1));
504 mock_quic_data
.AddRead(SYNCHRONOUS
, 0);
505 mock_quic_data
.AddSocketDataToFactory(&socket_factory_
);
507 scoped_refptr
<X509Certificate
> cert(
508 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem"));
509 ASSERT_TRUE(cert
.get());
510 // This certificate is valid for the proxy, but not for the origin.
511 bool common_name_fallback_used
;
512 EXPECT_TRUE(cert
->VerifyNameMatch(proxy_host
, &common_name_fallback_used
));
513 EXPECT_FALSE(cert
->VerifyNameMatch(origin_host
, &common_name_fallback_used
));
514 ProofVerifyDetailsChromium verify_details
;
515 verify_details
.cert_verify_result
.verified_cert
= cert
;
516 crypto_client_stream_factory_
.AddProofVerifyDetails(&verify_details
);
518 request_
.url
= GURL("http://" + origin_host
);
519 AddHangingNonAlternateProtocolSocketData();
520 CreateSessionWithNextProtos();
521 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE
);
522 SendRequestAndExpectQuicResponseFromProxyOnPort("hello!", 70);
525 TEST_P(QuicNetworkTransactionTest
, ForceQuicWithErrorConnecting
) {
526 params_
.origin_to_force_quic_on
=
527 HostPortPair::FromString("www.google.com:80");
529 MockQuicData mock_quic_data
;
530 mock_quic_data
.AddRead(ASYNC
, ERR_SOCKET_NOT_CONNECTED
);
532 mock_quic_data
.AddSocketDataToFactory(&socket_factory_
);
536 scoped_ptr
<HttpNetworkTransaction
> trans(
537 new HttpNetworkTransaction(DEFAULT_PRIORITY
, session_
.get()));
538 TestCompletionCallback callback
;
539 int rv
= trans
->Start(&request_
, callback
.callback(), net_log_
.bound());
540 EXPECT_EQ(ERR_IO_PENDING
, rv
);
541 EXPECT_EQ(ERR_CONNECTION_CLOSED
, callback
.WaitForResult());
544 TEST_P(QuicNetworkTransactionTest
, DoNotForceQuicForHttps
) {
545 // Attempt to "force" quic on 443, which will not be honored.
546 params_
.origin_to_force_quic_on
=
547 HostPortPair::FromString("www.google.com:443");
549 MockRead http_reads
[] = {
550 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
551 MockRead("hello world"),
552 MockRead(SYNCHRONOUS
, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ
),
556 StaticSocketDataProvider
data(http_reads
, arraysize(http_reads
), nullptr, 0);
557 socket_factory_
.AddSocketDataProvider(&data
);
558 SSLSocketDataProvider
ssl(ASYNC
, OK
);
559 socket_factory_
.AddSSLSocketDataProvider(&ssl
);
563 SendRequestAndExpectHttpResponse("hello world");
566 TEST_P(QuicNetworkTransactionTest
, UseAlternateProtocolForQuic
) {
567 MockRead http_reads
[] = {
568 MockRead("HTTP/1.1 200 OK\r\n"),
569 MockRead(kQuicAlternateProtocolHttpHeader
),
570 MockRead("hello world"),
571 MockRead(SYNCHRONOUS
, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ
),
575 StaticSocketDataProvider
http_data(http_reads
, arraysize(http_reads
),
577 socket_factory_
.AddSocketDataProvider(&http_data
);
579 MockQuicData mock_quic_data
;
580 mock_quic_data
.AddWrite(
581 ConstructRequestHeadersPacket(1, kClientDataStreamId1
, true, true,
582 GetRequestHeaders("GET", "http", "/")));
583 mock_quic_data
.AddRead(
584 ConstructResponseHeadersPacket(1, kClientDataStreamId1
, false, false,
585 GetResponseHeaders("200 OK")));
586 mock_quic_data
.AddRead(
587 ConstructDataPacket(2, kClientDataStreamId1
, false, true, 0, "hello!"));
588 mock_quic_data
.AddWrite(ConstructAckPacket(2, 1));
589 mock_quic_data
.AddRead(SYNCHRONOUS
, 0); // EOF
591 mock_quic_data
.AddSocketDataToFactory(&socket_factory_
);
593 // The non-alternate protocol job needs to hang in order to guarantee that
594 // the alternate-protocol job will "win".
595 AddHangingNonAlternateProtocolSocketData();
597 CreateSessionWithNextProtos();
599 SendRequestAndExpectHttpResponse("hello world");
600 SendRequestAndExpectQuicResponse("hello!");
603 TEST_P(QuicNetworkTransactionTest
, AlternateProtocolDifferentPort
) {
604 MockRead http_reads
[] = {
605 MockRead("HTTP/1.1 200 OK\r\n"),
606 MockRead(kQuicAlternateProtocolDifferentPortHttpHeader
),
607 MockRead("hello world"),
608 MockRead(SYNCHRONOUS
, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ
),
609 MockRead(ASYNC
, OK
)};
611 StaticSocketDataProvider
http_data(http_reads
, arraysize(http_reads
), nullptr,
613 socket_factory_
.AddSocketDataProvider(&http_data
);
615 MockQuicData mock_quic_data
;
616 mock_quic_data
.AddWrite(
617 ConstructRequestHeadersPacket(1, kClientDataStreamId1
, true, true,
618 GetRequestHeaders("GET", "http", "/")));
619 mock_quic_data
.AddRead(ConstructResponseHeadersPacket(
620 1, kClientDataStreamId1
, false, false, GetResponseHeaders("200 OK")));
621 mock_quic_data
.AddRead(
622 ConstructDataPacket(2, kClientDataStreamId1
, false, true, 0, "hello!"));
623 mock_quic_data
.AddWrite(ConstructAckPacket(2, 1));
624 mock_quic_data
.AddRead(SYNCHRONOUS
, 0); // EOF
626 mock_quic_data
.AddSocketDataToFactory(&socket_factory_
);
628 // The non-alternate protocol job needs to hang in order to guarantee that
629 // the alternate-protocol job will "win".
630 AddHangingNonAlternateProtocolSocketData();
632 CreateSessionWithNextProtos();
634 SendRequestAndExpectHttpResponse("hello world");
635 SendRequestAndExpectQuicResponseOnPort("hello!", 137);
638 TEST_P(QuicNetworkTransactionTest
, ConfirmAlternativeService
) {
639 MockRead http_reads
[] = {
640 MockRead("HTTP/1.1 200 OK\r\n"),
641 MockRead(kQuicAlternateProtocolHttpHeader
),
642 MockRead("hello world"),
643 MockRead(SYNCHRONOUS
, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ
),
644 MockRead(ASYNC
, OK
)};
646 StaticSocketDataProvider
http_data(http_reads
, arraysize(http_reads
), nullptr,
648 socket_factory_
.AddSocketDataProvider(&http_data
);
650 MockQuicData mock_quic_data
;
651 mock_quic_data
.AddWrite(
652 ConstructRequestHeadersPacket(1, kClientDataStreamId1
, true, true,
653 GetRequestHeaders("GET", "http", "/")));
654 mock_quic_data
.AddRead(ConstructResponseHeadersPacket(
655 1, kClientDataStreamId1
, false, false, GetResponseHeaders("200 OK")));
656 mock_quic_data
.AddRead(
657 ConstructDataPacket(2, kClientDataStreamId1
, false, true, 0, "hello!"));
658 mock_quic_data
.AddWrite(ConstructAckPacket(2, 1));
659 mock_quic_data
.AddRead(SYNCHRONOUS
, 0); // EOF
661 mock_quic_data
.AddSocketDataToFactory(&socket_factory_
);
663 // The non-alternate protocol job needs to hang in order to guarantee that
664 // the alternate-protocol job will "win".
665 AddHangingNonAlternateProtocolSocketData();
667 CreateSessionWithNextProtos();
669 AlternativeService
alternative_service(QUIC
,
670 HostPortPair::FromURL(request_
.url
));
671 http_server_properties_
.MarkAlternativeServiceRecentlyBroken(
672 alternative_service
);
673 EXPECT_TRUE(http_server_properties_
.WasAlternativeServiceRecentlyBroken(
674 alternative_service
));
676 SendRequestAndExpectHttpResponse("hello world");
677 SendRequestAndExpectQuicResponse("hello!");
679 EXPECT_FALSE(http_server_properties_
.WasAlternativeServiceRecentlyBroken(
680 alternative_service
));
683 TEST_P(QuicNetworkTransactionTest
, UseAlternateProtocolProbabilityForQuic
) {
684 MockRead http_reads
[] = {
685 MockRead("HTTP/1.1 200 OK\r\n"),
686 MockRead(kQuicAlternateProtocol50pctHttpHeader
),
687 MockRead("hello world"),
688 MockRead(SYNCHRONOUS
, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ
),
692 StaticSocketDataProvider
http_data(http_reads
, arraysize(http_reads
),
694 socket_factory_
.AddSocketDataProvider(&http_data
);
696 MockQuicData mock_quic_data
;
697 mock_quic_data
.AddWrite(
698 ConstructRequestHeadersPacket(1, kClientDataStreamId1
, true, true,
699 GetRequestHeaders("GET", "http", "/")));
700 mock_quic_data
.AddRead(
701 ConstructResponseHeadersPacket(1, kClientDataStreamId1
, false, false,
702 GetResponseHeaders("200 OK")));
703 mock_quic_data
.AddRead(
704 ConstructDataPacket(2, kClientDataStreamId1
, false, true, 0, "hello!"));
705 mock_quic_data
.AddWrite(ConstructAckPacket(2, 1));
706 mock_quic_data
.AddRead(SYNCHRONOUS
, 0); // EOF
708 mock_quic_data
.AddSocketDataToFactory(&socket_factory_
);
710 // The non-alternate protocol job needs to hang in order to guarantee that
711 // the alternate-protocol job will "win".
712 AddHangingNonAlternateProtocolSocketData();
714 params_
.alternative_service_probability_threshold
= .25;
715 CreateSessionWithNextProtos();
717 SendRequestAndExpectHttpResponse("hello world");
718 SendRequestAndExpectQuicResponse("hello!");
721 TEST_P(QuicNetworkTransactionTest
, DontUseAlternateProtocolProbabilityForQuic
) {
722 MockRead http_reads
[] = {
723 MockRead("HTTP/1.1 200 OK\r\n"),
724 MockRead(kQuicAlternateProtocol50pctHttpHeader
),
725 MockRead("hello world"),
726 MockRead(SYNCHRONOUS
, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ
),
730 StaticSocketDataProvider
http_data(http_reads
, arraysize(http_reads
),
732 socket_factory_
.AddSocketDataProvider(&http_data
);
733 socket_factory_
.AddSocketDataProvider(&http_data
);
735 params_
.alternative_service_probability_threshold
= .75;
736 CreateSessionWithNextProtos();
738 SendRequestAndExpectHttpResponse("hello world");
739 SendRequestAndExpectHttpResponse("hello world");
742 TEST_P(QuicNetworkTransactionTest
, DontUseAlternateProtocolForInsecureQuic
) {
743 MockRead http_reads
[] = {MockRead("HTTP/1.1 200 OK\r\n"),
744 MockRead("Content-length: 11\r\n"),
745 MockRead("Alternate-Protocol: 443:quic\r\n\r\n"),
746 MockRead("hello world"),
747 MockRead("HTTP/1.1 200 OK\r\n"),
748 MockRead("Content-length: 11\r\n"),
749 MockRead("Alternate-Protocol: 443:quic\r\n\r\n"),
750 MockRead("hello world"),
751 MockRead(ASYNC
, OK
)};
753 StaticSocketDataProvider
http_data(http_reads
, arraysize(http_reads
), nullptr,
755 socket_factory_
.AddSocketDataProvider(&http_data
);
756 socket_factory_
.AddSocketDataProvider(&http_data
);
758 params_
.disable_insecure_quic
= true;
759 CreateSessionWithNextProtos();
761 SendRequestAndExpectHttpResponse("hello world");
762 SendRequestAndExpectHttpResponse("hello world");
765 TEST_P(QuicNetworkTransactionTest
,
766 DontUseAlternateProtocolWithBadProbabilityForQuic
) {
767 MockRead http_reads
[] = {
768 MockRead("HTTP/1.1 200 OK\r\n"),
769 MockRead("Alternate-Protocol: 443:quic,p=2\r\n\r\n"),
770 MockRead("hello world"),
771 MockRead(SYNCHRONOUS
, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ
),
775 StaticSocketDataProvider
http_data(http_reads
, arraysize(http_reads
),
777 socket_factory_
.AddSocketDataProvider(&http_data
);
778 socket_factory_
.AddSocketDataProvider(&http_data
);
780 params_
.alternative_service_probability_threshold
= .75;
781 CreateSessionWithNextProtos();
783 SendRequestAndExpectHttpResponse("hello world");
784 SendRequestAndExpectHttpResponse("hello world");
787 TEST_P(QuicNetworkTransactionTest
, UseAlternateProtocolForQuicForHttps
) {
788 params_
.origin_to_force_quic_on
=
789 HostPortPair::FromString("www.google.com:443");
791 MockRead http_reads
[] = {
792 MockRead("HTTP/1.1 200 OK\r\n"),
793 MockRead(kQuicAlternateProtocolHttpsHeader
),
794 MockRead("hello world"),
795 MockRead(SYNCHRONOUS
, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ
),
799 StaticSocketDataProvider
http_data(http_reads
, arraysize(http_reads
),
801 socket_factory_
.AddSocketDataProvider(&http_data
);
803 MockQuicData mock_quic_data
;
804 mock_quic_data
.AddWrite(
805 ConstructRequestHeadersPacket(1, kClientDataStreamId1
, true, true,
806 GetRequestHeaders("GET", "http", "/")));
807 mock_quic_data
.AddRead(
808 ConstructResponseHeadersPacket(1, kClientDataStreamId1
, false, false,
809 GetResponseHeaders("200 OK")));
810 mock_quic_data
.AddRead(
811 ConstructDataPacket(2, kClientDataStreamId1
, false, true, 0, "hello!"));
812 mock_quic_data
.AddWrite(ConstructAckPacket(2, 1));
813 mock_quic_data
.AddRead(SYNCHRONOUS
, 0); // EOF
815 mock_quic_data
.AddSocketDataToFactory(&socket_factory_
);
817 // The non-alternate protocol job needs to hang in order to guarantee that
818 // the alternate-protocol job will "win".
819 AddHangingNonAlternateProtocolSocketData();
821 CreateSessionWithNextProtos();
823 // TODO(rtenneti): Test QUIC over HTTPS, GetSSLInfo().
824 SendRequestAndExpectHttpResponse("hello world");
827 class QuicAltSvcCertificateVerificationTest
828 : public QuicNetworkTransactionTest
{
830 void Run(bool valid
) {
831 HostPortPair
origin(valid
? "mail.example.org" : "invalid.example.org",
833 HostPortPair
alternative("www.example.org", 443);
834 std::string
url("https://");
835 url
.append(origin
.host());
837 request_
.url
= GURL(url
);
839 maker_
.set_hostname(origin
.host());
840 MockQuicData mock_quic_data
;
841 mock_quic_data
.AddWrite(
842 ConstructRequestHeadersPacket(1, kClientDataStreamId1
, true, true,
843 GetRequestHeaders("GET", "https", "/")));
844 mock_quic_data
.AddRead(ConstructResponseHeadersPacket(
845 1, kClientDataStreamId1
, false, false, GetResponseHeaders("200 OK")));
846 mock_quic_data
.AddRead(
847 ConstructDataPacket(2, kClientDataStreamId1
, false, true, 0, "hello!"));
848 mock_quic_data
.AddWrite(ConstructAckPacket(2, 1));
849 mock_quic_data
.AddRead(SYNCHRONOUS
, 0);
850 mock_quic_data
.AddSocketDataToFactory(&socket_factory_
);
852 scoped_refptr
<X509Certificate
> cert(
853 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem"));
854 ASSERT_TRUE(cert
.get());
855 bool common_name_fallback_used
;
857 cert
->VerifyNameMatch(origin
.host(), &common_name_fallback_used
));
859 cert
->VerifyNameMatch(alternative
.host(), &common_name_fallback_used
));
860 ProofVerifyDetailsChromium verify_details
;
861 verify_details
.cert_verify_result
.verified_cert
= cert
;
862 verify_details
.cert_verify_result
.is_issued_by_known_root
= true;
863 crypto_client_stream_factory_
.AddProofVerifyDetails(&verify_details
);
864 crypto_client_stream_factory_
.set_handshake_mode(
865 MockCryptoClientStream::CONFIRM_HANDSHAKE
);
867 // Connection to |origin| fails, so that success of |request| depends on
868 // connection to |alternate| only.
869 MockConnect
refused_connect(ASYNC
, ERR_CONNECTION_REFUSED
);
870 StaticSocketDataProvider refused_data
;
871 refused_data
.set_connect_data(refused_connect
);
872 socket_factory_
.AddSocketDataProvider(&refused_data
);
874 CreateSessionWithNextProtos();
875 AlternativeService
alternative_service(QUIC
, alternative
);
876 session_
->http_server_properties()->SetAlternativeService(
877 origin
, alternative_service
, 1.0);
878 scoped_ptr
<HttpNetworkTransaction
> trans(
879 new HttpNetworkTransaction(DEFAULT_PRIORITY
, session_
.get()));
880 TestCompletionCallback callback
;
881 int rv
= trans
->Start(&request_
, callback
.callback(), net_log_
.bound());
882 EXPECT_EQ(ERR_IO_PENDING
, rv
);
883 rv
= callback
.WaitForResult();
886 CheckWasQuicResponse(trans
);
887 CheckResponsePort(trans
, 443);
888 CheckResponseData(trans
, "hello!");
890 EXPECT_EQ(ERR_CONNECTION_REFUSED
, rv
);
895 INSTANTIATE_TEST_CASE_P(Version
,
896 QuicAltSvcCertificateVerificationTest
,
897 ::testing::ValuesIn(QuicSupportedVersions()));
899 TEST_P(QuicAltSvcCertificateVerificationTest
,
900 RequestSucceedsWithValidCertificate
) {
904 TEST_P(QuicAltSvcCertificateVerificationTest
,
905 RequestFailsWithInvalidCertificate
) {
909 TEST_P(QuicNetworkTransactionTest
, HungAlternateProtocol
) {
910 crypto_client_stream_factory_
.set_handshake_mode(
911 MockCryptoClientStream::COLD_START
);
913 MockWrite http_writes
[] = {
914 MockWrite(SYNCHRONOUS
, 0, "GET / HTTP/1.1\r\n"),
915 MockWrite(SYNCHRONOUS
, 1, "Host: www.google.com\r\n"),
916 MockWrite(SYNCHRONOUS
, 2, "Connection: keep-alive\r\n\r\n")
919 MockRead http_reads
[] = {
920 MockRead(SYNCHRONOUS
, 3, "HTTP/1.1 200 OK\r\n"),
921 MockRead(SYNCHRONOUS
, 4, kQuicAlternateProtocolHttpHeader
),
922 MockRead(SYNCHRONOUS
, 5, "hello world"),
923 MockRead(SYNCHRONOUS
, OK
, 6)
926 DeterministicMockClientSocketFactory socket_factory
;
928 DeterministicSocketData
http_data(http_reads
, arraysize(http_reads
),
929 http_writes
, arraysize(http_writes
));
930 socket_factory
.AddSocketDataProvider(&http_data
);
932 // The QUIC transaction will not be allowed to complete.
933 MockWrite quic_writes
[] = {
934 MockWrite(ASYNC
, ERR_IO_PENDING
, 0)
936 MockRead quic_reads
[] = {
937 MockRead(ASYNC
, ERR_IO_PENDING
, 1),
939 DeterministicSocketData
quic_data(quic_reads
, arraysize(quic_reads
),
940 quic_writes
, arraysize(quic_writes
));
941 socket_factory
.AddSocketDataProvider(&quic_data
);
943 // The HTTP transaction will complete.
944 DeterministicSocketData
http_data2(http_reads
, arraysize(http_reads
),
945 http_writes
, arraysize(http_writes
));
946 socket_factory
.AddSocketDataProvider(&http_data2
);
948 CreateSessionWithFactory(&socket_factory
, true);
950 // Run the first request.
951 http_data
.StopAfter(arraysize(http_reads
) + arraysize(http_writes
));
952 SendRequestAndExpectHttpResponse("hello world");
953 ASSERT_TRUE(http_data
.AllReadDataConsumed());
954 ASSERT_TRUE(http_data
.AllWriteDataConsumed());
956 // Now run the second request in which the QUIC socket hangs,
957 // and verify the the transaction continues over HTTP.
958 http_data2
.StopAfter(arraysize(http_reads
) + arraysize(http_writes
));
959 SendRequestAndExpectHttpResponse("hello world");
961 ASSERT_TRUE(http_data2
.AllReadDataConsumed());
962 ASSERT_TRUE(http_data2
.AllWriteDataConsumed());
963 ASSERT_TRUE(!quic_data
.AllReadDataConsumed());
964 ASSERT_TRUE(!quic_data
.AllWriteDataConsumed());
967 TEST_P(QuicNetworkTransactionTest
, ZeroRTTWithHttpRace
) {
968 MockQuicData mock_quic_data
;
969 mock_quic_data
.AddWrite(
970 ConstructRequestHeadersPacket(1, kClientDataStreamId1
, true, true,
971 GetRequestHeaders("GET", "http", "/")));
972 mock_quic_data
.AddRead(
973 ConstructResponseHeadersPacket(1, kClientDataStreamId1
, false, false,
974 GetResponseHeaders("200 OK")));
975 mock_quic_data
.AddRead(
976 ConstructDataPacket(2, kClientDataStreamId1
, false, true, 0, "hello!"));
977 mock_quic_data
.AddWrite(ConstructAckPacket(2, 1));
978 mock_quic_data
.AddRead(SYNCHRONOUS
, 0); // EOF
980 mock_quic_data
.AddSocketDataToFactory(&socket_factory_
);
982 // The non-alternate protocol job needs to hang in order to guarantee that
983 // the alternate-protocol job will "win".
984 AddHangingNonAlternateProtocolSocketData();
986 CreateSessionWithNextProtos();
987 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT
);
988 SendRequestAndExpectQuicResponse("hello!");
991 TEST_P(QuicNetworkTransactionTest
, ZeroRTTWithNoHttpRace
) {
992 MockQuicData mock_quic_data
;
993 mock_quic_data
.AddWrite(
994 ConstructRequestHeadersPacket(1, kClientDataStreamId1
, true, true,
995 GetRequestHeaders("GET", "http", "/")));
996 mock_quic_data
.AddRead(
997 ConstructResponseHeadersPacket(1, kClientDataStreamId1
, false, false,
998 GetResponseHeaders("200 OK")));
999 mock_quic_data
.AddRead(
1000 ConstructDataPacket(2, kClientDataStreamId1
, false, true, 0, "hello!"));
1001 mock_quic_data
.AddWrite(ConstructAckPacket(2, 1));
1002 mock_quic_data
.AddRead(SYNCHRONOUS
, 0); // EOF
1003 mock_quic_data
.AddSocketDataToFactory(&socket_factory_
);
1005 // In order for a new QUIC session to be established via alternate-protocol
1006 // without racing an HTTP connection, we need the host resolution to happen
1008 host_resolver_
.set_synchronous_mode(true);
1009 host_resolver_
.rules()->AddIPLiteralRule("www.google.com", "192.168.0.1", "");
1010 HostResolver::RequestInfo
info(HostPortPair("www.google.com", 80));
1011 AddressList address
;
1012 host_resolver_
.Resolve(info
,
1015 CompletionCallback(),
1019 CreateSessionWithNextProtos();
1020 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT
);
1021 SendRequestAndExpectQuicResponse("hello!");
1024 TEST_P(QuicNetworkTransactionTest
, ZeroRTTWithProxy
) {
1025 proxy_service_
.reset(
1026 ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
1028 // Since we are using a proxy, the QUIC job will not succeed.
1029 MockWrite http_writes
[] = {
1030 MockWrite(SYNCHRONOUS
, 0, "GET http://www.google.com/ HTTP/1.1\r\n"),
1031 MockWrite(SYNCHRONOUS
, 1, "Host: www.google.com\r\n"),
1032 MockWrite(SYNCHRONOUS
, 2, "Proxy-Connection: keep-alive\r\n\r\n")
1035 MockRead http_reads
[] = {
1036 MockRead(SYNCHRONOUS
, 3, "HTTP/1.1 200 OK\r\n"),
1037 MockRead(SYNCHRONOUS
, 4, kQuicAlternateProtocolHttpHeader
),
1038 MockRead(SYNCHRONOUS
, 5, "hello world"),
1039 MockRead(SYNCHRONOUS
, OK
, 6)
1042 StaticSocketDataProvider
http_data(http_reads
, arraysize(http_reads
),
1043 http_writes
, arraysize(http_writes
));
1044 socket_factory_
.AddSocketDataProvider(&http_data
);
1046 // In order for a new QUIC session to be established via alternate-protocol
1047 // without racing an HTTP connection, we need the host resolution to happen
1049 host_resolver_
.set_synchronous_mode(true);
1050 host_resolver_
.rules()->AddIPLiteralRule("www.google.com", "192.168.0.1", "");
1051 HostResolver::RequestInfo
info(HostPortPair("www.google.com", 80));
1052 AddressList address
;
1053 host_resolver_
.Resolve(info
,
1056 CompletionCallback(),
1060 CreateSessionWithNextProtos();
1061 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT
);
1062 SendRequestAndExpectHttpResponse("hello world");
1065 TEST_P(QuicNetworkTransactionTest
, ZeroRTTWithConfirmationRequired
) {
1066 MockQuicData mock_quic_data
;
1067 mock_quic_data
.AddWrite(
1068 ConstructRequestHeadersPacket(1, kClientDataStreamId1
, true, true,
1069 GetRequestHeaders("GET", "http", "/")));
1070 mock_quic_data
.AddRead(
1071 ConstructResponseHeadersPacket(1, kClientDataStreamId1
, false, false,
1072 GetResponseHeaders("200 OK")));
1073 mock_quic_data
.AddRead(
1074 ConstructDataPacket(2, kClientDataStreamId1
, false, true, 0, "hello!"));
1075 mock_quic_data
.AddWrite(ConstructAckPacket(2, 1));
1076 mock_quic_data
.AddRead(SYNCHRONOUS
, 0); // EOF
1077 mock_quic_data
.AddSocketDataToFactory(&socket_factory_
);
1079 // The non-alternate protocol job needs to hang in order to guarantee that
1080 // the alternate-protocol job will "win".
1081 AddHangingNonAlternateProtocolSocketData();
1083 // In order for a new QUIC session to be established via alternate-protocol
1084 // without racing an HTTP connection, we need the host resolution to happen
1085 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
1086 // connection to the the server, in this test we require confirmation
1087 // before encrypting so the HTTP job will still start.
1088 host_resolver_
.set_synchronous_mode(true);
1089 host_resolver_
.rules()->AddIPLiteralRule("www.google.com", "192.168.0.1", "");
1090 HostResolver::RequestInfo
info(HostPortPair("www.google.com", 80));
1091 AddressList address
;
1092 host_resolver_
.Resolve(info
, DEFAULT_PRIORITY
, &address
,
1093 CompletionCallback(), nullptr, net_log_
.bound());
1095 CreateSessionWithNextProtos();
1096 session_
->quic_stream_factory()->set_require_confirmation(true);
1097 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT
);
1099 scoped_ptr
<HttpNetworkTransaction
> trans(
1100 new HttpNetworkTransaction(DEFAULT_PRIORITY
, session_
.get()));
1101 TestCompletionCallback callback
;
1102 int rv
= trans
->Start(&request_
, callback
.callback(), net_log_
.bound());
1103 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1105 crypto_client_stream_factory_
.last_stream()->SendOnCryptoHandshakeEvent(
1106 QuicSession::HANDSHAKE_CONFIRMED
);
1107 EXPECT_EQ(OK
, callback
.WaitForResult());
1110 TEST_P(QuicNetworkTransactionTest
, BrokenAlternateProtocol
) {
1111 // Alternate-protocol job
1112 scoped_ptr
<QuicEncryptedPacket
> close(ConstructConnectionClosePacket(1));
1113 MockRead quic_reads
[] = {
1114 MockRead(ASYNC
, close
->data(), close
->length()),
1115 MockRead(ASYNC
, OK
), // EOF
1117 StaticSocketDataProvider
quic_data(quic_reads
, arraysize(quic_reads
),
1119 socket_factory_
.AddSocketDataProvider(&quic_data
);
1121 // Main job which will succeed even though the alternate job fails.
1122 MockRead http_reads
[] = {
1123 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
1124 MockRead("hello from http"),
1125 MockRead(SYNCHRONOUS
, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ
),
1129 StaticSocketDataProvider
http_data(http_reads
, arraysize(http_reads
),
1131 socket_factory_
.AddSocketDataProvider(&http_data
);
1133 CreateSessionWithNextProtos();
1134 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START
);
1135 SendRequestAndExpectHttpResponse("hello from http");
1136 ExpectBrokenAlternateProtocolMapping();
1139 TEST_P(QuicNetworkTransactionTest
, BrokenAlternateProtocolReadError
) {
1140 // Alternate-protocol job
1141 MockRead quic_reads
[] = {
1142 MockRead(ASYNC
, ERR_SOCKET_NOT_CONNECTED
),
1144 StaticSocketDataProvider
quic_data(quic_reads
, arraysize(quic_reads
),
1146 socket_factory_
.AddSocketDataProvider(&quic_data
);
1148 // Main job which will succeed even though the alternate job fails.
1149 MockRead http_reads
[] = {
1150 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
1151 MockRead("hello from http"),
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 CreateSessionWithNextProtos();
1162 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START
);
1163 SendRequestAndExpectHttpResponse("hello from http");
1164 ExpectBrokenAlternateProtocolMapping();
1167 TEST_P(QuicNetworkTransactionTest
, NoBrokenAlternateProtocolIfTcpFails
) {
1168 // Alternate-protocol job will fail when the session attempts to read.
1169 MockRead quic_reads
[] = {
1170 MockRead(ASYNC
, ERR_SOCKET_NOT_CONNECTED
),
1172 StaticSocketDataProvider
quic_data(quic_reads
, arraysize(quic_reads
),
1174 socket_factory_
.AddSocketDataProvider(&quic_data
);
1176 // Main job will also fail.
1177 MockRead http_reads
[] = {
1178 MockRead(ASYNC
, ERR_SOCKET_NOT_CONNECTED
),
1181 StaticSocketDataProvider
http_data(http_reads
, arraysize(http_reads
),
1183 http_data
.set_connect_data(MockConnect(ASYNC
, ERR_SOCKET_NOT_CONNECTED
));
1184 socket_factory_
.AddSocketDataProvider(&http_data
);
1186 CreateSessionWithNextProtos();
1188 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START
);
1189 scoped_ptr
<HttpNetworkTransaction
> trans(
1190 new HttpNetworkTransaction(DEFAULT_PRIORITY
, session_
.get()));
1191 TestCompletionCallback callback
;
1192 int rv
= trans
->Start(&request_
, callback
.callback(), net_log_
.bound());
1193 EXPECT_EQ(ERR_IO_PENDING
, rv
);
1194 EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED
, callback
.WaitForResult());
1195 ExpectQuicAlternateProtocolMapping();
1198 TEST_P(QuicNetworkTransactionTest
, FailedZeroRttBrokenAlternateProtocol
) {
1199 // Alternate-protocol job
1200 MockRead quic_reads
[] = {
1201 MockRead(ASYNC
, ERR_SOCKET_NOT_CONNECTED
),
1203 StaticSocketDataProvider
quic_data(quic_reads
, arraysize(quic_reads
),
1205 socket_factory_
.AddSocketDataProvider(&quic_data
);
1207 AddHangingNonAlternateProtocolSocketData();
1209 // Second Alternate-protocol job which will race with the TCP job.
1210 StaticSocketDataProvider
quic_data2(quic_reads
, arraysize(quic_reads
),
1212 socket_factory_
.AddSocketDataProvider(&quic_data2
);
1214 // Final job that will proceed when the QUIC job fails.
1215 MockRead http_reads
[] = {
1216 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
1217 MockRead("hello from http"),
1218 MockRead(SYNCHRONOUS
, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ
),
1222 StaticSocketDataProvider
http_data(http_reads
, arraysize(http_reads
),
1224 socket_factory_
.AddSocketDataProvider(&http_data
);
1226 CreateSessionWithNextProtos();
1228 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT
);
1230 SendRequestAndExpectHttpResponse("hello from http");
1232 ExpectBrokenAlternateProtocolMapping();
1234 EXPECT_TRUE(quic_data
.AllReadDataConsumed());
1235 EXPECT_TRUE(quic_data
.AllWriteDataConsumed());
1238 TEST_P(QuicNetworkTransactionTest
, DISABLED_HangingZeroRttFallback
) {
1239 // Alternate-protocol job
1240 MockRead quic_reads
[] = {
1241 MockRead(ASYNC
, ERR_IO_PENDING
),
1243 StaticSocketDataProvider
quic_data(quic_reads
, arraysize(quic_reads
),
1245 socket_factory_
.AddSocketDataProvider(&quic_data
);
1247 // Main job that will proceed when the QUIC job fails.
1248 MockRead http_reads
[] = {
1249 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
1250 MockRead("hello from http"),
1251 MockRead(SYNCHRONOUS
, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ
),
1255 StaticSocketDataProvider
http_data(http_reads
, arraysize(http_reads
),
1257 socket_factory_
.AddSocketDataProvider(&http_data
);
1259 CreateSessionWithNextProtos();
1261 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT
);
1263 SendRequestAndExpectHttpResponse("hello from http");
1266 TEST_P(QuicNetworkTransactionTest
, BrokenAlternateProtocolOnConnectFailure
) {
1267 // Alternate-protocol job will fail before creating a QUIC session.
1268 StaticSocketDataProvider
quic_data(nullptr, 0, nullptr, 0);
1269 quic_data
.set_connect_data(MockConnect(SYNCHRONOUS
,
1270 ERR_INTERNET_DISCONNECTED
));
1271 socket_factory_
.AddSocketDataProvider(&quic_data
);
1273 // Main job which will succeed even though the alternate job fails.
1274 MockRead http_reads
[] = {
1275 MockRead("HTTP/1.1 200 OK\r\n\r\n"),
1276 MockRead("hello from http"),
1277 MockRead(SYNCHRONOUS
, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ
),
1281 StaticSocketDataProvider
http_data(http_reads
, arraysize(http_reads
),
1283 socket_factory_
.AddSocketDataProvider(&http_data
);
1285 CreateSessionWithNextProtos();
1286 AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START
);
1287 SendRequestAndExpectHttpResponse("hello from http");
1289 ExpectBrokenAlternateProtocolMapping();
1292 TEST_P(QuicNetworkTransactionTest
, ConnectionCloseDuringConnect
) {
1293 MockQuicData mock_quic_data
;
1294 mock_quic_data
.AddSynchronousRead(ConstructConnectionClosePacket(1));
1295 mock_quic_data
.AddWrite(
1296 ConstructRequestHeadersPacket(1, kClientDataStreamId1
, true, true,
1297 GetRequestHeaders("GET", "http", "/")));
1298 mock_quic_data
.AddWrite(ConstructAckPacket(2, 1));
1299 mock_quic_data
.AddSocketDataToFactory(&socket_factory_
);
1301 // When the QUIC connection fails, we will try the request again over HTTP.
1302 MockRead http_reads
[] = {
1303 MockRead("HTTP/1.1 200 OK\r\n"),
1304 MockRead(kQuicAlternateProtocolHttpHeader
),
1305 MockRead("hello world"),
1306 MockRead(SYNCHRONOUS
, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ
),
1310 StaticSocketDataProvider
http_data(http_reads
, arraysize(http_reads
),
1312 socket_factory_
.AddSocketDataProvider(&http_data
);
1314 // In order for a new QUIC session to be established via alternate-protocol
1315 // without racing an HTTP connection, we need the host resolution to happen
1317 host_resolver_
.set_synchronous_mode(true);
1318 host_resolver_
.rules()->AddIPLiteralRule("www.google.com", "192.168.0.1", "");
1319 HostResolver::RequestInfo
info(HostPortPair("www.google.com", 80));
1320 AddressList address
;
1321 host_resolver_
.Resolve(info
,
1324 CompletionCallback(),
1328 CreateSessionWithNextProtos();
1329 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT
);
1330 SendRequestAndExpectHttpResponse("hello world");
1333 // Test that a secure request over an insecure QUIC connection fails with
1334 // the appropriate error code. Note that this never happens in production,
1335 // because the handshake (which this test mocks) would fail in this scenario.
1336 TEST_P(QuicNetworkTransactionTest
, SecureResourceOverInsecureQuic
) {
1337 maker_
.set_hostname("www.example.org");
1338 MockQuicData mock_quic_data
;
1339 mock_quic_data
.AddWrite(
1340 ConstructRequestHeadersPacket(1, kClientDataStreamId1
, true, true,
1341 GetRequestHeaders("GET", "https", "/")));
1342 mock_quic_data
.AddRead(ConstructResponseHeadersPacket(
1343 1, kClientDataStreamId1
, false, false, GetResponseHeaders("200 OK")));
1344 mock_quic_data
.AddRead(
1345 ConstructDataPacket(2, kClientDataStreamId1
, false, true, 0, "hello!"));
1346 mock_quic_data
.AddWrite(ConstructAckPacket(2, 1));
1347 mock_quic_data
.AddRead(SYNCHRONOUS
, 0);
1348 mock_quic_data
.AddSocketDataToFactory(&socket_factory_
);
1350 request_
.url
= GURL("https://www.example.org:443");
1351 AddHangingNonAlternateProtocolSocketData();
1352 CreateSessionWithNextProtos();
1353 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE
);
1354 scoped_ptr
<HttpNetworkTransaction
> trans(
1355 new HttpNetworkTransaction(DEFAULT_PRIORITY
, session_
.get()));
1356 TestCompletionCallback callback
;
1357 int rv
= trans
->Start(&request_
, callback
.callback(), net_log_
.bound());
1358 EXPECT_EQ(ERR_REQUEST_FOR_SECURE_RESOURCE_OVER_INSECURE_QUIC
,
1359 callback
.GetResult(rv
));
1362 TEST_P(QuicNetworkTransactionTest
, SecureResourceOverSecureQuic
) {
1363 maker_
.set_hostname("www.example.org");
1364 MockQuicData mock_quic_data
;
1365 mock_quic_data
.AddWrite(
1366 ConstructRequestHeadersPacket(1, kClientDataStreamId1
, true, true,
1367 GetRequestHeaders("GET", "https", "/")));
1368 mock_quic_data
.AddRead(ConstructResponseHeadersPacket(
1369 1, kClientDataStreamId1
, false, false, GetResponseHeaders("200 OK")));
1370 mock_quic_data
.AddRead(
1371 ConstructDataPacket(2, kClientDataStreamId1
, false, true, 0, "hello!"));
1372 mock_quic_data
.AddWrite(ConstructAckPacket(2, 1));
1373 mock_quic_data
.AddRead(SYNCHRONOUS
, 0);
1374 mock_quic_data
.AddSocketDataToFactory(&socket_factory_
);
1376 scoped_refptr
<X509Certificate
> cert(
1377 ImportCertFromFile(GetTestCertsDirectory(), "spdy_pooling.pem"));
1378 ASSERT_TRUE(cert
.get());
1379 bool common_name_fallback_used
;
1381 cert
->VerifyNameMatch("www.example.org", &common_name_fallback_used
));
1382 ProofVerifyDetailsChromium verify_details
;
1383 verify_details
.cert_verify_result
.verified_cert
= cert
;
1384 crypto_client_stream_factory_
.AddProofVerifyDetails(&verify_details
);
1386 request_
.url
= GURL("https://www.example.org:443");
1387 AddHangingNonAlternateProtocolSocketData();
1388 CreateSessionWithNextProtos();
1389 AddQuicAlternateProtocolMapping(MockCryptoClientStream::CONFIRM_HANDSHAKE
);
1390 SendRequestAndExpectQuicResponse("hello!");