Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(414)

Side by Side Diff: net/quic/chromium/quic_network_transaction_unittest.cc

Issue 2811993005: Revert of When HttpNetworkTransaction encounters QUIC errors, retry the request (Closed)
Patch Set: Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « net/http/http_network_transaction.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include <memory> 5 #include <memory>
6 #include <ostream> 6 #include <ostream>
7 #include <string> 7 #include <string>
8 #include <utility> 8 #include <utility>
9 #include <vector> 9 #include <vector>
10 10
(...skipping 1721 matching lines...) Expand 10 before | Expand all | Expand 10 after
1732 trans.reset(); 1732 trans.reset();
1733 1733
1734 // Run the QUIC session to completion. 1734 // Run the QUIC session to completion.
1735 quic_task_runner_->RunUntilIdle(); 1735 quic_task_runner_->RunUntilIdle();
1736 1736
1737 ExpectQuicAlternateProtocolMapping(); 1737 ExpectQuicAlternateProtocolMapping();
1738 1738
1739 ASSERT_TRUE(quic_data.AllWriteDataConsumed()); 1739 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
1740 } 1740 }
1741 1741
1742 // Verify that if a QUIC protocol error occurs after the handshake is confirmed
1743 // the request fails with QUIC_PROTOCOL_ERROR.
1744 TEST_P(QuicNetworkTransactionTest, ProtocolErrorAfterHandshakeConfirmed) {
1745 // The request will initially go out over QUIC.
1746 MockQuicData quic_data;
1747 QuicStreamOffset header_stream_offset = 0;
1748 quic_data.AddWrite(ConstructClientRequestHeadersPacket(
1749 1, kClientDataStreamId1, true, true,
1750 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
1751 quic_data.AddWrite(ConstructSettingsPacket(2, SETTINGS_MAX_HEADER_LIST_SIZE,
1752 kDefaultMaxUncompressedHeaderSize,
1753 &header_stream_offset));
1754 // Peer sending data from an non-existing stream causes this end to raise
1755 // error and close connection.
1756 quic_data.AddRead(
1757 ConstructServerRstPacket(1, false, 99, QUIC_STREAM_LAST_ERROR));
1758 std::string quic_error_details = "Data for nonexistent stream";
1759 quic_data.AddWrite(ConstructClientAckAndConnectionClosePacket(
1760 3, QuicTime::Delta::Zero(), 1, 1, QUIC_INVALID_STREAM_ID,
1761 quic_error_details));
1762 quic_data.AddSocketDataToFactory(&socket_factory_);
1763
1764 // In order for a new QUIC session to be established via alternate-protocol
1765 // without racing an HTTP connection, we need the host resolution to happen
1766 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
1767 // connection to the the server, in this test we require confirmation
1768 // before encrypting so the HTTP job will still start.
1769 host_resolver_.set_synchronous_mode(true);
1770 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
1771 "");
1772 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
1773 AddressList address;
1774 std::unique_ptr<HostResolver::Request> request;
1775 host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address, CompletionCallback(),
1776 &request, net_log_.bound());
1777
1778 CreateSession();
1779
1780 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
1781
1782 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
1783 TestCompletionCallback callback;
1784 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
1785 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
1786
1787 // Pump the message loop to get the request started.
1788 base::RunLoop().RunUntilIdle();
1789 // Explicitly confirm the handshake.
1790 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
1791 QuicSession::HANDSHAKE_CONFIRMED);
1792
1793 ASSERT_FALSE(quic_data.AllReadDataConsumed());
1794
1795 // Run the QUIC session to completion.
1796 base::RunLoop().RunUntilIdle();
1797 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
1798 ASSERT_TRUE(quic_data.AllReadDataConsumed());
1799
1800 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR));
1801 ExpectQuicAlternateProtocolMapping();
1802 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
1803 }
1804
1805 // Verify that with mark_quic_broken_when_network_blackholes enabled, if a QUIC 1742 // Verify that with mark_quic_broken_when_network_blackholes enabled, if a QUIC
1806 // connection times out, then QUIC will be marked as broken and the request 1743 // connection times out, then QUIC will be marked as broken and the request
1807 // retried over TCP. 1744 // retried over TCP.
1808 TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmedThenBroken) { 1745 TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmedThenBroken) {
1809 params_.mark_quic_broken_when_network_blackholes = true; 1746 params_.mark_quic_broken_when_network_blackholes = true;
1810 params_.quic_idle_connection_timeout_seconds = 5; 1747 params_.quic_idle_connection_timeout_seconds = 5;
1811 1748
1812 // The request will initially go out over QUIC. 1749 // The request will initially go out over QUIC.
1813 MockQuicData quic_data; 1750 MockQuicData quic_data;
1814 QuicStreamOffset header_stream_offset = 0; 1751 QuicStreamOffset header_stream_offset = 0;
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
1912 1849
1913 ExpectBrokenAlternateProtocolMapping(); 1850 ExpectBrokenAlternateProtocolMapping();
1914 ASSERT_TRUE(quic_data.AllWriteDataConsumed()); 1851 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
1915 ASSERT_FALSE(http_data.AllReadDataConsumed()); 1852 ASSERT_FALSE(http_data.AllReadDataConsumed());
1916 1853
1917 // Read the response body over TCP. 1854 // Read the response body over TCP.
1918 CheckResponseData(&trans, "hello world"); 1855 CheckResponseData(&trans, "hello world");
1919 ASSERT_TRUE(http_data.AllWriteDataConsumed()); 1856 ASSERT_TRUE(http_data.AllWriteDataConsumed());
1920 ASSERT_TRUE(http_data.AllReadDataConsumed()); 1857 ASSERT_TRUE(http_data.AllReadDataConsumed());
1921 } 1858 }
1922
1923 // Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
1924 // connection times out, then QUIC will be marked as broken and the request
1925 // retried over TCP.
1926 TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmedThenBroken2) {
1927 params_.retry_without_alt_svc_on_quic_errors = true;
1928 params_.quic_idle_connection_timeout_seconds = 5;
1929
1930 // The request will initially go out over QUIC.
1931 MockQuicData quic_data;
1932 QuicStreamOffset header_stream_offset = 0;
1933 SpdyPriority priority =
1934 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
1935
1936 std::string request_data;
1937 quic_data.AddWrite(client_maker_.MakeRequestHeadersPacketAndSaveData(
1938 1, kClientDataStreamId1, true, true, priority,
1939 GetRequestHeaders("GET", "https", "/"), nullptr, &header_stream_offset,
1940 &request_data));
1941
1942 std::string settings_data;
1943 QuicStreamOffset settings_offset = header_stream_offset;
1944 quic_data.AddWrite(client_maker_.MakeSettingsPacketAndSaveData(
1945 2, SETTINGS_MAX_HEADER_LIST_SIZE, kDefaultMaxUncompressedHeaderSize, true,
1946 &header_stream_offset, &settings_data));
1947 // TLP 1
1948 quic_data.AddWrite(client_maker_.MakeDataPacket(3, kHeadersStreamId, true,
1949 false, 0, request_data));
1950 // TLP 2
1951 quic_data.AddWrite(client_maker_.MakeDataPacket(
1952 4, kHeadersStreamId, true, false, settings_offset, settings_data));
1953 // RTO 1
1954 quic_data.AddWrite(client_maker_.MakeDataPacket(5, kHeadersStreamId, true,
1955 false, 0, request_data));
1956 quic_data.AddWrite(client_maker_.MakeDataPacket(
1957 6, kHeadersStreamId, true, false, settings_offset, settings_data));
1958 // RTO 2
1959 quic_data.AddWrite(client_maker_.MakeDataPacket(7, kHeadersStreamId, true,
1960 false, 0, request_data));
1961 quic_data.AddWrite(client_maker_.MakeDataPacket(
1962 8, kHeadersStreamId, true, false, settings_offset, settings_data));
1963 // RTO 3
1964 quic_data.AddWrite(client_maker_.MakeDataPacket(9, kHeadersStreamId, true,
1965 false, 0, request_data));
1966 quic_data.AddWrite(client_maker_.MakeDataPacket(
1967 10, kHeadersStreamId, true, false, settings_offset, settings_data));
1968
1969 quic_data.AddRead(ASYNC, ERR_IO_PENDING);
1970 quic_data.AddRead(ASYNC, OK);
1971 quic_data.AddSocketDataToFactory(&socket_factory_);
1972
1973 // After that fails, it will be resent via TCP.
1974 MockWrite http_writes[] = {
1975 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
1976 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
1977 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
1978
1979 MockRead http_reads[] = {
1980 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
1981 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
1982 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
1983 SequencedSocketData http_data(http_reads, arraysize(http_reads), http_writes,
1984 arraysize(http_writes));
1985 socket_factory_.AddSocketDataProvider(&http_data);
1986 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
1987
1988 // In order for a new QUIC session to be established via alternate-protocol
1989 // without racing an HTTP connection, we need the host resolution to happen
1990 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
1991 // connection to the the server, in this test we require confirmation
1992 // before encrypting so the HTTP job will still start.
1993 host_resolver_.set_synchronous_mode(true);
1994 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
1995 "");
1996 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
1997 AddressList address;
1998 std::unique_ptr<HostResolver::Request> request;
1999 host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address, CompletionCallback(),
2000 &request, net_log_.bound());
2001
2002 CreateSession();
2003 // Use a TestTaskRunner to avoid waiting in real time for timeouts.
2004 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(clock_));
2005 QuicStreamFactoryPeer::SetAlarmFactory(
2006 session_->quic_stream_factory(),
2007 base::MakeUnique<QuicChromiumAlarmFactory>(quic_task_runner_.get(),
2008 clock_));
2009
2010 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
2011
2012 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2013 TestCompletionCallback callback;
2014 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
2015 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2016
2017 // Pump the message loop to get the request started.
2018 base::RunLoop().RunUntilIdle();
2019 // Explicitly confirm the handshake.
2020 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
2021 QuicSession::HANDSHAKE_CONFIRMED);
2022
2023 // Run the QUIC session to completion.
2024 quic_task_runner_->RunUntilIdle();
2025 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2026
2027 ExpectQuicAlternateProtocolMapping();
2028
2029 // Let the transaction proceed which will result in QUIC being marked
2030 // as broken and the request falling back to TCP.
2031 EXPECT_THAT(callback.WaitForResult(), IsOk());
2032
2033 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2034 ASSERT_FALSE(http_data.AllReadDataConsumed());
2035
2036 // Read the response body over TCP.
2037 CheckResponseData(&trans, "hello world");
2038 ExpectBrokenAlternateProtocolMapping();
2039 ASSERT_TRUE(http_data.AllWriteDataConsumed());
2040 ASSERT_TRUE(http_data.AllReadDataConsumed());
2041 }
2042 1859
2043 // Verify that with mark_quic_broken_when_network_blackholes enabled, if a QUIC 1860 // Verify that with mark_quic_broken_when_network_blackholes enabled, if a QUIC
2044 // connection times out, then QUIC will be marked as broken but the request 1861 // connection times out, then QUIC will be marked as broken but the request
2045 // will not be retried over TCP. 1862 // will not be retried over TCP.
2046 TEST_P(QuicNetworkTransactionTest, 1863 TEST_P(QuicNetworkTransactionTest,
2047 TimeoutAfterHandshakeConfirmedAndHeadersThenBrokenNotRetried) { 1864 TimeoutAfterHandshakeConfirmedAndHeadersThenBrokenNotRetried) {
2048 params_.mark_quic_broken_when_network_blackholes = true; 1865 params_.mark_quic_broken_when_network_blackholes = true;
2049 params_.quic_idle_connection_timeout_seconds = 5; 1866 params_.quic_idle_connection_timeout_seconds = 5;
2050 1867
2051 // The request will initially go out over QUIC. 1868 // The request will initially go out over QUIC.
(...skipping 328 matching lines...) Expand 10 before | Expand all | Expand 10 after
2380 trans.reset(); 2197 trans.reset();
2381 2198
2382 // Run the QUIC session to completion. 2199 // Run the QUIC session to completion.
2383 quic_task_runner_->RunUntilIdle(); 2200 quic_task_runner_->RunUntilIdle();
2384 2201
2385 ExpectBrokenAlternateProtocolMapping(); 2202 ExpectBrokenAlternateProtocolMapping();
2386 2203
2387 ASSERT_TRUE(quic_data.AllWriteDataConsumed()); 2204 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2388 } 2205 }
2389 2206
2390 // Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
2391 // protocol error occurs after the handshake is confirmed, the request
2392 // retried over TCP and the QUIC will be marked as broken.
2393 TEST_P(QuicNetworkTransactionTest,
2394 ProtocolErrorAfterHandshakeConfirmedThenBroken) {
2395 params_.retry_without_alt_svc_on_quic_errors = true;
2396 params_.quic_idle_connection_timeout_seconds = 5;
2397
2398 // The request will initially go out over QUIC.
2399 MockQuicData quic_data;
2400 QuicStreamOffset header_stream_offset = 0;
2401 quic_data.AddWrite(ConstructClientRequestHeadersPacket(
2402 1, kClientDataStreamId1, true, true,
2403 GetRequestHeaders("GET", "https", "/"), &header_stream_offset));
2404 quic_data.AddWrite(ConstructSettingsPacket(2, SETTINGS_MAX_HEADER_LIST_SIZE,
2405 kDefaultMaxUncompressedHeaderSize,
2406 &header_stream_offset));
2407 // Peer sending data from an non-existing stream causes this end to raise
2408 // error and close connection.
2409 quic_data.AddRead(
2410 ConstructServerRstPacket(1, false, 99, QUIC_STREAM_LAST_ERROR));
2411 std::string quic_error_details = "Data for nonexistent stream";
2412 quic_data.AddWrite(ConstructClientAckAndConnectionClosePacket(
2413 3, QuicTime::Delta::Zero(), 1, 1, QUIC_INVALID_STREAM_ID,
2414 quic_error_details));
2415 quic_data.AddSocketDataToFactory(&socket_factory_);
2416
2417 // After that fails, it will be resent via TCP.
2418 MockWrite http_writes[] = {
2419 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
2420 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
2421 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
2422
2423 MockRead http_reads[] = {
2424 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
2425 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
2426 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
2427 SequencedSocketData http_data(http_reads, arraysize(http_reads), http_writes,
2428 arraysize(http_writes));
2429 socket_factory_.AddSocketDataProvider(&http_data);
2430 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2431
2432 // In order for a new QUIC session to be established via alternate-protocol
2433 // without racing an HTTP connection, we need the host resolution to happen
2434 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2435 // connection to the the server, in this test we require confirmation
2436 // before encrypting so the HTTP job will still start.
2437 host_resolver_.set_synchronous_mode(true);
2438 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2439 "");
2440 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
2441 AddressList address;
2442 std::unique_ptr<HostResolver::Request> request;
2443 host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address, CompletionCallback(),
2444 &request, net_log_.bound());
2445
2446 CreateSession();
2447
2448 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
2449
2450 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2451 TestCompletionCallback callback;
2452 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
2453 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2454
2455 // Pump the message loop to get the request started.
2456 base::RunLoop().RunUntilIdle();
2457 // Explicitly confirm the handshake.
2458 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
2459 QuicSession::HANDSHAKE_CONFIRMED);
2460
2461 // Run the QUIC session to completion.
2462 base::RunLoop().RunUntilIdle();
2463 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2464
2465 ExpectQuicAlternateProtocolMapping();
2466
2467 // Let the transaction proceed which will result in QUIC being marked
2468 // as broken and the request falling back to TCP.
2469 EXPECT_THAT(callback.WaitForResult(), IsOk());
2470
2471 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2472 ASSERT_FALSE(http_data.AllReadDataConsumed());
2473
2474 // Read the response body over TCP.
2475 CheckResponseData(&trans, "hello world");
2476 ExpectBrokenAlternateProtocolMapping();
2477 ASSERT_TRUE(http_data.AllWriteDataConsumed());
2478 ASSERT_TRUE(http_data.AllReadDataConsumed());
2479 }
2480
2481 TEST_P(QuicNetworkTransactionTest, 2207 TEST_P(QuicNetworkTransactionTest,
2482 DoNotUseAlternativeServiceQuicUnsupportedVersion) { 2208 DoNotUseAlternativeServiceQuicUnsupportedVersion) {
2483 std::string altsvc_header = base::StringPrintf( 2209 std::string altsvc_header = base::StringPrintf(
2484 "Alt-Svc: quic=\":443\"; v=\"%u\"\r\n\r\n", version_ - 1); 2210 "Alt-Svc: quic=\":443\"; v=\"%u\"\r\n\r\n", version_ - 1);
2485 MockRead http_reads[] = { 2211 MockRead http_reads[] = {
2486 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()), 2212 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
2487 MockRead("hello world"), 2213 MockRead("hello world"),
2488 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ), 2214 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2489 MockRead(ASYNC, OK)}; 2215 MockRead(ASYNC, OK)};
2490 2216
(...skipping 2219 matching lines...) Expand 10 before | Expand all | Expand 10 after
4710 4436
4711 request_.url = GURL("https://mail.example.org/pushed.jpg"); 4437 request_.url = GURL("https://mail.example.org/pushed.jpg");
4712 ChunkedUploadDataStream upload_data(0); 4438 ChunkedUploadDataStream upload_data(0);
4713 upload_data.AppendData("1", 1, true); 4439 upload_data.AppendData("1", 1, true);
4714 request_.upload_data_stream = &upload_data; 4440 request_.upload_data_stream = &upload_data;
4715 SendRequestAndExpectQuicResponse("and hello!"); 4441 SendRequestAndExpectQuicResponse("and hello!");
4716 } 4442 }
4717 4443
4718 } // namespace test 4444 } // namespace test
4719 } // namespace net 4445 } // namespace net
OLDNEW
« no previous file with comments | « net/http/http_network_transaction.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698