OLD | NEW |
---|---|
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 Loading... | |
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 Loading... | |
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 |
OLD | NEW |