| Index: net/quic/quic_network_transaction_unittest.cc
|
| diff --git a/net/quic/quic_network_transaction_unittest.cc b/net/quic/quic_network_transaction_unittest.cc
|
| index 0edf99bbbff8b1283efea4346fd4f676e984393f..0579e1cc0266083db4e53bb927fb9474d6c9c3e1 100644
|
| --- a/net/quic/quic_network_transaction_unittest.cc
|
| +++ b/net/quic/quic_network_transaction_unittest.cc
|
| @@ -61,7 +61,8 @@ class QuicNetworkTransactionTest : public PlatformTest {
|
| proxy_service_(ProxyService::CreateDirect()),
|
| compressor_(new QuicSpdyCompressor()),
|
| auth_handler_factory_(
|
| - HttpAuthHandlerFactory::CreateDefault(&host_resolver_)) {
|
| + HttpAuthHandlerFactory::CreateDefault(&host_resolver_)),
|
| + hanging_data_(NULL, 0, NULL, 0) {
|
| request_.method = "GET";
|
| request_.url = GURL("http://www.google.com/");
|
| request_.load_flags = 0;
|
| @@ -211,10 +212,14 @@ class QuicNetworkTransactionTest : public PlatformTest {
|
| }
|
|
|
| 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_.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_;
|
| @@ -296,10 +301,9 @@ class QuicNetworkTransactionTest : public PlatformTest {
|
| }
|
|
|
| void AddHangingNonAlternateProtocolSocketData() {
|
| - MockConnect never_finishing_connect(SYNCHRONOUS, ERR_IO_PENDING);
|
| - StaticSocketDataProvider data(NULL, 0, NULL, 0);
|
| - data.set_connect_data(never_finishing_connect);
|
| - socket_factory_.AddSocketDataProvider(&data);
|
| + MockConnect hanging_connect(SYNCHRONOUS, ERR_IO_PENDING);
|
| + hanging_data_.set_connect_data(hanging_connect);
|
| + socket_factory_.AddSocketDataProvider(&hanging_data_);
|
| }
|
|
|
| QuicPacketHeader header_;
|
| @@ -319,6 +323,7 @@ class QuicNetworkTransactionTest : public PlatformTest {
|
| HttpNetworkSession::Params params_;
|
| HttpRequestInfo request_;
|
| CapturingBoundNetLog net_log_;
|
| + StaticSocketDataProvider hanging_data_;
|
| };
|
|
|
| TEST_F(QuicNetworkTransactionTest, ForceQuic) {
|
| @@ -487,6 +492,65 @@ TEST_F(QuicNetworkTransactionTest, UseAlternateProtocolForQuic) {
|
| SendRequestAndExpectQuicResponse("hello!");
|
| }
|
|
|
| +TEST_F(QuicNetworkTransactionTest, HungAlternateProtocol) {
|
| + HttpStreamFactory::EnableNpnSpdy(); // Enables QUIC too.
|
| + 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);
|
| +
|
| + // The QUIC transaction will not be allowed to complete.
|
| + 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);
|
| +
|
| + // The HTTP transaction will complete.
|
| + DeterministicSocketData http_data2(http_reads, arraysize(http_reads),
|
| + http_writes, arraysize(http_writes));
|
| + socket_factory.AddSocketDataProvider(&http_data2);
|
| +
|
| + CreateSessionWithFactory(&socket_factory);
|
| +
|
| + // Run the first request.
|
| + 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());
|
| +
|
| + // Now run the second request in which the QUIC socket hangs,
|
| + // and verify the the transaction continues over HTTP.
|
| + 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_F(QuicNetworkTransactionTest, DontUseAlternateProtocolForQuicHttps) {
|
| HttpStreamFactory::EnableNpnSpdy(); // Enables QUIC too.
|
|
|
| @@ -542,6 +606,11 @@ TEST_F(QuicNetworkTransactionTest, ZeroRTT) {
|
|
|
| socket_factory_.AddSocketDataProvider(&quic_data);
|
|
|
| + // TODO(rch): Ideally, we would not need this, but since we have to do a DNS
|
| + // lookup, it's not synchronous. Perhaps we can configure the HostResolver
|
| + // to return immediately.
|
| + AddHangingNonAlternateProtocolSocketData();
|
| +
|
| CreateSession();
|
| AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
|
| SendRequestAndExpectQuicResponse("hello!");
|
|
|