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 "base/basictypes.h"
      6 #include "base/compiler_specific.h"
      7 #include "base/memory/scoped_ptr.h"
      8 #include "base/stl_util.h"
      9 #include "net/base/capturing_net_log.h"
     10 #include "net/base/net_log_unittest.h"
     11 #include "net/base/test_completion_callback.h"
     12 #include "net/cert/mock_cert_verifier.h"
     13 #include "net/dns/mock_host_resolver.h"
     14 #include "net/http/http_auth_handler_factory.h"
     15 #include "net/http/http_network_session.h"
     16 #include "net/http/http_network_transaction.h"
     17 #include "net/http/http_server_properties_impl.h"
     18 #include "net/http/http_stream.h"
     19 #include "net/http/http_stream_factory.h"
     20 #include "net/http/http_transaction_unittest.h"
     21 #include "net/http/transport_security_state.h"
     22 #include "net/proxy/proxy_config_service_fixed.h"
     23 #include "net/proxy/proxy_resolver.h"
     24 #include "net/proxy/proxy_service.h"
     25 #include "net/quic/crypto/quic_decrypter.h"
     26 #include "net/quic/crypto/quic_encrypter.h"
     27 #include "net/quic/quic_framer.h"
     28 #include "net/quic/test_tools/crypto_test_utils.h"
     29 #include "net/quic/test_tools/mock_clock.h"
     30 #include "net/quic/test_tools/mock_crypto_client_stream_factory.h"
     31 #include "net/quic/test_tools/mock_random.h"
     32 #include "net/quic/test_tools/quic_test_utils.h"
     33 #include "net/socket/client_socket_factory.h"
     34 #include "net/socket/mock_client_socket_pool_manager.h"
     35 #include "net/socket/socket_test_util.h"
     36 #include "net/socket/ssl_client_socket.h"
     37 #include "net/spdy/spdy_frame_builder.h"
     38 #include "net/spdy/spdy_framer.h"
     39 #include "net/ssl/ssl_config_service_defaults.h"
     40 #include "testing/gtest/include/gtest/gtest.h"
     41 #include "testing/platform_test.h"
     42 
     43 //-----------------------------------------------------------------------------
     44 
     45 namespace {
     46 
     47 // This is the expected return from a current server advertising QUIC.
     48 static const char kQuicAlternateProtocolHttpHeader[] =
     49     "Alternate-Protocol: 80:quic\r\n\r\n";
     50 static const char kQuicAlternateProtocolHttpsHeader[] =
     51     "Alternate-Protocol: 443:quic\r\n\r\n";
     52 }  // namespace
     53 
     54 namespace net {
     55 namespace test {
     56 
     57 class QuicNetworkTransactionTest : public PlatformTest {
     58  protected:
     59   QuicNetworkTransactionTest()
     60       : clock_(new MockClock),
     61         ssl_config_service_(new SSLConfigServiceDefaults),
     62         proxy_service_(ProxyService::CreateDirect()),
     63         compressor_(new QuicSpdyCompressor()),
     64         auth_handler_factory_(
     65             HttpAuthHandlerFactory::CreateDefault(&host_resolver_)),
     66         hanging_data_(NULL, 0, NULL, 0) {
     67     request_.method = "GET";
     68     request_.url = GURL("http://www.google.com/");
     69     request_.load_flags = 0;
     70   }
     71 
     72   virtual void SetUp() {
     73     NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
     74     base::MessageLoop::current()->RunUntilIdle();
     75   }
     76 
     77   virtual void TearDown() {
     78     NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
     79     // Empty the current queue.
     80     base::MessageLoop::current()->RunUntilIdle();
     81     PlatformTest::TearDown();
     82     NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
     83     base::MessageLoop::current()->RunUntilIdle();
     84     HttpStreamFactory::set_use_alternate_protocols(false);
     85     HttpStreamFactory::SetNextProtos(std::vector<NextProto>());
     86   }
     87 
     88   scoped_ptr<QuicEncryptedPacket> ConstructRstPacket(
     89       QuicPacketSequenceNumber num,
     90       QuicStreamId stream_id) {
     91     QuicPacketHeader header;
     92     header.public_header.guid = 0xDEADBEEF;
     93     header.public_header.reset_flag = false;
     94     header.public_header.version_flag = false;
     95     header.packet_sequence_number = num;
     96     header.entropy_flag = false;
     97     header.fec_flag = false;
     98     header.fec_group = 0;
     99 
    100     QuicRstStreamFrame rst(stream_id, QUIC_STREAM_NO_ERROR);
    101     return scoped_ptr<QuicEncryptedPacket>(
    102         ConstructPacket(header, QuicFrame(&rst)));
    103   }
    104 
    105   scoped_ptr<QuicEncryptedPacket> ConstructConnectionClosePacket(
    106       QuicPacketSequenceNumber num) {
    107     QuicPacketHeader header;
    108     header.public_header.guid = 0xDEADBEEF;
    109     header.public_header.reset_flag = false;
    110     header.public_header.version_flag = false;
    111     header.packet_sequence_number = num;
    112     header.entropy_flag = false;
    113     header.fec_flag = false;
    114     header.fec_group = 0;
    115 
    116     QuicAckFrame ack_frame(0, QuicTime::Zero(), 0);
    117     QuicConnectionCloseFrame close;
    118     close.error_code = QUIC_CRYPTO_VERSION_NOT_SUPPORTED;
    119     close.error_details = "Time to panic!";
    120     close.ack_frame = ack_frame;
    121     return scoped_ptr<QuicEncryptedPacket>(
    122         ConstructPacket(header, QuicFrame(&close)));
    123   }
    124 
    125   scoped_ptr<QuicEncryptedPacket> ConstructAckPacket(
    126       QuicPacketSequenceNumber largest_received,
    127       QuicPacketSequenceNumber least_unacked) {
    128     QuicPacketHeader header;
    129     header.public_header.guid = 0xDEADBEEF;
    130     header.public_header.reset_flag = false;
    131     header.public_header.version_flag = false;
    132     header.packet_sequence_number = 2;
    133     header.entropy_flag = false;
    134     header.fec_flag = false;
    135     header.fec_group = 0;
    136 
    137     QuicAckFrame ack(largest_received, QuicTime::Zero(), least_unacked);
    138 
    139     QuicCongestionFeedbackFrame feedback;
    140     feedback.type = kTCP;
    141     feedback.tcp.accumulated_number_of_lost_packets = 0;
    142     feedback.tcp.receive_window = 256000;
    143 
    144     QuicFramer framer(QuicVersionMax(), QuicTime::Zero(), false);
    145     QuicFrames frames;
    146     frames.push_back(QuicFrame(&ack));
    147     frames.push_back(QuicFrame(&feedback));
    148     scoped_ptr<QuicPacket> packet(
    149         framer.BuildUnsizedDataPacket(header, frames).packet);
    150     return scoped_ptr<QuicEncryptedPacket>(framer.EncryptPacket(
    151         ENCRYPTION_NONE, header.packet_sequence_number, *packet));
    152   }
    153 
    154   std::string GetRequestString(const std::string& method,
    155                                const std::string& scheme,
    156                                const std::string& path) {
    157     SpdyHeaderBlock headers;
    158     headers[":method"] = method;
    159     headers[":host"] = "www.google.com";
    160     headers[":path"] = path;
    161     headers[":scheme"] = scheme;
    162     headers[":version"] = "HTTP/1.1";
    163     return SerializeHeaderBlock(headers);
    164   }
    165 
    166   std::string GetResponseString(const std::string& status,
    167                                 const std::string& body) {
    168     SpdyHeaderBlock headers;
    169     headers[":status"] = status;
    170     headers[":version"] = "HTTP/1.1";
    171     headers["content-type"] = "text/plain";
    172     return compressor_->CompressHeaders(headers) + body;
    173   }
    174 
    175   std::string SerializeHeaderBlock(const SpdyHeaderBlock& headers) {
    176     QuicSpdyCompressor compressor;
    177     return compressor.CompressHeaders(headers);
    178   }
    179 
    180   // Returns a newly created packet to send kData on stream 1.
    181   QuicEncryptedPacket* ConstructDataPacket(
    182       QuicPacketSequenceNumber sequence_number,
    183       QuicStreamId stream_id,
    184       bool should_include_version,
    185       bool fin,
    186       QuicStreamOffset offset,
    187       base::StringPiece data) {
    188     InitializeHeader(sequence_number, should_include_version);
    189     QuicStreamFrame frame(stream_id, fin, offset, data);
    190     return ConstructPacket(header_, QuicFrame(&frame)).release();
    191   }
    192 
    193   scoped_ptr<QuicEncryptedPacket> ConstructPacket(
    194       const QuicPacketHeader& header,
    195       const QuicFrame& frame) {
    196     QuicFramer framer(QuicVersionMax(), QuicTime::Zero(), false);
    197     QuicFrames frames;
    198     frames.push_back(frame);
    199     scoped_ptr<QuicPacket> packet(
    200         framer.BuildUnsizedDataPacket(header, frames).packet);
    201     return scoped_ptr<QuicEncryptedPacket>(framer.EncryptPacket(
    202         ENCRYPTION_NONE, header.packet_sequence_number, *packet));
    203   }
    204 
    205   void InitializeHeader(QuicPacketSequenceNumber sequence_number,
    206                         bool should_include_version) {
    207     header_.public_header.guid = random_generator_.RandUint64();
    208     header_.public_header.reset_flag = false;
    209     header_.public_header.version_flag = should_include_version;
    210     header_.packet_sequence_number = sequence_number;
    211     header_.fec_group = 0;
    212     header_.entropy_flag = false;
    213     header_.fec_flag = false;
    214   }
    215 
    216   void CreateSession() {
    217     CreateSessionWithFactory(&socket_factory_);
    218   }
    219 
    220   void CreateSessionWithFactory(ClientSocketFactory* socket_factory) {
    221     params_.enable_quic = true;
    222     params_.quic_clock = clock_;
    223     params_.quic_random = &random_generator_;
    224     params_.client_socket_factory = socket_factory;
    225     params_.quic_crypto_client_stream_factory = &crypto_client_stream_factory_;
    226     params_.host_resolver = &host_resolver_;
    227     params_.cert_verifier = &cert_verifier_;
    228     params_.transport_security_state = &transport_security_state_;
    229     params_.proxy_service = proxy_service_.get();
    230     params_.ssl_config_service = ssl_config_service_.get();
    231     params_.http_auth_handler_factory = auth_handler_factory_.get();
    232     params_.http_server_properties = http_server_properties.GetWeakPtr();
    233 
    234     session_ = new HttpNetworkSession(params_);
    235   }
    236 
    237   void CheckWasQuicResponse(const scoped_ptr<HttpNetworkTransaction>& trans) {
    238     const HttpResponseInfo* response = trans->GetResponseInfo();
    239     ASSERT_TRUE(response != NULL);
    240     ASSERT_TRUE(response->headers.get() != NULL);
    241     EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
    242     EXPECT_TRUE(response->was_fetched_via_spdy);
    243     EXPECT_TRUE(response->was_npn_negotiated);
    244     EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_QUIC1_SPDY3,
    245               response->connection_info);
    246   }
    247 
    248   void CheckWasHttpResponse(const scoped_ptr<HttpNetworkTransaction>& trans) {
    249     const HttpResponseInfo* response = trans->GetResponseInfo();
    250     ASSERT_TRUE(response != NULL);
    251     ASSERT_TRUE(response->headers.get() != NULL);
    252     EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
    253     EXPECT_FALSE(response->was_fetched_via_spdy);
    254     EXPECT_FALSE(response->was_npn_negotiated);
    255     EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP1,
    256               response->connection_info);
    257   }
    258 
    259   void CheckResponseData(HttpNetworkTransaction* trans,
    260                          const std::string& expected) {
    261     std::string response_data;
    262     ASSERT_EQ(OK, ReadTransaction(trans, &response_data));
    263     EXPECT_EQ(expected, response_data);
    264   }
    265 
    266   void RunTransaction(HttpNetworkTransaction* trans) {
    267     TestCompletionCallback callback;
    268     int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
    269     EXPECT_EQ(ERR_IO_PENDING, rv);
    270     EXPECT_EQ(OK, callback.WaitForResult());
    271   }
    272 
    273   void SendRequestAndExpectHttpResponse(const std::string& expected) {
    274     scoped_ptr<HttpNetworkTransaction> trans(
    275         new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
    276     RunTransaction(trans.get());
    277     CheckWasHttpResponse(trans);
    278     CheckResponseData(trans.get(), expected);
    279   }
    280 
    281   void SendRequestAndExpectQuicResponse(const std::string& expected) {
    282     scoped_ptr<HttpNetworkTransaction> trans(
    283         new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
    284     RunTransaction(trans.get());
    285     CheckWasQuicResponse(trans);
    286     CheckResponseData(trans.get(), expected);
    287   }
    288 
    289   void AddQuicAlternateProtocolMapping(
    290       MockCryptoClientStream::HandshakeMode handshake_mode) {
    291     crypto_client_stream_factory_.set_handshake_mode(handshake_mode);
    292     session_->http_server_properties()->SetAlternateProtocol(
    293         HostPortPair::FromURL(request_.url), 80, QUIC);
    294   }
    295 
    296   void ExpectBrokenAlternateProtocolMapping() {
    297     ASSERT_TRUE(session_->http_server_properties()->HasAlternateProtocol(
    298         HostPortPair::FromURL(request_.url)));
    299     const PortAlternateProtocolPair alternate =
    300         session_->http_server_properties()->GetAlternateProtocol(
    301             HostPortPair::FromURL(request_.url));
    302     EXPECT_EQ(ALTERNATE_PROTOCOL_BROKEN, alternate.protocol);
    303   }
    304 
    305   void AddHangingNonAlternateProtocolSocketData() {
    306     MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
    307     hanging_data_.set_connect_data(hanging_connect);
    308     socket_factory_.AddSocketDataProvider(&hanging_data_);
    309   }
    310 
    311   QuicPacketHeader header_;
    312   scoped_refptr<HttpNetworkSession> session_;
    313   MockClientSocketFactory socket_factory_;
    314   MockCryptoClientStreamFactory crypto_client_stream_factory_;
    315   MockClock* clock_;  // Owned by QuicStreamFactory after CreateSession.
    316   MockHostResolver host_resolver_;
    317   MockCertVerifier cert_verifier_;
    318   TransportSecurityState transport_security_state_;
    319   scoped_refptr<SSLConfigServiceDefaults> ssl_config_service_;
    320   scoped_ptr<ProxyService> proxy_service_;
    321   scoped_ptr<QuicSpdyCompressor> compressor_;
    322   scoped_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
    323   MockRandom random_generator_;
    324   HttpServerPropertiesImpl http_server_properties;
    325   HttpNetworkSession::Params params_;
    326   HttpRequestInfo request_;
    327   CapturingBoundNetLog net_log_;
    328   StaticSocketDataProvider hanging_data_;
    329 };
    330 
    331 TEST_F(QuicNetworkTransactionTest, ForceQuic) {
    332   params_.origin_to_force_quic_on =
    333       HostPortPair::FromString("www.google.com:80");
    334 
    335   QuicStreamId stream_id = 3;
    336   scoped_ptr<QuicEncryptedPacket> req(
    337       ConstructDataPacket(1, stream_id, true, true, 0,
    338                           GetRequestString("GET", "http", "/")));
    339   scoped_ptr<QuicEncryptedPacket> ack(ConstructAckPacket(1, 0));
    340 
    341   MockWrite quic_writes[] = {
    342     MockWrite(SYNCHRONOUS, req->data(), req->length()),
    343     MockWrite(SYNCHRONOUS, ack->data(), ack->length()),
    344   };
    345 
    346   scoped_ptr<QuicEncryptedPacket> resp(
    347       ConstructDataPacket(
    348           1, stream_id, false, true, 0, GetResponseString("200 OK", "hello!")));
    349   MockRead quic_reads[] = {
    350     MockRead(SYNCHRONOUS, resp->data(), resp->length()),
    351     MockRead(ASYNC, OK),  // EOF
    352   };
    353 
    354   DelayedSocketData quic_data(
    355       1,  // wait for one write to finish before reading.
    356       quic_reads, arraysize(quic_reads),
    357       quic_writes, arraysize(quic_writes));
    358 
    359   socket_factory_.AddSocketDataProvider(&quic_data);
    360 
    361   // The non-alternate protocol job needs to hang in order to guarantee that
    362   // the alternate-protocol job will "win".
    363   AddHangingNonAlternateProtocolSocketData();
    364 
    365   CreateSession();
    366 
    367   SendRequestAndExpectQuicResponse("hello!");
    368 
    369   // Check that the NetLog was filled reasonably.
    370   net::CapturingNetLog::CapturedEntryList entries;
    371   net_log_.GetEntries(&entries);
    372   EXPECT_LT(0u, entries.size());
    373 
    374   // Check that we logged a QUIC_SESSION_PACKET_RECEIVED.
    375   int pos = net::ExpectLogContainsSomewhere(
    376       entries, 0,
    377       net::NetLog::TYPE_QUIC_SESSION_PACKET_RECEIVED,
    378       net::NetLog::PHASE_NONE);
    379   EXPECT_LT(0, pos);
    380 
    381   // ... and also a TYPE_QUIC_SESSION_PACKET_HEADER_RECEIVED.
    382   pos = net::ExpectLogContainsSomewhere(
    383       entries, 0,
    384       net::NetLog::TYPE_QUIC_SESSION_PACKET_HEADER_RECEIVED,
    385       net::NetLog::PHASE_NONE);
    386   EXPECT_LT(0, pos);
    387 
    388   std::string packet_sequence_number;
    389   ASSERT_TRUE(entries[pos].GetStringValue(
    390       "packet_sequence_number", &packet_sequence_number));
    391   EXPECT_EQ("1", packet_sequence_number);
    392 
    393   // ... and also a QUIC_SESSION_STREAM_FRAME_RECEIVED.
    394   pos = net::ExpectLogContainsSomewhere(
    395       entries, 0,
    396       net::NetLog::TYPE_QUIC_SESSION_STREAM_FRAME_RECEIVED,
    397       net::NetLog::PHASE_NONE);
    398   EXPECT_LT(0, pos);
    399 
    400   int log_stream_id;
    401   ASSERT_TRUE(entries[pos].GetIntegerValue("stream_id", &log_stream_id));
    402   EXPECT_EQ(stream_id, static_cast<QuicStreamId>(log_stream_id));
    403 }
    404 
    405 TEST_F(QuicNetworkTransactionTest, ForceQuicWithErrorConnecting) {
    406   params_.origin_to_force_quic_on =
    407       HostPortPair::FromString("www.google.com:80");
    408 
    409   MockRead quic_reads[] = {
    410     MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
    411   };
    412   StaticSocketDataProvider quic_data(quic_reads, arraysize(quic_reads),
    413                                      NULL, 0);
    414   socket_factory_.AddSocketDataProvider(&quic_data);
    415 
    416   CreateSession();
    417 
    418   scoped_ptr<HttpNetworkTransaction> trans(
    419       new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
    420   TestCompletionCallback callback;
    421   int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
    422   EXPECT_EQ(ERR_IO_PENDING, rv);
    423   EXPECT_EQ(ERR_CONNECTION_CLOSED, callback.WaitForResult());
    424 }
    425 
    426 TEST_F(QuicNetworkTransactionTest, DoNotForceQuicForHttps) {
    427   // Attempt to "force" quic on 443, which will not be honored.
    428   params_.origin_to_force_quic_on =
    429       HostPortPair::FromString("www.google.com:443");
    430 
    431   MockRead http_reads[] = {
    432     MockRead("HTTP/1.1 200 OK\r\n\r\n"),
    433     MockRead("hello world"),
    434     MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
    435     MockRead(ASYNC, OK)
    436   };
    437 
    438   StaticSocketDataProvider data(http_reads, arraysize(http_reads), NULL, 0);
    439   socket_factory_.AddSocketDataProvider(&data);
    440   SSLSocketDataProvider ssl(ASYNC, OK);
    441   socket_factory_.AddSSLSocketDataProvider(&ssl);
    442 
    443   CreateSession();
    444 
    445   SendRequestAndExpectHttpResponse("hello world");
    446 }
    447 
    448 TEST_F(QuicNetworkTransactionTest, UseAlternateProtocolForQuic) {
    449   HttpStreamFactory::EnableNpnSpdy();  // Enables QUIC too.
    450 
    451   MockRead http_reads[] = {
    452     MockRead("HTTP/1.1 200 OK\r\n"),
    453     MockRead(kQuicAlternateProtocolHttpHeader),
    454     MockRead("hello world"),
    455     MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
    456     MockRead(ASYNC, OK)
    457   };
    458 
    459   StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
    460                                      NULL, 0);
    461   socket_factory_.AddSocketDataProvider(&http_data);
    462 
    463   scoped_ptr<QuicEncryptedPacket> req(
    464       ConstructDataPacket(1, 3, true, true, 0,
    465                           GetRequestString("GET", "http", "/")));
    466   scoped_ptr<QuicEncryptedPacket> ack(ConstructAckPacket(1, 0));
    467 
    468   MockWrite quic_writes[] = {
    469     MockWrite(SYNCHRONOUS, req->data(), req->length()),
    470     MockWrite(SYNCHRONOUS, ack->data(), ack->length()),
    471   };
    472 
    473   scoped_ptr<QuicEncryptedPacket> resp(
    474       ConstructDataPacket(
    475           1, 3, false, true, 0, GetResponseString("200 OK", "hello!")));
    476   MockRead quic_reads[] = {
    477     MockRead(SYNCHRONOUS, resp->data(), resp->length()),
    478     MockRead(ASYNC, OK),  // EOF
    479   };
    480 
    481   DelayedSocketData quic_data(
    482       1,  // wait for one write to finish before reading.
    483       quic_reads, arraysize(quic_reads),
    484       quic_writes, arraysize(quic_writes));
    485 
    486   socket_factory_.AddSocketDataProvider(&quic_data);
    487 
    488   // The non-alternate protocol job needs to hang in order to guarantee that
    489   // the alternate-protocol job will "win".
    490   AddHangingNonAlternateProtocolSocketData();
    491 
    492   CreateSession();
    493 
    494   SendRequestAndExpectHttpResponse("hello world");
    495   SendRequestAndExpectQuicResponse("hello!");
    496 }
    497 
    498 TEST_F(QuicNetworkTransactionTest, UseAlternateProtocolForQuicForHttps) {
    499   params_.origin_to_force_quic_on =
    500       HostPortPair::FromString("www.google.com:443");
    501   params_.enable_quic_https = true;
    502   HttpStreamFactory::EnableNpnSpdy();  // Enables QUIC too.
    503 
    504   MockRead http_reads[] = {
    505     MockRead("HTTP/1.1 200 OK\r\n"),
    506     MockRead(kQuicAlternateProtocolHttpsHeader),
    507     MockRead("hello world"),
    508     MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
    509     MockRead(ASYNC, OK)
    510   };
    511 
    512   StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
    513                                      NULL, 0);
    514   socket_factory_.AddSocketDataProvider(&http_data);
    515 
    516   scoped_ptr<QuicEncryptedPacket> req(
    517       ConstructDataPacket(1, 3, true, true, 0,
    518                           GetRequestString("GET", "https", "/")));
    519   scoped_ptr<QuicEncryptedPacket> ack(ConstructAckPacket(1, 0));
    520 
    521   MockWrite quic_writes[] = {
    522     MockWrite(SYNCHRONOUS, req->data(), req->length()),
    523     MockWrite(SYNCHRONOUS, ack->data(), ack->length()),
    524   };
    525 
    526   scoped_ptr<QuicEncryptedPacket> resp(
    527       ConstructDataPacket(
    528           1, 3, false, true, 0, GetResponseString("200 OK", "hello!")));
    529   MockRead quic_reads[] = {
    530     MockRead(SYNCHRONOUS, resp->data(), resp->length()),
    531     MockRead(ASYNC, OK),  // EOF
    532   };
    533 
    534   DelayedSocketData quic_data(
    535       1,  // wait for one write to finish before reading.
    536       quic_reads, arraysize(quic_reads),
    537       quic_writes, arraysize(quic_writes));
    538 
    539   socket_factory_.AddSocketDataProvider(&quic_data);
    540 
    541   // The non-alternate protocol job needs to hang in order to guarantee that
    542   // the alternate-protocol job will "win".
    543   AddHangingNonAlternateProtocolSocketData();
    544 
    545   CreateSession();
    546 
    547   // TODO(rtenneti): Test QUIC over HTTPS, GetSSLInfo().
    548   SendRequestAndExpectHttpResponse("hello world");
    549 }
    550 
    551 TEST_F(QuicNetworkTransactionTest, HungAlternateProtocol) {
    552   HttpStreamFactory::EnableNpnSpdy();  // Enables QUIC too.
    553   crypto_client_stream_factory_.set_handshake_mode(
    554       MockCryptoClientStream::COLD_START);
    555 
    556   MockWrite http_writes[] = {
    557     MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
    558     MockWrite(SYNCHRONOUS, 1, "Host: www.google.com\r\n"),
    559     MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")
    560   };
    561 
    562   MockRead http_reads[] = {
    563     MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
    564     MockRead(SYNCHRONOUS, 4, kQuicAlternateProtocolHttpHeader),
    565     MockRead(SYNCHRONOUS, 5, "hello world"),
    566     MockRead(SYNCHRONOUS, OK, 6)
    567   };
    568 
    569   DeterministicMockClientSocketFactory socket_factory;
    570 
    571   DeterministicSocketData http_data(http_reads, arraysize(http_reads),
    572                                     http_writes, arraysize(http_writes));
    573   socket_factory.AddSocketDataProvider(&http_data);
    574 
    575   // The QUIC transaction will not be allowed to complete.
    576   MockWrite quic_writes[] = {
    577     MockWrite(ASYNC, ERR_IO_PENDING, 0)
    578   };
    579   MockRead quic_reads[] = {
    580     MockRead(ASYNC, ERR_IO_PENDING, 1),
    581   };
    582   DeterministicSocketData quic_data(quic_reads, arraysize(quic_reads),
    583                                     quic_writes, arraysize(quic_writes));
    584   socket_factory.AddSocketDataProvider(&quic_data);
    585 
    586   // The HTTP transaction will complete.
    587   DeterministicSocketData http_data2(http_reads, arraysize(http_reads),
    588                                      http_writes, arraysize(http_writes));
    589   socket_factory.AddSocketDataProvider(&http_data2);
    590 
    591   CreateSessionWithFactory(&socket_factory);
    592 
    593   // Run the first request.
    594   http_data.StopAfter(arraysize(http_reads) + arraysize(http_writes));
    595   SendRequestAndExpectHttpResponse("hello world");
    596   ASSERT_TRUE(http_data.at_read_eof());
    597   ASSERT_TRUE(http_data.at_write_eof());
    598 
    599   // Now run the second request in which the QUIC socket hangs,
    600   // and verify the the transaction continues over HTTP.
    601   http_data2.StopAfter(arraysize(http_reads) + arraysize(http_writes));
    602   SendRequestAndExpectHttpResponse("hello world");
    603 
    604   ASSERT_TRUE(http_data2.at_read_eof());
    605   ASSERT_TRUE(http_data2.at_write_eof());
    606   ASSERT_TRUE(!quic_data.at_read_eof());
    607   ASSERT_TRUE(!quic_data.at_write_eof());
    608 }
    609 
    610 TEST_F(QuicNetworkTransactionTest, ZeroRTTWithHttpRace) {
    611   HttpStreamFactory::EnableNpnSpdy();  // Enables QUIC too.
    612 
    613   scoped_ptr<QuicEncryptedPacket> req(
    614       ConstructDataPacket(1, 3, true, true, 0,
    615                           GetRequestString("GET", "http", "/")));
    616   scoped_ptr<QuicEncryptedPacket> ack(ConstructAckPacket(1, 0));
    617 
    618   MockWrite quic_writes[] = {
    619     MockWrite(SYNCHRONOUS, req->data(), req->length()),
    620     MockWrite(SYNCHRONOUS, ack->data(), ack->length()),
    621   };
    622 
    623   scoped_ptr<QuicEncryptedPacket> resp(
    624       ConstructDataPacket(
    625           1, 3, false, true, 0, GetResponseString("200 OK", "hello!")));
    626   MockRead quic_reads[] = {
    627     MockRead(SYNCHRONOUS, resp->data(), resp->length()),
    628     MockRead(ASYNC, OK),  // EOF
    629   };
    630 
    631   DelayedSocketData quic_data(
    632       1,  // wait for one write to finish before reading.
    633       quic_reads, arraysize(quic_reads),
    634       quic_writes, arraysize(quic_writes));
    635 
    636   socket_factory_.AddSocketDataProvider(&quic_data);
    637 
    638   // The non-alternate protocol job needs to hang in order to guarantee that
    639   // the alternate-protocol job will "win".
    640   AddHangingNonAlternateProtocolSocketData();
    641 
    642   CreateSession();
    643   AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
    644   SendRequestAndExpectQuicResponse("hello!");
    645 }
    646 
    647 TEST_F(QuicNetworkTransactionTest, ZeroRTTWithNoHttpRace) {
    648   HttpStreamFactory::EnableNpnSpdy();  // Enables QUIC too.
    649 
    650   scoped_ptr<QuicEncryptedPacket> req(
    651       ConstructDataPacket(1, 3, true, true, 0,
    652                           GetRequestString("GET", "http", "/")));
    653   scoped_ptr<QuicEncryptedPacket> ack(ConstructAckPacket(1, 0));
    654 
    655   MockWrite quic_writes[] = {
    656     MockWrite(SYNCHRONOUS, req->data(), req->length()),
    657     MockWrite(SYNCHRONOUS, ack->data(), ack->length()),
    658   };
    659 
    660   scoped_ptr<QuicEncryptedPacket> resp(
    661       ConstructDataPacket(
    662           1, 3, false, true, 0, GetResponseString("200 OK", "hello!")));
    663   MockRead quic_reads[] = {
    664     MockRead(SYNCHRONOUS, resp->data(), resp->length()),
    665     MockRead(ASYNC, OK),  // EOF
    666   };
    667 
    668   DelayedSocketData quic_data(
    669       1,  // wait for one write to finish before reading.
    670       quic_reads, arraysize(quic_reads),
    671       quic_writes, arraysize(quic_writes));
    672 
    673   socket_factory_.AddSocketDataProvider(&quic_data);
    674 
    675   // In order for a new QUIC session to be established via alternate-protocol
    676   // without racing an HTTP connection, we need the host resolution to happen
    677   // synchronously.
    678   host_resolver_.set_synchronous_mode(true);
    679   host_resolver_.rules()->AddIPLiteralRule("www.google.com", "192.168.0.1", "");
    680   HostResolver::RequestInfo info(HostPortPair("www.google.com", 80));
    681   AddressList address;
    682   host_resolver_.Resolve(info, &address, CompletionCallback(), NULL,
    683                          net_log_.bound());
    684 
    685   CreateSession();
    686   AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
    687   SendRequestAndExpectQuicResponse("hello!");
    688 }
    689 
    690 TEST_F(QuicNetworkTransactionTest, BrokenAlternateProtocol) {
    691   HttpStreamFactory::EnableNpnSpdy();  // Enables QUIC too.
    692 
    693   // Alternate-protocol job
    694   scoped_ptr<QuicEncryptedPacket> close(ConstructConnectionClosePacket(1));
    695   MockRead quic_reads[] = {
    696     MockRead(ASYNC, close->data(), close->length()),
    697     MockRead(ASYNC, OK),  // EOF
    698   };
    699   StaticSocketDataProvider quic_data(quic_reads, arraysize(quic_reads),
    700                                      NULL, 0);
    701   socket_factory_.AddSocketDataProvider(&quic_data);
    702 
    703   // Main job which will succeed even though the alternate job fails.
    704   MockRead http_reads[] = {
    705     MockRead("HTTP/1.1 200 OK\r\n\r\n"),
    706     MockRead("hello from http"),
    707     MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
    708     MockRead(ASYNC, OK)
    709   };
    710 
    711   StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
    712                                      NULL, 0);
    713   socket_factory_.AddSocketDataProvider(&http_data);
    714 
    715   CreateSession();
    716   AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
    717   SendRequestAndExpectHttpResponse("hello from http");
    718   ExpectBrokenAlternateProtocolMapping();
    719 }
    720 
    721 TEST_F(QuicNetworkTransactionTest, BrokenAlternateProtocolReadError) {
    722   HttpStreamFactory::EnableNpnSpdy();  // Enables QUIC too.
    723 
    724   // Alternate-protocol job
    725   MockRead quic_reads[] = {
    726     MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
    727   };
    728   StaticSocketDataProvider quic_data(quic_reads, arraysize(quic_reads),
    729                                      NULL, 0);
    730   socket_factory_.AddSocketDataProvider(&quic_data);
    731 
    732   // Main job which will succeed even though the alternate job fails.
    733   MockRead http_reads[] = {
    734     MockRead("HTTP/1.1 200 OK\r\n\r\n"),
    735     MockRead("hello from http"),
    736     MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
    737     MockRead(ASYNC, OK)
    738   };
    739 
    740   StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
    741                                      NULL, 0);
    742   socket_factory_.AddSocketDataProvider(&http_data);
    743 
    744   CreateSession();
    745 
    746   AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
    747   SendRequestAndExpectHttpResponse("hello from http");
    748   ExpectBrokenAlternateProtocolMapping();
    749 }
    750 
    751 }  // namespace test
    752 }  // namespace net
    753