| Index: net/quic/chromium/quic_network_transaction_unittest.cc
|
| diff --git a/net/quic/chromium/quic_network_transaction_unittest.cc b/net/quic/chromium/quic_network_transaction_unittest.cc
|
| index e5e8648d1ea4193568dffa6953c76275e513487d..c99526f3599422ff6f118adcb2e96e79265a115e 100644
|
| --- a/net/quic/chromium/quic_network_transaction_unittest.cc
|
| +++ b/net/quic/chromium/quic_network_transaction_unittest.cc
|
| @@ -700,6 +700,67 @@ class QuicNetworkTransactionTest
|
| SendRequestAndExpectHttpResponseFromProxy("hello from http", true, 443);
|
| }
|
|
|
| + // Preconnects to a HTTPS proxy with a QUIC alternative proxy. Verifies that
|
| + // if the alternative proxy job returns |error_code|, the preconnection still
|
| + // succeeds.
|
| + void TestAlternativeProxyPreconnect(int error_code) {
|
| + base::HistogramTester histogram_tester;
|
| + // Data for the alternative proxy server job.
|
| + MockWrite quic_writes[] = {MockWrite(SYNCHRONOUS, error_code, 1)};
|
| + MockRead quic_reads[] = {
|
| + MockRead(SYNCHRONOUS, error_code, 0),
|
| + };
|
| +
|
| + SequencedSocketData quic_data(quic_reads, arraysize(quic_reads),
|
| + quic_writes, arraysize(quic_writes));
|
| + socket_factory_.AddSocketDataProvider(&quic_data);
|
| +
|
| + // Main job succeeds and the alternative job fails.
|
| + // Add data for two requests that will be read by the main job.
|
| + 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_1(http_reads, arraysize(http_reads),
|
| + nullptr, 0);
|
| + socket_factory_.AddSocketDataProvider(&http_data_1);
|
| + socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
|
| +
|
| + TestProxyDelegate test_proxy_delegate;
|
| + // Proxy URL is different from the request URL.
|
| + test_proxy_delegate.set_alternative_proxy_server(
|
| + ProxyServer::FromPacString("QUIC myproxy.org:443"));
|
| +
|
| + params_.proxy_delegate = &test_proxy_delegate;
|
| + params_.race_preconnects_to_http2_proxies = true;
|
| + proxy_service_ =
|
| + ProxyService::CreateFixedFromPacResult("HTTPS myproxy.org:443");
|
| +
|
| + CreateSession();
|
| + EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_valid());
|
| +
|
| + HttpRequestInfo request_info;
|
| + request_info.method = "GET";
|
| + // Use a non-cryptographic scheme for the preconnect URL since this will be
|
| + // fetched via proxy with QUIC as the alternative service.
|
| + request_info.url = GURL("http://www.google.com");
|
| +
|
| + session_->http_stream_factory()->PreconnectStreams(1 /*num_streams*/,
|
| + request_info);
|
| + base::RunLoop().RunUntilIdle();
|
| +
|
| + // Even through the alternative proxy server job failed, the proxy should
|
| + // not be marked as bad since the main job succeeded.
|
| + EXPECT_TRUE(session_->proxy_service()->proxy_retry_info().empty());
|
| +
|
| + // The alternative proxy server should no longer be in use.
|
| + EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_valid());
|
| +
|
| + histogram_tester.ExpectTotalCount(
|
| + "Net.QuicAlternativeProxy.PreconnectRace.FirstJobFinished", 1);
|
| + }
|
| +
|
| const QuicVersion version_;
|
| QuicFlagSaver flags_; // Save/restore all QUIC flag values.
|
| MockClock* clock_; // Owned by QuicStreamFactory after CreateSession.
|
| @@ -1853,6 +1914,65 @@ TEST_P(QuicNetworkTransactionTest, QuicProxyWithRacing) {
|
| 1);
|
| }
|
|
|
| +// Tests that the connection to an HTTPS proxy is raced with an available
|
| +// alternative proxy server.
|
| +TEST_P(QuicNetworkTransactionTest, QuicProxyWithRacingForPreconnect) {
|
| + base::HistogramTester histogram_tester;
|
| + proxy_service_ =
|
| + ProxyService::CreateFixedFromPacResult("HTTPS mail.example.org:443");
|
| +
|
| + MockQuicData mock_quic_data;
|
| + QuicStreamOffset header_stream_offset = 0;
|
| + mock_quic_data.AddWrite(ConstructSettingsPacket(
|
| + 1, SETTINGS_MAX_HEADER_LIST_SIZE, kDefaultMaxUncompressedHeaderSize,
|
| + &header_stream_offset));
|
| + mock_quic_data.AddWrite(ConstructClientRequestHeadersPacket(
|
| + 2, kClientDataStreamId1, true, true,
|
| + GetRequestHeaders("GET", "http", "/"), &header_stream_offset));
|
| + mock_quic_data.AddRead(ConstructServerResponseHeadersPacket(
|
| + 1, kClientDataStreamId1, false, false, GetResponseHeaders("200 OK")));
|
| + mock_quic_data.AddRead(ConstructServerDataPacket(2, kClientDataStreamId1,
|
| + false, true, 0, "hello!"));
|
| + mock_quic_data.AddWrite(ConstructClientAckPacket(3, 2, 1));
|
| + mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
|
| + mock_quic_data.AddRead(ASYNC, 0); // EOF
|
| +
|
| + mock_quic_data.AddSocketDataToFactory(&socket_factory_);
|
| +
|
| + // There is no need to set up main job, because no attempt will be made to
|
| + // speak to the proxy over TCP.
|
| + params_.enable_quic_alternative_service_with_different_host = false;
|
| + TestProxyDelegate test_proxy_delegate;
|
| + const HostPortPair host_port_pair("mail.example.org", 443);
|
| +
|
| + test_proxy_delegate.set_alternative_proxy_server(
|
| + ProxyServer::FromPacString("QUIC mail.example.org:443"));
|
| + params_.proxy_delegate = &test_proxy_delegate;
|
| + params_.race_preconnects_to_http2_proxies = true;
|
| + CreateSession();
|
| + EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
|
| +
|
| + // The main job needs to hang in order to guarantee that the alternative
|
| + // proxy server job will "win".
|
| + AddHangingNonAlternateProtocolSocketData();
|
| +
|
| + HttpRequestInfo request_info;
|
| + request_info.method = "GET";
|
| + request_info.url = GURL("http://www.google.com");
|
| +
|
| + session_->http_stream_factory()->PreconnectStreams(1 /* num_streams */,
|
| + request_info);
|
| + base::RunLoop().RunUntilIdle();
|
| + histogram_tester.ExpectTotalCount(
|
| + "Net.QuicAlternativeProxy.PreconnectRace.FirstJobFinished", 1);
|
| +
|
| + // Verify that the alternative proxy server is not marked as broken.
|
| + EXPECT_TRUE(test_proxy_delegate.alternative_proxy_server().is_quic());
|
| +
|
| + // Verify that the proxy server is not marked as broken.
|
| + EXPECT_TRUE(session_->proxy_service()->proxy_retry_info().empty());
|
| +}
|
| +
|
| TEST_P(QuicNetworkTransactionTest, HungAlternativeService) {
|
| crypto_client_stream_factory_.set_handshake_mode(
|
| MockCryptoClientStream::COLD_START);
|
| @@ -2515,6 +2635,38 @@ TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyAddressUnreachable) {
|
| TestAlternativeProxy(ERR_ADDRESS_UNREACHABLE);
|
| }
|
|
|
| +TEST_P(QuicNetworkTransactionTest,
|
| + BrokenAlternativeProxySocketNotConnectedPreconnect) {
|
| + TestAlternativeProxyPreconnect(ERR_SOCKET_NOT_CONNECTED);
|
| +}
|
| +TEST_P(QuicNetworkTransactionTest,
|
| + BrokenAlternativeProxyConnectionFailedPreconnect) {
|
| + TestAlternativeProxyPreconnect(ERR_CONNECTION_FAILED);
|
| +}
|
| +TEST_P(QuicNetworkTransactionTest,
|
| + BrokenAlternativeProxyConnectionTimedOutPreconnect) {
|
| + TestAlternativeProxyPreconnect(ERR_CONNECTION_TIMED_OUT);
|
| +}
|
| +TEST_P(QuicNetworkTransactionTest,
|
| + BrokenAlternativeProxyConnectionRefusedPreconnect) {
|
| + TestAlternativeProxyPreconnect(ERR_CONNECTION_REFUSED);
|
| +}
|
| +TEST_P(QuicNetworkTransactionTest,
|
| + BrokenAlternativeProxyQuicHandshakeFailedPreconnect) {
|
| + TestAlternativeProxyPreconnect(ERR_QUIC_HANDSHAKE_FAILED);
|
| +}
|
| +TEST_P(QuicNetworkTransactionTest,
|
| + BrokenAlternativeProxyQuicProtocolErrorPreconnect) {
|
| + TestAlternativeProxyPreconnect(ERR_QUIC_PROTOCOL_ERROR);
|
| +}
|
| +TEST_P(QuicNetworkTransactionTest, BrokenAlternativeProxyIOPendingPreconnect) {
|
| + TestAlternativeProxyPreconnect(ERR_IO_PENDING);
|
| +}
|
| +TEST_P(QuicNetworkTransactionTest,
|
| + BrokenAlternativeProxyAddressUnreachablePreconnect) {
|
| + TestAlternativeProxyPreconnect(ERR_ADDRESS_UNREACHABLE);
|
| +}
|
| +
|
| TEST_P(QuicNetworkTransactionTest, ConnectionCloseDuringConnectProxy) {
|
| MockQuicData mock_quic_data;
|
| mock_quic_data.AddSynchronousRead(ConstructServerConnectionClosePacket(1));
|
|
|