OLD | NEW |
---|---|
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 23 matching lines...) Expand all Loading... | |
34 #include "net/log/test_net_log.h" | 34 #include "net/log/test_net_log.h" |
35 #include "net/log/test_net_log_entry.h" | 35 #include "net/log/test_net_log_entry.h" |
36 #include "net/log/test_net_log_util.h" | 36 #include "net/log/test_net_log_util.h" |
37 #include "net/proxy/proxy_config_service_fixed.h" | 37 #include "net/proxy/proxy_config_service_fixed.h" |
38 #include "net/proxy/proxy_resolver.h" | 38 #include "net/proxy/proxy_resolver.h" |
39 #include "net/proxy/proxy_service.h" | 39 #include "net/proxy/proxy_service.h" |
40 #include "net/quic/chromium/crypto/proof_verifier_chromium.h" | 40 #include "net/quic/chromium/crypto/proof_verifier_chromium.h" |
41 #include "net/quic/chromium/mock_crypto_client_stream_factory.h" | 41 #include "net/quic/chromium/mock_crypto_client_stream_factory.h" |
42 #include "net/quic/chromium/mock_network_change_notifier.h" | 42 #include "net/quic/chromium/mock_network_change_notifier.h" |
43 #include "net/quic/chromium/mock_quic_data.h" | 43 #include "net/quic/chromium/mock_quic_data.h" |
44 #include "net/quic/chromium/quic_chromium_alarm_factory.h" | |
44 #include "net/quic/chromium/quic_http_utils.h" | 45 #include "net/quic/chromium/quic_http_utils.h" |
46 #include "net/quic/chromium/quic_stream_factory_peer.h" | |
45 #include "net/quic/chromium/quic_test_packet_maker.h" | 47 #include "net/quic/chromium/quic_test_packet_maker.h" |
48 #include "net/quic/chromium/test_task_runner.h" | |
46 #include "net/quic/core/crypto/quic_decrypter.h" | 49 #include "net/quic/core/crypto/quic_decrypter.h" |
47 #include "net/quic/core/crypto/quic_encrypter.h" | 50 #include "net/quic/core/crypto/quic_encrypter.h" |
48 #include "net/quic/core/quic_framer.h" | 51 #include "net/quic/core/quic_framer.h" |
49 #include "net/quic/platform/api/quic_string_piece.h" | 52 #include "net/quic/platform/api/quic_string_piece.h" |
50 #include "net/quic/test_tools/crypto_test_utils.h" | 53 #include "net/quic/test_tools/crypto_test_utils.h" |
51 #include "net/quic/test_tools/mock_clock.h" | 54 #include "net/quic/test_tools/mock_clock.h" |
52 #include "net/quic/test_tools/mock_random.h" | 55 #include "net/quic/test_tools/mock_random.h" |
53 #include "net/quic/test_tools/quic_test_utils.h" | 56 #include "net/quic/test_tools/quic_test_utils.h" |
54 #include "net/socket/client_socket_factory.h" | 57 #include "net/socket/client_socket_factory.h" |
55 #include "net/socket/mock_client_socket_pool_manager.h" | 58 #include "net/socket/mock_client_socket_pool_manager.h" |
(...skipping 230 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
286 | 289 |
287 std::unique_ptr<QuicEncryptedPacket> ConstructClientAckPacket( | 290 std::unique_ptr<QuicEncryptedPacket> ConstructClientAckPacket( |
288 QuicPacketNumber packet_number, | 291 QuicPacketNumber packet_number, |
289 QuicPacketNumber largest_received, | 292 QuicPacketNumber largest_received, |
290 QuicPacketNumber least_unacked) { | 293 QuicPacketNumber least_unacked) { |
291 return client_maker_.MakeAckPacket(packet_number, largest_received, | 294 return client_maker_.MakeAckPacket(packet_number, largest_received, |
292 least_unacked, least_unacked, true); | 295 least_unacked, least_unacked, true); |
293 } | 296 } |
294 | 297 |
295 std::unique_ptr<QuicEncryptedPacket> ConstructClientAckPacket( | 298 std::unique_ptr<QuicEncryptedPacket> ConstructClientAckPacket( |
299 QuicPacketNumber packet_number, | |
300 QuicPacketNumber largest_received, | |
301 QuicPacketNumber least_unacked, | |
302 QuicTime::Delta ack_delay_time) { | |
303 return client_maker_.MakeAckPacket(packet_number, largest_received, | |
304 least_unacked, least_unacked, true, | |
305 ack_delay_time); | |
306 } | |
307 | |
308 std::unique_ptr<QuicEncryptedPacket> ConstructClientAckPacket( | |
296 QuicPacketNumber largest_received, | 309 QuicPacketNumber largest_received, |
297 QuicPacketNumber least_unacked) { | 310 QuicPacketNumber least_unacked) { |
298 return client_maker_.MakeAckPacket(2, largest_received, least_unacked, | 311 return client_maker_.MakeAckPacket(2, largest_received, least_unacked, |
299 least_unacked, true); | 312 least_unacked, true); |
300 } | 313 } |
301 | 314 |
302 std::unique_ptr<QuicEncryptedPacket> ConstructClientAckPacket( | 315 std::unique_ptr<QuicEncryptedPacket> ConstructClientAckPacket( |
303 QuicPacketNumber packet_number, | 316 QuicPacketNumber packet_number, |
304 QuicPacketNumber largest_received, | 317 QuicPacketNumber largest_received, |
305 QuicPacketNumber ack_least_unacked, | 318 QuicPacketNumber ack_least_unacked, |
(...skipping 1041 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
1347 EXPECT_THAT(callback.WaitForResult(), IsOk()); | 1360 EXPECT_THAT(callback.WaitForResult(), IsOk()); |
1348 | 1361 |
1349 // Check whether this transaction is correctly marked as received a go-away | 1362 // Check whether this transaction is correctly marked as received a go-away |
1350 // because of migrating port. | 1363 // because of migrating port. |
1351 NetErrorDetails details; | 1364 NetErrorDetails details; |
1352 EXPECT_FALSE(details.quic_port_migration_detected); | 1365 EXPECT_FALSE(details.quic_port_migration_detected); |
1353 trans.PopulateNetErrorDetails(&details); | 1366 trans.PopulateNetErrorDetails(&details); |
1354 EXPECT_TRUE(details.quic_port_migration_detected); | 1367 EXPECT_TRUE(details.quic_port_migration_detected); |
1355 } | 1368 } |
1356 | 1369 |
1370 // Verify that if a QUIC connection times out, the QuicHttpStream will | |
1371 // return QUIC_PROTOCOL_ERROR. | |
1372 TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmed) { | |
1373 params_.quic_idle_connection_timeout_seconds = 5; | |
1374 | |
1375 // The request will initially go out over QUIC. | |
1376 MockQuicData quic_data; | |
1377 QuicStreamOffset header_stream_offset = 0; | |
1378 SpdyPriority priority = | |
1379 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY); | |
1380 | |
1381 std::string request_data; | |
1382 quic_data.AddWrite(client_maker_.MakeRequestHeadersPacketAndSaveData( | |
1383 1, kClientDataStreamId1, true, true, priority, | |
1384 GetRequestHeaders("GET", "https", "/"), nullptr, &header_stream_offset, | |
1385 &request_data)); | |
1386 | |
1387 std::string settings_data; | |
1388 QuicStreamOffset settings_offset = header_stream_offset; | |
1389 quic_data.AddWrite(client_maker_.MakeSettingsPacketAndSaveData( | |
1390 2, SETTINGS_MAX_HEADER_LIST_SIZE, kDefaultMaxUncompressedHeaderSize, true, | |
1391 &header_stream_offset, &settings_data)); | |
1392 // TLP 1 | |
1393 quic_data.AddWrite(client_maker_.MakeDataPacket(3, kHeadersStreamId, true, | |
1394 false, 0, request_data)); | |
1395 // TLP 2 | |
1396 quic_data.AddWrite(client_maker_.MakeDataPacket( | |
1397 4, kHeadersStreamId, true, false, settings_offset, settings_data)); | |
1398 // RTO 1 | |
1399 quic_data.AddWrite(client_maker_.MakeDataPacket(5, kHeadersStreamId, true, | |
1400 false, 0, request_data)); | |
1401 quic_data.AddWrite(client_maker_.MakeDataPacket( | |
1402 6, kHeadersStreamId, true, false, settings_offset, settings_data)); | |
1403 // RTO 2 | |
1404 quic_data.AddWrite(client_maker_.MakeDataPacket(7, kHeadersStreamId, true, | |
1405 false, 0, request_data)); | |
1406 quic_data.AddWrite(client_maker_.MakeDataPacket( | |
1407 8, kHeadersStreamId, true, false, settings_offset, settings_data)); | |
1408 // RTO 3 | |
1409 quic_data.AddWrite(client_maker_.MakeDataPacket(9, kHeadersStreamId, true, | |
Jana
2017/04/06 02:29:18
Is it easy to set the number of timeouts for conne
Ryan Hamilton
2017/04/06 03:43:39
I didn't see an obvious mechanism :/
| |
1410 false, 0, request_data)); | |
1411 quic_data.AddWrite(client_maker_.MakeDataPacket( | |
1412 10, kHeadersStreamId, true, false, settings_offset, settings_data)); | |
1413 | |
1414 quic_data.AddRead(ASYNC, ERR_IO_PENDING); | |
1415 quic_data.AddRead(ASYNC, OK); | |
1416 quic_data.AddSocketDataToFactory(&socket_factory_); | |
1417 | |
1418 // In order for a new QUIC session to be established via alternate-protocol | |
1419 // without racing an HTTP connection, we need the host resolution to happen | |
1420 // synchronously. Of course, even though QUIC *could* perform a 0-RTT | |
1421 // connection to the the server, in this test we require confirmation | |
1422 // before encrypting so the HTTP job will still start. | |
Jana
2017/04/06 02:29:18
Nice -- thanks for the elaborate comments!
Ryan Hamilton
2017/04/06 03:43:38
Yay! Thanks!
| |
1423 host_resolver_.set_synchronous_mode(true); | |
1424 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1", | |
1425 ""); | |
1426 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443)); | |
1427 AddressList address; | |
1428 std::unique_ptr<HostResolver::Request> request; | |
1429 host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address, CompletionCallback(), | |
1430 &request, net_log_.bound()); | |
1431 | |
1432 CreateSession(); | |
1433 // Use a TestTaskRunner to avoid waiting in real time for timeouts. | |
1434 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(clock_)); | |
1435 QuicStreamFactoryPeer::SetAlarmFactory( | |
1436 session_->quic_stream_factory(), | |
1437 base::MakeUnique<QuicChromiumAlarmFactory>(quic_task_runner_.get(), | |
1438 clock_)); | |
1439 | |
1440 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT); | |
1441 | |
1442 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get()); | |
1443 TestCompletionCallback callback; | |
1444 int rv = trans.Start(&request_, callback.callback(), net_log_.bound()); | |
1445 EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); | |
1446 | |
1447 // Pump the message loop to get the request started. | |
1448 base::RunLoop().RunUntilIdle(); | |
1449 // Explicitly confirm the handshake. | |
1450 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent( | |
1451 QuicSession::HANDSHAKE_CONFIRMED); | |
1452 | |
1453 // Run the QUIC session to completion. | |
1454 quic_task_runner_->RunUntilIdle(); | |
1455 | |
1456 ASSERT_TRUE(quic_data.AllWriteDataConsumed()); | |
1457 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR)); | |
1458 } | |
1459 | |
1460 // Verify that if a QUIC connection RTOs, the QuicHttpStream will | |
1461 // return QUIC_PROTOCOL_ERROR. | |
1462 TEST_P(QuicNetworkTransactionTest, TooManyRtosAfterHandshakeConfirmed) { | |
Jana
2017/04/06 02:29:18
Isn't the test above sufficient to test this case?
Ryan Hamilton
2017/04/06 03:43:38
The previous test handles the IDLE_NETWORK_TIMEOUT
| |
1463 params_.quic_connection_options.push_back(k5RTO); | |
1464 | |
1465 // The request will initially go out over QUIC. | |
1466 MockQuicData quic_data; | |
1467 QuicStreamOffset header_stream_offset = 0; | |
1468 SpdyPriority priority = | |
1469 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY); | |
1470 | |
1471 std::string request_data; | |
1472 quic_data.AddWrite(client_maker_.MakeRequestHeadersPacketAndSaveData( | |
1473 1, kClientDataStreamId1, true, true, priority, | |
1474 GetRequestHeaders("GET", "https", "/"), nullptr, &header_stream_offset, | |
1475 &request_data)); | |
1476 | |
1477 std::string settings_data; | |
1478 QuicStreamOffset settings_offset = header_stream_offset; | |
1479 quic_data.AddWrite(client_maker_.MakeSettingsPacketAndSaveData( | |
1480 2, SETTINGS_MAX_HEADER_LIST_SIZE, kDefaultMaxUncompressedHeaderSize, true, | |
1481 &header_stream_offset, &settings_data)); | |
1482 // TLP 1 | |
1483 quic_data.AddWrite(client_maker_.MakeDataPacket(3, kHeadersStreamId, true, | |
1484 false, 0, request_data)); | |
1485 // TLP 2 | |
1486 quic_data.AddWrite(client_maker_.MakeDataPacket( | |
1487 4, kHeadersStreamId, true, false, settings_offset, settings_data)); | |
1488 // RTO 1 | |
1489 quic_data.AddWrite(client_maker_.MakeDataPacket(5, kHeadersStreamId, true, | |
1490 false, 0, request_data)); | |
1491 quic_data.AddWrite(client_maker_.MakeDataPacket( | |
1492 6, kHeadersStreamId, true, false, settings_offset, settings_data)); | |
1493 // RTO 2 | |
1494 quic_data.AddWrite(client_maker_.MakeDataPacket(7, kHeadersStreamId, true, | |
1495 false, 0, request_data)); | |
1496 quic_data.AddWrite(client_maker_.MakeDataPacket( | |
1497 8, kHeadersStreamId, true, false, settings_offset, settings_data)); | |
1498 // RTO 3 | |
1499 quic_data.AddWrite(client_maker_.MakeDataPacket(9, kHeadersStreamId, true, | |
1500 false, 0, request_data)); | |
1501 quic_data.AddWrite(client_maker_.MakeDataPacket( | |
1502 10, kHeadersStreamId, true, false, settings_offset, settings_data)); | |
1503 // RTO 4 | |
1504 quic_data.AddWrite(client_maker_.MakeDataPacket(11, kHeadersStreamId, true, | |
1505 false, 0, request_data)); | |
1506 quic_data.AddWrite(client_maker_.MakeDataPacket( | |
1507 12, kHeadersStreamId, true, false, settings_offset, settings_data)); | |
1508 // RTO 5 | |
1509 quic_data.AddWrite(client_maker_.MakeAckAndConnectionClosePacket( | |
1510 13, true, QuicTime::Delta::Infinite(), 0, 1, QUIC_TOO_MANY_RTOS, | |
1511 "5 consecutive retransmission timeouts")); | |
1512 | |
1513 quic_data.AddRead(ASYNC, OK); | |
1514 quic_data.AddSocketDataToFactory(&socket_factory_); | |
1515 | |
1516 // In order for a new QUIC session to be established via alternate-protocol | |
1517 // without racing an HTTP connection, we need the host resolution to happen | |
1518 // synchronously. Of course, even though QUIC *could* perform a 0-RTT | |
1519 // connection to the the server, in this test we require confirmation | |
1520 // before encrypting so the HTTP job will still start. | |
1521 host_resolver_.set_synchronous_mode(true); | |
1522 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1", | |
1523 ""); | |
1524 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443)); | |
1525 AddressList address; | |
1526 std::unique_ptr<HostResolver::Request> request; | |
1527 host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address, CompletionCallback(), | |
1528 &request, net_log_.bound()); | |
1529 | |
1530 CreateSession(); | |
1531 // Use a TestTaskRunner to avoid waiting in real time for timeouts. | |
1532 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(clock_)); | |
1533 QuicStreamFactoryPeer::SetAlarmFactory( | |
1534 session_->quic_stream_factory(), | |
1535 base::MakeUnique<QuicChromiumAlarmFactory>(quic_task_runner_.get(), | |
1536 clock_)); | |
1537 | |
1538 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT); | |
1539 | |
1540 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get()); | |
1541 TestCompletionCallback callback; | |
1542 int rv = trans.Start(&request_, callback.callback(), net_log_.bound()); | |
1543 EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); | |
1544 | |
1545 // Pump the message loop to get the request started. | |
1546 base::RunLoop().RunUntilIdle(); | |
1547 // Explicitly confirm the handshake. | |
1548 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent( | |
1549 QuicSession::HANDSHAKE_CONFIRMED); | |
1550 | |
1551 // Run the QUIC session to completion. | |
1552 quic_task_runner_->RunUntilIdle(); | |
1553 | |
1554 ASSERT_TRUE(quic_data.AllWriteDataConsumed()); | |
1555 EXPECT_THAT(callback.WaitForResult(), IsError(ERR_QUIC_PROTOCOL_ERROR)); | |
1556 } | |
1557 | |
1558 // Verify that with mark_quic_broken_when_network_suspected enabled, if a QUIC | |
1559 // connection times out, then QUIC will be marked as broken and the request | |
1560 // retried over TCP. | |
1561 TEST_P(QuicNetworkTransactionTest, TimeoutAfterHandshakeConfirmedThenBroken) { | |
1562 params_.mark_quic_broken_when_network_suspected = true; | |
1563 params_.quic_idle_connection_timeout_seconds = 5; | |
1564 | |
1565 // The request will initially go out over QUIC. | |
1566 MockQuicData quic_data; | |
1567 QuicStreamOffset header_stream_offset = 0; | |
1568 SpdyPriority priority = | |
1569 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY); | |
1570 | |
1571 std::string request_data; | |
1572 quic_data.AddWrite(client_maker_.MakeRequestHeadersPacketAndSaveData( | |
1573 1, kClientDataStreamId1, true, true, priority, | |
1574 GetRequestHeaders("GET", "https", "/"), nullptr, &header_stream_offset, | |
1575 &request_data)); | |
1576 | |
1577 std::string settings_data; | |
1578 QuicStreamOffset settings_offset = header_stream_offset; | |
1579 quic_data.AddWrite(client_maker_.MakeSettingsPacketAndSaveData( | |
1580 2, SETTINGS_MAX_HEADER_LIST_SIZE, kDefaultMaxUncompressedHeaderSize, true, | |
1581 &header_stream_offset, &settings_data)); | |
1582 // TLP 1 | |
1583 quic_data.AddWrite(client_maker_.MakeDataPacket(3, kHeadersStreamId, true, | |
1584 false, 0, request_data)); | |
1585 // TLP 2 | |
1586 quic_data.AddWrite(client_maker_.MakeDataPacket( | |
1587 4, kHeadersStreamId, true, false, settings_offset, settings_data)); | |
1588 // RTO 1 | |
1589 quic_data.AddWrite(client_maker_.MakeDataPacket(5, kHeadersStreamId, true, | |
1590 false, 0, request_data)); | |
1591 quic_data.AddWrite(client_maker_.MakeDataPacket( | |
1592 6, kHeadersStreamId, true, false, settings_offset, settings_data)); | |
1593 // RTO 2 | |
1594 quic_data.AddWrite(client_maker_.MakeDataPacket(7, kHeadersStreamId, true, | |
1595 false, 0, request_data)); | |
1596 quic_data.AddWrite(client_maker_.MakeDataPacket( | |
1597 8, kHeadersStreamId, true, false, settings_offset, settings_data)); | |
1598 // RTO 3 | |
1599 quic_data.AddWrite(client_maker_.MakeDataPacket(9, kHeadersStreamId, true, | |
1600 false, 0, request_data)); | |
1601 quic_data.AddWrite(client_maker_.MakeDataPacket( | |
1602 10, kHeadersStreamId, true, false, settings_offset, settings_data)); | |
1603 | |
1604 quic_data.AddRead(ASYNC, ERR_IO_PENDING); | |
1605 quic_data.AddRead(ASYNC, OK); | |
1606 quic_data.AddSocketDataToFactory(&socket_factory_); | |
1607 | |
1608 // After that fails, it will be resent via HTTP. | |
Jana
2017/04/06 02:29:18
via TCP?
Ryan Hamilton
2017/04/06 03:43:38
Done.
| |
1609 MockWrite http_writes[] = { | |
1610 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"), | |
1611 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"), | |
1612 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")}; | |
1613 | |
1614 MockRead http_reads[] = { | |
1615 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"), | |
1616 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader), | |
1617 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)}; | |
1618 SequencedSocketData http_data(http_reads, arraysize(http_reads), http_writes, | |
1619 arraysize(http_writes)); | |
1620 socket_factory_.AddSocketDataProvider(&http_data); | |
1621 socket_factory_.AddSSLSocketDataProvider(&ssl_data_); | |
1622 | |
1623 // In order for a new QUIC session to be established via alternate-protocol | |
1624 // without racing an HTTP connection, we need the host resolution to happen | |
1625 // synchronously. Of course, even though QUIC *could* perform a 0-RTT | |
1626 // connection to the the server, in this test we require confirmation | |
1627 // before encrypting so the HTTP job will still start. | |
1628 host_resolver_.set_synchronous_mode(true); | |
1629 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1", | |
1630 ""); | |
1631 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443)); | |
1632 AddressList address; | |
1633 std::unique_ptr<HostResolver::Request> request; | |
1634 host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address, CompletionCallback(), | |
1635 &request, net_log_.bound()); | |
1636 | |
1637 CreateSession(); | |
1638 // Use a TestTaskRunner to avoid waiting in real time for timeouts. | |
1639 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(clock_)); | |
1640 QuicStreamFactoryPeer::SetAlarmFactory( | |
1641 session_->quic_stream_factory(), | |
1642 base::MakeUnique<QuicChromiumAlarmFactory>(quic_task_runner_.get(), | |
1643 clock_)); | |
1644 | |
1645 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT); | |
1646 | |
1647 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get()); | |
1648 TestCompletionCallback callback; | |
1649 int rv = trans.Start(&request_, callback.callback(), net_log_.bound()); | |
1650 EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); | |
1651 | |
1652 // Pump the message loop to get the request started. | |
1653 base::RunLoop().RunUntilIdle(); | |
1654 // Explicitly confirm the handshake. | |
1655 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent( | |
1656 QuicSession::HANDSHAKE_CONFIRMED); | |
1657 | |
1658 // Run the QUIC session to completion. | |
1659 quic_task_runner_->RunUntilIdle(); | |
1660 ASSERT_TRUE(quic_data.AllWriteDataConsumed()); | |
1661 | |
1662 // Let the transaction proceed which will result in QUIC being marked | |
1663 // as broken and the request falling back to TCP. | |
1664 EXPECT_THAT(callback.WaitForResult(), IsOk()); | |
1665 | |
1666 ExpectBrokenAlternateProtocolMapping(); | |
1667 ASSERT_TRUE(quic_data.AllWriteDataConsumed()); | |
1668 ASSERT_FALSE(http_data.AllReadDataConsumed()); | |
1669 | |
1670 // Read the response body over TCP. | |
1671 CheckResponseData(&trans, "hello world"); | |
1672 ASSERT_TRUE(http_data.AllWriteDataConsumed()); | |
1673 ASSERT_TRUE(http_data.AllReadDataConsumed()); | |
1674 } | |
1675 | |
1676 // Verify that with mark_quic_broken_when_network_suspected enabled, if a QUIC | |
1677 // connection times out, then QUIC will be marked as broken but the request | |
1678 // will not be retried over TCP. | |
1679 TEST_P(QuicNetworkTransactionTest, | |
1680 TimeoutAfterHandshakeConfirmedAndHeadersThenBrokenNotRetried) { | |
1681 params_.mark_quic_broken_when_network_suspected = true; | |
1682 params_.quic_idle_connection_timeout_seconds = 5; | |
1683 | |
1684 // The request will initially go out over QUIC. | |
1685 MockQuicData quic_data; | |
1686 QuicStreamOffset header_stream_offset = 0; | |
1687 SpdyPriority priority = | |
1688 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY); | |
1689 | |
1690 std::string request_data; | |
1691 quic_data.AddWrite(client_maker_.MakeRequestHeadersPacketAndSaveData( | |
1692 1, kClientDataStreamId1, true, true, priority, | |
1693 GetRequestHeaders("GET", "https", "/"), nullptr, &header_stream_offset, | |
1694 &request_data)); | |
1695 | |
1696 std::string settings_data; | |
1697 QuicStreamOffset settings_offset = header_stream_offset; | |
1698 quic_data.AddWrite(client_maker_.MakeSettingsPacketAndSaveData( | |
1699 2, SETTINGS_MAX_HEADER_LIST_SIZE, kDefaultMaxUncompressedHeaderSize, true, | |
1700 &header_stream_offset, &settings_data)); | |
1701 | |
1702 quic_data.AddRead(ConstructServerResponseHeadersPacket( | |
1703 1, kClientDataStreamId1, false, false, GetResponseHeaders("200 OK"))); | |
1704 // quic_data.AddWrite(ConstructClientAckPacket(3, 1, 1)); | |
1705 quic_data.AddWrite( | |
1706 ConstructClientAckPacket(3, 1, 1, QuicTime::Delta::FromMilliseconds(25))); | |
1707 | |
1708 // TLP 1 | |
1709 quic_data.AddWrite(client_maker_.MakeDataPacket(4, kHeadersStreamId, false, | |
1710 false, 0, request_data)); | |
1711 // TLP 2 | |
1712 quic_data.AddWrite(client_maker_.MakeDataPacket( | |
1713 5, kHeadersStreamId, false, false, settings_offset, settings_data)); | |
1714 // RTO 1 | |
1715 quic_data.AddWrite(client_maker_.MakeDataPacket(6, kHeadersStreamId, false, | |
1716 false, 0, request_data)); | |
1717 quic_data.AddWrite(client_maker_.MakeDataPacket( | |
1718 7, kHeadersStreamId, false, false, settings_offset, settings_data)); | |
1719 // RTO 2 | |
1720 quic_data.AddWrite(client_maker_.MakeDataPacket(8, kHeadersStreamId, false, | |
1721 false, 0, request_data)); | |
1722 quic_data.AddWrite(client_maker_.MakeDataPacket( | |
1723 9, kHeadersStreamId, false, false, settings_offset, settings_data)); | |
1724 // RTO 3 | |
1725 quic_data.AddWrite(client_maker_.MakeDataPacket(10, kHeadersStreamId, false, | |
1726 false, 0, request_data)); | |
1727 quic_data.AddWrite(client_maker_.MakeDataPacket( | |
1728 11, kHeadersStreamId, false, false, settings_offset, settings_data)); | |
1729 | |
1730 quic_data.AddRead(ASYNC, ERR_IO_PENDING); | |
1731 quic_data.AddRead(ASYNC, OK); | |
1732 quic_data.AddSocketDataToFactory(&socket_factory_); | |
1733 | |
1734 // In order for a new QUIC session to be established via alternate-protocol | |
1735 // without racing an HTTP connection, we need the host resolution to happen | |
1736 // synchronously. Of course, even though QUIC *could* perform a 0-RTT | |
1737 // connection to the the server, in this test we require confirmation | |
1738 // before encrypting so the HTTP job will still start. | |
1739 host_resolver_.set_synchronous_mode(true); | |
1740 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1", | |
1741 ""); | |
1742 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443)); | |
1743 AddressList address; | |
1744 std::unique_ptr<HostResolver::Request> request; | |
1745 host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address, CompletionCallback(), | |
1746 &request, net_log_.bound()); | |
1747 | |
1748 CreateSession(); | |
1749 // Use a TestTaskRunner to avoid waiting in real time for timeouts. | |
1750 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(clock_)); | |
1751 QuicStreamFactoryPeer::SetAlarmFactory( | |
1752 session_->quic_stream_factory(), | |
1753 base::MakeUnique<QuicChromiumAlarmFactory>(quic_task_runner_.get(), | |
1754 clock_)); | |
1755 | |
1756 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT); | |
1757 | |
1758 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get()); | |
1759 TestCompletionCallback callback; | |
1760 int rv = trans.Start(&request_, callback.callback(), net_log_.bound()); | |
1761 EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); | |
1762 | |
1763 // Pump the message loop to get the request started. | |
1764 base::RunLoop().RunUntilIdle(); | |
1765 // Explicitly confirm the handshake. | |
1766 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent( | |
1767 QuicSession::HANDSHAKE_CONFIRMED); | |
1768 | |
1769 // Pump the message loop to get the request started. | |
1770 base::RunLoop().RunUntilIdle(); | |
1771 | |
1772 // Run the QUIC session to completion. | |
1773 quic_task_runner_->RunUntilIdle(); | |
1774 ASSERT_TRUE(quic_data.AllWriteDataConsumed()); | |
1775 | |
1776 // Let the transaction proceed which will result in QUIC being marked | |
1777 // as broken and the request falling back to TCP. | |
1778 EXPECT_THAT(callback.WaitForResult(), IsOk()); | |
1779 | |
1780 ExpectBrokenAlternateProtocolMapping(); | |
1781 ASSERT_TRUE(quic_data.AllWriteDataConsumed()); | |
1782 | |
1783 std::string response_data; | |
1784 ASSERT_THAT(ReadTransaction(&trans, &response_data), | |
1785 IsError(ERR_QUIC_PROTOCOL_ERROR)); | |
1786 } | |
1787 | |
1788 // Verify that with mark_quic_broken_when_network_suspected enabled, if a QUIC | |
1789 // connection RTOs, then QUIC will be marked as broken and the request retried | |
1790 // over TCP. | |
1791 TEST_P(QuicNetworkTransactionTest, | |
1792 TooManyRtosAfterHandshakeConfirmedThenBroken) { | |
1793 params_.mark_quic_broken_when_network_suspected = true; | |
1794 params_.quic_connection_options.push_back(k5RTO); | |
1795 | |
1796 // The request will initially go out over QUIC. | |
1797 MockQuicData quic_data; | |
1798 QuicStreamOffset header_stream_offset = 0; | |
1799 SpdyPriority priority = | |
1800 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY); | |
1801 | |
1802 std::string request_data; | |
1803 quic_data.AddWrite(client_maker_.MakeRequestHeadersPacketAndSaveData( | |
1804 1, kClientDataStreamId1, true, true, priority, | |
1805 GetRequestHeaders("GET", "https", "/"), nullptr, &header_stream_offset, | |
1806 &request_data)); | |
1807 | |
1808 std::string settings_data; | |
1809 QuicStreamOffset settings_offset = header_stream_offset; | |
1810 quic_data.AddWrite(client_maker_.MakeSettingsPacketAndSaveData( | |
1811 2, SETTINGS_MAX_HEADER_LIST_SIZE, kDefaultMaxUncompressedHeaderSize, true, | |
1812 &header_stream_offset, &settings_data)); | |
1813 // TLP 1 | |
1814 quic_data.AddWrite(client_maker_.MakeDataPacket(3, kHeadersStreamId, true, | |
1815 false, 0, request_data)); | |
1816 // TLP 2 | |
1817 quic_data.AddWrite(client_maker_.MakeDataPacket( | |
1818 4, kHeadersStreamId, true, false, settings_offset, settings_data)); | |
1819 // RTO 1 | |
1820 quic_data.AddWrite(client_maker_.MakeDataPacket(5, kHeadersStreamId, true, | |
1821 false, 0, request_data)); | |
1822 quic_data.AddWrite(client_maker_.MakeDataPacket( | |
1823 6, kHeadersStreamId, true, false, settings_offset, settings_data)); | |
1824 // RTO 2 | |
1825 quic_data.AddWrite(client_maker_.MakeDataPacket(7, kHeadersStreamId, true, | |
1826 false, 0, request_data)); | |
1827 quic_data.AddWrite(client_maker_.MakeDataPacket( | |
1828 8, kHeadersStreamId, true, false, settings_offset, settings_data)); | |
1829 // RTO 3 | |
1830 quic_data.AddWrite(client_maker_.MakeDataPacket(9, kHeadersStreamId, true, | |
1831 false, 0, request_data)); | |
1832 quic_data.AddWrite(client_maker_.MakeDataPacket( | |
1833 10, kHeadersStreamId, true, false, settings_offset, settings_data)); | |
1834 // RTO 4 | |
1835 quic_data.AddWrite(client_maker_.MakeDataPacket(11, kHeadersStreamId, true, | |
1836 false, 0, request_data)); | |
1837 quic_data.AddWrite(client_maker_.MakeDataPacket( | |
1838 12, kHeadersStreamId, true, false, settings_offset, settings_data)); | |
1839 | |
1840 quic_data.AddWrite(client_maker_.MakeAckAndConnectionClosePacket( | |
1841 13, true, QuicTime::Delta::Infinite(), 0, 1, QUIC_TOO_MANY_RTOS, | |
1842 "5 consecutive retransmission timeouts")); | |
1843 | |
1844 quic_data.AddRead(ASYNC, OK); | |
1845 quic_data.AddSocketDataToFactory(&socket_factory_); | |
1846 | |
1847 // After that fails, it will be resent via HTTP. | |
1848 MockWrite http_writes[] = { | |
1849 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"), | |
1850 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"), | |
1851 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")}; | |
1852 | |
1853 MockRead http_reads[] = { | |
1854 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"), | |
1855 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader), | |
1856 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)}; | |
1857 SequencedSocketData http_data(http_reads, arraysize(http_reads), http_writes, | |
1858 arraysize(http_writes)); | |
1859 socket_factory_.AddSocketDataProvider(&http_data); | |
1860 socket_factory_.AddSSLSocketDataProvider(&ssl_data_); | |
1861 | |
1862 // In order for a new QUIC session to be established via alternate-protocol | |
1863 // without racing an HTTP connection, we need the host resolution to happen | |
1864 // synchronously. Of course, even though QUIC *could* perform a 0-RTT | |
1865 // connection to the the server, in this test we require confirmation | |
1866 // before encrypting so the HTTP job will still start. | |
1867 host_resolver_.set_synchronous_mode(true); | |
1868 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1", | |
1869 ""); | |
1870 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443)); | |
1871 AddressList address; | |
1872 std::unique_ptr<HostResolver::Request> request; | |
1873 host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address, CompletionCallback(), | |
1874 &request, net_log_.bound()); | |
1875 | |
1876 CreateSession(); | |
1877 // Use a TestTaskRunner to avoid waiting in real time for timeouts. | |
1878 scoped_refptr<TestTaskRunner> quic_task_runner_(new TestTaskRunner(clock_)); | |
1879 QuicStreamFactoryPeer::SetAlarmFactory( | |
1880 session_->quic_stream_factory(), | |
1881 base::MakeUnique<QuicChromiumAlarmFactory>(quic_task_runner_.get(), | |
1882 clock_)); | |
1883 | |
1884 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT); | |
1885 | |
1886 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get()); | |
1887 TestCompletionCallback callback; | |
1888 int rv = trans.Start(&request_, callback.callback(), net_log_.bound()); | |
1889 EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); | |
1890 | |
1891 // Pump the message loop to get the request started. | |
1892 base::RunLoop().RunUntilIdle(); | |
1893 // Explicitly confirm the handshake. | |
1894 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent( | |
1895 QuicSession::HANDSHAKE_CONFIRMED); | |
1896 | |
1897 // Run the QUIC session to completion. | |
1898 quic_task_runner_->RunUntilIdle(); | |
1899 ASSERT_TRUE(quic_data.AllWriteDataConsumed()); | |
1900 | |
1901 // Let the transaction proceed which will result in QUIC being marked | |
1902 // as broken and the request falling back to TCP. | |
1903 EXPECT_THAT(callback.WaitForResult(), IsOk()); | |
1904 | |
1905 ExpectBrokenAlternateProtocolMapping(); | |
1906 ASSERT_TRUE(quic_data.AllWriteDataConsumed()); | |
1907 ASSERT_FALSE(http_data.AllReadDataConsumed()); | |
1908 | |
1909 // Read the response body over TCP. | |
1910 CheckResponseData(&trans, "hello world"); | |
1911 ASSERT_TRUE(http_data.AllWriteDataConsumed()); | |
1912 ASSERT_TRUE(http_data.AllReadDataConsumed()); | |
1913 } | |
1914 | |
1357 TEST_P(QuicNetworkTransactionTest, | 1915 TEST_P(QuicNetworkTransactionTest, |
1358 DoNotUseAlternativeServiceQuicUnsupportedVersion) { | 1916 DoNotUseAlternativeServiceQuicUnsupportedVersion) { |
1359 std::string altsvc_header = base::StringPrintf( | 1917 std::string altsvc_header = base::StringPrintf( |
1360 "Alt-Svc: quic=\":443\"; v=\"%u\"\r\n\r\n", version_ - 1); | 1918 "Alt-Svc: quic=\":443\"; v=\"%u\"\r\n\r\n", version_ - 1); |
1361 MockRead http_reads[] = { | 1919 MockRead http_reads[] = { |
1362 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()), | 1920 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()), |
1363 MockRead("hello world"), | 1921 MockRead("hello world"), |
1364 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ), | 1922 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ), |
1365 MockRead(ASYNC, OK)}; | 1923 MockRead(ASYNC, OK)}; |
1366 | 1924 |
(...skipping 2146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
3513 AddHangingSocketData(); | 4071 AddHangingSocketData(); |
3514 | 4072 |
3515 SendRequestAndExpectQuicResponse(origin1_); | 4073 SendRequestAndExpectQuicResponse(origin1_); |
3516 SendRequestAndExpectQuicResponse(origin2_); | 4074 SendRequestAndExpectQuicResponse(origin2_); |
3517 | 4075 |
3518 EXPECT_TRUE(AllDataConsumed()); | 4076 EXPECT_TRUE(AllDataConsumed()); |
3519 } | 4077 } |
3520 | 4078 |
3521 } // namespace test | 4079 } // namespace test |
3522 } // namespace net | 4080 } // namespace net |
OLD | NEW |