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