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

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

Issue 1121043002: Make alternate Jobs not use HTTP/1.1 sockets. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Re: #13. Created 5 years, 7 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
« no previous file with comments | « no previous file | net/http/http_stream_factory_impl_job.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 <string> 9 #include <string>
10 #include <vector> 10 #include <vector>
(...skipping 11953 matching lines...) Expand 10 before | Expand all | Expand 10 after
11964 // The alternative service host must exhibit a certificate that is valid for the 11964 // The alternative service host must exhibit a certificate that is valid for the
11965 // origin host. Test that this is enforced when opening a new connection. 11965 // origin host. Test that this is enforced when opening a new connection.
11966 TEST_P(AltSvcCertificateVerificationTest, NewConnectionValid) { 11966 TEST_P(AltSvcCertificateVerificationTest, NewConnectionValid) {
11967 Run(false, true); 11967 Run(false, true);
11968 } 11968 }
11969 11969
11970 TEST_P(AltSvcCertificateVerificationTest, NewConnectionInvalid) { 11970 TEST_P(AltSvcCertificateVerificationTest, NewConnectionInvalid) {
11971 Run(false, false); 11971 Run(false, false);
11972 } 11972 }
11973 11973
11974 // Alternative service requires HTTP/2 (or SPDY), but HTTP/1.1 is negotiated
11975 // with the alternative server. That connection should not be used.
11976 TEST_P(HttpNetworkTransactionTest, AlternativeServiceNotOnHttp11) {
11977 HostPortPair origin("origin.example.org", 443);
11978 HostPortPair alternative("alternative.example.org", 443);
11979
11980 // Negotiate HTTP/1.1 with alternative.example.org.
11981 SSLSocketDataProvider ssl(ASYNC, OK);
11982 ssl.SetNextProto(kProtoHTTP11);
11983 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
11984
11985 // No data should be read from the alternative, because HTTP/1.1 is
11986 // negotiated.
11987 StaticSocketDataProvider data;
11988 session_deps_.socket_factory->AddSocketDataProvider(&data);
11989
11990 // This test documents that an alternate Job should not be used if HTTP/1.1 is
11991 // negotiated. In order to test this, a failed connection to the origin is
11992 // mocked. This way the request relies on the alternate Job.
11993 StaticSocketDataProvider data_refused;
11994 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
11995 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
11996
11997 // Set up alternative service for origin.
11998 session_deps_.use_alternate_protocols = true;
11999 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12000 base::WeakPtr<HttpServerProperties> http_server_properties =
12001 session->http_server_properties();
12002 AlternativeService alternative_service(
12003 AlternateProtocolFromNextProto(GetParam()), alternative);
12004 http_server_properties->SetAlternativeService(origin, alternative_service,
12005 1.0);
12006
12007 scoped_ptr<HttpTransaction> trans(
12008 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12009 HttpRequestInfo request;
12010 request.method = "GET";
12011 request.url = GURL("https://origin.example.org:443");
12012 request.load_flags = 0;
12013 TestCompletionCallback callback;
12014
12015 // HTTP/2 (or SPDY) is required for alternative service, if HTTP/1.1 is
12016 // negotiated, the alternate Job should fail with ERR_NPN_NEGOTIATION_FAILED.
12017 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12018 EXPECT_EQ(ERR_NPN_NEGOTIATION_FAILED, callback.GetResult(rv));
12019 }
12020
12021 // Alternative service requires HTTP/2 (or SPDY), but there is already a
12022 // HTTP/1.1 socket open to the alternative server. That socket should not be
12023 // used.
12024 TEST_P(HttpNetworkTransactionTest, AlternativeServiceShouldNotPoolToHttp11) {
12025 HostPortPair origin("origin.example.org", 443);
12026 HostPortPair alternative("alternative.example.org", 443);
12027 std::string origin_url = "https://origin.example.org:443";
12028 std::string alternative_url = "https://alternative.example.org:443";
12029
12030 // Negotiate HTTP/1.1 with alternative.example.org.
12031 SSLSocketDataProvider ssl(ASYNC, OK);
12032 ssl.SetNextProto(kProtoHTTP11);
12033 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12034
12035 // HTTP/1.1 data for |request1| and |request2|.
12036 MockWrite http_writes[] = {
12037 MockWrite(
12038 "GET / HTTP/1.1\r\n"
12039 "Host: alternative.example.org\r\n"
12040 "Connection: keep-alive\r\n\r\n"),
12041 MockWrite(
12042 "GET / HTTP/1.1\r\n"
12043 "Host: alternative.example.org\r\n"
12044 "Connection: keep-alive\r\n\r\n"),
12045 };
12046
12047 MockRead http_reads[] = {
12048 MockRead(
12049 "HTTP/1.1 200 OK\r\n"
12050 "Content-Type: text/html; charset=iso-8859-1\r\n"
12051 "Content-Length: 40\r\n\r\n"
12052 "first HTTP/1.1 response from alternative"),
12053 MockRead(
12054 "HTTP/1.1 200 OK\r\n"
12055 "Content-Type: text/html; charset=iso-8859-1\r\n"
12056 "Content-Length: 41\r\n\r\n"
12057 "second HTTP/1.1 response from alternative"),
12058 };
12059 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
12060 http_writes, arraysize(http_writes));
12061 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
12062
12063 // This test documents that an alternate Job should not pool to an already
12064 // existing HTTP/1.1 connection. In order to test this, a failed connection
12065 // to the origin is mocked. This way |request2| relies on the alternate Job.
12066 StaticSocketDataProvider data_refused;
12067 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
12068 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
12069
12070 // Set up alternative service for origin.
12071 session_deps_.use_alternate_protocols = true;
12072 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12073 base::WeakPtr<HttpServerProperties> http_server_properties =
12074 session->http_server_properties();
12075 AlternativeService alternative_service(
12076 AlternateProtocolFromNextProto(GetParam()), alternative);
12077 http_server_properties->SetAlternativeService(origin, alternative_service,
12078 1.0);
12079
12080 // First transaction to alternative to open an HTTP/1.1 socket.
12081 scoped_ptr<HttpTransaction> trans1(
12082 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12083 HttpRequestInfo request1;
12084 request1.method = "GET";
12085 request1.url = GURL(alternative_url);
12086 request1.load_flags = 0;
12087 TestCompletionCallback callback1;
12088
12089 int rv = trans1->Start(&request1, callback1.callback(), BoundNetLog());
12090 EXPECT_EQ(OK, callback1.GetResult(rv));
12091 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
12092 ASSERT_TRUE(response1);
12093 ASSERT_TRUE(response1->headers.get());
12094 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
12095 EXPECT_TRUE(response1->was_npn_negotiated);
12096 EXPECT_FALSE(response1->was_fetched_via_spdy);
12097 std::string response_data1;
12098 ASSERT_EQ(OK, ReadTransaction(trans1.get(), &response_data1));
12099 EXPECT_EQ("first HTTP/1.1 response from alternative", response_data1);
12100
12101 // Request for origin.example.org, which has an alternative service. This
12102 // will start two Jobs: the alternative looks for connections to pool to,
12103 // finds one which is HTTP/1.1, and should ignore it, and should not try to
12104 // open other connections to alternative server. The Job to origin fails, so
12105 // this request fails.
12106 scoped_ptr<HttpTransaction> trans2(
12107 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12108 HttpRequestInfo request2;
12109 request2.method = "GET";
12110 request2.url = GURL(origin_url);
12111 request2.load_flags = 0;
12112 TestCompletionCallback callback2;
12113
12114 rv = trans2->Start(&request2, callback2.callback(), BoundNetLog());
12115 EXPECT_EQ(ERR_CONNECTION_REFUSED, callback2.GetResult(rv));
12116
12117 // Another transaction to alternative. This is to test that the HTTP/1.1
12118 // socket is still open and in the pool.
12119 scoped_ptr<HttpTransaction> trans3(
12120 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12121 HttpRequestInfo request3;
12122 request3.method = "GET";
12123 request3.url = GURL(alternative_url);
12124 request3.load_flags = 0;
12125 TestCompletionCallback callback3;
12126
12127 rv = trans3->Start(&request3, callback3.callback(), BoundNetLog());
12128 EXPECT_EQ(OK, callback3.GetResult(rv));
12129 const HttpResponseInfo* response3 = trans3->GetResponseInfo();
12130 ASSERT_TRUE(response3);
12131 ASSERT_TRUE(response3->headers.get());
12132 EXPECT_EQ("HTTP/1.1 200 OK", response3->headers->GetStatusLine());
12133 EXPECT_TRUE(response3->was_npn_negotiated);
12134 EXPECT_FALSE(response3->was_fetched_via_spdy);
12135 std::string response_data3;
12136 ASSERT_EQ(OK, ReadTransaction(trans3.get(), &response_data3));
12137 EXPECT_EQ("second HTTP/1.1 response from alternative", response_data3);
12138 }
12139
11974 TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) { 12140 TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
11975 const std::string https_url = "https://www.example.org:8080/"; 12141 const std::string https_url = "https://www.example.org:8080/";
11976 const std::string http_url = "http://www.example.org:8080/"; 12142 const std::string http_url = "http://www.example.org:8080/";
11977 12143
11978 // SPDY GET for HTTPS URL (through CONNECT tunnel) 12144 // SPDY GET for HTTPS URL (through CONNECT tunnel)
11979 const HostPortPair host_port_pair("www.example.org", 8080); 12145 const HostPortPair host_port_pair("www.example.org", 8080);
11980 scoped_ptr<SpdyFrame> connect( 12146 scoped_ptr<SpdyFrame> connect(
11981 spdy_util_.ConstructSpdyConnect(NULL, 0, 1, LOWEST, host_port_pair)); 12147 spdy_util_.ConstructSpdyConnect(NULL, 0, 1, LOWEST, host_port_pair));
11982 scoped_ptr<SpdyFrame> req1( 12148 scoped_ptr<SpdyFrame> req1(
11983 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST)); 12149 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST));
(...skipping 2022 matching lines...) Expand 10 before | Expand all | Expand 10 after
14006 ASSERT_TRUE(response); 14172 ASSERT_TRUE(response);
14007 ASSERT_TRUE(response->headers.get()); 14173 ASSERT_TRUE(response->headers.get());
14008 14174
14009 EXPECT_EQ(101, response->headers->response_code()); 14175 EXPECT_EQ(101, response->headers->response_code());
14010 14176
14011 trans.reset(); 14177 trans.reset();
14012 session->CloseAllConnections(); 14178 session->CloseAllConnections();
14013 } 14179 }
14014 14180
14015 } // namespace net 14181 } // namespace net
OLDNEW
« no previous file with comments | « no previous file | net/http/http_stream_factory_impl_job.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698