Supervised user whitelists: Cleanup
[chromium-blink-merge.git] / net / quic / quic_network_transaction_unittest.cc
blobc312993c93ca46aab206a5df17e3dbbe04b8d8fc
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.
5 #include <vector>
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 //-----------------------------------------------------------------------------
49 namespace {
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";
61 } // namespace
63 namespace net {
64 namespace test {
66 // Helper class to encapsulate MockReads and MockWrites for QUIC.
67 // Simplify ownership issues and the interaction with the MockSocketFactory.
68 class MockQuicData {
69 public:
70 MockQuicData() : sequence_number_(0) {}
72 ~MockQuicData() {
73 STLDeleteElements(&packets_);
76 void AddSynchronousRead(scoped_ptr<QuicEncryptedPacket> packet) {
77 reads_.push_back(MockRead(SYNCHRONOUS, packet->data(), packet->length(),
78 sequence_number_++));
79 packets_.push_back(packet.release());
82 void AddRead(scoped_ptr<QuicEncryptedPacket> packet) {
83 reads_.push_back(
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(),
94 sequence_number_++));
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];
101 socket_data_.reset(
102 new SequencedSocketData(reads, reads_.size(), writes, writes_.size()));
103 factory->AddSocketDataProvider(socket_data_.get());
106 private:
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 {
115 public:
116 ProxyHeadersHandler() : was_called_(false) {}
118 bool was_called() { return was_called_; }
120 void OnBeforeProxyHeadersSent(const ProxyInfo& proxy_info,
121 HttpRequestHeaders* request_headers) {
122 was_called_ = true;
125 private:
126 bool was_called_;
129 class QuicNetworkTransactionTest
130 : public PlatformTest,
131 public ::testing::WithParamInterface<QuicVersion> {
132 protected:
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,
187 bool fin,
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,
198 bool fin,
199 const SpdyHeaderBlock& headers) {
200 QuicPriority priority =
201 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
202 return maker_.MakeRequestHeadersPacket(sequence_number, stream_id,
203 should_include_version, fin,
204 priority, headers);
207 scoped_ptr<QuicEncryptedPacket> ConstructResponseHeadersPacket(
208 QuicPacketSequenceNumber sequence_number,
209 QuicStreamId stream_id,
210 bool should_include_version,
211 bool fin,
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,
263 uint16 port) {
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,
307 uint16 port) {
308 SendRequestAndExpectQuicResponseMaybeFromProxy(expected, false, port);
311 void SendRequestAndExpectQuicResponseFromProxyOnPort(
312 const std::string& expected,
313 uint16 port) {
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_;
366 private:
367 void SendRequestAndExpectQuicResponseMaybeFromProxy(
368 const std::string& expected,
369 bool used_proxy,
370 uint16 port) {
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();
410 CreateSession();
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,
422 NetLog::PHASE_NONE);
423 EXPECT_LT(0, pos);
425 // ... and also a TYPE_QUIC_SESSION_PACKET_HEADER_RECEIVED.
426 pos = ExpectLogContainsSomewhere(
427 entries, 0, NetLog::TYPE_QUIC_SESSION_PACKET_HEADER_RECEIVED,
428 NetLog::PHASE_NONE);
429 EXPECT_LT(0, pos);
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,
439 NetLog::PHASE_NONE);
440 EXPECT_LT(0, pos);
442 int log_stream_id;
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.
469 CreateSession();
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_);
483 CreateSession();
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),
502 MockRead(ASYNC, OK)
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);
510 CreateSession();
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),
521 MockRead(ASYNC, OK)
524 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
525 nullptr, 0);
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);
622 EXPECT_TRUE(
623 session_->http_server_properties()->WasAlternativeServiceRecentlyBroken(
624 alternative_service));
626 SendRequestAndExpectHttpResponse("hello world");
627 SendRequestAndExpectQuicResponse("hello!");
629 EXPECT_FALSE(
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),
640 MockRead(ASYNC, OK)
643 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
644 nullptr, 0);
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),
678 MockRead(ASYNC, OK)
681 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
682 nullptr, 0);
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),
700 MockRead(ASYNC, OK)
703 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
704 nullptr, 0);
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),
724 MockRead(ASYNC, OK)
727 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
728 nullptr, 0);
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
853 // synchronously.
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));
857 AddressList address;
858 host_resolver_.Resolve(info,
859 DEFAULT_PRIORITY,
860 &address,
861 CompletionCallback(),
862 nullptr,
863 net_log_.bound());
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
894 // synchronously.
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));
898 AddressList address;
899 host_resolver_.Resolve(info,
900 DEFAULT_PRIORITY,
901 &address,
902 CompletionCallback(),
903 nullptr,
904 net_log_.bound());
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));
937 AddressList address;
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),
964 nullptr, 0);
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),
972 MockRead(ASYNC, OK)
975 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
976 nullptr, 0);
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),
991 nullptr, 0);
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),
999 MockRead(ASYNC, OK)
1002 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
1003 nullptr, 0);
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),
1019 nullptr, 0);
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),
1028 nullptr, 0);
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),
1050 nullptr, 0);
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),
1057 nullptr, 0);
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),
1065 MockRead(ASYNC, OK)
1068 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
1069 nullptr, 0);
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),
1090 nullptr, 0);
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),
1098 MockRead(ASYNC, OK)
1101 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
1102 nullptr, 0);
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),
1124 MockRead(ASYNC, OK)
1127 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
1128 nullptr, 0);
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),
1153 MockRead(ASYNC, OK)
1156 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
1157 nullptr, 0);
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
1162 // synchronously.
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,
1168 DEFAULT_PRIORITY,
1169 &address,
1170 CompletionCallback(),
1171 nullptr,
1172 net_log_.bound());
1174 CreateSessionWithNextProtos();
1175 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
1176 SendRequestAndExpectHttpResponse("hello world");
1179 } // namespace test
1180 } // namespace net