Chromium Code Reviews| 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)); | |
|
Zhongyi Shi
2017/03/30 22:33:02
awesome!
| |
| 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 |