This source file includes following definitions.
- AddRead
- AddRead
- AddWrite
- AddDelayedSocketDataToFactory
- hanging_data_
- SetUp
- TearDown
- ConstructRstPacket
- ConstructConnectionClosePacket
- ConstructAckPacket
- GetRequestHeaders
- GetResponseHeaders
- ConstructDataPacket
- ConstructRequestHeadersPacket
- ConstructResponseHeadersPacket
- CreateSession
- CreateSessionWithFactory
- CheckWasQuicResponse
- CheckWasHttpResponse
- CheckResponseData
- RunTransaction
- SendRequestAndExpectHttpResponse
- SendRequestAndExpectQuicResponse
- AddQuicAlternateProtocolMapping
- ExpectBrokenAlternateProtocolMapping
- AddHangingNonAlternateProtocolSocketData
- TEST_P
- TEST_P
- TEST_P
- TEST_P
- TEST_P
- TEST_P
- TEST_P
- TEST_P
- TEST_P
- TEST_P
- TEST_P
- TEST_P
- TEST_P
- TEST_P
- TEST_P
#include <vector>
#include "base/basictypes.h"
#include "base/compiler_specific.h"
#include "base/memory/scoped_ptr.h"
#include "base/stl_util.h"
#include "net/base/capturing_net_log.h"
#include "net/base/net_log_unittest.h"
#include "net/base/test_completion_callback.h"
#include "net/cert/mock_cert_verifier.h"
#include "net/dns/mock_host_resolver.h"
#include "net/http/http_auth_handler_factory.h"
#include "net/http/http_network_session.h"
#include "net/http/http_network_transaction.h"
#include "net/http/http_server_properties_impl.h"
#include "net/http/http_stream.h"
#include "net/http/http_stream_factory.h"
#include "net/http/http_transaction_unittest.h"
#include "net/http/transport_security_state.h"
#include "net/proxy/proxy_config_service_fixed.h"
#include "net/proxy/proxy_resolver.h"
#include "net/proxy/proxy_service.h"
#include "net/quic/crypto/quic_decrypter.h"
#include "net/quic/crypto/quic_encrypter.h"
#include "net/quic/quic_framer.h"
#include "net/quic/quic_http_utils.h"
#include "net/quic/test_tools/crypto_test_utils.h"
#include "net/quic/test_tools/mock_clock.h"
#include "net/quic/test_tools/mock_crypto_client_stream_factory.h"
#include "net/quic/test_tools/mock_random.h"
#include "net/quic/test_tools/quic_test_packet_maker.h"
#include "net/quic/test_tools/quic_test_utils.h"
#include "net/socket/client_socket_factory.h"
#include "net/socket/mock_client_socket_pool_manager.h"
#include "net/socket/socket_test_util.h"
#include "net/socket/ssl_client_socket.h"
#include "net/spdy/spdy_frame_builder.h"
#include "net/spdy/spdy_framer.h"
#include "net/ssl/ssl_config_service_defaults.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "testing/platform_test.h"
namespace {
static const char kQuicAlternateProtocolHttpHeader[] =
    "Alternate-Protocol: 80:quic\r\n\r\n";
static const char kQuicAlternateProtocolHttpsHeader[] =
    "Alternate-Protocol: 443:quic\r\n\r\n";
const net::QuicStreamId kStreamId5 = 5;
}  
namespace net {
namespace test {
class MockQuicData {
 public:
  ~MockQuicData() {
    STLDeleteElements(&packets_);
  }
  void AddRead(scoped_ptr<QuicEncryptedPacket> packet) {
    reads_.push_back(MockRead(SYNCHRONOUS, packet->data(), packet->length(),
                              sequence_number_++));
    packets_.push_back(packet.release());
  }
  void AddRead(IoMode mode, int rv) {
    reads_.push_back(MockRead(mode, rv));
  }
  void AddWrite(scoped_ptr<QuicEncryptedPacket> packet) {
    writes_.push_back(MockWrite(SYNCHRONOUS, packet->data(), packet->length(),
                                sequence_number_++));
    packets_.push_back(packet.release());
  }
  void AddDelayedSocketDataToFactory(MockClientSocketFactory* factory,
                                     size_t delay) {
    MockRead* reads = reads_.empty() ? NULL  : &reads_[0];
    MockWrite* writes = writes_.empty() ? NULL  : &writes_[0];
    socket_data_.reset(new DelayedSocketData(
        delay, reads, reads_.size(), writes, writes_.size()));
    factory->AddSocketDataProvider(socket_data_.get());
  }
 private:
  std::vector<QuicEncryptedPacket*> packets_;
  std::vector<MockWrite> writes_;
  std::vector<MockRead> reads_;
  size_t sequence_number_;
  scoped_ptr<SocketDataProvider> socket_data_;
};
class QuicNetworkTransactionTest
    : public PlatformTest,
      public ::testing::WithParamInterface<QuicVersion> {
 protected:
  QuicNetworkTransactionTest()
      : maker_(GetParam(), 0),
        clock_(new MockClock),
        ssl_config_service_(new SSLConfigServiceDefaults),
        proxy_service_(ProxyService::CreateDirect()),
        auth_handler_factory_(
            HttpAuthHandlerFactory::CreateDefault(&host_resolver_)),
        random_generator_(0),
        hanging_data_(NULL, 0, NULL, 0) {
    request_.method = "GET";
    request_.url = GURL("http://www.google.com/");
    request_.load_flags = 0;
    clock_->AdvanceTime(QuicTime::Delta::FromMilliseconds(20));
  }
  virtual void SetUp() {
    NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
    base::MessageLoop::current()->RunUntilIdle();
  }
  virtual void TearDown() {
    NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
    
    base::MessageLoop::current()->RunUntilIdle();
    PlatformTest::TearDown();
    NetworkChangeNotifier::NotifyObserversOfIPAddressChangeForTests();
    base::MessageLoop::current()->RunUntilIdle();
    HttpStreamFactory::set_use_alternate_protocols(false);
    HttpStreamFactory::SetNextProtos(std::vector<NextProto>());
  }
  scoped_ptr<QuicEncryptedPacket> ConstructRstPacket(
      QuicPacketSequenceNumber num,
      QuicStreamId stream_id) {
    return maker_.MakeRstPacket(
        num, false, stream_id, QUIC_STREAM_NO_ERROR);
  }
  scoped_ptr<QuicEncryptedPacket> ConstructConnectionClosePacket(
      QuicPacketSequenceNumber num) {
    return maker_.MakeConnectionClosePacket(num);
  }
  scoped_ptr<QuicEncryptedPacket> ConstructAckPacket(
      QuicPacketSequenceNumber largest_received,
      QuicPacketSequenceNumber least_unacked) {
    return maker_.MakeAckPacket(2, largest_received, least_unacked, true);
  }
  SpdyHeaderBlock GetRequestHeaders(const std::string& method,
                                    const std::string& scheme,
                                    const std::string& path) {
    return maker_.GetRequestHeaders(method, scheme, path);
  }
  SpdyHeaderBlock GetResponseHeaders(const std::string& status) {
    return maker_.GetResponseHeaders(status);
  }
  scoped_ptr<QuicEncryptedPacket> ConstructDataPacket(
      QuicPacketSequenceNumber sequence_number,
      QuicStreamId stream_id,
      bool should_include_version,
      bool fin,
      QuicStreamOffset offset,
      base::StringPiece data) {
    return maker_.MakeDataPacket(
        sequence_number, stream_id, should_include_version, fin, offset, data);
  }
  scoped_ptr<QuicEncryptedPacket> ConstructRequestHeadersPacket(
      QuicPacketSequenceNumber sequence_number,
      QuicStreamId stream_id,
      bool should_include_version,
      bool fin,
      const SpdyHeaderBlock& headers) {
    return maker_.MakeRequestHeadersPacket(
        sequence_number, stream_id, should_include_version, fin, headers);
  }
  scoped_ptr<QuicEncryptedPacket> ConstructResponseHeadersPacket(
      QuicPacketSequenceNumber sequence_number,
      QuicStreamId stream_id,
      bool should_include_version,
      bool fin,
      const SpdyHeaderBlock& headers) {
    return maker_.MakeResponseHeadersPacket(
        sequence_number, stream_id, should_include_version, fin, headers);
  }
  void CreateSession() {
    CreateSessionWithFactory(&socket_factory_);
  }
  void CreateSessionWithFactory(ClientSocketFactory* socket_factory) {
    params_.enable_quic = true;
    params_.quic_clock = clock_;
    params_.quic_random = &random_generator_;
    params_.client_socket_factory = socket_factory;
    params_.quic_crypto_client_stream_factory = &crypto_client_stream_factory_;
    params_.host_resolver = &host_resolver_;
    params_.cert_verifier = &cert_verifier_;
    params_.transport_security_state = &transport_security_state_;
    params_.proxy_service = proxy_service_.get();
    params_.ssl_config_service = ssl_config_service_.get();
    params_.http_auth_handler_factory = auth_handler_factory_.get();
    params_.http_server_properties = http_server_properties.GetWeakPtr();
    params_.quic_supported_versions = SupportedVersions(GetParam());
    session_ = new HttpNetworkSession(params_);
    session_->quic_stream_factory()->set_require_confirmation(false);
  }
  void CheckWasQuicResponse(const scoped_ptr<HttpNetworkTransaction>& trans) {
    const HttpResponseInfo* response = trans->GetResponseInfo();
    ASSERT_TRUE(response != NULL);
    ASSERT_TRUE(response->headers.get() != NULL);
    EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
    EXPECT_TRUE(response->was_fetched_via_spdy);
    EXPECT_TRUE(response->was_npn_negotiated);
    EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_QUIC1_SPDY3,
              response->connection_info);
  }
  void CheckWasHttpResponse(const scoped_ptr<HttpNetworkTransaction>& trans) {
    const HttpResponseInfo* response = trans->GetResponseInfo();
    ASSERT_TRUE(response != NULL);
    ASSERT_TRUE(response->headers.get() != NULL);
    EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
    EXPECT_FALSE(response->was_fetched_via_spdy);
    EXPECT_FALSE(response->was_npn_negotiated);
    EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP1,
              response->connection_info);
  }
  void CheckResponseData(HttpNetworkTransaction* trans,
                         const std::string& expected) {
    std::string response_data;
    ASSERT_EQ(OK, ReadTransaction(trans, &response_data));
    EXPECT_EQ(expected, response_data);
  }
  void RunTransaction(HttpNetworkTransaction* trans) {
    TestCompletionCallback callback;
    int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
    EXPECT_EQ(ERR_IO_PENDING, rv);
    EXPECT_EQ(OK, callback.WaitForResult());
  }
  void SendRequestAndExpectHttpResponse(const std::string& expected) {
    scoped_ptr<HttpNetworkTransaction> trans(
        new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
    RunTransaction(trans.get());
    CheckWasHttpResponse(trans);
    CheckResponseData(trans.get(), expected);
  }
  void SendRequestAndExpectQuicResponse(const std::string& expected) {
    scoped_ptr<HttpNetworkTransaction> trans(
        new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
    RunTransaction(trans.get());
    CheckWasQuicResponse(trans);
    CheckResponseData(trans.get(), expected);
  }
  void AddQuicAlternateProtocolMapping(
      MockCryptoClientStream::HandshakeMode handshake_mode) {
    crypto_client_stream_factory_.set_handshake_mode(handshake_mode);
    session_->http_server_properties()->SetAlternateProtocol(
        HostPortPair::FromURL(request_.url), 80, QUIC);
  }
  void ExpectBrokenAlternateProtocolMapping() {
    ASSERT_TRUE(session_->http_server_properties()->HasAlternateProtocol(
        HostPortPair::FromURL(request_.url)));
    const PortAlternateProtocolPair alternate =
        session_->http_server_properties()->GetAlternateProtocol(
            HostPortPair::FromURL(request_.url));
    EXPECT_EQ(ALTERNATE_PROTOCOL_BROKEN, alternate.protocol);
  }
  void AddHangingNonAlternateProtocolSocketData() {
    MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
    hanging_data_.set_connect_data(hanging_connect);
    socket_factory_.AddSocketDataProvider(&hanging_data_);
  }
  QuicTestPacketMaker maker_;
  scoped_refptr<HttpNetworkSession> session_;
  MockClientSocketFactory socket_factory_;
  MockCryptoClientStreamFactory crypto_client_stream_factory_;
  MockClock* clock_;  
  MockHostResolver host_resolver_;
  MockCertVerifier cert_verifier_;
  TransportSecurityState transport_security_state_;
  scoped_refptr<SSLConfigServiceDefaults> ssl_config_service_;
  scoped_ptr<ProxyService> proxy_service_;
  scoped_ptr<HttpAuthHandlerFactory> auth_handler_factory_;
  MockRandom random_generator_;
  HttpServerPropertiesImpl http_server_properties;
  HttpNetworkSession::Params params_;
  HttpRequestInfo request_;
  CapturingBoundNetLog net_log_;
  StaticSocketDataProvider hanging_data_;
};
INSTANTIATE_TEST_CASE_P(Version, QuicNetworkTransactionTest,
                        ::testing::ValuesIn(QuicSupportedVersions()));
TEST_P(QuicNetworkTransactionTest, ForceQuic) {
  params_.origin_to_force_quic_on =
      HostPortPair::FromString("www.google.com:80");
  MockQuicData mock_quic_data;
  mock_quic_data.AddWrite(
      ConstructRequestHeadersPacket(1, kStreamId5, true, true,
                                    GetRequestHeaders("GET", "http", "/")));
  mock_quic_data.AddRead(
      ConstructResponseHeadersPacket(1, kStreamId5, false, false,
                                     GetResponseHeaders("200 OK")));
  mock_quic_data.AddRead(
      ConstructDataPacket(2, kStreamId5, false, true, 0, "hello!"));
  mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
  mock_quic_data.AddRead(SYNCHRONOUS, 0);  
  mock_quic_data.AddDelayedSocketDataToFactory(&socket_factory_, 1);
  
  
  AddHangingNonAlternateProtocolSocketData();
  CreateSession();
  SendRequestAndExpectQuicResponse("hello!");
  
  net::CapturingNetLog::CapturedEntryList entries;
  net_log_.GetEntries(&entries);
  EXPECT_LT(0u, entries.size());
  
  int pos = net::ExpectLogContainsSomewhere(
      entries, 0,
      net::NetLog::TYPE_QUIC_SESSION_PACKET_RECEIVED,
      net::NetLog::PHASE_NONE);
  EXPECT_LT(0, pos);
  
  pos = net::ExpectLogContainsSomewhere(
      entries, 0,
      net::NetLog::TYPE_QUIC_SESSION_PACKET_HEADER_RECEIVED,
      net::NetLog::PHASE_NONE);
  EXPECT_LT(0, pos);
  std::string packet_sequence_number;
  ASSERT_TRUE(entries[pos].GetStringValue(
      "packet_sequence_number", &packet_sequence_number));
  EXPECT_EQ("1", packet_sequence_number);
  
  pos = net::ExpectLogContainsSomewhere(
      entries, 0,
      net::NetLog::TYPE_QUIC_SESSION_STREAM_FRAME_RECEIVED,
      net::NetLog::PHASE_NONE);
  EXPECT_LT(0, pos);
  int log_stream_id;
  ASSERT_TRUE(entries[pos].GetIntegerValue("stream_id", &log_stream_id));
  EXPECT_EQ(3, log_stream_id);
}
TEST_P(QuicNetworkTransactionTest, QuicProxy) {
  proxy_service_.reset(
      ProxyService::CreateFixedFromPacResult("QUIC myproxy:70"));
  MockQuicData mock_quic_data;
  mock_quic_data.AddWrite(
      ConstructRequestHeadersPacket(1, kStreamId5, true, true,
                                    GetRequestHeaders("GET", "http", "/")));
  mock_quic_data.AddRead(
      ConstructResponseHeadersPacket(1, kStreamId5, false, false,
                                     GetResponseHeaders("200 OK")));
  mock_quic_data.AddRead(
      ConstructDataPacket(2, kStreamId5, false, true, 0, "hello!"));
  mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
  mock_quic_data.AddRead(SYNCHRONOUS, 0);  
  mock_quic_data.AddDelayedSocketDataToFactory(&socket_factory_, 1);
  
  
  CreateSession();
  SendRequestAndExpectQuicResponse("hello!");
}
TEST_P(QuicNetworkTransactionTest, ForceQuicWithErrorConnecting) {
  params_.origin_to_force_quic_on =
      HostPortPair::FromString("www.google.com:80");
  MockQuicData mock_quic_data;
  mock_quic_data.AddRead(ASYNC, ERR_SOCKET_NOT_CONNECTED);
  mock_quic_data.AddDelayedSocketDataToFactory(&socket_factory_, 0);
  CreateSession();
  scoped_ptr<HttpNetworkTransaction> trans(
      new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
  TestCompletionCallback callback;
  int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
  EXPECT_EQ(ERR_IO_PENDING, rv);
  EXPECT_EQ(ERR_CONNECTION_CLOSED, callback.WaitForResult());
}
TEST_P(QuicNetworkTransactionTest, DoNotForceQuicForHttps) {
  
  params_.origin_to_force_quic_on =
      HostPortPair::FromString("www.google.com:443");
  MockRead http_reads[] = {
    MockRead("HTTP/1.1 200 OK\r\n\r\n"),
    MockRead("hello world"),
    MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
    MockRead(ASYNC, OK)
  };
  StaticSocketDataProvider data(http_reads, arraysize(http_reads), NULL, 0);
  socket_factory_.AddSocketDataProvider(&data);
  SSLSocketDataProvider ssl(ASYNC, OK);
  socket_factory_.AddSSLSocketDataProvider(&ssl);
  CreateSession();
  SendRequestAndExpectHttpResponse("hello world");
}
TEST_P(QuicNetworkTransactionTest, UseAlternateProtocolForQuic) {
  HttpStreamFactory::EnableNpnSpdy3();  
  MockRead http_reads[] = {
    MockRead("HTTP/1.1 200 OK\r\n"),
    MockRead(kQuicAlternateProtocolHttpHeader),
    MockRead("hello world"),
    MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
    MockRead(ASYNC, OK)
  };
  StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
                                     NULL, 0);
  socket_factory_.AddSocketDataProvider(&http_data);
  MockQuicData mock_quic_data;
  mock_quic_data.AddWrite(
      ConstructRequestHeadersPacket(1, kStreamId5, true, true,
                                    GetRequestHeaders("GET", "http", "/")));
  mock_quic_data.AddRead(
      ConstructResponseHeadersPacket(1, kStreamId5, false, false,
                                     GetResponseHeaders("200 OK")));
  mock_quic_data.AddRead(
      ConstructDataPacket(2, kStreamId5, false, true, 0, "hello!"));
  mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
  mock_quic_data.AddRead(SYNCHRONOUS, 0);  
  mock_quic_data.AddDelayedSocketDataToFactory(&socket_factory_, 1);
  
  
  AddHangingNonAlternateProtocolSocketData();
  CreateSession();
  SendRequestAndExpectHttpResponse("hello world");
  SendRequestAndExpectQuicResponse("hello!");
}
TEST_P(QuicNetworkTransactionTest, UseAlternateProtocolForQuicForHttps) {
  params_.origin_to_force_quic_on =
      HostPortPair::FromString("www.google.com:443");
  params_.enable_quic_https = true;
  HttpStreamFactory::EnableNpnSpdy3();  
  MockRead http_reads[] = {
    MockRead("HTTP/1.1 200 OK\r\n"),
    MockRead(kQuicAlternateProtocolHttpsHeader),
    MockRead("hello world"),
    MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
    MockRead(ASYNC, OK)
  };
  StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
                                     NULL, 0);
  socket_factory_.AddSocketDataProvider(&http_data);
  MockQuicData mock_quic_data;
  mock_quic_data.AddWrite(
      ConstructRequestHeadersPacket(1, kStreamId5, true, true,
                                    GetRequestHeaders("GET", "http", "/")));
  mock_quic_data.AddRead(
      ConstructResponseHeadersPacket(1, kStreamId5, false, false,
                                     GetResponseHeaders("200 OK")));
  mock_quic_data.AddRead(
      ConstructDataPacket(2, kStreamId5, false, true, 0, "hello!"));
  mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
  mock_quic_data.AddRead(SYNCHRONOUS, 0);  
  mock_quic_data.AddDelayedSocketDataToFactory(&socket_factory_, 1);
  
  
  AddHangingNonAlternateProtocolSocketData();
  CreateSession();
  
  SendRequestAndExpectHttpResponse("hello world");
}
TEST_P(QuicNetworkTransactionTest, HungAlternateProtocol) {
  HttpStreamFactory::EnableNpnSpdy3();  
  crypto_client_stream_factory_.set_handshake_mode(
      MockCryptoClientStream::COLD_START);
  MockWrite http_writes[] = {
    MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
    MockWrite(SYNCHRONOUS, 1, "Host: www.google.com\r\n"),
    MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")
  };
  MockRead http_reads[] = {
    MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
    MockRead(SYNCHRONOUS, 4, kQuicAlternateProtocolHttpHeader),
    MockRead(SYNCHRONOUS, 5, "hello world"),
    MockRead(SYNCHRONOUS, OK, 6)
  };
  DeterministicMockClientSocketFactory socket_factory;
  DeterministicSocketData http_data(http_reads, arraysize(http_reads),
                                    http_writes, arraysize(http_writes));
  socket_factory.AddSocketDataProvider(&http_data);
  
  MockWrite quic_writes[] = {
    MockWrite(ASYNC, ERR_IO_PENDING, 0)
  };
  MockRead quic_reads[] = {
    MockRead(ASYNC, ERR_IO_PENDING, 1),
  };
  DeterministicSocketData quic_data(quic_reads, arraysize(quic_reads),
                                    quic_writes, arraysize(quic_writes));
  socket_factory.AddSocketDataProvider(&quic_data);
  
  DeterministicSocketData http_data2(http_reads, arraysize(http_reads),
                                     http_writes, arraysize(http_writes));
  socket_factory.AddSocketDataProvider(&http_data2);
  CreateSessionWithFactory(&socket_factory);
  
  http_data.StopAfter(arraysize(http_reads) + arraysize(http_writes));
  SendRequestAndExpectHttpResponse("hello world");
  ASSERT_TRUE(http_data.at_read_eof());
  ASSERT_TRUE(http_data.at_write_eof());
  
  
  http_data2.StopAfter(arraysize(http_reads) + arraysize(http_writes));
  SendRequestAndExpectHttpResponse("hello world");
  ASSERT_TRUE(http_data2.at_read_eof());
  ASSERT_TRUE(http_data2.at_write_eof());
  ASSERT_TRUE(!quic_data.at_read_eof());
  ASSERT_TRUE(!quic_data.at_write_eof());
}
TEST_P(QuicNetworkTransactionTest, ZeroRTTWithHttpRace) {
  HttpStreamFactory::EnableNpnSpdy3();  
  MockQuicData mock_quic_data;
  mock_quic_data.AddWrite(
      ConstructRequestHeadersPacket(1, kStreamId5, true, true,
                                    GetRequestHeaders("GET", "http", "/")));
  mock_quic_data.AddRead(
      ConstructResponseHeadersPacket(1, kStreamId5, false, false,
                                     GetResponseHeaders("200 OK")));
  mock_quic_data.AddRead(
      ConstructDataPacket(2, kStreamId5, false, true, 0, "hello!"));
  mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
  mock_quic_data.AddRead(SYNCHRONOUS, 0);  
  mock_quic_data.AddDelayedSocketDataToFactory(&socket_factory_, 1);
  
  
  AddHangingNonAlternateProtocolSocketData();
  CreateSession();
  AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
  SendRequestAndExpectQuicResponse("hello!");
}
TEST_P(QuicNetworkTransactionTest, ZeroRTTWithNoHttpRace) {
  HttpStreamFactory::EnableNpnSpdy3();  
  MockQuicData mock_quic_data;
  mock_quic_data.AddWrite(
      ConstructRequestHeadersPacket(1, kStreamId5, true, true,
                                    GetRequestHeaders("GET", "http", "/")));
  mock_quic_data.AddRead(
      ConstructResponseHeadersPacket(1, kStreamId5, false, false,
                                     GetResponseHeaders("200 OK")));
  mock_quic_data.AddRead(
      ConstructDataPacket(2, kStreamId5, false, true, 0, "hello!"));
  mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
  mock_quic_data.AddRead(SYNCHRONOUS, 0);  
  mock_quic_data.AddDelayedSocketDataToFactory(&socket_factory_, 1);
  
  
  
  host_resolver_.set_synchronous_mode(true);
  host_resolver_.rules()->AddIPLiteralRule("www.google.com", "192.168.0.1", "");
  HostResolver::RequestInfo info(HostPortPair("www.google.com", 80));
  AddressList address;
  host_resolver_.Resolve(info,
                         DEFAULT_PRIORITY,
                         &address,
                         CompletionCallback(),
                         NULL,
                         net_log_.bound());
  CreateSession();
  AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
  SendRequestAndExpectQuicResponse("hello!");
}
TEST_P(QuicNetworkTransactionTest, ZeroRTTWithProxy) {
  proxy_service_.reset(
      ProxyService::CreateFixedFromPacResult("PROXY myproxy:70"));
  HttpStreamFactory::EnableNpnSpdy3();  
  
  MockWrite http_writes[] = {
    MockWrite(SYNCHRONOUS, 0, "GET http://www.google.com/ HTTP/1.1\r\n"),
    MockWrite(SYNCHRONOUS, 1, "Host: www.google.com\r\n"),
    MockWrite(SYNCHRONOUS, 2, "Proxy-Connection: keep-alive\r\n\r\n")
  };
  MockRead http_reads[] = {
    MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
    MockRead(SYNCHRONOUS, 4, kQuicAlternateProtocolHttpHeader),
    MockRead(SYNCHRONOUS, 5, "hello world"),
    MockRead(SYNCHRONOUS, OK, 6)
  };
  StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
                                     http_writes, arraysize(http_writes));
  socket_factory_.AddSocketDataProvider(&http_data);
  
  
  
  host_resolver_.set_synchronous_mode(true);
  host_resolver_.rules()->AddIPLiteralRule("www.google.com", "192.168.0.1", "");
  HostResolver::RequestInfo info(HostPortPair("www.google.com", 80));
  AddressList address;
  host_resolver_.Resolve(info,
                         DEFAULT_PRIORITY,
                         &address,
                         CompletionCallback(),
                         NULL,
                         net_log_.bound());
  CreateSession();
  AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
  SendRequestAndExpectHttpResponse("hello world");
}
TEST_P(QuicNetworkTransactionTest, ZeroRTTWithConfirmationRequired) {
  HttpStreamFactory::EnableNpnSpdy3();  
  MockQuicData mock_quic_data;
  mock_quic_data.AddWrite(
      ConstructRequestHeadersPacket(1, kStreamId5, true, true,
                                    GetRequestHeaders("GET", "http", "/")));
  mock_quic_data.AddRead(
      ConstructResponseHeadersPacket(1, kStreamId5, false, false,
                                     GetResponseHeaders("200 OK")));
  mock_quic_data.AddRead(
      ConstructDataPacket(2, kStreamId5, false, true, 0, "hello!"));
  mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
  mock_quic_data.AddRead(SYNCHRONOUS, 0);  
  mock_quic_data.AddDelayedSocketDataToFactory(&socket_factory_, 1);
  
  
  AddHangingNonAlternateProtocolSocketData();
  
  
  
  
  
  host_resolver_.set_synchronous_mode(true);
  host_resolver_.rules()->AddIPLiteralRule("www.google.com", "192.168.0.1", "");
  HostResolver::RequestInfo info(HostPortPair("www.google.com", 80));
  AddressList address;
  host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address,
                         CompletionCallback(), NULL, net_log_.bound());
  CreateSession();
  session_->quic_stream_factory()->set_require_confirmation(true);
  AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
  scoped_ptr<HttpNetworkTransaction> trans(
      new HttpNetworkTransaction(DEFAULT_PRIORITY, session_.get()));
  TestCompletionCallback callback;
  int rv = trans->Start(&request_, callback.callback(), net_log_.bound());
  EXPECT_EQ(ERR_IO_PENDING, rv);
  crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
      QuicSession::HANDSHAKE_CONFIRMED);
  EXPECT_EQ(OK, callback.WaitForResult());
}
TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocol) {
  HttpStreamFactory::EnableNpnSpdy3();  
  
  scoped_ptr<QuicEncryptedPacket> close(ConstructConnectionClosePacket(1));
  MockRead quic_reads[] = {
    MockRead(ASYNC, close->data(), close->length()),
    MockRead(ASYNC, OK),  
  };
  StaticSocketDataProvider quic_data(quic_reads, arraysize(quic_reads),
                                     NULL, 0);
  socket_factory_.AddSocketDataProvider(&quic_data);
  
  MockRead http_reads[] = {
    MockRead("HTTP/1.1 200 OK\r\n\r\n"),
    MockRead("hello from http"),
    MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
    MockRead(ASYNC, OK)
  };
  StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
                                     NULL, 0);
  socket_factory_.AddSocketDataProvider(&http_data);
  CreateSession();
  AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
  SendRequestAndExpectHttpResponse("hello from http");
  ExpectBrokenAlternateProtocolMapping();
}
TEST_P(QuicNetworkTransactionTest, BrokenAlternateProtocolReadError) {
  HttpStreamFactory::EnableNpnSpdy3();  
  
  MockRead quic_reads[] = {
    MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
  };
  StaticSocketDataProvider quic_data(quic_reads, arraysize(quic_reads),
                                     NULL, 0);
  socket_factory_.AddSocketDataProvider(&quic_data);
  
  MockRead http_reads[] = {
    MockRead("HTTP/1.1 200 OK\r\n\r\n"),
    MockRead("hello from http"),
    MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
    MockRead(ASYNC, OK)
  };
  StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
                                     NULL, 0);
  socket_factory_.AddSocketDataProvider(&http_data);
  CreateSession();
  AddQuicAlternateProtocolMapping(MockCryptoClientStream::COLD_START);
  SendRequestAndExpectHttpResponse("hello from http");
  ExpectBrokenAlternateProtocolMapping();
}
TEST_P(QuicNetworkTransactionTest, FailedZeroRttBrokenAlternateProtocol) {
  HttpStreamFactory::EnableNpnSpdy3();  
  
  MockRead quic_reads[] = {
    MockRead(ASYNC, ERR_SOCKET_NOT_CONNECTED),
  };
  StaticSocketDataProvider quic_data(quic_reads, arraysize(quic_reads),
                                     NULL, 0);
  socket_factory_.AddSocketDataProvider(&quic_data);
  AddHangingNonAlternateProtocolSocketData();
  
  MockRead http_reads[] = {
    MockRead("HTTP/1.1 200 OK\r\n\r\n"),
    MockRead("hello from http"),
    MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
    MockRead(ASYNC, OK)
  };
  StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
                                     NULL, 0);
  socket_factory_.AddSocketDataProvider(&http_data);
  CreateSession();
  AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
  SendRequestAndExpectHttpResponse("hello from http");
  ExpectBrokenAlternateProtocolMapping();
  EXPECT_TRUE(quic_data.at_read_eof());
  EXPECT_TRUE(quic_data.at_write_eof());
}
TEST_P(QuicNetworkTransactionTest, ConnectionCloseDuringConnect) {
  HttpStreamFactory::EnableNpnSpdy3();  
  MockQuicData mock_quic_data;
  mock_quic_data.AddRead(ConstructConnectionClosePacket(1));
  mock_quic_data.AddWrite(
      ConstructRequestHeadersPacket(1, kStreamId5, true, true,
                                    GetRequestHeaders("GET", "http", "/")));
  mock_quic_data.AddWrite(ConstructAckPacket(2, 1));
  mock_quic_data.AddDelayedSocketDataToFactory(&socket_factory_, 0);
  
  MockRead http_reads[] = {
    MockRead("HTTP/1.1 200 OK\r\n"),
    MockRead(kQuicAlternateProtocolHttpHeader),
    MockRead("hello world"),
    MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
    MockRead(ASYNC, OK)
  };
  StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
                                     NULL, 0);
  socket_factory_.AddSocketDataProvider(&http_data);
  
  
  
  host_resolver_.set_synchronous_mode(true);
  host_resolver_.rules()->AddIPLiteralRule("www.google.com", "192.168.0.1", "");
  HostResolver::RequestInfo info(HostPortPair("www.google.com", 80));
  AddressList address;
  host_resolver_.Resolve(info,
                         DEFAULT_PRIORITY,
                         &address,
                         CompletionCallback(),
                         NULL,
                         net_log_.bound());
  CreateSession();
  AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
  SendRequestAndExpectHttpResponse("hello world");
}
}  
}