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