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

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