Index: net/quic/chromium/quic_network_transaction_unittest.cc |
diff --git a/net/quic/chromium/quic_network_transaction_unittest.cc b/net/quic/chromium/quic_network_transaction_unittest.cc |
index 0d56c1d49b71e99e0098ff87acb016a814ec02fe..a57a96c883fc22c671d9c44ef2f899242c1a1174 100644 |
--- a/net/quic/chromium/quic_network_transaction_unittest.cc |
+++ b/net/quic/chromium/quic_network_transaction_unittest.cc |
@@ -14,6 +14,7 @@ |
#include "base/memory/ptr_util.h" |
#include "base/run_loop.h" |
#include "base/stl_util.h" |
+#include "base/strings/string_number_conversions.h" |
#include "base/strings/stringprintf.h" |
#include "base/test/histogram_tester.h" |
#include "net/base/chunked_upload_data_stream.h" |
@@ -127,6 +128,17 @@ struct PoolingTestParams { |
DestinationType destination_type; |
}; |
+std::string GenerateQuicVersionsListForAltSvcHeader( |
+ const QuicVersionVector& versions) { |
+ std::string result = ""; |
+ for (const QuicVersion& version : versions) { |
+ if (!result.empty()) |
+ result.append(","); |
+ result.append(base::IntToString(version)); |
+ } |
+ return result; |
+} |
+ |
std::vector<PoolingTestParams> GetPoolingTestParams() { |
std::vector<PoolingTestParams> params; |
QuicVersionVector all_supported_versions = AllSupportedVersions(); |
@@ -499,9 +511,9 @@ class QuicNetworkTransactionTest |
std::move(headers), offset); |
} |
- void CreateSession() { |
+ void CreateSession(const QuicVersionVector& supported_versions) { |
session_params_.enable_quic = true; |
- session_params_.quic_supported_versions = SupportedVersions(version_); |
+ session_params_.quic_supported_versions = supported_versions; |
session_context_.quic_clock = &clock_; |
session_context_.quic_random = &random_generator_; |
@@ -526,6 +538,8 @@ class QuicNetworkTransactionTest |
session_->quic_stream_factory()->set_require_confirmation(false); |
} |
+ void CreateSession() { return CreateSession(SupportedVersions(version_)); } |
+ |
void CheckWasQuicResponse(HttpNetworkTransaction* trans) { |
const HttpResponseInfo* response = trans->GetResponseInfo(); |
ASSERT_TRUE(response != nullptr); |
@@ -611,8 +625,9 @@ class QuicNetworkTransactionTest |
url::SchemeHostPort server(request_.url); |
AlternativeService alternative_service(kProtoQUIC, server.host(), 443); |
base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1); |
- http_server_properties_.SetAlternativeService(server, alternative_service, |
- expiration); |
+ http_server_properties_.SetAlternativeService( |
+ server, alternative_service, expiration, |
+ HttpNetworkSession::Params().quic_supported_versions); |
} |
void AddQuicRemoteAlternativeServiceMapping( |
@@ -623,8 +638,9 @@ class QuicNetworkTransactionTest |
AlternativeService alternative_service(kProtoQUIC, alternative.host(), |
alternative.port()); |
base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1); |
- http_server_properties_.SetAlternativeService(server, alternative_service, |
- expiration); |
+ http_server_properties_.SetAlternativeService( |
+ server, alternative_service, expiration, |
+ HttpNetworkSession::Params().quic_supported_versions); |
} |
void ExpectBrokenAlternateProtocolMapping() { |
@@ -1186,8 +1202,9 @@ TEST_P(QuicNetworkTransactionTest, RetryMisdirectedRequest) { |
AlternativeService alternative_service(kProtoQUIC, kDefaultServerHostName, |
443); |
base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1); |
- http_server_properties_.SetAlternativeService(server, alternative_service, |
- expiration); |
+ http_server_properties_.SetAlternativeService( |
+ server, alternative_service, expiration, |
+ HttpNetworkSession::Params().quic_supported_versions); |
// First try: The alternative job uses QUIC and reports an HTTP 421 |
// Misdirected Request error. The main job uses TCP, but |http_data| below is |
@@ -1447,6 +1464,74 @@ TEST_P(QuicNetworkTransactionTest, DoNotGetAltSvcForDifferentOrigin) { |
SendRequestAndExpectHttpResponse("hello world"); |
} |
+TEST_P(QuicNetworkTransactionTest, |
+ StoreMutuallySupportedVersionsWhenProcessAltSvc) { |
+ std::string advertised_versions_list_str = |
+ GenerateQuicVersionsListForAltSvcHeader(AllSupportedVersions()); |
+ std::string altsvc_header = |
+ base::StringPrintf("Alt-Svc: quic=\":443\"; v=\"%s\"\r\n\r\n", |
+ advertised_versions_list_str.c_str()); |
+ MockRead http_reads[] = { |
+ MockRead("HTTP/1.1 200 OK\r\n"), MockRead(altsvc_header.c_str()), |
+ MockRead("hello world"), |
+ MockRead(SYNCHRONOUS, ERR_TEST_PEER_CLOSE_AFTER_NEXT_MOCK_READ), |
+ MockRead(ASYNC, OK)}; |
+ |
+ StaticSocketDataProvider http_data(http_reads, arraysize(http_reads), nullptr, |
+ 0); |
+ socket_factory_.AddSocketDataProvider(&http_data); |
+ socket_factory_.AddSSLSocketDataProvider(&ssl_data_); |
+ |
+ MockQuicData mock_quic_data; |
+ QuicStreamOffset header_stream_offset = 0; |
+ mock_quic_data.AddWrite( |
+ ConstructInitialSettingsPacket(1, &header_stream_offset)); |
+ mock_quic_data.AddWrite(ConstructClientRequestHeadersPacket( |
+ 2, GetNthClientInitiatedStreamId(0), true, true, |
+ GetRequestHeaders("GET", "https", "/"), &header_stream_offset)); |
+ mock_quic_data.AddRead(ConstructServerResponseHeadersPacket( |
+ 1, GetNthClientInitiatedStreamId(0), false, false, |
+ GetResponseHeaders("200 OK"))); |
+ mock_quic_data.AddRead(ConstructServerDataPacket( |
+ 2, GetNthClientInitiatedStreamId(0), false, true, 0, "hello!")); |
+ mock_quic_data.AddWrite(ConstructClientAckPacket(3, 2, 1, 1)); |
+ mock_quic_data.AddRead(ASYNC, ERR_IO_PENDING); // No more data to read |
+ mock_quic_data.AddRead(ASYNC, 0); // EOF |
+ |
+ mock_quic_data.AddSocketDataToFactory(&socket_factory_); |
+ |
+ AddHangingNonAlternateProtocolSocketData(); |
+ |
+ // Generate a list of QUIC versions suppored by netstack. |
+ QuicVersionVector current_supported_versions = SupportedVersions(version_); |
+ if (version_ != QUIC_VERSION_40) { |
+ current_supported_versions.push_back(QUIC_VERSION_40); |
+ } else { |
+ current_supported_versions.push_back(QUIC_VERSION_37); |
+ } |
+ |
+ CreateSession(current_supported_versions); |
+ |
+ SendRequestAndExpectHttpResponse("hello world"); |
+ SendRequestAndExpectQuicResponse("hello!"); |
+ |
+ // Check alternative service is set with only mutually supported versions. |
+ const url::SchemeHostPort https_server(request_.url); |
+ const AlternativeServiceInfoVector alt_svc_info_vector = |
+ session_->http_server_properties()->GetAlternativeServiceInfos( |
+ https_server); |
+ EXPECT_EQ(1u, alt_svc_info_vector.size()); |
+ EXPECT_EQ(kProtoQUIC, alt_svc_info_vector[0].alternative_service.protocol); |
+ EXPECT_EQ(2u, alt_svc_info_vector[0].advertised_versions().size()); |
+ // Advertised versions will be lised in a sorted order. |
+ std::sort(current_supported_versions.begin(), |
+ current_supported_versions.end()); |
+ EXPECT_EQ(current_supported_versions[0], |
+ alt_svc_info_vector[0].advertised_versions()[0]); |
+ EXPECT_EQ(current_supported_versions[1], |
+ alt_svc_info_vector[0].advertised_versions()[1]); |
+} |
+ |
TEST_P(QuicNetworkTransactionTest, UseAlternativeServiceAllSupportedVersion) { |
std::string altsvc_header = |
base::StringPrintf("Alt-Svc: quic=\":443\"; v=\"%u\"\r\n\r\n", version_); |
@@ -2783,16 +2868,18 @@ TEST_P(QuicNetworkTransactionTest, PoolByOrigin) { |
url::SchemeHostPort server(request_.url); |
AlternativeService alternative_service(kProtoQUIC, destination1, 443); |
base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1); |
- http_server_properties_.SetAlternativeService(server, alternative_service, |
- expiration); |
+ http_server_properties_.SetAlternativeService( |
+ server, alternative_service, expiration, |
+ HttpNetworkSession::Params().quic_supported_versions); |
// First request opens connection to |destination1| |
// with QuicServerId.host() == kDefaultServerHostName. |
SendRequestAndExpectQuicResponse("hello!"); |
// Set up alternative service entry to a different destination. |
alternative_service = AlternativeService(kProtoQUIC, destination2, 443); |
- http_server_properties_.SetAlternativeService(server, alternative_service, |
- expiration); |
+ http_server_properties_.SetAlternativeService( |
+ server, alternative_service, expiration, |
+ HttpNetworkSession::Params().quic_supported_versions); |
// Second request pools to existing connection with same QuicServerId, |
// even though alternative service destination is different. |
SendRequestAndExpectQuicResponse("hello!"); |
@@ -2856,7 +2943,8 @@ TEST_P(QuicNetworkTransactionTest, PoolByDestination) { |
AlternativeService alternative_service1(kProtoQUIC, destination1, 443); |
base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1); |
http_server_properties_.SetAlternativeService( |
- url::SchemeHostPort(origin1), alternative_service1, expiration); |
+ url::SchemeHostPort(origin1), alternative_service1, expiration, |
+ HttpNetworkSession::Params().quic_supported_versions); |
// Set up multiple alternative service entries for |origin2|, |
// the first one with a different destination as for |origin1|, |
@@ -4374,7 +4462,7 @@ class QuicNetworkTransactionWithDestinationTest |
base::Time expiration = base::Time::Now() + base::TimeDelta::FromDays(1); |
http_server_properties_.SetAlternativeService( |
url::SchemeHostPort("https", origin, 443), alternative_service, |
- expiration); |
+ expiration, HttpNetworkSession::Params().quic_supported_versions); |
} |
std::unique_ptr<QuicEncryptedPacket> ConstructClientRequestHeadersPacket( |