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

Side by Side Diff: net/http/http_network_transaction_unittest.cc

Issue 2771263002: Retry upon 421 status code without IP pooling. (Closed)
Patch Set: Rebase. Created 3 years, 8 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 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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698