| 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 <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  Loading... | 
| 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  Loading... | 
| 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 | 
| OLD | NEW | 
|---|