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

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

Issue 2933773002: When a stream is created for a QUIC session to a server which has been (Closed)
Patch Set: Fix zhongyi's comments Created 3 years, 6 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
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 <algorithm> 5 #include <algorithm>
6 #include <memory> 6 #include <memory>
7 #include <ostream> 7 #include <ostream>
8 #include <string> 8 #include <string>
9 #include <utility> 9 #include <utility>
10 #include <vector> 10 #include <vector>
(...skipping 2558 matching lines...) Expand 10 before | Expand all | Expand 10 after
2569 ASSERT_TRUE(quic_data.AllWriteDataConsumed()); 2569 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2570 ASSERT_FALSE(http_data.AllReadDataConsumed()); 2570 ASSERT_FALSE(http_data.AllReadDataConsumed());
2571 2571
2572 // Read the response body over TCP. 2572 // Read the response body over TCP.
2573 CheckResponseData(&trans, "hello world"); 2573 CheckResponseData(&trans, "hello world");
2574 ExpectBrokenAlternateProtocolMapping(); 2574 ExpectBrokenAlternateProtocolMapping();
2575 ASSERT_TRUE(http_data.AllWriteDataConsumed()); 2575 ASSERT_TRUE(http_data.AllWriteDataConsumed());
2576 ASSERT_TRUE(http_data.AllReadDataConsumed()); 2576 ASSERT_TRUE(http_data.AllReadDataConsumed());
2577 } 2577 }
2578 2578
2579 // Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
2580 // request is reset from, then QUIC will be marked as broken and the request
2581 // retried over TCP.
2582 TEST_P(QuicNetworkTransactionTest, ResetAfterHandshakeConfirmedThenBroken) {
2583 session_params_.retry_without_alt_svc_on_quic_errors = true;
2584
2585 // The request will initially go out over QUIC.
2586 MockQuicData quic_data;
2587 QuicStreamOffset header_stream_offset = 0;
2588 SpdyPriority priority =
2589 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY);
2590
2591 std::string request_data;
2592 quic_data.AddWrite(client_maker_.MakeRequestHeadersPacketAndSaveData(
2593 1, GetNthClientInitiatedStreamId(0), true, true, priority,
2594 GetRequestHeaders("GET", "https", "/"), nullptr, &header_stream_offset,
2595 &request_data));
2596
2597 std::string settings_data;
2598 // QuicStreamOffset settings_offset = header_stream_offset;
2599 quic_data.AddWrite(client_maker_.MakeInitialSettingsPacketAndSaveData(
2600 2, &header_stream_offset, &settings_data));
2601
2602 quic_data.AddRead(ConstructServerRstPacket(
2603 1, false, GetNthClientInitiatedStreamId(0), QUIC_HEADERS_TOO_LARGE));
2604
2605 quic_data.AddRead(ASYNC, OK);
2606 quic_data.AddSocketDataToFactory(&socket_factory_);
2607
2608 // After that fails, it will be resent via TCP.
2609 MockWrite http_writes[] = {
2610 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
2611 MockWrite(SYNCHRONOUS, 1, "Host: mail.example.org\r\n"),
2612 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
2613
2614 MockRead http_reads[] = {
2615 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
2616 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
2617 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
2618 SequencedSocketData http_data(http_reads, arraysize(http_reads), http_writes,
2619 arraysize(http_writes));
2620 socket_factory_.AddSocketDataProvider(&http_data);
2621 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2622
2623 // In order for a new QUIC session to be established via alternate-protocol
2624 // without racing an HTTP connection, we need the host resolution to happen
2625 // synchronously. Of course, even though QUIC *could* perform a 0-RTT
2626 // connection to the the server, in this test we require confirmation
2627 // before encrypting so the HTTP job will still start.
2628 host_resolver_.set_synchronous_mode(true);
2629 host_resolver_.rules()->AddIPLiteralRule("mail.example.org", "192.168.0.1",
2630 "");
2631 HostResolver::RequestInfo info(HostPortPair("mail.example.org", 443));
2632 AddressList address;
2633 std::unique_ptr<HostResolver::Request> request;
2634 host_resolver_.Resolve(info, DEFAULT_PRIORITY, &address, CompletionCallback(),
2635 &request, net_log_.bound());
2636
2637 CreateSession();
2638
2639 AddQuicAlternateProtocolMapping(MockCryptoClientStream::ZERO_RTT);
2640
2641 HttpNetworkTransaction trans(DEFAULT_PRIORITY, session_.get());
2642 TestCompletionCallback callback;
2643 int rv = trans.Start(&request_, callback.callback(), net_log_.bound());
2644 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
2645
2646 // Pump the message loop to get the request started.
2647 base::RunLoop().RunUntilIdle();
2648 // Explicitly confirm the handshake.
2649 crypto_client_stream_factory_.last_stream()->SendOnCryptoHandshakeEvent(
2650 QuicSession::HANDSHAKE_CONFIRMED);
2651
2652 // Run the QUIC session to completion.
2653 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2654
2655 ExpectQuicAlternateProtocolMapping();
2656
2657 // Let the transaction proceed which will result in QUIC being marked
2658 // as broken and the request falling back to TCP.
2659 EXPECT_THAT(callback.WaitForResult(), IsOk());
2660
2661 ASSERT_TRUE(quic_data.AllWriteDataConsumed());
2662 ASSERT_FALSE(http_data.AllReadDataConsumed());
2663
2664 // Read the response body over TCP.
2665 CheckResponseData(&trans, "hello world");
2666 ExpectBrokenAlternateProtocolMapping();
2667 ASSERT_TRUE(http_data.AllWriteDataConsumed());
2668 ASSERT_TRUE(http_data.AllReadDataConsumed());
2669 }
2670
2671 // Verify that with retry_without_alt_svc_on_quic_errors enabled, if a QUIC
2672 // request is reset from, then QUIC will be marked as broken and the request
2673 // retried over TCP. Then, subsequent requests will go over a new QUIC
2674 // connection instead of going back to the broken QUIC connection.
2675 // This is a regression tests for crbug/731303.
2676 TEST_P(QuicNetworkTransactionTest,
2677 ResetPooledAfterHandshakeConfirmedThenBroken) {
2678 session_params_.retry_without_alt_svc_on_quic_errors = true;
2679
2680 GURL origin1 = request_.url;
2681 GURL origin2("https://www.example.org/");
2682 ASSERT_NE(origin1.host(), origin2.host());
2683
2684 MockQuicData mock_quic_data;
2685 QuicStreamOffset request_header_offset(0);
2686 QuicStreamOffset response_header_offset(0);
2687
2688 scoped_refptr<X509Certificate> cert(
2689 ImportCertFromFile(GetTestCertsDirectory(), "wildcard.pem"));
2690 ASSERT_TRUE(cert->VerifyNameMatch("www.example.org", false));
2691 ASSERT_TRUE(cert->VerifyNameMatch("mail.example.org", false));
2692
2693 ProofVerifyDetailsChromium verify_details;
2694 verify_details.cert_verify_result.verified_cert = cert;
2695 verify_details.cert_verify_result.is_issued_by_known_root = true;
2696 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2697
2698 mock_quic_data.AddWrite(
2699 ConstructInitialSettingsPacket(1, &request_header_offset));
2700 // First request.
2701 mock_quic_data.AddWrite(ConstructClientRequestHeadersPacket(
2702 2, GetNthClientInitiatedStreamId(0), true, true,
2703 GetRequestHeaders("GET", "https", "/"), &request_header_offset));
2704 mock_quic_data.AddRead(ConstructServerResponseHeadersPacket(
2705 1, GetNthClientInitiatedStreamId(0), false, false,
2706 GetResponseHeaders("200 OK"), &response_header_offset));
2707 mock_quic_data.AddRead(ConstructServerDataPacket(
2708 2, GetNthClientInitiatedStreamId(0), false, true, 0, "hello!"));
2709 mock_quic_data.AddWrite(ConstructClientAckPacket(3, 2, 1, 1));
2710
2711 // Second request will go over the pooled QUIC connection, but will be
2712 // reset by the server.
2713 QuicTestPacketMaker client_maker2(version_, 0, &clock_, origin2.host(),
2714 Perspective::IS_CLIENT);
2715 QuicTestPacketMaker server_maker2(version_, 0, &clock_, origin2.host(),
2716 Perspective::IS_SERVER);
2717 mock_quic_data.AddWrite(ConstructClientRequestHeadersPacket(
2718 4, GetNthClientInitiatedStreamId(1), false, true,
2719 GetRequestHeaders("GET", "https", "/", &client_maker2),
2720 &request_header_offset));
2721 mock_quic_data.AddRead(ConstructServerRstPacket(
2722 3, false, GetNthClientInitiatedStreamId(1), QUIC_HEADERS_TOO_LARGE));
2723 mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2724 mock_quic_data.AddRead(ASYNC, 0); // EOF
2725
2726 mock_quic_data.AddSocketDataToFactory(&socket_factory_);
2727
2728 // After that fails, it will be resent via TCP.
2729 MockWrite http_writes[] = {
2730 MockWrite(SYNCHRONOUS, 0, "GET / HTTP/1.1\r\n"),
2731 MockWrite(SYNCHRONOUS, 1, "Host: www.example.org\r\n"),
2732 MockWrite(SYNCHRONOUS, 2, "Connection: keep-alive\r\n\r\n")};
2733
2734 MockRead http_reads[] = {
2735 MockRead(SYNCHRONOUS, 3, "HTTP/1.1 200 OK\r\n"),
2736 MockRead(SYNCHRONOUS, 4, kQuicAlternativeServiceHeader),
2737 MockRead(SYNCHRONOUS, 5, "hello world"), MockRead(SYNCHRONOUS, OK, 6)};
2738 SequencedSocketData http_data(http_reads, arraysize(http_reads), http_writes,
2739 arraysize(http_writes));
2740 socket_factory_.AddSocketDataProvider(&http_data);
2741 socket_factory_.AddSSLSocketDataProvider(&ssl_data_);
2742
2743 // Then the next request to the second origin will go over a new QUIC
2744 // connection.
2745 MockQuicData mock_quic_data2;
2746 QuicTestPacketMaker client_maker3(version_, 0, &clock_, origin2.host(),
2747 Perspective::IS_CLIENT);
2748 QuicTestPacketMaker server_maker3(version_, 0, &clock_, origin2.host(),
2749 Perspective::IS_SERVER);
2750 QuicStreamOffset request_header_offset2(0);
2751 QuicStreamOffset response_header_offset2(0);
2752
2753 crypto_client_stream_factory_.AddProofVerifyDetails(&verify_details);
2754
2755 mock_quic_data2.AddWrite(
2756 client_maker3.MakeInitialSettingsPacket(1, &request_header_offset2));
2757 mock_quic_data2.AddWrite(
2758 client_maker3.MakeRequestHeadersPacketWithOffsetTracking(
2759 2, GetNthClientInitiatedStreamId(0), true, true,
2760 ConvertRequestPriorityToQuicPriority(DEFAULT_PRIORITY),
2761 GetRequestHeaders("GET", "https", "/", &client_maker3),
2762 &request_header_offset2));
2763 mock_quic_data2.AddRead(
2764 server_maker2.MakeResponseHeadersPacketWithOffsetTracking(
2765 1, GetNthClientInitiatedStreamId(0), false, false,
2766 GetResponseHeaders("200 OK"), &response_header_offset2));
2767 mock_quic_data2.AddRead(server_maker2.MakeDataPacket(
2768 2, GetNthClientInitiatedStreamId(0), false, true, 0, "hello!"));
2769 mock_quic_data2.AddWrite(ConstructClientAckPacket(3, 2, 1, 1));
2770 mock_quic_data2.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read
2771 mock_quic_data2.AddRead(ASYNC, 0); // EOF
2772
2773 mock_quic_data2.AddSocketDataToFactory(&socket_factory_);
2774
2775 CreateSession();
2776
2777 // Set up alternative service for |origin1|.
2778 base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1);
2779 http_server_properties_.SetAlternativeService(
2780 url::SchemeHostPort(origin1),
2781 AlternativeService(kProtoQUIC, "mail.example.com", 443), expiration);
2782
2783 // Set up alternative service for |origin2|.
2784 AlternativeServiceInfoVector alternative_services;
2785 http_server_properties_.SetAlternativeService(
2786 url::SchemeHostPort(origin2),
2787 AlternativeService(kProtoQUIC, "www.example.com", 443), expiration);
2788 // First request opens connection to |destination1|
2789 // with QuicServerId.host() == origin1.host().
2790 SendRequestAndExpectQuicResponse("hello!");
2791
2792 // Second request pools to existing connection with same destination,
2793 // because certificate matches, even though QuicServerId is different.
2794 // After it is reset, it will fail back to QUIC and mark QUIC as broken.
2795 request_.url = origin2;
2796 SendRequestAndExpectHttpResponse("hello world");
2797
2798 // The third request should use a new QUIC connection, not the broken
2799 // QUIC connection.
2800 SendRequestAndExpectQuicResponse("hello!");
2801 }
2802
2579 TEST_P(QuicNetworkTransactionTest, 2803 TEST_P(QuicNetworkTransactionTest,
2580 DoNotUseAlternativeServiceQuicUnsupportedVersion) { 2804 DoNotUseAlternativeServiceQuicUnsupportedVersion) {
2581 std::string altsvc_header = base::StringPrintf( 2805 std::string altsvc_header = base::StringPrintf(
2582 "Alt-Svc: quic=\":443\"; v=\"%u\"\r\n\r\n", version_ - 1); 2806 "Alt-Svc: quic=\":443\"; v=\"%u\"\r\n\r\n", version_ - 1);
2583 MockRead http_reads[] = { 2807 MockRead http_reads[] = {
2584 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()), 2808 MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()),
2585 MockRead("hello world"), 2809 MockRead("hello world"),
2586 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ), 2810 MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ),
2587 MockRead(ASYNC, OK)}; 2811 MockRead(ASYNC, OK)};
2588 2812
(...skipping 2213 matching lines...) Expand 10 before | Expand all | Expand 10 after
4802 5026
4803 request_.url = GURL("https://mail.example.org/pushed.jpg"); 5027 request_.url = GURL("https://mail.example.org/pushed.jpg");
4804 ChunkedUploadDataStream upload_data(0); 5028 ChunkedUploadDataStream upload_data(0);
4805 upload_data.AppendData("1", 1, true); 5029 upload_data.AppendData("1", 1, true);
4806 request_.upload_data_stream = &upload_data; 5030 request_.upload_data_stream = &upload_data;
4807 SendRequestAndExpectQuicResponse("and hello!"); 5031 SendRequestAndExpectQuicResponse("and hello!");
4808 } 5032 }
4809 5033
4810 } // namespace test 5034 } // namespace test
4811 } // namespace net 5035 } // namespace net
OLDNEW
« no previous file with comments | « net/quic/chromium/quic_chromium_client_session.cc ('k') | net/quic/chromium/quic_stream_factory.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698