OLD | NEW |
1 // Copyright 2013 The Chromium Authors. All rights reserved. | 1 // Copyright 2013 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 "net/http/http_network_transaction.h" | 5 #include "net/http/http_network_transaction.h" |
6 | 6 |
7 #include <math.h> // ceil | 7 #include <math.h> // ceil |
8 #include <stdarg.h> | 8 #include <stdarg.h> |
9 #include <stdint.h> | 9 #include <stdint.h> |
10 | 10 |
(...skipping 13576 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
13587 response = trans2.GetResponseInfo(); | 13587 response = trans2.GetResponseInfo(); |
13588 ASSERT_TRUE(response); | 13588 ASSERT_TRUE(response); |
13589 ASSERT_TRUE(response->headers); | 13589 ASSERT_TRUE(response->headers); |
13590 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine()); | 13590 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine()); |
13591 EXPECT_TRUE(response->was_fetched_via_spdy); | 13591 EXPECT_TRUE(response->was_fetched_via_spdy); |
13592 EXPECT_TRUE(response->was_alpn_negotiated); | 13592 EXPECT_TRUE(response->was_alpn_negotiated); |
13593 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk()); | 13593 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk()); |
13594 EXPECT_EQ("hello!", response_data); | 13594 EXPECT_EQ("hello!", response_data); |
13595 } | 13595 } |
13596 | 13596 |
| 13597 // Regression test for https://crbug.com/546991. |
| 13598 // The server might not be able to serve an IP pooled request, and might send a |
| 13599 // 421 Misdirected Request response status to indicate this. |
| 13600 // HttpNetworkTransaction should reset the request and retry without IP pooling. |
| 13601 TEST_F(HttpNetworkTransactionTest, RetryWithoutConnectionPooling) { |
| 13602 // Two hosts resolve to the same IP address. |
| 13603 const std::string ip_addr = "1.2.3.4"; |
| 13604 IPAddress ip; |
| 13605 ASSERT_TRUE(ip.AssignFromIPLiteral(ip_addr)); |
| 13606 IPEndPoint peer_addr = IPEndPoint(ip, 443); |
| 13607 |
| 13608 session_deps_.host_resolver.reset(new MockCachingHostResolver()); |
| 13609 session_deps_.host_resolver->rules()->AddRule("www.example.org", ip_addr); |
| 13610 session_deps_.host_resolver->rules()->AddRule("mail.example.org", ip_addr); |
| 13611 |
| 13612 std::unique_ptr<HttpNetworkSession> session(CreateSession(&session_deps_)); |
| 13613 |
| 13614 // Two requests on the first connection. |
| 13615 SpdySerializedFrame req1( |
| 13616 spdy_util_.ConstructSpdyGet("https://www.example.org", 1, LOWEST)); |
| 13617 spdy_util_.UpdateWithStreamDestruction(1); |
| 13618 SpdySerializedFrame req2( |
| 13619 spdy_util_.ConstructSpdyGet("https://mail.example.org", 3, LOWEST)); |
| 13620 SpdySerializedFrame rst( |
| 13621 spdy_util_.ConstructSpdyRstStream(3, ERROR_CODE_CANCEL)); |
| 13622 MockWrite writes1[] = { |
| 13623 CreateMockWrite(req1, 0), CreateMockWrite(req2, 3), |
| 13624 CreateMockWrite(rst, 6), |
| 13625 }; |
| 13626 |
| 13627 // The first one succeeds, the second gets error 421 Misdirected Request. |
| 13628 SpdySerializedFrame resp1(spdy_util_.ConstructSpdyGetReply(nullptr, 0, 1)); |
| 13629 SpdySerializedFrame body1(spdy_util_.ConstructSpdyDataFrame(1, true)); |
| 13630 SpdyHeaderBlock response_headers; |
| 13631 response_headers[SpdyTestUtil::GetStatusKey()] = "421"; |
| 13632 SpdySerializedFrame resp2( |
| 13633 spdy_util_.ConstructSpdyReply(3, std::move(response_headers))); |
| 13634 MockRead reads1[] = {CreateMockRead(resp1, 1), CreateMockRead(body1, 2), |
| 13635 CreateMockRead(resp2, 4), MockRead(ASYNC, 0, 5)}; |
| 13636 |
| 13637 MockConnect connect1(ASYNC, OK, peer_addr); |
| 13638 SequencedSocketData data1(connect1, reads1, arraysize(reads1), writes1, |
| 13639 arraysize(writes1)); |
| 13640 session_deps_.socket_factory->AddSocketDataProvider(&data1); |
| 13641 |
| 13642 AddSSLSocketData(); |
| 13643 |
| 13644 // Retry the second request on a second connection. |
| 13645 SpdyTestUtil spdy_util2; |
| 13646 SpdySerializedFrame req3( |
| 13647 spdy_util2.ConstructSpdyGet("https://mail.example.org", 1, LOWEST)); |
| 13648 MockWrite writes2[] = { |
| 13649 CreateMockWrite(req3, 0), |
| 13650 }; |
| 13651 |
| 13652 SpdySerializedFrame resp3(spdy_util2.ConstructSpdyGetReply(nullptr, 0, 1)); |
| 13653 SpdySerializedFrame body3(spdy_util2.ConstructSpdyDataFrame(1, true)); |
| 13654 MockRead reads2[] = {CreateMockRead(resp3, 1), CreateMockRead(body3, 2), |
| 13655 MockRead(ASYNC, 0, 3)}; |
| 13656 |
| 13657 MockConnect connect2(ASYNC, OK, peer_addr); |
| 13658 SequencedSocketData data2(connect2, reads2, arraysize(reads2), writes2, |
| 13659 arraysize(writes2)); |
| 13660 session_deps_.socket_factory->AddSocketDataProvider(&data2); |
| 13661 |
| 13662 AddSSLSocketData(); |
| 13663 |
| 13664 // Preload mail.example.org into HostCache. |
| 13665 HostPortPair host_port("mail.example.org", 443); |
| 13666 HostResolver::RequestInfo resolve_info(host_port); |
| 13667 AddressList ignored; |
| 13668 std::unique_ptr<HostResolver::Request> request; |
| 13669 TestCompletionCallback callback; |
| 13670 int rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY, |
| 13671 &ignored, callback.callback(), |
| 13672 &request, NetLogWithSource()); |
| 13673 EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); |
| 13674 rv = callback.WaitForResult(); |
| 13675 EXPECT_THAT(rv, IsOk()); |
| 13676 |
| 13677 HttpRequestInfo request1; |
| 13678 request1.method = "GET"; |
| 13679 request1.url = GURL("https://www.example.org/"); |
| 13680 request1.load_flags = 0; |
| 13681 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get()); |
| 13682 |
| 13683 rv = trans1.Start(&request1, callback.callback(), NetLogWithSource()); |
| 13684 EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); |
| 13685 rv = callback.WaitForResult(); |
| 13686 EXPECT_THAT(rv, IsOk()); |
| 13687 |
| 13688 const HttpResponseInfo* response = trans1.GetResponseInfo(); |
| 13689 ASSERT_TRUE(response); |
| 13690 ASSERT_TRUE(response->headers); |
| 13691 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine()); |
| 13692 EXPECT_TRUE(response->was_fetched_via_spdy); |
| 13693 EXPECT_TRUE(response->was_alpn_negotiated); |
| 13694 std::string response_data; |
| 13695 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk()); |
| 13696 EXPECT_EQ("hello!", response_data); |
| 13697 |
| 13698 HttpRequestInfo request2; |
| 13699 request2.method = "GET"; |
| 13700 request2.url = GURL("https://mail.example.org/"); |
| 13701 request2.load_flags = 0; |
| 13702 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get()); |
| 13703 |
| 13704 BoundTestNetLog log; |
| 13705 rv = trans2.Start(&request2, callback.callback(), log.bound()); |
| 13706 EXPECT_THAT(rv, IsError(ERR_IO_PENDING)); |
| 13707 rv = callback.WaitForResult(); |
| 13708 EXPECT_THAT(rv, IsOk()); |
| 13709 |
| 13710 response = trans2.GetResponseInfo(); |
| 13711 ASSERT_TRUE(response); |
| 13712 ASSERT_TRUE(response->headers); |
| 13713 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine()); |
| 13714 EXPECT_TRUE(response->was_fetched_via_spdy); |
| 13715 EXPECT_TRUE(response->was_alpn_negotiated); |
| 13716 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk()); |
| 13717 EXPECT_EQ("hello!", response_data); |
| 13718 |
| 13719 TestNetLogEntry::List entries; |
| 13720 log.GetEntries(&entries); |
| 13721 size_t pos = ExpectLogContainsSomewhere( |
| 13722 entries, 0, NetLogEventType::HTTP_TRANSACTION_RESTART_AFTER_ERROR, |
| 13723 NetLogEventPhase::NONE); |
| 13724 EXPECT_TRUE(entries[pos].GetIntegerValue("net_error", &rv)); |
| 13725 EXPECT_THAT(rv, IsError(ERR_MISDIRECTED_REQUEST)); |
| 13726 } |
| 13727 |
13597 class OneTimeCachingHostResolver : public HostResolver { | 13728 class OneTimeCachingHostResolver : public HostResolver { |
13598 public: | 13729 public: |
13599 explicit OneTimeCachingHostResolver(const HostPortPair& host_port) | 13730 explicit OneTimeCachingHostResolver(const HostPortPair& host_port) |
13600 : host_port_(host_port) {} | 13731 : host_port_(host_port) {} |
13601 ~OneTimeCachingHostResolver() override {} | 13732 ~OneTimeCachingHostResolver() override {} |
13602 | 13733 |
13603 RuleBasedHostResolverProc* rules() { return host_resolver_.rules(); } | 13734 RuleBasedHostResolverProc* rules() { return host_resolver_.rules(); } |
13604 | 13735 |
13605 // HostResolver methods: | 13736 // HostResolver methods: |
13606 int Resolve(const RequestInfo& info, | 13737 int Resolve(const RequestInfo& info, |
(...skipping 1339 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
14946 // RequestStream() (which may be NULL if it was destroyed already). | 15077 // RequestStream() (which may be NULL if it was destroyed already). |
14947 base::WeakPtr<FakeStreamRequest> last_stream_request() { | 15078 base::WeakPtr<FakeStreamRequest> last_stream_request() { |
14948 return last_stream_request_; | 15079 return last_stream_request_; |
14949 } | 15080 } |
14950 | 15081 |
14951 HttpStreamRequest* RequestStream(const HttpRequestInfo& info, | 15082 HttpStreamRequest* RequestStream(const HttpRequestInfo& info, |
14952 RequestPriority priority, | 15083 RequestPriority priority, |
14953 const SSLConfig& server_ssl_config, | 15084 const SSLConfig& server_ssl_config, |
14954 const SSLConfig& proxy_ssl_config, | 15085 const SSLConfig& proxy_ssl_config, |
14955 HttpStreamRequest::Delegate* delegate, | 15086 HttpStreamRequest::Delegate* delegate, |
| 15087 bool enable_ip_based_pooling, |
14956 const NetLogWithSource& net_log) override { | 15088 const NetLogWithSource& net_log) override { |
14957 FakeStreamRequest* fake_request = new FakeStreamRequest(priority, delegate); | 15089 FakeStreamRequest* fake_request = new FakeStreamRequest(priority, delegate); |
14958 last_stream_request_ = fake_request->AsWeakPtr(); | 15090 last_stream_request_ = fake_request->AsWeakPtr(); |
14959 return fake_request; | 15091 return fake_request; |
14960 } | 15092 } |
14961 | 15093 |
14962 HttpStreamRequest* RequestBidirectionalStreamImpl( | 15094 HttpStreamRequest* RequestBidirectionalStreamImpl( |
14963 const HttpRequestInfo& info, | 15095 const HttpRequestInfo& info, |
14964 RequestPriority priority, | 15096 RequestPriority priority, |
14965 const SSLConfig& server_ssl_config, | 15097 const SSLConfig& server_ssl_config, |
14966 const SSLConfig& proxy_ssl_config, | 15098 const SSLConfig& proxy_ssl_config, |
14967 HttpStreamRequest::Delegate* delegate, | 15099 HttpStreamRequest::Delegate* delegate, |
| 15100 bool enable_ip_based_pooling, |
14968 const NetLogWithSource& net_log) override { | 15101 const NetLogWithSource& net_log) override { |
14969 NOTREACHED(); | 15102 NOTREACHED(); |
14970 return nullptr; | 15103 return nullptr; |
14971 } | 15104 } |
14972 | 15105 |
14973 HttpStreamRequest* RequestWebSocketHandshakeStream( | 15106 HttpStreamRequest* RequestWebSocketHandshakeStream( |
14974 const HttpRequestInfo& info, | 15107 const HttpRequestInfo& info, |
14975 RequestPriority priority, | 15108 RequestPriority priority, |
14976 const SSLConfig& server_ssl_config, | 15109 const SSLConfig& server_ssl_config, |
14977 const SSLConfig& proxy_ssl_config, | 15110 const SSLConfig& proxy_ssl_config, |
14978 HttpStreamRequest::Delegate* delegate, | 15111 HttpStreamRequest::Delegate* delegate, |
14979 WebSocketHandshakeStreamBase::CreateHelper* create_helper, | 15112 WebSocketHandshakeStreamBase::CreateHelper* create_helper, |
| 15113 bool enable_ip_based_pooling, |
14980 const NetLogWithSource& net_log) override { | 15114 const NetLogWithSource& net_log) override { |
14981 FakeStreamRequest* fake_request = | 15115 FakeStreamRequest* fake_request = |
14982 new FakeStreamRequest(priority, delegate, create_helper); | 15116 new FakeStreamRequest(priority, delegate, create_helper); |
14983 last_stream_request_ = fake_request->AsWeakPtr(); | 15117 last_stream_request_ = fake_request->AsWeakPtr(); |
14984 return fake_request; | 15118 return fake_request; |
14985 } | 15119 } |
14986 | 15120 |
14987 void PreconnectStreams(int num_streams, | 15121 void PreconnectStreams(int num_streams, |
14988 const HttpRequestInfo& info) override { | 15122 const HttpRequestInfo& info) override { |
14989 ADD_FAILURE(); | 15123 ADD_FAILURE(); |
(...skipping 1529 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
16519 base::RunLoop().RunUntilIdle(); | 16653 base::RunLoop().RunUntilIdle(); |
16520 | 16654 |
16521 EXPECT_TRUE(trans.GetResponseInfo()->was_fetched_via_spdy); | 16655 EXPECT_TRUE(trans.GetResponseInfo()->was_fetched_via_spdy); |
16522 HttpRequestHeaders headers; | 16656 HttpRequestHeaders headers; |
16523 ASSERT_TRUE(trans.GetFullRequestHeaders(&headers)); | 16657 ASSERT_TRUE(trans.GetFullRequestHeaders(&headers)); |
16524 EXPECT_TRUE(headers.HasHeader(HttpRequestHeaders::kTokenBinding)); | 16658 EXPECT_TRUE(headers.HasHeader(HttpRequestHeaders::kTokenBinding)); |
16525 } | 16659 } |
16526 #endif // !defined(OS_IOS) | 16660 #endif // !defined(OS_IOS) |
16527 | 16661 |
16528 } // namespace net | 16662 } // namespace net |
OLD | NEW |