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