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

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

Issue 2771263002: Retry upon 421 status code without IP pooling. (Closed)
Patch Set: Created 3 years, 9 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.com", ip_addr);
Zhongyi Shi 2017/03/29 03:05:06 optional nit: s/mail.example.com/mail.example.org,
Bence 2017/03/29 16:46:08 Done. BTW RFC2606 Section 3 allows both example.c
Zhongyi Shi 2017/03/30 22:33:02 Acknowledged.
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.com", 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.com", 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 TestCompletionCallback callback;
13665 HttpRequestInfo request1;
13666 request1.method = "GET";
13667 request1.url = GURL("https://www.example.org/");
13668 request1.load_flags = 0;
13669 HttpNetworkTransaction trans1(DEFAULT_PRIORITY, session.get());
13670
13671 int rv = trans1.Start(&request1, callback.callback(), NetLogWithSource());
13672 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13673 rv = callback.WaitForResult();
13674 EXPECT_THAT(rv, IsOk());
13675
13676 const HttpResponseInfo* response = trans1.GetResponseInfo();
13677 ASSERT_TRUE(response);
13678 ASSERT_TRUE(response->headers);
13679 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
13680 EXPECT_TRUE(response->was_fetched_via_spdy);
13681 EXPECT_TRUE(response->was_alpn_negotiated);
13682 std::string response_data;
13683 ASSERT_THAT(ReadTransaction(&trans1, &response_data), IsOk());
13684 EXPECT_EQ("hello!", response_data);
13685
13686 // Preload mail.example.com into HostCache.
Zhongyi Shi 2017/03/29 03:05:06 nit: This seemed to be part of the test setting up
Bence 2017/03/29 16:46:08 Done.
13687 HostPortPair host_port("mail.example.com", 443);
13688 HostResolver::RequestInfo resolve_info(host_port);
13689 AddressList ignored;
13690 std::unique_ptr<HostResolver::Request> request;
13691 rv = session_deps_.host_resolver->Resolve(resolve_info, DEFAULT_PRIORITY,
13692 &ignored, callback.callback(),
13693 &request, NetLogWithSource());
13694 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13695 rv = callback.WaitForResult();
13696 EXPECT_THAT(rv, IsOk());
13697
13698 HttpRequestInfo request2;
13699 request2.method = "GET";
13700 request2.url = GURL("https://mail.example.com/");
13701 request2.load_flags = 0;
13702 HttpNetworkTransaction trans2(DEFAULT_PRIORITY, session.get());
13703
13704 rv = trans2.Start(&request2, callback.callback(), NetLogWithSource());
Zhongyi Shi 2017/03/29 03:05:06 Seems like we are only verifying the second reques
Bence 2017/03/29 16:46:08 Excellent idea, thank you! Done.
13705 EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
13706 rv = callback.WaitForResult();
13707 EXPECT_THAT(rv, IsOk());
13708
13709 response = trans2.GetResponseInfo();
13710 ASSERT_TRUE(response);
13711 ASSERT_TRUE(response->headers);
13712 EXPECT_EQ("HTTP/1.1 200", response->headers->GetStatusLine());
13713 EXPECT_TRUE(response->was_fetched_via_spdy);
13714 EXPECT_TRUE(response->was_alpn_negotiated);
13715 ASSERT_THAT(ReadTransaction(&trans2, &response_data), IsOk());
13716 EXPECT_EQ("hello!", response_data);
13717 }
13718
13597 class OneTimeCachingHostResolver : public HostResolver { 13719 class OneTimeCachingHostResolver : public HostResolver {
13598 public: 13720 public:
13599 explicit OneTimeCachingHostResolver(const HostPortPair& host_port) 13721 explicit OneTimeCachingHostResolver(const HostPortPair& host_port)
13600 : host_port_(host_port) {} 13722 : host_port_(host_port) {}
13601 ~OneTimeCachingHostResolver() override {} 13723 ~OneTimeCachingHostResolver() override {}
13602 13724
13603 RuleBasedHostResolverProc* rules() { return host_resolver_.rules(); } 13725 RuleBasedHostResolverProc* rules() { return host_resolver_.rules(); }
13604 13726
13605 // HostResolver methods: 13727 // HostResolver methods:
13606 int Resolve(const RequestInfo& info, 13728 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). 15068 // RequestStream() (which may be NULL if it was destroyed already).
14947 base::WeakPtr<FakeStreamRequest> last_stream_request() { 15069 base::WeakPtr<FakeStreamRequest> last_stream_request() {
14948 return last_stream_request_; 15070 return last_stream_request_;
14949 } 15071 }
14950 15072
14951 HttpStreamRequest* RequestStream(const HttpRequestInfo& info, 15073 HttpStreamRequest* RequestStream(const HttpRequestInfo& info,
14952 RequestPriority priority, 15074 RequestPriority priority,
14953 const SSLConfig& server_ssl_config, 15075 const SSLConfig& server_ssl_config,
14954 const SSLConfig& proxy_ssl_config, 15076 const SSLConfig& proxy_ssl_config,
14955 HttpStreamRequest::Delegate* delegate, 15077 HttpStreamRequest::Delegate* delegate,
15078 bool enable_ip_based_pooling,
14956 const NetLogWithSource& net_log) override { 15079 const NetLogWithSource& net_log) override {
14957 FakeStreamRequest* fake_request = new FakeStreamRequest(priority, delegate); 15080 FakeStreamRequest* fake_request = new FakeStreamRequest(priority, delegate);
14958 last_stream_request_ = fake_request->AsWeakPtr(); 15081 last_stream_request_ = fake_request->AsWeakPtr();
14959 return fake_request; 15082 return fake_request;
14960 } 15083 }
14961 15084
14962 HttpStreamRequest* RequestBidirectionalStreamImpl( 15085 HttpStreamRequest* RequestBidirectionalStreamImpl(
14963 const HttpRequestInfo& info, 15086 const HttpRequestInfo& info,
14964 RequestPriority priority, 15087 RequestPriority priority,
14965 const SSLConfig& server_ssl_config, 15088 const SSLConfig& server_ssl_config,
14966 const SSLConfig& proxy_ssl_config, 15089 const SSLConfig& proxy_ssl_config,
14967 HttpStreamRequest::Delegate* delegate, 15090 HttpStreamRequest::Delegate* delegate,
15091 bool enable_ip_based_pooling,
14968 const NetLogWithSource& net_log) override { 15092 const NetLogWithSource& net_log) override {
14969 NOTREACHED(); 15093 NOTREACHED();
14970 return nullptr; 15094 return nullptr;
14971 } 15095 }
14972 15096
14973 HttpStreamRequest* RequestWebSocketHandshakeStream( 15097 HttpStreamRequest* RequestWebSocketHandshakeStream(
14974 const HttpRequestInfo& info, 15098 const HttpRequestInfo& info,
14975 RequestPriority priority, 15099 RequestPriority priority,
14976 const SSLConfig& server_ssl_config, 15100 const SSLConfig& server_ssl_config,
14977 const SSLConfig& proxy_ssl_config, 15101 const SSLConfig& proxy_ssl_config,
14978 HttpStreamRequest::Delegate* delegate, 15102 HttpStreamRequest::Delegate* delegate,
14979 WebSocketHandshakeStreamBase::CreateHelper* create_helper, 15103 WebSocketHandshakeStreamBase::CreateHelper* create_helper,
15104 bool enable_ip_based_pooling,
14980 const NetLogWithSource& net_log) override { 15105 const NetLogWithSource& net_log) override {
14981 FakeStreamRequest* fake_request = 15106 FakeStreamRequest* fake_request =
14982 new FakeStreamRequest(priority, delegate, create_helper); 15107 new FakeStreamRequest(priority, delegate, create_helper);
14983 last_stream_request_ = fake_request->AsWeakPtr(); 15108 last_stream_request_ = fake_request->AsWeakPtr();
14984 return fake_request; 15109 return fake_request;
14985 } 15110 }
14986 15111
14987 void PreconnectStreams(int num_streams, 15112 void PreconnectStreams(int num_streams,
14988 const HttpRequestInfo& info) override { 15113 const HttpRequestInfo& info) override {
14989 ADD_FAILURE(); 15114 ADD_FAILURE();
(...skipping 1529 matching lines...) Expand 10 before | Expand all | Expand 10 after
16519 base::RunLoop().RunUntilIdle(); 16644 base::RunLoop().RunUntilIdle();
16520 16645
16521 EXPECT_TRUE(trans.GetResponseInfo()->was_fetched_via_spdy); 16646 EXPECT_TRUE(trans.GetResponseInfo()->was_fetched_via_spdy);
16522 HttpRequestHeaders headers; 16647 HttpRequestHeaders headers;
16523 ASSERT_TRUE(trans.GetFullRequestHeaders(&headers)); 16648 ASSERT_TRUE(trans.GetFullRequestHeaders(&headers));
16524 EXPECT_TRUE(headers.HasHeader(HttpRequestHeaders::kTokenBinding)); 16649 EXPECT_TRUE(headers.HasHeader(HttpRequestHeaders::kTokenBinding));
16525 } 16650 }
16526 #endif // !defined(OS_IOS) 16651 #endif // !defined(OS_IOS)
16527 16652
16528 } // namespace net 16653 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698