Chromium Code Reviews| 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 |