Update To 11.40.268.0
[platform/framework/web/crosswalk.git] / src / net / quic / quic_network_transaction_unittest.cc
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.
4
5 #include <vector>
6
7 #include "base/basictypes.h"
8 #include "base/compiler_specific.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/stl_util.h"
11 #include "net/base/capturing_net_log.h"
12 #include "net/base/net_log_unittest.h"
13 #include "net/base/test_completion_callback.h"
14 #include "net/cert/mock_cert_verifier.h"
15 #include "net/dns/mock_host_resolver.h"
16 #include "net/http/http_auth_handler_factory.h"
17 #include "net/http/http_network_session.h"
18 #include "net/http/http_network_transaction.h"
19 #include "net/http/http_server_properties_impl.h"
20 #include "net/http/http_stream.h"
21 #include "net/http/http_stream_factory.h"
22 #include "net/http/http_transaction_test_util.h"
23 #include "net/http/transport_security_state.h"
24 #include "net/proxy/proxy_config_service_fixed.h"
25 #include "net/proxy/proxy_resolver.h"
26 #include "net/proxy/proxy_service.h"
27 #include "net/quic/crypto/quic_decrypter.h"
28 #include "net/quic/crypto/quic_encrypter.h"
29 #include "net/quic/quic_framer.h"
30 #include "net/quic/quic_http_utils.h"
31 #include "net/quic/test_tools/crypto_test_utils.h"
32 #include "net/quic/test_tools/mock_clock.h"
33 #include "net/quic/test_tools/mock_crypto_client_stream_factory.h"
34 #include "net/quic/test_tools/mock_random.h"
35 #include "net/quic/test_tools/quic_test_packet_maker.h"
36 #include "net/quic/test_tools/quic_test_utils.h"
37 #include "net/socket/client_socket_factory.h"
38 #include "net/socket/mock_client_socket_pool_manager.h"
39 #include "net/socket/socket_test_util.h"
40 #include "net/socket/ssl_client_socket.h"
41 #include "net/spdy/spdy_frame_builder.h"
42 #include "net/spdy/spdy_framer.h"
43 #include "net/ssl/ssl_config_service_defaults.h"
44 #include "testing/gtest/include/gtest/gtest.h"
45 #include "testing/platform_test.h"
46
47 //-----------------------------------------------------------------------------
48
49 namespace {
50
51 // This is the expected return from a current server advertising QUIC.
52 static const char kQuicAlternateProtocolHttpHeader[] =
53     "Alternate-Protocol: 80:quic\r\n\r\n";
54 static const char kQuicAlternateProtocol50pctHttpHeader[] =
55     "Alternate-Protocol: 80:quic,p=.5\r\n\r\n";
56 static const char kQuicAlternateProtocolHttpsHeader[] =
57     "Alternate-Protocol: 443:quic\r\n\r\n";
58
59 }  // namespace
60
61 namespace net {
62 namespace test {
63
64 // Helper class to encapsulate MockReads and MockWrites for QUIC.
65 // Simplify ownership issues and the interaction with the MockSocketFactory.
66 class MockQuicData {
67  public:
68   ~MockQuicData() {
69     STLDeleteElements(&packets_);
70   }
71
72   void AddRead(scoped_ptr<QuicEncryptedPacket> packet) {
73     reads_.push_back(MockRead(SYNCHRONOUS, packet->data(), packet->length(),
74                               sequence_number_++));
75     packets_.push_back(packet.release());
76   }
77
78   void AddRead(IoMode mode, int rv) {
79     reads_.push_back(MockRead(mode, rv));
80   }
81
82   void AddWrite(scoped_ptr<QuicEncryptedPacket> packet) {
83     writes_.push_back(MockWrite(SYNCHRONOUS, packet->data(), packet->length(),
84                                 sequence_number_++));
85     packets_.push_back(packet.release());
86   }
87
88   void AddDelayedSocketDataToFactory(MockClientSocketFactory* factory,
89                                      size_t delay) {
90     MockRead* reads = reads_.empty() ? nullptr  : &reads_[0];
91     MockWrite* writes = writes_.empty() ? nullptr  : &writes_[0];
92     socket_data_.reset(new DelayedSocketData(
93         delay, reads, reads_.size(), writes, writes_.size()));
94     factory->AddSocketDataProvider(socket_data_.get());
95   }
96
97  private:
98   std::vector<QuicEncryptedPacket*> packets_;
99   std::vector<MockWrite> writes_;
100   std::vector<MockRead> reads_;
101   size_t sequence_number_;
102   scoped_ptr<SocketDataProvider> socket_data_;
103 };
104
105 class QuicNetworkTransactionTest
106     : public PlatformTest,
107       public ::testing::WithParamInterface<QuicVersion> {
108  protected:
109   QuicNetworkTransactionTest()
110       : clock_(new MockClock),
111         maker_(GetParam(), 0, clock_),
112         ssl_config_service_(new SSLConfigServiceDefaults),
113         proxy_service_(ProxyService::CreateDirect()),
114         auth_handler_factory_(
115             HttpAuthHandlerFactory::CreateDefault(&host_resolver_)),
116         random_generator_(0),
117         hanging_data_(nullptr, 0, nullptr, 0) {
118     request_.method = "GET";
119     request_.url = GURL("http://www.google.com/");
120     request_.load_flags = 0;
121     clock_->AdvanceTime(QuicTime::Delta::FromMilliseconds(20));
122   }
123
124   void SetUp() override {
125     NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
126     base::MessageLoop::current()->RunUntilIdle();
127   }
128
129   void TearDown() override {
130     NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
131     // Empty the current queue.
132     base::MessageLoop::current()->RunUntilIdle();
133     PlatformTest::TearDown();
134     NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
135     base::MessageLoop::current()->RunUntilIdle();
136   }
137
138   scoped_ptr<QuicEncryptedPacket> ConstructConnectionClosePacket(
139       QuicPacketSequenceNumber num) {
140     return maker_.MakeConnectionClosePacket(num);
141   }
142
143   scoped_ptr<QuicEncryptedPacket> ConstructAckPacket(
144       QuicPacketSequenceNumber largest_received,
145       QuicPacketSequenceNumber least_unacked) {
146     return maker_.MakeAckPacket(2, largest_received, least_unacked, true);
147   }
148
149   SpdyHeaderBlock GetRequestHeaders(const std::string& method,
150                                     const std::string& scheme,
151                                     const std::string& path) {
152     return maker_.GetRequestHeaders(method, scheme, path);
153   }
154
155   SpdyHeaderBlock GetResponseHeaders(const std::string& status) {
156     return maker_.GetResponseHeaders(status);
157   }
158
159   scoped_ptr<QuicEncryptedPacket> ConstructDataPacket(
160       QuicPacketSequenceNumber sequence_number,
161       QuicStreamId stream_id,
162       bool should_include_version,
163       bool fin,
164       QuicStreamOffset offset,
165       base::StringPiece data) {
166     return maker_.MakeDataPacket(
167         sequence_number, stream_id, should_include_version, fin, offset, data);
168   }
169
170   scoped_ptr<QuicEncryptedPacket> ConstructRequestHeadersPacket(
171       QuicPacketSequenceNumber sequence_number,
172       QuicStreamId stream_id,
173       bool should_include_version,
174       bool fin,
175       const SpdyHeaderBlock& headers) {
176     return maker_.MakeRequestHeadersPacket(
177         sequence_number, stream_id, should_include_version, fin, headers);
178   }
179
180   scoped_ptr<QuicEncryptedPacket> ConstructResponseHeadersPacket(
181       QuicPacketSequenceNumber sequence_number,
182       QuicStreamId stream_id,
183       bool should_include_version,
184       bool fin,
185       const SpdyHeaderBlock& headers) {
186     return maker_.MakeResponseHeadersPacket(
187         sequence_number, stream_id, should_include_version, fin, headers);
188   }
189
190   void CreateSession() {
191     CreateSessionWithFactory(&socket_factory_, false);
192   }
193
194   void CreateSessionWithNextProtos() {
195     CreateSessionWithFactory(&socket_factory_, true);
196   }
197
198   // If |use_next_protos| is true, enables SPDY and QUIC.
199   void CreateSessionWithFactory(ClientSocketFactory* socket_factory,
200                                 bool use_next_protos) {
201     params_.enable_quic = true;
202     params_.quic_clock = clock_;
203     params_.quic_random = &random_generator_;
204     params_.client_socket_factory = socket_factory;
205     params_.quic_crypto_client_stream_factory = &crypto_client_stream_factory_;
206     params_.host_resolver = &host_resolver_;
207     params_.cert_verifier = &cert_verifier_;
208     params_.transport_security_state = &transport_security_state_;
209     params_.proxy_service = proxy_service_.get();
210     params_.ssl_config_service = ssl_config_service_.get();
211     params_.http_auth_handler_factory = auth_handler_factory_.get();
212     params_.http_server_properties = http_server_properties.GetWeakPtr();
213     params_.quic_supported_versions = SupportedVersions(GetParam());
214
215     if (use_next_protos) {
216       params_.use_alternate_protocols = true;
217       params_.next_protos = NextProtosWithSpdyAndQuic(true, true);
218     }
219
220     session_ = new HttpNetworkSession(params_);
221     session_->quic_stream_factory()->set_require_confirmation(false);
222   }
223
224   void CheckWasQuicResponse(const scoped_ptr<HttpNetworkTransaction>& trans) {
225     const HttpResponseInfo* response = trans->GetResponseInfo();
226     ASSERT_TRUE(response != nullptr);
227     ASSERT_TRUE(response->headers.get() != nullptr);
228     EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
229     EXPECT_TRUE(response->was_fetched_via_spdy);
230     EXPECT_TRUE(response->was_npn_negotiated);
231     EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_QUIC1_SPDY3,
232               response->connection_info);
233   }
234
235   void CheckWasHttpResponse(const scoped_ptr<HttpNetworkTransaction>& trans) {
236     const HttpResponseInfo* response = trans->GetResponseInfo();
237     ASSERT_TRUE(response != nullptr);
238     ASSERT_TRUE(response->headers.get() != nullptr);
239     EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
240     EXPECT_FALSE(response->was_fetched_via_spdy);
241     EXPECT_FALSE(response->was_npn_negotiated);
242     EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP1,
243               response->connection_info);
244   }
245
246   void CheckResponseData(HttpNetworkTransaction* trans,
247                          const std::string& expected) {
248     std::string response_data;
249     ASSERT_EQ(OK, ReadTransaction(trans, &response_data));
250     EXPECT_EQ(expected, response_data);
251   }
252
253   void RunTransaction(HttpNetworkTransaction* trans) {
254     TestCompletionCallback callback;
255     int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
256     EXPECT_EQ(ERR_IO_PENDING, rv);
257     EXPECT_EQ(OK, callback.WaitForResult());
258   }
259
260   void SendRequestAndExpectHttpResponse(const std::string& expected) {
261     scoped_ptr<HttpNetworkTransaction> trans(
262         new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
263     RunTransaction(trans.get());
264     CheckWasHttpResponse(trans);
265     CheckResponseData(trans.get(), expected);
266   }
267
268   void SendRequestAndExpectQuicResponse(const std::string& expected) {
269     scoped_ptr<HttpNetworkTransaction> trans(
270         new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
271     RunTransaction(trans.get());
272     CheckWasQuicResponse(trans);
273     CheckResponseData(trans.get(), expected);
274   }
275
276   void AddQuicAlternateProtocolMapping(
277       MockCryptoClientStream::HandshakeMode handshake_mode) {
278     crypto_client_stream_factory_.set_handshake_mode(handshake_mode);
279     session_->http_server_properties()->SetAlternateProtocol(
280         HostPortPair::FromURL(request_.url), 80, QUIC, 1);
281   }
282
283   void ExpectBrokenAlternateProtocolMapping() {
284     ASSERT_TRUE(session_->http_server_properties()->HasAlternateProtocol(
285         HostPortPair::FromURL(request_.url)));
286     const AlternateProtocolInfo alternate =
287         session_->http_server_properties()->GetAlternateProtocol(
288             HostPortPair::FromURL(request_.url));
289     EXPECT_TRUE(alternate.is_broken);
290   }
291
292   void ExpectQuicAlternateProtocolMapping() {
293     ASSERT_TRUE(session_->http_server_properties()->HasAlternateProtocol(
294         HostPortPair::FromURL(request_.url)));
295     const AlternateProtocolInfo alternate =
296         session_->http_server_properties()->GetAlternateProtocol(
297             HostPortPair::FromURL(request_.url));
298     EXPECT_EQ(QUIC, alternate.protocol);
299   }
300
301   void AddHangingNonAlternateProtocolSocketData() {
302     MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
303     hanging_data_.set_connect_data(hanging_connect);
304     socket_factory_.AddSocketDataProvider(&hanging_data_);
305   }
306
307   MockClock* clock_;  // Owned by QuicStreamFactory after CreateSession.
308   QuicTestPacketMaker maker_;
309   scoped_refptr<HttpNetworkSession> session_;
310   MockClientSocketFactory socket_factory_;
311   MockCryptoClientStreamFactory crypto_client_stream_factory_;
312   MockHostResolver host_resolver_;
313   MockCertVerifier cert_verifier_;
314   TransportSecurityState transport_security_state_;
315   scoped_refptr<SSLConfigServiceDefaults> ssl_config_service_;
316   scoped_ptr<ProxyService> proxy_service_;
317   scoped_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
318   MockRandom random_generator_;
319   HttpServerPropertiesImpl http_server_properties;
320   HttpNetworkSession::Params params_;
321   HttpRequestInfo request_;
322   CapturingBoundNetLog net_log_;
323   StaticSocketDataProvider hanging_data_;
324 };
325
326 INSTANTIATE_TEST_CASE_P(Version, QuicNetworkTransactionTest,
327                         ::testing::ValuesIn(QuicSupportedVersions()));
328
329 TEST_P(QuicNetworkTransactionTest, ForceQuic) {
330   params_.origin_to_force_quic_on =
331       HostPortPair::FromString("www.google.com:80");
332
333   MockQuicData mock_quic_data;
334   mock_quic_data.AddWrite(
335       ConstructRequestHeadersPacket(1, kClientDataStreamId1, true, true,
336                                     GetRequestHeaders("GET", "http", "/")));
337   mock_quic_data.AddRead(
338       ConstructResponseHeadersPacket(1, kClientDataStreamId1, false, false,
339                                      GetResponseHeaders("200 OK")));
340   mock_quic_data.AddRead(
341       ConstructDataPacket(2, kClientDataStreamId1, false, true, 0, "hello!"));
342   mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
343   mock_quic_data.AddRead(SYNCHRONOUS, 0);  // EOF
344
345   mock_quic_data.AddDelayedSocketDataToFactory(&socket_factory_, 1);
346
347   // The non-alternate protocol job needs to hang in order to guarantee that
348   // the alternate-protocol job will "win".
349   AddHangingNonAlternateProtocolSocketData();
350
351   CreateSession();
352
353   SendRequestAndExpectQuicResponse("hello!");
354
355   // Check that the NetLog was filled reasonably.
356   net::CapturingNetLog::CapturedEntryList entries;
357   net_log_.GetEntries(&entries);
358   EXPECT_LT(0u, entries.size());
359
360   // Check that we logged a QUIC_SESSION_PACKET_RECEIVED.
361   int pos = net::ExpectLogContainsSomewhere(
362       entries, 0,
363       net::NetLog::TYPE_QUIC_SESSION_PACKET_RECEIVED,
364       net::NetLog::PHASE_NONE);
365   EXPECT_LT(0, pos);
366
367   // ... and also a TYPE_QUIC_SESSION_PACKET_HEADER_RECEIVED.
368   pos = net::ExpectLogContainsSomewhere(
369       entries, 0,
370       net::NetLog::TYPE_QUIC_SESSION_PACKET_HEADER_RECEIVED,
371       net::NetLog::PHASE_NONE);
372   EXPECT_LT(0, pos);
373
374   std::string packet_sequence_number;
375   ASSERT_TRUE(entries[pos].GetStringValue(
376       "packet_sequence_number", &packet_sequence_number));
377   EXPECT_EQ("1", packet_sequence_number);
378
379   // ... and also a QUIC_SESSION_STREAM_FRAME_RECEIVED.
380   pos = net::ExpectLogContainsSomewhere(
381       entries, 0,
382       net::NetLog::TYPE_QUIC_SESSION_STREAM_FRAME_RECEIVED,
383       net::NetLog::PHASE_NONE);
384   EXPECT_LT(0, pos);
385
386   int log_stream_id;
387   ASSERT_TRUE(entries[pos].GetIntegerValue("stream_id", &log_stream_id));
388   EXPECT_EQ(3, log_stream_id);
389 }
390
391 TEST_P(QuicNetworkTransactionTest, QuicProxy) {
392   proxy_service_.reset(
393       ProxyService::CreateFixedFromPacResult("QUIC myproxy:70"));
394
395   MockQuicData mock_quic_data;
396   mock_quic_data.AddWrite(
397       ConstructRequestHeadersPacket(1, kClientDataStreamId1, true, true,
398                                     GetRequestHeaders("GET", "http", "/")));
399   mock_quic_data.AddRead(
400       ConstructResponseHeadersPacket(1, kClientDataStreamId1, false, false,
401                                      GetResponseHeaders("200 OK")));
402   mock_quic_data.AddRead(
403       ConstructDataPacket(2, kClientDataStreamId1, false, true, 0, "hello!"));
404   mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
405   mock_quic_data.AddRead(SYNCHRONOUS, 0);  // EOF
406
407   mock_quic_data.AddDelayedSocketDataToFactory(&socket_factory_, 1);
408
409   // There is no need to set up an alternate protocol job, because
410   // no attempt will be made to speak to the proxy over TCP.
411
412   CreateSession();
413
414   SendRequestAndExpectQuicResponse("hello!");
415 }
416
417 TEST_P(QuicNetworkTransactionTest, ForceQuicWithErrorConnecting) {
418   params_.origin_to_force_quic_on =
419       HostPortPair::FromString("www.google.com:80");
420
421   MockQuicData mock_quic_data;
422   mock_quic_data.AddRead(ASYNC, ERR_SOCKET_NOT_CONNECTED);
423
424   mock_quic_data.AddDelayedSocketDataToFactory(&socket_factory_, 0);
425
426   CreateSession();
427
428   scoped_ptr<HttpNetworkTransaction> trans(
429       new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
430   TestCompletionCallback callback;
431   int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
432   EXPECT_EQ(ERR_IO_PENDING, rv);
433   EXPECT_EQ(ERR_CONNECTION_CLOSED, callback.WaitForResult());
434 }
435
436 TEST_P(QuicNetworkTransactionTest, DoNotForceQuicForHttps) {
437   // Attempt to "force" quic on 443, which will not be honored.
438   params_.origin_to_force_quic_on =
439       HostPortPair::FromString("www.google.com:443");
440
441   MockRead http_reads[] = {
442     MockRead("HTTP/1.1 200 OK\r\n\r\n"),
443     MockRead("hello world"),
444     MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
445     MockRead(ASYNC, OK)
446   };
447
448   StaticSocketDataProvider data(http_reads, arraysize(http_reads), nullptr, 0);
449   socket_factory_.AddSocketDataProvider(&data);
450   SSLSocketDataProvider ssl(ASYNC, OK);
451   socket_factory_.AddSSLSocketDataProvider(&ssl);
452
453   CreateSession();
454
455   SendRequestAndExpectHttpResponse("hello world");
456 }
457
458 TEST_P(QuicNetworkTransactionTest, UseAlternateProtocolForQuic) {
459   MockRead http_reads[] = {
460     MockRead("HTTP/1.1 200 OK\r\n"),
461     MockRead(kQuicAlternateProtocolHttpHeader),
462     MockRead("hello world"),
463     MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
464     MockRead(ASYNC, OK)
465   };
466
467   StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
468                                      nullptr, 0);
469   socket_factory_.AddSocketDataProvider(&http_data);
470
471   MockQuicData mock_quic_data;
472   mock_quic_data.AddWrite(
473       ConstructRequestHeadersPacket(1, kClientDataStreamId1, true, true,
474                                     GetRequestHeaders("GET", "http", "/")));
475   mock_quic_data.AddRead(
476       ConstructResponseHeadersPacket(1, kClientDataStreamId1, false, false,
477                                      GetResponseHeaders("200 OK")));
478   mock_quic_data.AddRead(
479       ConstructDataPacket(2, kClientDataStreamId1, false, true, 0, "hello!"));
480   mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
481   mock_quic_data.AddRead(SYNCHRONOUS, 0);  // EOF
482
483   mock_quic_data.AddDelayedSocketDataToFactory(&socket_factory_, 1);
484
485   // The non-alternate protocol job needs to hang in order to guarantee that
486   // the alternate-protocol job will "win".
487   AddHangingNonAlternateProtocolSocketData();
488
489   CreateSessionWithNextProtos();
490
491   SendRequestAndExpectHttpResponse("hello world");
492   SendRequestAndExpectQuicResponse("hello!");
493 }
494
495 TEST_P(QuicNetworkTransactionTest, UseAlternateProtocolProbabilityForQuic) {
496   MockRead http_reads[] = {
497     MockRead("HTTP/1.1 200 OK\r\n"),
498     MockRead(kQuicAlternateProtocol50pctHttpHeader),
499     MockRead("hello world"),
500     MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
501     MockRead(ASYNC, OK)
502   };
503
504   StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
505                                      nullptr, 0);
506   socket_factory_.AddSocketDataProvider(&http_data);
507
508   MockQuicData mock_quic_data;
509   mock_quic_data.AddWrite(
510       ConstructRequestHeadersPacket(1, kClientDataStreamId1, true, true,
511                                     GetRequestHeaders("GET", "http", "/")));
512   mock_quic_data.AddRead(
513       ConstructResponseHeadersPacket(1, kClientDataStreamId1, false, false,
514                                      GetResponseHeaders("200 OK")));
515   mock_quic_data.AddRead(
516       ConstructDataPacket(2, kClientDataStreamId1, false, true, 0, "hello!"));
517   mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
518   mock_quic_data.AddRead(SYNCHRONOUS, 0);  // EOF
519
520   mock_quic_data.AddDelayedSocketDataToFactory(&socket_factory_, 1);
521
522   // The non-alternate protocol job needs to hang in order to guarantee that
523   // the alternate-protocol job will "win".
524   AddHangingNonAlternateProtocolSocketData();
525
526   params_.alternate_protocol_probability_threshold = .25;
527   CreateSessionWithNextProtos();
528
529   SendRequestAndExpectHttpResponse("hello world");
530   SendRequestAndExpectQuicResponse("hello!");
531 }
532
533 TEST_P(QuicNetworkTransactionTest, DontUseAlternateProtocolProbabilityForQuic) {
534   MockRead http_reads[] = {
535     MockRead("HTTP/1.1 200 OK\r\n"),
536     MockRead(kQuicAlternateProtocol50pctHttpHeader),
537     MockRead("hello world"),
538     MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
539     MockRead(ASYNC, OK)
540   };
541
542   StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
543                                      nullptr, 0);
544   socket_factory_.AddSocketDataProvider(&http_data);
545   socket_factory_.AddSocketDataProvider(&http_data);
546
547   params_.alternate_protocol_probability_threshold = .75;
548   CreateSessionWithNextProtos();
549
550   SendRequestAndExpectHttpResponse("hello world");
551   SendRequestAndExpectHttpResponse("hello world");
552 }
553
554 TEST_P(QuicNetworkTransactionTest,
555        DontUseAlternateProtocolWithBadProbabilityForQuic) {
556   MockRead http_reads[] = {
557     MockRead("HTTP/1.1 200 OK\r\n"),
558     MockRead("Alternate-Protocol: 443:quic,p=2\r\n\r\n"),
559     MockRead("hello world"),
560     MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
561     MockRead(ASYNC, OK)
562   };
563
564   StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
565                                      nullptr, 0);
566   socket_factory_.AddSocketDataProvider(&http_data);
567   socket_factory_.AddSocketDataProvider(&http_data);
568
569   params_.alternate_protocol_probability_threshold = .75;
570   CreateSessionWithNextProtos();
571
572   SendRequestAndExpectHttpResponse("hello world");
573   SendRequestAndExpectHttpResponse("hello world");
574 }
575
576 TEST_P(QuicNetworkTransactionTest, UseAlternateProtocolForQuicForHttps) {
577   params_.origin_to_force_quic_on =
578       HostPortPair::FromString("www.google.com:443");
579
580   MockRead http_reads[] = {
581     MockRead("HTTP/1.1 200 OK\r\n"),
582     MockRead(kQuicAlternateProtocolHttpsHeader),
583     MockRead("hello world"),
584     MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
585     MockRead(ASYNC, OK)
586   };
587
588   StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
589                                      nullptr, 0);
590   socket_factory_.AddSocketDataProvider(&http_data);
591
592   MockQuicData mock_quic_data;
593   mock_quic_data.AddWrite(
594       ConstructRequestHeadersPacket(1, kClientDataStreamId1, true, true,
595                                     GetRequestHeaders("GET", "http", "/")));
596   mock_quic_data.AddRead(
597       ConstructResponseHeadersPacket(1, kClientDataStreamId1, false, false,
598                                      GetResponseHeaders("200 OK")));
599   mock_quic_data.AddRead(
600       ConstructDataPacket(2, kClientDataStreamId1, false, true, 0, "hello!"));
601   mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
602   mock_quic_data.AddRead(SYNCHRONOUS, 0);  // EOF
603
604   mock_quic_data.AddDelayedSocketDataToFactory(&socket_factory_, 1);
605
606   // The non-alternate protocol job needs to hang in order to guarantee that
607   // the alternate-protocol job will "win".
608   AddHangingNonAlternateProtocolSocketData();
609
610   CreateSessionWithNextProtos();
611
612   // TODO(rtenneti): Test QUIC over HTTPS, GetSSLInfo().
613   SendRequestAndExpectHttpResponse("hello world");
614 }
615
616 TEST_P(QuicNetworkTransactionTest, HungAlternateProtocol) {
617   crypto_client_stream_factory_.set_handshake_mode(
618       MockCryptoClientStream::COLD_START);
619
620   MockWrite http_writes[] = {
621     MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
622     MockWrite(SYNCHRONOUS, 1, "Host: www.google.com\r\n"),
623     MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")
624   };
625
626   MockRead http_reads[] = {
627     MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
628     MockRead(SYNCHRONOUS, 4, kQuicAlternateProtocolHttpHeader),
629     MockRead(SYNCHRONOUS, 5, "hello world"),
630     MockRead(SYNCHRONOUS, OK, 6)
631   };
632
633   DeterministicMockClientSocketFactory socket_factory;
634
635   DeterministicSocketData http_data(http_reads, arraysize(http_reads),
636                                     http_writes, arraysize(http_writes));
637   socket_factory.AddSocketDataProvider(&http_data);
638
639   // The QUIC transaction will not be allowed to complete.
640   MockWrite quic_writes[] = {
641     MockWrite(ASYNC, ERR_IO_PENDING, 0)
642   };
643   MockRead quic_reads[] = {
644     MockRead(ASYNC, ERR_IO_PENDING, 1),
645   };
646   DeterministicSocketData quic_data(quic_reads, arraysize(quic_reads),
647                                     quic_writes, arraysize(quic_writes));
648   socket_factory.AddSocketDataProvider(&quic_data);
649
650   // The HTTP transaction will complete.
651   DeterministicSocketData http_data2(http_reads, arraysize(http_reads),
652                                      http_writes, arraysize(http_writes));
653   socket_factory.AddSocketDataProvider(&http_data2);
654
655   CreateSessionWithFactory(&socket_factory, true);
656
657   // Run the first request.
658   http_data.StopAfter(arraysize(http_reads) + arraysize(http_writes));
659   SendRequestAndExpectHttpResponse("hello world");
660   ASSERT_TRUE(http_data.at_read_eof());
661   ASSERT_TRUE(http_data.at_write_eof());
662
663   // Now run the second request in which the QUIC socket hangs,
664   // and verify the the transaction continues over HTTP.
665   http_data2.StopAfter(arraysize(http_reads) + arraysize(http_writes));
666   SendRequestAndExpectHttpResponse("hello world");
667
668   ASSERT_TRUE(http_data2.at_read_eof());
669   ASSERT_TRUE(http_data2.at_write_eof());
670   ASSERT_TRUE(!quic_data.at_read_eof());
671   ASSERT_TRUE(!quic_data.at_write_eof());
672 }
673
674 TEST_P(QuicNetworkTransactionTest, ZeroRTTWithHttpRace) {
675   MockQuicData mock_quic_data;
676   mock_quic_data.AddWrite(
677       ConstructRequestHeadersPacket(1, kClientDataStreamId1, true, true,
678                                     GetRequestHeaders("GET", "http", "/")));
679   mock_quic_data.AddRead(
680       ConstructResponseHeadersPacket(1, kClientDataStreamId1, false, false,
681                                      GetResponseHeaders("200 OK")));
682   mock_quic_data.AddRead(
683       ConstructDataPacket(2, kClientDataStreamId1, false, true, 0, "hello!"));
684   mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
685   mock_quic_data.AddRead(SYNCHRONOUS, 0);  // EOF
686
687   mock_quic_data.AddDelayedSocketDataToFactory(&socket_factory_, 1);
688
689   // The non-alternate protocol job needs to hang in order to guarantee that
690   // the alternate-protocol job will "win".
691   AddHangingNonAlternateProtocolSocketData();
692
693   CreateSessionWithNextProtos();
694   AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
695   SendRequestAndExpectQuicResponse("hello!");
696 }
697
698 TEST_P(QuicNetworkTransactionTest, ZeroRTTWithNoHttpRace) {
699   MockQuicData mock_quic_data;
700   mock_quic_data.AddWrite(
701       ConstructRequestHeadersPacket(1, kClientDataStreamId1, true, true,
702                                     GetRequestHeaders("GET", "http", "/")));
703   mock_quic_data.AddRead(
704       ConstructResponseHeadersPacket(1, kClientDataStreamId1, false, false,
705                                      GetResponseHeaders("200 OK")));
706   mock_quic_data.AddRead(
707       ConstructDataPacket(2, kClientDataStreamId1, false, true, 0, "hello!"));
708   mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
709   mock_quic_data.AddRead(SYNCHRONOUS, 0);  // EOF
710   mock_quic_data.AddDelayedSocketDataToFactory(&socket_factory_, 1);
711
712   // In order for a new QUIC session to be established via alternate-protocol
713   // without racing an HTTP connection, we need the host resolution to happen
714   // synchronously.
715   host_resolver_.set_synchronous_mode(true);
716   host_resolver_.rules()->AddIPLiteralRule("www.google.com", "192.168.0.1", "");
717   HostResolver::RequestInfo info(HostPortPair("www.google.com", 80));
718   AddressList address;
719   host_resolver_.Resolve(info,
720                          DEFAULT_PRIORITY,
721                          &address,
722                          CompletionCallback(),
723                          nullptr,
724                          net_log_.bound());
725
726   CreateSessionWithNextProtos();
727   AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
728   SendRequestAndExpectQuicResponse("hello!");
729 }
730
731 TEST_P(QuicNetworkTransactionTest, ZeroRTTWithProxy) {
732   proxy_service_.reset(
733       ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
734
735   // Since we are using a proxy, the QUIC job will not succeed.
736   MockWrite http_writes[] = {
737     MockWrite(SYNCHRONOUS, 0, "GET http://www.google.com/ HTTP/1.1\r\n"),
738     MockWrite(SYNCHRONOUS, 1, "Host: www.google.com\r\n"),
739     MockWrite(SYNCHRONOUS, 2, "Proxy-Connection: keep-alive\r\n\r\n")
740   };
741
742   MockRead http_reads[] = {
743     MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
744     MockRead(SYNCHRONOUS, 4, kQuicAlternateProtocolHttpHeader),
745     MockRead(SYNCHRONOUS, 5, "hello world"),
746     MockRead(SYNCHRONOUS, OK, 6)
747   };
748
749   StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
750                                      http_writes, arraysize(http_writes));
751   socket_factory_.AddSocketDataProvider(&http_data);
752
753   // In order for a new QUIC session to be established via alternate-protocol
754   // without racing an HTTP connection, we need the host resolution to happen
755   // synchronously.
756   host_resolver_.set_synchronous_mode(true);
757   host_resolver_.rules()->AddIPLiteralRule("www.google.com", "192.168.0.1", "");
758   HostResolver::RequestInfo info(HostPortPair("www.google.com", 80));
759   AddressList address;
760   host_resolver_.Resolve(info,
761                          DEFAULT_PRIORITY,
762                          &address,
763                          CompletionCallback(),
764                          nullptr,
765                          net_log_.bound());
766
767   CreateSessionWithNextProtos();
768   AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
769   SendRequestAndExpectHttpResponse("hello world");
770 }
771
772 TEST_P(QuicNetworkTransactionTest, ZeroRTTWithConfirmationRequired) {
773   MockQuicData mock_quic_data;
774   mock_quic_data.AddWrite(
775       ConstructRequestHeadersPacket(1, kClientDataStreamId1, true, true,
776                                     GetRequestHeaders("GET", "http", "/")));
777   mock_quic_data.AddRead(
778       ConstructResponseHeadersPacket(1, kClientDataStreamId1, false, false,
779                                      GetResponseHeaders("200 OK")));
780   mock_quic_data.AddRead(
781       ConstructDataPacket(2, kClientDataStreamId1, false, true, 0, "hello!"));
782   mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
783   mock_quic_data.AddRead(SYNCHRONOUS, 0);  // EOF
784   mock_quic_data.AddDelayedSocketDataToFactory(&socket_factory_, 1);
785
786   // The non-alternate protocol job needs to hang in order to guarantee that
787   // the alternate-protocol job will "win".
788   AddHangingNonAlternateProtocolSocketData();
789
790   // In order for a new QUIC session to be established via alternate-protocol
791   // without racing an HTTP connection, we need the host resolution to happen
792   // synchronously.  Of course, even though QUIC *could* perform a 0-RTT
793   // connection to the the server, in this test we require confirmation
794   // before encrypting so the HTTP job will still start.
795   host_resolver_.set_synchronous_mode(true);
796   host_resolver_.rules()->AddIPLiteralRule("www.google.com", "192.168.0.1", "");
797   HostResolver::RequestInfo info(HostPortPair("www.google.com", 80));
798   AddressList address;
799   host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
800                          CompletionCallback(), nullptr, net_log_.bound());
801
802   CreateSessionWithNextProtos();
803   session_->quic_stream_factory()->set_require_confirmation(true);
804   AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
805
806   scoped_ptr<HttpNetworkTransaction> trans(
807       new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
808   TestCompletionCallback callback;
809   int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
810   EXPECT_EQ(ERR_IO_PENDING, rv);
811
812   crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
813       QuicSession::HANDSHAKE_CONFIRMED);
814   EXPECT_EQ(OK, callback.WaitForResult());
815 }
816
817 TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocol) {
818   // Alternate-protocol job
819   scoped_ptr<QuicEncryptedPacket> close(ConstructConnectionClosePacket(1));
820   MockRead quic_reads[] = {
821     MockRead(ASYNC, close->data(), close->length()),
822     MockRead(ASYNC, OK),  // EOF
823   };
824   StaticSocketDataProvider quic_data(quic_reads, arraysize(quic_reads),
825                                      nullptr, 0);
826   socket_factory_.AddSocketDataProvider(&quic_data);
827
828   // Main job which will succeed even though the alternate job fails.
829   MockRead http_reads[] = {
830     MockRead("HTTP/1.1 200 OK\r\n\r\n"),
831     MockRead("hello from http"),
832     MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
833     MockRead(ASYNC, OK)
834   };
835
836   StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
837                                      nullptr, 0);
838   socket_factory_.AddSocketDataProvider(&http_data);
839
840   CreateSessionWithNextProtos();
841   AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
842   SendRequestAndExpectHttpResponse("hello from http");
843   ExpectBrokenAlternateProtocolMapping();
844 }
845
846 TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocolReadError) {
847   // Alternate-protocol job
848   MockRead quic_reads[] = {
849     MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
850   };
851   StaticSocketDataProvider quic_data(quic_reads, arraysize(quic_reads),
852                                      nullptr, 0);
853   socket_factory_.AddSocketDataProvider(&quic_data);
854
855   // Main job which will succeed even though the alternate job fails.
856   MockRead http_reads[] = {
857     MockRead("HTTP/1.1 200 OK\r\n\r\n"),
858     MockRead("hello from http"),
859     MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
860     MockRead(ASYNC, OK)
861   };
862
863   StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
864                                      nullptr, 0);
865   socket_factory_.AddSocketDataProvider(&http_data);
866
867   CreateSessionWithNextProtos();
868
869   AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
870   SendRequestAndExpectHttpResponse("hello from http");
871   ExpectBrokenAlternateProtocolMapping();
872 }
873
874 TEST_P(QuicNetworkTransactionTest, NoBrokenAlternateProtocolIfTcpFails) {
875   // Alternate-protocol job will fail when the session attempts to read.
876   MockRead quic_reads[] = {
877     MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
878   };
879   StaticSocketDataProvider quic_data(quic_reads, arraysize(quic_reads),
880                                      nullptr, 0);
881   socket_factory_.AddSocketDataProvider(&quic_data);
882
883   // Main job will also fail.
884   MockRead http_reads[] = {
885     MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
886   };
887
888   StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
889                                      nullptr, 0);
890   http_data.set_connect_data(MockConnect(ASYNC, ERR_SOCKET_NOT_CONNECTED));
891   socket_factory_.AddSocketDataProvider(&http_data);
892
893   CreateSessionWithNextProtos();
894
895   AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
896   scoped_ptr<HttpNetworkTransaction> trans(
897       new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
898   TestCompletionCallback callback;
899   int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
900   EXPECT_EQ(ERR_IO_PENDING, rv);
901   EXPECT_EQ(ERR_SOCKET_NOT_CONNECTED, callback.WaitForResult());
902   ExpectQuicAlternateProtocolMapping();
903 }
904
905 TEST_P(QuicNetworkTransactionTest, FailedZeroRttBrokenAlternateProtocol) {
906   // Alternate-protocol job
907   MockRead quic_reads[] = {
908     MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
909   };
910   StaticSocketDataProvider quic_data(quic_reads, arraysize(quic_reads),
911                                      nullptr, 0);
912   socket_factory_.AddSocketDataProvider(&quic_data);
913
914   AddHangingNonAlternateProtocolSocketData();
915
916   // Second Alternate-protocol job which will race with the TCP job.
917   StaticSocketDataProvider quic_data2(quic_reads, arraysize(quic_reads),
918                                       nullptr, 0);
919   socket_factory_.AddSocketDataProvider(&quic_data2);
920
921   // Final job that will proceed when the QUIC job fails.
922   MockRead http_reads[] = {
923     MockRead("HTTP/1.1 200 OK\r\n\r\n"),
924     MockRead("hello from http"),
925     MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
926     MockRead(ASYNC, OK)
927   };
928
929   StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
930                                      nullptr, 0);
931   socket_factory_.AddSocketDataProvider(&http_data);
932
933   CreateSessionWithNextProtos();
934
935   AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
936
937   SendRequestAndExpectHttpResponse("hello from http");
938
939   ExpectBrokenAlternateProtocolMapping();
940
941   EXPECT_TRUE(quic_data.at_read_eof());
942   EXPECT_TRUE(quic_data.at_write_eof());
943 }
944
945 TEST_P(QuicNetworkTransactionTest, DISABLED_HangingZeroRttFallback) {
946   // Alternate-protocol job
947   MockRead quic_reads[] = {
948     MockRead(ASYNC, ERR_IO_PENDING),
949   };
950   StaticSocketDataProvider quic_data(quic_reads, arraysize(quic_reads),
951                                      nullptr, 0);
952   socket_factory_.AddSocketDataProvider(&quic_data);
953
954   // Main job that will proceed when the QUIC job fails.
955   MockRead http_reads[] = {
956     MockRead("HTTP/1.1 200 OK\r\n\r\n"),
957     MockRead("hello from http"),
958     MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
959     MockRead(ASYNC, OK)
960   };
961
962   StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
963                                      nullptr, 0);
964   socket_factory_.AddSocketDataProvider(&http_data);
965
966   CreateSessionWithNextProtos();
967
968   AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
969
970   SendRequestAndExpectHttpResponse("hello from http");
971 }
972
973 TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocolOnConnectFailure) {
974   // Alternate-protocol job will fail before creating a QUIC session.
975   StaticSocketDataProvider quic_data(nullptr, 0, nullptr, 0);
976   quic_data.set_connect_data(MockConnect(SYNCHRONOUS,
977                                          ERR_INTERNET_DISCONNECTED));
978   socket_factory_.AddSocketDataProvider(&quic_data);
979
980   // Main job which will succeed even though the alternate job fails.
981   MockRead http_reads[] = {
982     MockRead("HTTP/1.1 200 OK\r\n\r\n"),
983     MockRead("hello from http"),
984     MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
985     MockRead(ASYNC, OK)
986   };
987
988   StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
989                                      nullptr, 0);
990   socket_factory_.AddSocketDataProvider(&http_data);
991
992   CreateSessionWithNextProtos();
993   AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
994   SendRequestAndExpectHttpResponse("hello from http");
995
996   ExpectBrokenAlternateProtocolMapping();
997 }
998
999 TEST_P(QuicNetworkTransactionTest, ConnectionCloseDuringConnect) {
1000   MockQuicData mock_quic_data;
1001   mock_quic_data.AddRead(ConstructConnectionClosePacket(1));
1002   mock_quic_data.AddWrite(
1003       ConstructRequestHeadersPacket(1, kClientDataStreamId1, true, true,
1004                                     GetRequestHeaders("GET", "http", "/")));
1005   mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
1006   mock_quic_data.AddDelayedSocketDataToFactory(&socket_factory_, 0);
1007
1008   // When the QUIC connection fails, we will try the request again over HTTP.
1009   MockRead http_reads[] = {
1010     MockRead("HTTP/1.1 200 OK\r\n"),
1011     MockRead(kQuicAlternateProtocolHttpHeader),
1012     MockRead("hello world"),
1013     MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
1014     MockRead(ASYNC, OK)
1015   };
1016
1017   StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
1018                                      nullptr, 0);
1019   socket_factory_.AddSocketDataProvider(&http_data);
1020
1021   // In order for a new QUIC session to be established via alternate-protocol
1022   // without racing an HTTP connection, we need the host resolution to happen
1023   // synchronously.
1024   host_resolver_.set_synchronous_mode(true);
1025   host_resolver_.rules()->AddIPLiteralRule("www.google.com", "192.168.0.1", "");
1026   HostResolver::RequestInfo info(HostPortPair("www.google.com", 80));
1027   AddressList address;
1028   host_resolver_.Resolve(info,
1029                          DEFAULT_PRIORITY,
1030                          &address,
1031                          CompletionCallback(),
1032                          nullptr,
1033                          net_log_.bound());
1034
1035   CreateSessionWithNextProtos();
1036   AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
1037   SendRequestAndExpectHttpResponse("hello world");
1038 }
1039
1040 }  // namespace test
1041 }  // namespace net