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

Unified Diff: net/spdy/spdy_network_transaction_unittest.cc

Issue 851503003: Update from https://crrev.com/311076 (Closed) Base URL: git@github.com:domokit/mojo.git@master
Patch Set: Created 5 years, 11 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « net/spdy/spdy_buffer.cc ('k') | net/spdy/spdy_protocol.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: net/spdy/spdy_network_transaction_unittest.cc
diff --git a/net/spdy/spdy_network_transaction_unittest.cc b/net/spdy/spdy_network_transaction_unittest.cc
index 4c6c2059e80e8d4787d31beba34c9e29c117f87a..21401b5e1f7c276fbc5b89b198427accc3edb21b 100644
--- a/net/spdy/spdy_network_transaction_unittest.cc
+++ b/net/spdy/spdy_network_transaction_unittest.cc
@@ -263,6 +263,12 @@ class SpdyNetworkTransactionTest
output_.rv = ReadTransaction(trans_.get(), &output_.response_data);
}
+ void FinishDefaultTestWithoutVerification() {
+ output_.rv = callback_.WaitForResult();
+ if (output_.rv != OK)
+ session_->spdy_session_pool()->CloseCurrentSessions(net::ERR_ABORTED);
+ }
+
// Most tests will want to call this function. In particular, the MockReads
// should end with an empty read, and that read needs to be processed to
// ensure proper deletion of the spdy_session_pool.
@@ -4550,6 +4556,208 @@ TEST_P(SpdyNetworkTransactionTest, CloseWithActiveStream) {
helper.VerifyDataConsumed();
}
+// Retry with HTTP/1.1 when receiving HTTP_1_1_REQUIRED. Note that no actual
+// protocol negotiation happens, instead this test forces protocols for both
+// sockets.
+TEST_P(SpdyNetworkTransactionTest, HTTP11RequiredRetry) {
+ // HTTP_1_1_REQUIRED is only supported by SPDY4.
+ if (spdy_util_.spdy_version() < SPDY4)
+ return;
+ // HTTP_1_1_REQUIRED implementation relies on the assumption that HTTP/2 is
+ // only spoken over SSL.
+ if (GetParam().ssl_type != SPDYSSL)
+ return;
+
+ HttpRequestInfo request;
+ request.method = "GET";
+ request.url = GURL("https://www.google.com/");
+ scoped_ptr<SpdySessionDependencies> session_deps(
+ CreateSpdySessionDependencies(GetParam()));
+ // Do not force SPDY so that second socket can negotiate HTTP/1.1.
+ session_deps->force_spdy_over_ssl = false;
+ session_deps->force_spdy_always = false;
+ session_deps->next_protos = SpdyNextProtos();
+ NormalSpdyTransactionHelper helper(request, DEFAULT_PRIORITY, BoundNetLog(),
+ GetParam(), session_deps.release());
+
+ // First socket: HTTP/2 request rejected with HTTP_1_1_REQUIRED.
+ const char* url = "https://www.google.com/";
+ scoped_ptr<SpdyHeaderBlock> headers(spdy_util_.ConstructGetHeaderBlock(url));
+ scoped_ptr<SpdyFrame> req(
+ spdy_util_.ConstructSpdySyn(1, *headers, LOWEST, false, true));
+ MockWrite writes0[] = {CreateMockWrite(*req)};
+ scoped_ptr<SpdyFrame> go_away(spdy_util_.ConstructSpdyGoAway(
+ 0, GOAWAY_HTTP_1_1_REQUIRED, "Try again using HTTP/1.1 please."));
+ MockRead reads0[] = {CreateMockRead(*go_away)};
+ DelayedSocketData data0(1, reads0, arraysize(reads0), writes0,
+ arraysize(writes0));
+
+ scoped_ptr<SSLSocketDataProvider> ssl_provider0(
+ new SSLSocketDataProvider(ASYNC, OK));
+ // Expect HTTP/2 protocols too in SSLConfig.
+ ssl_provider0->next_protos_expected_in_ssl_config.push_back(kProtoHTTP11);
+ ssl_provider0->next_protos_expected_in_ssl_config.push_back(kProtoSPDY31);
+ ssl_provider0->next_protos_expected_in_ssl_config.push_back(kProtoSPDY4_14);
+ ssl_provider0->next_protos_expected_in_ssl_config.push_back(kProtoSPDY4_15);
+ // Force SPDY.
+ ssl_provider0->SetNextProto(GetParam().protocol);
+ helper.AddDataWithSSLSocketDataProvider(&data0, ssl_provider0.Pass());
+
+ // Second socket: falling back to HTTP/1.1.
+ MockWrite writes1[] = {MockWrite(
+ "GET / HTTP/1.1\r\n"
+ "Host: www.google.com\r\n"
+ "Connection: keep-alive\r\n\r\n")};
+ MockRead reads1[] = {MockRead(
+ "HTTP/1.1 200 OK\r\n"
+ "Content-Length: 5\r\n\r\n"
+ "hello")};
+ DelayedSocketData data1(1, reads1, arraysize(reads1), writes1,
+ arraysize(writes1));
+
+ scoped_ptr<SSLSocketDataProvider> ssl_provider1(
+ new SSLSocketDataProvider(ASYNC, OK));
+ // Expect only HTTP/1.1 protocol in SSLConfig.
+ ssl_provider1->next_protos_expected_in_ssl_config.push_back(kProtoHTTP11);
+ // Force HTTP/1.1.
+ ssl_provider1->SetNextProto(kProtoHTTP11);
+ helper.AddDataWithSSLSocketDataProvider(&data1, ssl_provider1.Pass());
+
+ base::WeakPtr<HttpServerProperties> http_server_properties =
+ helper.session()->spdy_session_pool()->http_server_properties();
+ const HostPortPair host_port_pair = HostPortPair::FromURL(GURL(url));
+ EXPECT_FALSE(http_server_properties->RequiresHTTP11(host_port_pair));
+
+ helper.RunPreTestSetup();
+ helper.StartDefaultTest();
+ helper.FinishDefaultTestWithoutVerification();
+ helper.VerifyDataConsumed();
+ EXPECT_TRUE(http_server_properties->RequiresHTTP11(host_port_pair));
+
+ const HttpResponseInfo* response = helper.trans()->GetResponseInfo();
+ ASSERT_TRUE(response != nullptr);
+ ASSERT_TRUE(response->headers.get() != nullptr);
+ EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
+ EXPECT_FALSE(response->was_fetched_via_spdy);
+ EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP1, response->connection_info);
+ EXPECT_TRUE(response->was_npn_negotiated);
+ EXPECT_TRUE(request.url.SchemeIs("https"));
+ EXPECT_EQ("127.0.0.1", response->socket_address.host());
+ EXPECT_EQ(443, response->socket_address.port());
+ std::string response_data;
+ ASSERT_EQ(OK, ReadTransaction(helper.trans(), &response_data));
+ EXPECT_EQ("hello", response_data);
+}
+
+// Retry with HTTP/1.1 to the proxy when receiving HTTP_1_1_REQUIRED from the
+// proxy. Note that no actual protocol negotiation happens, instead this test
+// forces protocols for both sockets.
+TEST_P(SpdyNetworkTransactionTest, HTTP11RequiredProxyRetry) {
+ // HTTP_1_1_REQUIRED is only supported by SPDY4.
+ if (spdy_util_.spdy_version() < SPDY4)
+ return;
+ // HTTP_1_1_REQUIRED implementation relies on the assumption that HTTP/2 is
+ // only spoken over SSL.
+ if (GetParam().ssl_type != SPDYSSL)
+ return;
+
+ HttpRequestInfo request;
+ request.method = "GET";
+ request.url = GURL("https://www.google.com/");
+ scoped_ptr<SpdySessionDependencies> session_deps(
+ CreateSpdySessionDependencies(
+ GetParam(),
+ ProxyService::CreateFixedFromPacResult("HTTPS myproxy:70")));
+ // Do not force SPDY so that second socket can negotiate HTTP/1.1.
+ session_deps->force_spdy_over_ssl = false;
+ session_deps->force_spdy_always = false;
+ session_deps->next_protos = SpdyNextProtos();
+ NormalSpdyTransactionHelper helper(request, DEFAULT_PRIORITY, BoundNetLog(),
+ GetParam(), session_deps.release());
+
+ // First socket: HTTP/2 CONNECT rejected with HTTP_1_1_REQUIRED.
+ scoped_ptr<SpdyFrame> req(spdy_util_.ConstructSpdyConnect(
+ nullptr, 0, 1, LOWEST, HostPortPair("www.google.com", 443)));
+ MockWrite writes0[] = {CreateMockWrite(*req)};
+ scoped_ptr<SpdyFrame> go_away(spdy_util_.ConstructSpdyGoAway(
+ 0, GOAWAY_HTTP_1_1_REQUIRED, "Try again using HTTP/1.1 please."));
+ MockRead reads0[] = {CreateMockRead(*go_away)};
+ DelayedSocketData data0(1, reads0, arraysize(reads0), writes0,
+ arraysize(writes0));
+
+ scoped_ptr<SSLSocketDataProvider> ssl_provider0(
+ new SSLSocketDataProvider(ASYNC, OK));
+ // Expect HTTP/2 protocols too in SSLConfig.
+ ssl_provider0->next_protos_expected_in_ssl_config.push_back(kProtoHTTP11);
+ ssl_provider0->next_protos_expected_in_ssl_config.push_back(kProtoSPDY31);
+ ssl_provider0->next_protos_expected_in_ssl_config.push_back(kProtoSPDY4_14);
+ ssl_provider0->next_protos_expected_in_ssl_config.push_back(kProtoSPDY4_15);
+ // Force SPDY.
+ ssl_provider0->SetNextProto(GetParam().protocol);
+ helper.AddDataWithSSLSocketDataProvider(&data0, ssl_provider0.Pass());
+
+ // Second socket: retry using HTTP/1.1.
+ MockWrite writes1[] = {
+ MockWrite(ASYNC, 1,
+ "CONNECT www.google.com:443 HTTP/1.1\r\n"
+ "Host: www.google.com\r\n"
+ "Proxy-Connection: keep-alive\r\n\r\n"),
+ MockWrite(ASYNC, 3,
+ "GET / HTTP/1.1\r\n"
+ "Host: www.google.com\r\n"
+ "Connection: keep-alive\r\n\r\n"),
+ };
+
+ MockRead reads1[] = {
+ MockRead(ASYNC, 2, "HTTP/1.1 200 OK\r\n\r\n"),
+ MockRead(ASYNC, 4,
+ "HTTP/1.1 200 OK\r\n"
+ "Content-Length: 5\r\n\r\n"
+ "hello"),
+ };
+ DelayedSocketData data1(1, reads1, arraysize(reads1), writes1,
+ arraysize(writes1));
+
+ scoped_ptr<SSLSocketDataProvider> ssl_provider1(
+ new SSLSocketDataProvider(ASYNC, OK));
+ // Expect only HTTP/1.1 protocol in SSLConfig.
+ ssl_provider1->next_protos_expected_in_ssl_config.push_back(kProtoHTTP11);
+ // Force HTTP/1.1.
+ ssl_provider1->SetNextProto(kProtoHTTP11);
+ helper.AddDataWithSSLSocketDataProvider(&data1, ssl_provider1.Pass());
+
+ // A third socket is needed for the tunnelled connection.
+ scoped_ptr<SSLSocketDataProvider> ssl_provider2(
+ new SSLSocketDataProvider(ASYNC, OK));
+ helper.session_deps()->socket_factory->AddSSLSocketDataProvider(
+ ssl_provider2.get());
+
+ base::WeakPtr<HttpServerProperties> http_server_properties =
+ helper.session()->spdy_session_pool()->http_server_properties();
+ const HostPortPair proxy_host_port_pair = HostPortPair("myproxy", 70);
+ EXPECT_FALSE(http_server_properties->RequiresHTTP11(proxy_host_port_pair));
+
+ helper.RunPreTestSetup();
+ helper.StartDefaultTest();
+ helper.FinishDefaultTestWithoutVerification();
+ helper.VerifyDataConsumed();
+ EXPECT_TRUE(http_server_properties->RequiresHTTP11(proxy_host_port_pair));
+
+ const HttpResponseInfo* response = helper.trans()->GetResponseInfo();
+ ASSERT_TRUE(response != nullptr);
+ ASSERT_TRUE(response->headers.get() != nullptr);
+ EXPECT_EQ("HTTP/1.1 200 OK", response->headers->GetStatusLine());
+ EXPECT_FALSE(response->was_fetched_via_spdy);
+ EXPECT_EQ(HttpResponseInfo::CONNECTION_INFO_HTTP1, response->connection_info);
+ EXPECT_FALSE(response->was_npn_negotiated);
+ EXPECT_TRUE(request.url.SchemeIs("https"));
+ EXPECT_EQ("127.0.0.1", response->socket_address.host());
+ EXPECT_EQ(70, response->socket_address.port());
+ std::string response_data;
+ ASSERT_EQ(OK, ReadTransaction(helper.trans(), &response_data));
+ EXPECT_EQ("hello", response_data);
+}
+
// Test to make sure we can correctly connect through a proxy.
TEST_P(SpdyNetworkTransactionTest, ProxyConnect) {
NormalSpdyTransactionHelper helper(CreateGetRequest(), DEFAULT_PRIORITY,
« no previous file with comments | « net/spdy/spdy_buffer.cc ('k') | net/spdy/spdy_protocol.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698