diff options
author | rch@chromium.org <rch@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-07-08 23:01:00 +0000 |
---|---|---|
committer | rch@chromium.org <rch@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2014-07-08 23:01:00 +0000 |
commit | 287d941307e87364a4864187ea5c9b9df08daef8 (patch) | |
tree | 187d4672e5aec8ab417ca37f72bb15922ef591d2 /net/http | |
parent | 69e6f0e744a73856a4e4e90c34b0a857b9b0373f (diff) | |
download | chromium_src-287d941307e87364a4864187ea5c9b9df08daef8.zip chromium_src-287d941307e87364a4864187ea5c9b9df08daef8.tar.gz chromium_src-287d941307e87364a4864187ea5c9b9df08daef8.tar.bz2 |
Add a probability to Alternate-Protocol support. Can be enabled either via a field trial or a command line flag.
Committed: https://src.chromium.org/viewvc/chrome?view=rev&revision=281777
Review URL: https://codereview.chromium.org/339663010
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@281861 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/http')
-rw-r--r-- | net/http/http_network_layer.cc | 4 | ||||
-rw-r--r-- | net/http/http_network_session.cc | 4 | ||||
-rw-r--r-- | net/http/http_network_session.h | 1 | ||||
-rw-r--r-- | net/http/http_network_transaction.cc | 15 | ||||
-rw-r--r-- | net/http/http_network_transaction_unittest.cc | 25 | ||||
-rw-r--r-- | net/http/http_server_properties.cc | 7 | ||||
-rw-r--r-- | net/http/http_server_properties.h | 26 | ||||
-rw-r--r-- | net/http/http_server_properties_impl.cc | 40 | ||||
-rw-r--r-- | net/http/http_server_properties_impl.h | 12 | ||||
-rw-r--r-- | net/http/http_server_properties_impl_unittest.cc | 88 | ||||
-rw-r--r-- | net/http/http_stream_factory.cc | 82 | ||||
-rw-r--r-- | net/http/http_stream_factory.h | 2 | ||||
-rw-r--r-- | net/http/http_stream_factory_impl.cc | 15 | ||||
-rw-r--r-- | net/http/http_stream_factory_impl.h | 2 | ||||
-rw-r--r-- | net/http/http_stream_factory_impl_job.cc | 2 | ||||
-rw-r--r-- | net/http/http_stream_factory_impl_job.h | 2 | ||||
-rw-r--r-- | net/http/http_stream_factory_impl_unittest.cc | 3 |
17 files changed, 204 insertions, 126 deletions
diff --git a/net/http/http_network_layer.cc b/net/http/http_network_layer.cc index 0704de4..258555f 100644 --- a/net/http/http_network_layer.cc +++ b/net/http/http_network_layer.cc @@ -51,9 +51,7 @@ HttpTransactionFactory* HttpNetworkLayer::CreateFactory( // static void HttpNetworkLayer::ForceAlternateProtocol() { - PortAlternateProtocolPair pair; - pair.port = 443; - pair.protocol = NPN_SPDY_3; + AlternateProtocolInfo pair(443, NPN_SPDY_3, 1); HttpServerPropertiesImpl::ForceAlternateProtocol(pair); } diff --git a/net/http/http_network_session.cc b/net/http/http_network_session.cc index ff178da..43153f7 100644 --- a/net/http/http_network_session.cc +++ b/net/http/http_network_session.cc @@ -81,6 +81,7 @@ HttpNetworkSession::Params::Params() force_spdy_over_ssl(true), force_spdy_always(false), use_alternate_protocols(false), + alternate_protocol_probability_threshold(0), enable_websocket_over_spdy(false), enable_quic(false), enable_quic_port_selection(true), @@ -182,6 +183,9 @@ HttpNetworkSession::HttpNetworkSession(const Params& params) if (HpackHuffmanAggregator::UseAggregator()) { huffman_aggregator_.reset(new HpackHuffmanAggregator()); } + + http_server_properties_->SetAlternateProtocolProbabilityThreshold( + params.alternate_protocol_probability_threshold); } HttpNetworkSession::~HttpNetworkSession() { diff --git a/net/http/http_network_session.h b/net/http/http_network_session.h index 272f96e7..e265a91 100644 --- a/net/http/http_network_session.h +++ b/net/http/http_network_session.h @@ -104,6 +104,7 @@ class NET_EXPORT HttpNetworkSession // Noe: Using this in the case of NPN for HTTP only results in the browser // trying SSL and then falling back to http. bool use_alternate_protocols; + double alternate_protocol_probability_threshold; bool enable_websocket_over_spdy; bool enable_quic; diff --git a/net/http/http_network_transaction.cc b/net/http/http_network_transaction.cc index 0a2c8c4..f4df073 100644 --- a/net/http/http_network_transaction.cc +++ b/net/http/http_network_transaction.cc @@ -79,17 +79,20 @@ void ProcessAlternateProtocol( HttpNetworkSession* session, const HttpResponseHeaders& headers, const HostPortPair& http_host_port_pair) { - std::string alternate_protocol_str; - - if (!headers.EnumerateHeader(NULL, kAlternateProtocolHeader, - &alternate_protocol_str)) { - // Header is not present. + if (!headers.HasHeader(kAlternateProtocolHeader)) return; + + std::vector<std::string> alternate_protocol_values; + void* iter = NULL; + std::string alternate_protocol_str; + while (headers.EnumerateHeader(&iter, kAlternateProtocolHeader, + &alternate_protocol_str)) { + alternate_protocol_values.push_back(alternate_protocol_str); } session->http_stream_factory()->ProcessAlternateProtocol( session->http_server_properties(), - alternate_protocol_str, + alternate_protocol_values, http_host_port_pair, *session); } diff --git a/net/http/http_network_transaction_unittest.cc b/net/http/http_network_transaction_unittest.cc index ab64040..8c078c4 100644 --- a/net/http/http_network_transaction_unittest.cc +++ b/net/http/http_network_transaction_unittest.cc @@ -7536,7 +7536,7 @@ scoped_refptr<HttpNetworkSession> SetupSessionForGroupNameTests( session->http_server_properties(); http_server_properties->SetAlternateProtocol( HostPortPair("host.with.alternate", 80), 443, - AlternateProtocolFromNextProto(next_proto)); + AlternateProtocolFromNextProto(next_proto), 1); return session; } @@ -8448,11 +8448,10 @@ TEST_P(HttpNetworkTransactionTest, HonorAlternateProtocolHeader) { EXPECT_EQ("hello world", response_data); ASSERT_TRUE(http_server_properties.HasAlternateProtocol(http_host_port_pair)); - const PortAlternateProtocolPair alternate = + const AlternateProtocolInfo alternate = http_server_properties.GetAlternateProtocol(http_host_port_pair); - PortAlternateProtocolPair expected_alternate; - expected_alternate.port = 443; - expected_alternate.protocol = AlternateProtocolFromNextProto(GetParam()); + AlternateProtocolInfo expected_alternate( + 443, AlternateProtocolFromNextProto(GetParam()), 1); EXPECT_TRUE(expected_alternate.Equals(alternate)); } @@ -8488,7 +8487,7 @@ TEST_P(HttpNetworkTransactionTest, http_server_properties->SetAlternateProtocol( HostPortPair::FromURL(request.url), 666 /* port is ignored by MockConnect anyway */, - AlternateProtocolFromNextProto(GetParam())); + AlternateProtocolFromNextProto(GetParam()), 1); scoped_ptr<HttpTransaction> trans( new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); @@ -8509,7 +8508,7 @@ TEST_P(HttpNetworkTransactionTest, ASSERT_TRUE(http_server_properties->HasAlternateProtocol( HostPortPair::FromURL(request.url))); - const PortAlternateProtocolPair alternate = + const AlternateProtocolInfo alternate = http_server_properties->GetAlternateProtocol( HostPortPair::FromURL(request.url)); EXPECT_EQ(ALTERNATE_PROTOCOL_BROKEN, alternate.protocol); @@ -8550,7 +8549,7 @@ TEST_P(HttpNetworkTransactionTest, http_server_properties->SetAlternateProtocol( HostPortPair::FromURL(restricted_port_request.url), kUnrestrictedAlternatePort, - AlternateProtocolFromNextProto(GetParam())); + AlternateProtocolFromNextProto(GetParam()), 1); scoped_ptr<HttpTransaction> trans( new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); @@ -8601,7 +8600,7 @@ TEST_P(HttpNetworkTransactionTest, http_server_properties->SetAlternateProtocol( HostPortPair::FromURL(restricted_port_request.url), kUnrestrictedAlternatePort, - AlternateProtocolFromNextProto(GetParam())); + AlternateProtocolFromNextProto(GetParam()), 1); scoped_ptr<HttpTransaction> trans( new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); @@ -8649,7 +8648,7 @@ TEST_P(HttpNetworkTransactionTest, http_server_properties->SetAlternateProtocol( HostPortPair::FromURL(restricted_port_request.url), kRestrictedAlternatePort, - AlternateProtocolFromNextProto(GetParam())); + AlternateProtocolFromNextProto(GetParam()), 1); scoped_ptr<HttpTransaction> trans( new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); @@ -8698,7 +8697,7 @@ TEST_P(HttpNetworkTransactionTest, http_server_properties->SetAlternateProtocol( HostPortPair::FromURL(unrestricted_port_request.url), kRestrictedAlternatePort, - AlternateProtocolFromNextProto(GetParam())); + AlternateProtocolFromNextProto(GetParam()), 1); scoped_ptr<HttpTransaction> trans( new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); @@ -8746,7 +8745,7 @@ TEST_P(HttpNetworkTransactionTest, http_server_properties->SetAlternateProtocol( HostPortPair::FromURL(unrestricted_port_request.url), kUnrestrictedAlternatePort, - AlternateProtocolFromNextProto(GetParam())); + AlternateProtocolFromNextProto(GetParam()), 1); scoped_ptr<HttpTransaction> trans( new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); @@ -8789,7 +8788,7 @@ TEST_P(HttpNetworkTransactionTest, AlternateProtocolUnsafeBlocked) { http_server_properties->SetAlternateProtocol( HostPortPair::FromURL(request.url), kUnsafePort, - AlternateProtocolFromNextProto(GetParam())); + AlternateProtocolFromNextProto(GetParam()), 1); scoped_ptr<HttpTransaction> trans( new HttpNetworkTransaction(DEFAULT_PRIORITY, session.get())); diff --git a/net/http/http_server_properties.cc b/net/http/http_server_properties.cc index 1a9bfb6..abc5cb1 100644 --- a/net/http/http_server_properties.cc +++ b/net/http/http_server_properties.cc @@ -111,9 +111,10 @@ AlternateProtocol AlternateProtocolFromNextProto(NextProto next_proto) { return UNINITIALIZED_ALTERNATE_PROTOCOL; } -std::string PortAlternateProtocolPair::ToString() const { - return base::StringPrintf("%d:%s", port, - AlternateProtocolToString(protocol)); +std::string AlternateProtocolInfo::ToString() const { + return base::StringPrintf("%d:%s p=%f", port, + AlternateProtocolToString(protocol), + probability); } } // namespace net diff --git a/net/http/http_server_properties.h b/net/http/http_server_properties.h index 88d1f3c..718f4c5 100644 --- a/net/http/http_server_properties.h +++ b/net/http/http_server_properties.h @@ -92,19 +92,29 @@ NET_EXPORT AlternateProtocol AlternateProtocolFromString( NET_EXPORT_PRIVATE AlternateProtocol AlternateProtocolFromNextProto( NextProto next_proto); -struct NET_EXPORT PortAlternateProtocolPair { - bool Equals(const PortAlternateProtocolPair& other) const { - return port == other.port && protocol == other.protocol; +struct NET_EXPORT AlternateProtocolInfo { + AlternateProtocolInfo(uint16 port, + AlternateProtocol protocol, + double probability) + : port(port), + protocol(protocol), + probability(probability) {} + + bool Equals(const AlternateProtocolInfo& other) const { + return port == other.port && + protocol == other.protocol && + probability == other.probability; } std::string ToString() const; uint16 port; AlternateProtocol protocol; + double probability; }; typedef base::MRUCache< - HostPortPair, PortAlternateProtocolPair> AlternateProtocolMap; + HostPortPair, AlternateProtocolInfo> AlternateProtocolMap; typedef base::MRUCache<HostPortPair, SettingsMap> SpdySettingsMap; extern const char kAlternateProtocolHeader[]; @@ -143,13 +153,14 @@ class NET_EXPORT HttpServerProperties { // Returns the Alternate-Protocol and port for |server|. // HasAlternateProtocol(server) must be true. - virtual PortAlternateProtocolPair GetAlternateProtocol( + virtual AlternateProtocolInfo GetAlternateProtocol( const HostPortPair& server) = 0; // Sets the Alternate-Protocol for |server|. virtual void SetAlternateProtocol(const HostPortPair& server, uint16 alternate_port, - AlternateProtocol alternate_protocol) = 0; + AlternateProtocol alternate_protocol, + double probability) = 0; // Sets the Alternate-Protocol for |server| to be BROKEN. virtual void SetBrokenAlternateProtocol(const HostPortPair& server) = 0; @@ -170,6 +181,9 @@ class NET_EXPORT HttpServerProperties { virtual void SetAlternateProtocolExperiment( AlternateProtocolExperiment experiment) = 0; + virtual void SetAlternateProtocolProbabilityThreshold( + double threshold) = 0; + virtual AlternateProtocolExperiment GetAlternateProtocolExperiment() const = 0; diff --git a/net/http/http_server_properties_impl.cc b/net/http/http_server_properties_impl.cc index 96f3a7d..4bb544d 100644 --- a/net/http/http_server_properties_impl.cc +++ b/net/http/http_server_properties_impl.cc @@ -26,6 +26,7 @@ HttpServerPropertiesImpl::HttpServerPropertiesImpl() alternate_protocol_experiment_( ALTERNATE_PROTOCOL_NOT_PART_OF_EXPERIMENT), spdy_settings_map_(SpdySettingsMap::NO_AUTO_EVICT), + alternate_protocol_probability_threshold_(0), weak_ptr_factory_(this) { canoncial_suffixes_.push_back(".c.youtube.com"); canoncial_suffixes_.push_back(".googlevideo.com"); @@ -130,15 +131,15 @@ std::string HttpServerPropertiesImpl::GetFlattenedSpdyServer( return spdy_server; } -static const PortAlternateProtocolPair* g_forced_alternate_protocol = NULL; +static const AlternateProtocolInfo* g_forced_alternate_protocol = NULL; // static void HttpServerPropertiesImpl::ForceAlternateProtocol( - const PortAlternateProtocolPair& pair) { + const AlternateProtocolInfo& info) { // Note: we're going to leak this. if (g_forced_alternate_protocol) delete g_forced_alternate_protocol; - g_forced_alternate_protocol = new PortAlternateProtocolPair(pair); + g_forced_alternate_protocol = new AlternateProtocolInfo(info); } // static @@ -193,9 +194,13 @@ void HttpServerPropertiesImpl::SetSupportsSpdy( bool HttpServerPropertiesImpl::HasAlternateProtocol( const HostPortPair& server) { - if (alternate_protocol_map_.Get(server) != alternate_protocol_map_.end() || - g_forced_alternate_protocol) + if (g_forced_alternate_protocol) + return true; + AlternateProtocolMap::const_iterator it = alternate_protocol_map_.Get(server); + if (it != alternate_protocol_map_.end() && + it->second.probability > alternate_protocol_probability_threshold_) { return true; + } return GetCanonicalHost(server) != canonical_host_to_origin_map_.end(); } @@ -213,7 +218,7 @@ std::string HttpServerPropertiesImpl::GetCanonicalSuffix( return std::string(); } -PortAlternateProtocolPair +AlternateProtocolInfo HttpServerPropertiesImpl::GetAlternateProtocol( const HostPortPair& server) { DCHECK(HasAlternateProtocol(server)); @@ -236,17 +241,18 @@ HttpServerPropertiesImpl::GetAlternateProtocol( void HttpServerPropertiesImpl::SetAlternateProtocol( const HostPortPair& server, uint16 alternate_port, - AlternateProtocol alternate_protocol) { + AlternateProtocol alternate_protocol, + double alternate_probability) { if (alternate_protocol == ALTERNATE_PROTOCOL_BROKEN) { LOG(DFATAL) << "Call SetBrokenAlternateProtocol() instead."; return; } - PortAlternateProtocolPair alternate; - alternate.port = alternate_port; - alternate.protocol = alternate_protocol; + AlternateProtocolInfo alternate(alternate_port, + alternate_protocol, + alternate_probability); if (HasAlternateProtocol(server)) { - const PortAlternateProtocolPair existing_alternate = + const AlternateProtocolInfo existing_alternate = GetAlternateProtocol(server); if (existing_alternate.protocol == ALTERNATE_PROTOCOL_BROKEN) { @@ -260,8 +266,10 @@ void HttpServerPropertiesImpl::SetAlternateProtocol( << server.ToString() << " from [Port: " << existing_alternate.port << ", Protocol: " << existing_alternate.protocol + << ", Probability: " << existing_alternate.probability << "] to [Port: " << alternate_port << ", Protocol: " << alternate_protocol + << ", Probability: " << alternate_probability << "]."; } } else { @@ -292,8 +300,9 @@ void HttpServerPropertiesImpl::SetBrokenAlternateProtocol( if (it != alternate_protocol_map_.end()) { it->second.protocol = ALTERNATE_PROTOCOL_BROKEN; } else { - PortAlternateProtocolPair alternate; - alternate.protocol = ALTERNATE_PROTOCOL_BROKEN; + AlternateProtocolInfo alternate(server.port(), + ALTERNATE_PROTOCOL_BROKEN, + 1); alternate_protocol_map_.Put(server, alternate); } int count = ++broken_alternate_protocol_map_[server]; @@ -414,6 +423,11 @@ HttpServerPropertiesImpl::GetServerNetworkStats( return &it->second; } +void HttpServerPropertiesImpl::SetAlternateProtocolProbabilityThreshold( + double threshold) { + alternate_protocol_probability_threshold_ = threshold; +} + HttpServerPropertiesImpl::CanonicalHostMap::const_iterator HttpServerPropertiesImpl::GetCanonicalHost(HostPortPair server) const { for (size_t i = 0; i < canoncial_suffixes_.size(); ++i) { diff --git a/net/http/http_server_properties_impl.h b/net/http/http_server_properties_impl.h index c65d5e3..7d7ec11 100644 --- a/net/http/http_server_properties_impl.h +++ b/net/http/http_server_properties_impl.h @@ -55,7 +55,7 @@ class NET_EXPORT HttpServerPropertiesImpl // Debugging to simulate presence of an AlternateProtocol. // If we don't have an alternate protocol in the map for any given host/port // pair, force this ProtocolPortPair. - static void ForceAlternateProtocol(const PortAlternateProtocolPair& pair); + static void ForceAlternateProtocol(const AlternateProtocolInfo& pair); static void DisableForcedAlternateProtocol(); // Returns the canonical host suffix for |server|, or std::string() if none @@ -84,14 +84,15 @@ class NET_EXPORT HttpServerPropertiesImpl // Returns the Alternate-Protocol and port for |server|. // HasAlternateProtocol(server) must be true. - virtual PortAlternateProtocolPair GetAlternateProtocol( + virtual AlternateProtocolInfo GetAlternateProtocol( const HostPortPair& server) OVERRIDE; // Sets the Alternate-Protocol for |server|. virtual void SetAlternateProtocol( const HostPortPair& server, uint16 alternate_port, - AlternateProtocol alternate_protocol) OVERRIDE; + AlternateProtocol alternate_protocol, + double probability) OVERRIDE; // Sets the Alternate-Protocol for |server| to be BROKEN. virtual void SetBrokenAlternateProtocol(const HostPortPair& server) OVERRIDE; @@ -112,6 +113,9 @@ class NET_EXPORT HttpServerPropertiesImpl virtual void SetAlternateProtocolExperiment( AlternateProtocolExperiment experiment) OVERRIDE; + virtual void SetAlternateProtocolProbabilityThreshold( + double threshold) OVERRIDE; + virtual AlternateProtocolExperiment GetAlternateProtocolExperiment() const OVERRIDE; @@ -184,6 +188,8 @@ class NET_EXPORT HttpServerPropertiesImpl // ".googlevideo.com", ".googleusercontent.com") of canoncial hostnames. CanonicalSufficList canoncial_suffixes_; + double alternate_protocol_probability_threshold_; + base::WeakPtrFactory<HttpServerPropertiesImpl> weak_ptr_factory_; DISALLOW_COPY_AND_ASSIGN(HttpServerPropertiesImpl); diff --git a/net/http/http_server_properties_impl_unittest.cc b/net/http/http_server_properties_impl_unittest.cc index e3b08d4..f21c969 100644 --- a/net/http/http_server_properties_impl_unittest.cc +++ b/net/http/http_server_properties_impl_unittest.cc @@ -243,9 +243,9 @@ typedef HttpServerPropertiesImplTest AlternateProtocolServerPropertiesTest; TEST_F(AlternateProtocolServerPropertiesTest, Basic) { HostPortPair test_host_port_pair("foo", 80); EXPECT_FALSE(impl_.HasAlternateProtocol(test_host_port_pair)); - impl_.SetAlternateProtocol(test_host_port_pair, 443, NPN_SPDY_3); + impl_.SetAlternateProtocol(test_host_port_pair, 443, NPN_SPDY_3, 1); ASSERT_TRUE(impl_.HasAlternateProtocol(test_host_port_pair)); - const PortAlternateProtocolPair alternate = + const AlternateProtocolInfo alternate = impl_.GetAlternateProtocol(test_host_port_pair); EXPECT_EQ(443, alternate.port); EXPECT_EQ(NPN_SPDY_3, alternate.protocol); @@ -254,17 +254,38 @@ TEST_F(AlternateProtocolServerPropertiesTest, Basic) { EXPECT_FALSE(impl_.HasAlternateProtocol(test_host_port_pair)); } +TEST_F(AlternateProtocolServerPropertiesTest, Probability) { + impl_.SetAlternateProtocolProbabilityThreshold(.25); + + HostPortPair test_host_port_pair("foo", 80); + impl_.SetAlternateProtocol(test_host_port_pair, 443, NPN_SPDY_3, .5); + + ASSERT_TRUE(impl_.HasAlternateProtocol(test_host_port_pair)); + const AlternateProtocolInfo alternate = + impl_.GetAlternateProtocol(test_host_port_pair); + EXPECT_EQ(443, alternate.port); + EXPECT_EQ(NPN_SPDY_3, alternate.protocol); + EXPECT_EQ(.5, alternate.probability); +} + +TEST_F(AlternateProtocolServerPropertiesTest, ProbabilityExcluded) { + impl_.SetAlternateProtocolProbabilityThreshold(.75); + + HostPortPair test_host_port_pair("foo", 80); + + impl_.SetAlternateProtocol(test_host_port_pair, 443, NPN_SPDY_3, .5); + EXPECT_FALSE(impl_.HasAlternateProtocol(test_host_port_pair)); +} + TEST_F(AlternateProtocolServerPropertiesTest, Initialize) { HostPortPair test_host_port_pair1("foo1", 80); impl_.SetBrokenAlternateProtocol(test_host_port_pair1); HostPortPair test_host_port_pair2("foo2", 80); - impl_.SetAlternateProtocol(test_host_port_pair2, 443, NPN_SPDY_3); + impl_.SetAlternateProtocol(test_host_port_pair2, 443, NPN_SPDY_3, 1); AlternateProtocolMap alternate_protocol_map( AlternateProtocolMap::NO_AUTO_EVICT); - PortAlternateProtocolPair port_alternate_protocol_pair; - port_alternate_protocol_pair.port = 123; - port_alternate_protocol_pair.protocol = NPN_SPDY_3; + AlternateProtocolInfo port_alternate_protocol_pair(123, NPN_SPDY_3, 1); alternate_protocol_map.Put(test_host_port_pair2, port_alternate_protocol_pair); HostPortPair test_host_port_pair3("foo3", 80); @@ -294,9 +315,9 @@ TEST_F(AlternateProtocolServerPropertiesTest, Initialize) { TEST_F(AlternateProtocolServerPropertiesTest, MRUOfHasAlternateProtocol) { HostPortPair test_host_port_pair1("foo1", 80); - impl_.SetAlternateProtocol(test_host_port_pair1, 443, NPN_SPDY_3); + impl_.SetAlternateProtocol(test_host_port_pair1, 443, NPN_SPDY_3, 1); HostPortPair test_host_port_pair2("foo2", 80); - impl_.SetAlternateProtocol(test_host_port_pair2, 1234, NPN_SPDY_3); + impl_.SetAlternateProtocol(test_host_port_pair2, 1234, NPN_SPDY_3, 1); const net::AlternateProtocolMap& map = impl_.alternate_protocol_map(); net::AlternateProtocolMap::const_iterator it = map.begin(); @@ -314,9 +335,9 @@ TEST_F(AlternateProtocolServerPropertiesTest, MRUOfHasAlternateProtocol) { TEST_F(AlternateProtocolServerPropertiesTest, MRUOfGetAlternateProtocol) { HostPortPair test_host_port_pair1("foo1", 80); - impl_.SetAlternateProtocol(test_host_port_pair1, 443, NPN_SPDY_3); + impl_.SetAlternateProtocol(test_host_port_pair1, 443, NPN_SPDY_3, 1); HostPortPair test_host_port_pair2("foo2", 80); - impl_.SetAlternateProtocol(test_host_port_pair2, 1234, NPN_SPDY_3); + impl_.SetAlternateProtocol(test_host_port_pair2, 1234, NPN_SPDY_3, 1); const net::AlternateProtocolMap& map = impl_.alternate_protocol_map(); net::AlternateProtocolMap::const_iterator it = map.begin(); @@ -325,7 +346,7 @@ TEST_F(AlternateProtocolServerPropertiesTest, MRUOfGetAlternateProtocol) { EXPECT_EQ(NPN_SPDY_3, it->second.protocol); // GetAlternateProtocol should reoder the AlternateProtocol map. - PortAlternateProtocolPair alternate = + AlternateProtocolInfo alternate = impl_.GetAlternateProtocol(test_host_port_pair1); EXPECT_EQ(443, alternate.port); EXPECT_EQ(NPN_SPDY_3, alternate.protocol); @@ -339,14 +360,15 @@ TEST_F(AlternateProtocolServerPropertiesTest, SetBroken) { HostPortPair test_host_port_pair("foo", 80); impl_.SetBrokenAlternateProtocol(test_host_port_pair); ASSERT_TRUE(impl_.HasAlternateProtocol(test_host_port_pair)); - PortAlternateProtocolPair alternate = + AlternateProtocolInfo alternate = impl_.GetAlternateProtocol(test_host_port_pair); EXPECT_EQ(ALTERNATE_PROTOCOL_BROKEN, alternate.protocol); impl_.SetAlternateProtocol( test_host_port_pair, 1234, - NPN_SPDY_3); + NPN_SPDY_3, + 1); alternate = impl_.GetAlternateProtocol(test_host_port_pair); EXPECT_EQ(ALTERNATE_PROTOCOL_BROKEN, alternate.protocol) << "Second attempt should be ignored."; @@ -356,7 +378,7 @@ TEST_F(AlternateProtocolServerPropertiesTest, ClearBroken) { HostPortPair test_host_port_pair("foo", 80); impl_.SetBrokenAlternateProtocol(test_host_port_pair); ASSERT_TRUE(impl_.HasAlternateProtocol(test_host_port_pair)); - PortAlternateProtocolPair alternate = + AlternateProtocolInfo alternate = impl_.GetAlternateProtocol(test_host_port_pair); EXPECT_EQ(ALTERNATE_PROTOCOL_BROKEN, alternate.protocol); impl_.ClearAlternateProtocol(test_host_port_pair); @@ -366,21 +388,19 @@ TEST_F(AlternateProtocolServerPropertiesTest, ClearBroken) { TEST_F(AlternateProtocolServerPropertiesTest, Forced) { // Test forced alternate protocols. - PortAlternateProtocolPair default_protocol; - default_protocol.port = 1234; - default_protocol.protocol = NPN_SPDY_3; + AlternateProtocolInfo default_protocol(1234, NPN_SPDY_3, 1); HttpServerPropertiesImpl::ForceAlternateProtocol(default_protocol); // Verify the forced protocol. HostPortPair test_host_port_pair("foo", 80); EXPECT_TRUE(impl_.HasAlternateProtocol(test_host_port_pair)); - PortAlternateProtocolPair alternate = + AlternateProtocolInfo alternate = impl_.GetAlternateProtocol(test_host_port_pair); EXPECT_EQ(default_protocol.port, alternate.port); EXPECT_EQ(default_protocol.protocol, alternate.protocol); // Verify the real protocol overrides the forced protocol. - impl_.SetAlternateProtocol(test_host_port_pair, 443, NPN_SPDY_3); + impl_.SetAlternateProtocol(test_host_port_pair, 443, NPN_SPDY_3, 1); ASSERT_TRUE(impl_.HasAlternateProtocol(test_host_port_pair)); alternate = impl_.GetAlternateProtocol(test_host_port_pair); EXPECT_EQ(443, alternate.port); @@ -402,16 +422,15 @@ TEST_F(AlternateProtocolServerPropertiesTest, Canonical) { HostPortPair canonical_port_pair("bar.c.youtube.com", 80); EXPECT_FALSE(impl_.HasAlternateProtocol(canonical_port_pair)); - PortAlternateProtocolPair canonical_protocol; - canonical_protocol.port = 1234; - canonical_protocol.protocol = QUIC; + AlternateProtocolInfo canonical_protocol(1234, QUIC, 1); impl_.SetAlternateProtocol(canonical_port_pair, canonical_protocol.port, - canonical_protocol.protocol); + canonical_protocol.protocol, + 1); // Verify the forced protocol. ASSERT_TRUE(impl_.HasAlternateProtocol(test_host_port_pair)); - PortAlternateProtocolPair alternate = + AlternateProtocolInfo alternate = impl_.GetAlternateProtocol(test_host_port_pair); EXPECT_EQ(canonical_protocol.port, alternate.port); EXPECT_EQ(canonical_protocol.protocol, alternate.protocol); @@ -425,13 +444,12 @@ TEST_F(AlternateProtocolServerPropertiesTest, ClearCanonical) { HostPortPair test_host_port_pair("foo.c.youtube.com", 80); HostPortPair canonical_port_pair("bar.c.youtube.com", 80); - PortAlternateProtocolPair canonical_protocol; - canonical_protocol.port = 1234; - canonical_protocol.protocol = QUIC; + AlternateProtocolInfo canonical_protocol(1234, QUIC, 1); impl_.SetAlternateProtocol(canonical_port_pair, canonical_protocol.port, - canonical_protocol.protocol); + canonical_protocol.protocol, + canonical_protocol.probability); impl_.ClearAlternateProtocol(canonical_port_pair); EXPECT_FALSE(impl_.HasAlternateProtocol(test_host_port_pair)); @@ -441,13 +459,12 @@ TEST_F(AlternateProtocolServerPropertiesTest, CanonicalBroken) { HostPortPair test_host_port_pair("foo.c.youtube.com", 80); HostPortPair canonical_port_pair("bar.c.youtube.com", 80); - PortAlternateProtocolPair canonical_protocol; - canonical_protocol.port = 1234; - canonical_protocol.protocol = QUIC; + AlternateProtocolInfo canonical_protocol(1234, QUIC, 1); impl_.SetAlternateProtocol(canonical_port_pair, canonical_protocol.port, - canonical_protocol.protocol); + canonical_protocol.protocol, + canonical_protocol.probability); impl_.SetBrokenAlternateProtocol(canonical_port_pair); EXPECT_FALSE(impl_.HasAlternateProtocol(test_host_port_pair)); @@ -457,13 +474,12 @@ TEST_F(AlternateProtocolServerPropertiesTest, ClearWithCanonical) { HostPortPair test_host_port_pair("foo.c.youtube.com", 80); HostPortPair canonical_port_pair("bar.c.youtube.com", 80); - PortAlternateProtocolPair canonical_protocol; - canonical_protocol.port = 1234; - canonical_protocol.protocol = QUIC; + AlternateProtocolInfo canonical_protocol(1234, QUIC, 1); impl_.SetAlternateProtocol(canonical_port_pair, canonical_protocol.port, - canonical_protocol.protocol); + canonical_protocol.protocol, + canonical_protocol.probability); impl_.Clear(); EXPECT_FALSE(impl_.HasAlternateProtocol(test_host_port_pair)); diff --git a/net/http/http_stream_factory.cc b/net/http/http_stream_factory.cc index b60df85..e86d8f8 100644 --- a/net/http/http_stream_factory.cc +++ b/net/http/http_stream_factory.cc @@ -7,6 +7,7 @@ #include "base/logging.h" #include "base/strings/string_number_conversions.h" #include "base/strings/string_split.h" +#include "base/strings/string_util.h" #include "net/base/host_mapping_rules.h" #include "net/base/host_port_pair.h" #include "net/http/http_network_session.h" @@ -29,40 +30,60 @@ void HttpStreamFactory::ResetStaticSettingsToInit() { void HttpStreamFactory::ProcessAlternateProtocol( const base::WeakPtr<HttpServerProperties>& http_server_properties, - const std::string& alternate_protocol_str, + const std::vector<std::string>& alternate_protocol_values, const HostPortPair& http_host_port_pair, const HttpNetworkSession& session) { - std::vector<std::string> port_protocol_vector; - base::SplitString(alternate_protocol_str, ':', &port_protocol_vector); - if (port_protocol_vector.size() != 2) { - DVLOG(1) << kAlternateProtocolHeader - << " header has too many tokens: " - << alternate_protocol_str; - return; - } - - int port; - if (!base::StringToInt(port_protocol_vector[0], &port) || - port <= 0 || port >= 1 << 16) { - DVLOG(1) << kAlternateProtocolHeader - << " header has unrecognizable port: " - << port_protocol_vector[0]; - return; - } + AlternateProtocol protocol = UNINITIALIZED_ALTERNATE_PROTOCOL; + int port = 0; + double probability = 1; + for (size_t i = 0; i < alternate_protocol_values.size(); ++i) { + const std::string& alternate_protocol_str = alternate_protocol_values[i]; + if (StartsWithASCII(alternate_protocol_str, "p=", true)) { + if (!base::StringToDouble(alternate_protocol_str.substr(2), + &probability) || + probability < 0 || probability > 1) { + DVLOG(1) << kAlternateProtocolHeader + << " header has unrecognizable probability: " + << alternate_protocol_values[i]; + return; + } + continue; + } + + std::vector<std::string> port_protocol_vector; + base::SplitString(alternate_protocol_str, ':', &port_protocol_vector); + if (port_protocol_vector.size() != 2) { + DVLOG(1) << kAlternateProtocolHeader + << " header has too many tokens: " + << alternate_protocol_str; + return; + } - AlternateProtocol protocol = - AlternateProtocolFromString(port_protocol_vector[1]); - if (IsAlternateProtocolValid(protocol) && - !session.IsProtocolEnabled(protocol)) { - protocol = ALTERNATE_PROTOCOL_BROKEN; + if (!base::StringToInt(port_protocol_vector[0], &port) || + port <= 0 || port >= 1 << 16) { + DVLOG(1) << kAlternateProtocolHeader + << " header has unrecognizable port: " + << port_protocol_vector[0]; + return; + } + + protocol = + AlternateProtocolFromString(port_protocol_vector[1]); + if (IsAlternateProtocolValid(protocol) && + !session.IsProtocolEnabled(protocol)) { + protocol = ALTERNATE_PROTOCOL_BROKEN; + } + + if (protocol == ALTERNATE_PROTOCOL_BROKEN) { + DVLOG(1) << kAlternateProtocolHeader + << " header has unrecognized protocol: " + << port_protocol_vector[1]; + return; + } } - if (protocol == ALTERNATE_PROTOCOL_BROKEN) { - DVLOG(1) << kAlternateProtocolHeader - << " header has unrecognized protocol: " - << port_protocol_vector[1]; + if (protocol == UNINITIALIZED_ALTERNATE_PROTOCOL) return; - } HostPortPair host_port(http_host_port_pair); const HostMappingRules* mapping_rules = GetHostMappingRules(); @@ -70,14 +91,15 @@ void HttpStreamFactory::ProcessAlternateProtocol( mapping_rules->RewriteHost(&host_port); if (http_server_properties->HasAlternateProtocol(host_port)) { - const PortAlternateProtocolPair existing_alternate = + const AlternateProtocolInfo existing_alternate = http_server_properties->GetAlternateProtocol(host_port); // If we think the alternate protocol is broken, don't change it. if (existing_alternate.protocol == ALTERNATE_PROTOCOL_BROKEN) return; } - http_server_properties->SetAlternateProtocol(host_port, port, protocol); + http_server_properties->SetAlternateProtocol(host_port, port, protocol, + probability); } GURL HttpStreamFactory::ApplyHostMappingRules(const GURL& url, diff --git a/net/http/http_stream_factory.h b/net/http/http_stream_factory.h index f3b0203..8f6d892 100644 --- a/net/http/http_stream_factory.h +++ b/net/http/http_stream_factory.h @@ -179,7 +179,7 @@ class NET_EXPORT HttpStreamFactory { void ProcessAlternateProtocol( const base::WeakPtr<HttpServerProperties>& http_server_properties, - const std::string& alternate_protocol_str, + const std::vector<std::string>& alternate_protocol_values, const HostPortPair& http_host_port_pair, const HttpNetworkSession& session); diff --git a/net/http/http_stream_factory_impl.cc b/net/http/http_stream_factory_impl.cc index ad12091..ced5f2b 100644 --- a/net/http/http_stream_factory_impl.cc +++ b/net/http/http_stream_factory_impl.cc @@ -22,10 +22,6 @@ namespace net { namespace { -const PortAlternateProtocolPair kNoAlternateProtocol = { - 0, UNINITIALIZED_ALTERNATE_PROTOCOL -}; - GURL UpgradeUrlToHttps(const GURL& original_url, int port) { GURL::Replacements replacements; // new_sheme and new_port need to be in scope here because GURL::Replacements @@ -111,7 +107,7 @@ HttpStreamRequest* HttpStreamFactoryImpl::RequestStreamInternal( net_log); GURL alternate_url; - PortAlternateProtocolPair alternate = + AlternateProtocolInfo alternate = GetAlternateProtocolRequestFor(request_info.url, &alternate_url); Job* alternate_job = NULL; if (alternate.protocol != UNINITIALIZED_ALTERNATE_PROTOCOL) { @@ -155,7 +151,7 @@ void HttpStreamFactoryImpl::PreconnectStreams( const SSLConfig& proxy_ssl_config) { DCHECK(!for_websockets_); GURL alternate_url; - PortAlternateProtocolPair alternate = + AlternateProtocolInfo alternate = GetAlternateProtocolRequestFor(request_info.url, &alternate_url); Job* job = NULL; if (alternate.protocol != UNINITIALIZED_ALTERNATE_PROTOCOL) { @@ -176,9 +172,12 @@ const HostMappingRules* HttpStreamFactoryImpl::GetHostMappingRules() const { return session_->params().host_mapping_rules; } -PortAlternateProtocolPair HttpStreamFactoryImpl::GetAlternateProtocolRequestFor( +AlternateProtocolInfo HttpStreamFactoryImpl::GetAlternateProtocolRequestFor( const GURL& original_url, GURL* alternate_url) { + const AlternateProtocolInfo kNoAlternateProtocol = + AlternateProtocolInfo(0, UNINITIALIZED_ALTERNATE_PROTOCOL, 0); + if (!session_->params().use_alternate_protocols) return kNoAlternateProtocol; @@ -193,7 +192,7 @@ PortAlternateProtocolPair HttpStreamFactoryImpl::GetAlternateProtocolRequestFor( if (!http_server_properties.HasAlternateProtocol(origin)) return kNoAlternateProtocol; - PortAlternateProtocolPair alternate = + AlternateProtocolInfo alternate = http_server_properties.GetAlternateProtocol(origin); if (alternate.protocol == ALTERNATE_PROTOCOL_BROKEN) { HistogramAlternateProtocolUsage( diff --git a/net/http/http_stream_factory_impl.h b/net/http/http_stream_factory_impl.h index 8a6fdaf..7df0a67 100644 --- a/net/http/http_stream_factory_impl.h +++ b/net/http/http_stream_factory_impl.h @@ -76,7 +76,7 @@ class NET_EXPORT_PRIVATE HttpStreamFactoryImpl : public HttpStreamFactory { WebSocketHandshakeStreamBase::CreateHelper* create_helper, const BoundNetLog& net_log); - PortAlternateProtocolPair GetAlternateProtocolRequestFor( + AlternateProtocolInfo GetAlternateProtocolRequestFor( const GURL& original_url, GURL* alternate_url); diff --git a/net/http/http_stream_factory_impl_job.cc b/net/http/http_stream_factory_impl_job.cc index 79a9536..54147d6 100644 --- a/net/http/http_stream_factory_impl_job.cc +++ b/net/http/http_stream_factory_impl_job.cc @@ -171,7 +171,7 @@ LoadState HttpStreamFactoryImpl::Job::GetLoadState() const { void HttpStreamFactoryImpl::Job::MarkAsAlternate( const GURL& original_url, - PortAlternateProtocolPair alternate) { + AlternateProtocolInfo alternate) { DCHECK(!original_url_.get()); original_url_.reset(new GURL(original_url)); if (alternate.protocol == QUIC) { diff --git a/net/http/http_stream_factory_impl_job.h b/net/http/http_stream_factory_impl_job.h index 9659d45..c221211 100644 --- a/net/http/http_stream_factory_impl_job.h +++ b/net/http/http_stream_factory_impl_job.h @@ -60,7 +60,7 @@ class HttpStreamFactoryImpl::Job { // we fail to connect. |alternate| specifies the alternate protocol to use // and alternate port to connect to. void MarkAsAlternate(const GURL& original_url, - PortAlternateProtocolPair alternate); + AlternateProtocolInfo alternate); // Tells |this| to wait for |job| to resume it. void WaitFor(Job* job); diff --git a/net/http/http_stream_factory_impl_unittest.cc b/net/http/http_stream_factory_impl_unittest.cc index 6406957..3bf7396 100644 --- a/net/http/http_stream_factory_impl_unittest.cc +++ b/net/http/http_stream_factory_impl_unittest.cc @@ -1269,7 +1269,8 @@ TEST_P(HttpStreamFactoryTest, DISABLED_OrphanedWebSocketStream) { session->http_server_properties()->SetAlternateProtocol( HostPortPair("www.google.com", 8888), 9999, - NPN_SPDY_3); + NPN_SPDY_3, + 1); SSLConfig ssl_config; StreamRequestWaiter waiter; |