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

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: Another possible fix. 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
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 // Connection to the origin fails.
11991 StaticSocketDataProvider data_refused;
11992 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
11993 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
11994
11995 // Set up alternative service for origin.
11996 session_deps_.use_alternate_protocols = true;
11997 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
11998 base::WeakPtr<HttpServerProperties> http_server_properties =
11999 session->http_server_properties();
12000 AlternativeService alternative_service(
12001 AlternateProtocolFromNextProto(GetParam()), alternative);
12002 http_server_properties->SetAlternativeService(origin, alternative_service,
12003 1.0);
12004
12005 scoped_ptr<HttpTransaction> trans(
12006 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12007 HttpRequestInfo request;
12008 request.method = "GET";
12009 request.url = GURL("https://origin.example.org:443");
12010 request.load_flags = 0;
12011 TestCompletionCallback callback;
12012
12013 int rv = trans->Start(&request, callback.callback(), BoundNetLog());
12014 EXPECT_EQ(ERR_IO_PENDING, rv);
12015 rv = callback.WaitForResult();
davidben 2015/05/01 23:21:46 Since we don't actually care whether Start complet
Bence 2015/05/04 12:05:07 I'm not a big fan multiply nested function calls o
davidben 2015/05/04 16:11:51 That'll silently break if things, for some reason,
12016 // HTTP/2 (or SPDY) is required for alternative service.
12017 EXPECT_EQ(ERR_NPN_NEGOTIATION_FAILED, rv);
12018 }
12019
12020 // Alternative service requires HTTP/2 (or SPDY), but there is already a
12021 // HTTP/1.1 socket open to the alternative server. That socket should not be
12022 // used.
12023 TEST_P(HttpNetworkTransactionTest, AlternativeServiceShouldNotPoolToHttp11) {
12024 HostPortPair origin("origin.example.org", 443);
12025 HostPortPair alternative("alternative.example.org", 443);
12026 std::string origin_url = "https://origin.example.org:443";
12027 std::string alternative_url = "https://alternative.example.org:443";
12028
12029 // Negotiate HTTP/1.1 with alternative.example.org.
12030 SSLSocketDataProvider ssl(ASYNC, OK);
12031 ssl.SetNextProto(kProtoHTTP11);
12032 session_deps_.socket_factory->AddSSLSocketDataProvider(&ssl);
12033
12034 MockWrite http_writes[] = {
12035 MockWrite(
12036 "GET / HTTP/1.1\r\n"
12037 "Host: alternative.example.org\r\n"
12038 "Connection: keep-alive\r\n\r\n"),
12039 MockWrite(
12040 "GET / HTTP/1.1\r\n"
12041 "Host: alternative.example.org\r\n"
12042 "Connection: keep-alive\r\n\r\n"),
12043 };
12044
12045 MockRead http_reads[] = {
12046 MockRead(
12047 "HTTP/1.1 200 OK\r\n"
12048 "Content-Type: text/html; charset=iso-8859-1\r\n"
12049 "Content-Length: 40\r\n\r\n"
12050 "first HTTP/1.1 response from alternative"),
12051 MockRead(
12052 "HTTP/1.1 200 OK\r\n"
12053 "Content-Type: text/html; charset=iso-8859-1\r\n"
12054 "Content-Length: 41\r\n\r\n"
12055 "second HTTP/1.1 response from alternative"),
12056 };
12057 StaticSocketDataProvider http_data(http_reads, arraysize(http_reads),
12058 http_writes, arraysize(http_writes));
12059 session_deps_.socket_factory->AddSocketDataProvider(&http_data);
12060
12061 // Connection to the origin fails.
12062 StaticSocketDataProvider data_refused;
12063 data_refused.set_connect_data(MockConnect(ASYNC, ERR_CONNECTION_REFUSED));
12064 session_deps_.socket_factory->AddSocketDataProvider(&data_refused);
12065
12066 // Set up alternative service for origin.
12067 session_deps_.use_alternate_protocols = true;
12068 scoped_refptr<HttpNetworkSession> session(CreateSession(&session_deps_));
12069 base::WeakPtr<HttpServerProperties> http_server_properties =
12070 session->http_server_properties();
12071 AlternativeService alternative_service(
12072 AlternateProtocolFromNextProto(GetParam()), alternative);
12073 http_server_properties->SetAlternativeService(origin, alternative_service,
12074 1.0);
12075
12076 // First transaction to alternative to open an HTTP/1.1 socket.
12077 scoped_ptr<HttpTransaction> trans1(
12078 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12079 HttpRequestInfo request1;
12080 request1.method = "GET";
12081 request1.url = GURL(alternative_url);
12082 request1.load_flags = 0;
12083 TestCompletionCallback callback1;
12084
12085 int rv = trans1->Start(&request1, callback1.callback(), BoundNetLog());
12086 EXPECT_EQ(ERR_IO_PENDING, rv);
12087 rv = callback1.WaitForResult();
12088 EXPECT_EQ(OK, rv);
12089 const HttpResponseInfo* response1 = trans1->GetResponseInfo();
12090 ASSERT_TRUE(response1 != nullptr);
davidben 2015/05/01 23:21:46 Nit: I think this can just be ASSERT_TRUE(response
Bence 2015/05/04 12:05:07 Done.
12091 ASSERT_TRUE(response1->headers.get() != nullptr);
davidben 2015/05/01 23:21:46 Nit: Ditto.
Bence 2015/05/04 12:05:06 Done.
12092 EXPECT_EQ("HTTP/1.1 200 OK", response1->headers->GetStatusLine());
12093 EXPECT_TRUE(response1->was_npn_negotiated);
12094 EXPECT_FALSE(response1->was_fetched_via_spdy);
12095 std::string response_data1;
12096 ASSERT_EQ(OK, ReadTransaction(trans1.get(), &response_data1));
12097 EXPECT_EQ("first HTTP/1.1 response from alternative", response_data1);
12098
12099 // Request for origin.example.org, which has an alternative service. This
12100 // will start two Jobs: the alternative should find the HTTP/1.1, ignore it,
12101 // but not open other connections to alternative. The Job to origin fails,
12102 // so this request fails.
12103 scoped_ptr<HttpTransaction> trans2(
12104 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12105 HttpRequestInfo request2;
12106 request2.method = "GET";
12107 request2.url = GURL(origin_url);
12108 request2.load_flags = 0;
12109 TestCompletionCallback callback2;
12110
12111 rv = trans2->Start(&request2, callback2.callback(), BoundNetLog());
12112 EXPECT_EQ(ERR_IO_PENDING, rv);
12113 rv = callback2.WaitForResult();
12114 EXPECT_EQ(ERR_CONNECTION_REFUSED, rv);
12115
12116 // Another transaction to alternative. This is to test that the HTTP/1.1
12117 // socket is still open and in the pool.
davidben 2015/05/01 23:21:46 Huh, interesting. I guess this works because we do
Bence 2015/05/04 12:05:07 Yup. I think this is really essential for this te
12118 scoped_ptr<HttpTransaction> trans3(
12119 new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get()));
12120 HttpRequestInfo request3;
12121 request3.method = "GET";
12122 request3.url = GURL(alternative_url);
12123 request3.load_flags = 0;
12124 TestCompletionCallback callback3;
12125
12126 rv = trans3->Start(&request3, callback3.callback(), BoundNetLog());
12127 EXPECT_EQ(ERR_IO_PENDING, rv);
12128 rv = callback3.WaitForResult();
12129 EXPECT_EQ(OK, rv);
12130 const HttpResponseInfo* response3 = trans3->GetResponseInfo();
12131 ASSERT_TRUE(response3 != nullptr);
12132 ASSERT_TRUE(response3->headers.get() != nullptr);
davidben 2015/05/01 23:21:46 Ditto.
Bence 2015/05/04 12:05:07 Done.
12133 EXPECT_EQ("HTTP/1.1 200 OK", response3->headers->GetStatusLine());
12134 EXPECT_TRUE(response3->was_npn_negotiated);
12135 EXPECT_FALSE(response3->was_fetched_via_spdy);
12136 std::string response_data3;
12137 ASSERT_EQ(OK, ReadTransaction(trans3.get(), &response_data3));
12138 EXPECT_EQ("second HTTP/1.1 response from alternative", response_data3);
12139 }
12140
11974 TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) { 12141 TEST_P(HttpNetworkTransactionTest, DoNotUseSpdySessionForHttpOverTunnel) {
11975 const std::string https_url = "https://www.example.org:8080/"; 12142 const std::string https_url = "https://www.example.org:8080/";
11976 const std::string http_url = "http://www.example.org:8080/"; 12143 const std::string http_url = "http://www.example.org:8080/";
11977 12144
11978 // SPDY GET for HTTPS URL (through CONNECT tunnel) 12145 // SPDY GET for HTTPS URL (through CONNECT tunnel)
11979 const HostPortPair host_port_pair("www.example.org", 8080); 12146 const HostPortPair host_port_pair("www.example.org", 8080);
11980 scoped_ptr<SpdyFrame> connect( 12147 scoped_ptr<SpdyFrame> connect(
11981 spdy_util_.ConstructSpdyConnect(NULL, 0, 1, LOWEST, host_port_pair)); 12148 spdy_util_.ConstructSpdyConnect(NULL, 0, 1, LOWEST, host_port_pair));
11982 scoped_ptr<SpdyFrame> req1( 12149 scoped_ptr<SpdyFrame> req1(
11983 spdy_util_.ConstructSpdyGet(https_url.c_str(), false, 1, LOWEST)); 12150 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); 14173 ASSERT_TRUE(response);
14007 ASSERT_TRUE(response->headers.get()); 14174 ASSERT_TRUE(response->headers.get());
14008 14175
14009 EXPECT_EQ(101, response->headers->response_code()); 14176 EXPECT_EQ(101, response->headers->response_code());
14010 14177
14011 trans.reset(); 14178 trans.reset();
14012 session->CloseAllConnections(); 14179 session->CloseAllConnections();
14013 } 14180 }
14014 14181
14015 } // namespace net 14182 } // namespace net
OLDNEW
« no previous file with comments | « no previous file | net/http/http_stream_factory_impl_job.cc » ('j') | net/http/http_stream_factory_impl_job.cc » ('J')

Powered by Google App Engine
This is Rietveld 408576698