summaryrefslogtreecommitdiffstats
path: root/net/http
diff options
context:
space:
mode:
authorrch@chromium.org <rch@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-07-08 23:01:00 +0000
committerrch@chromium.org <rch@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2014-07-08 23:01:00 +0000
commit287d941307e87364a4864187ea5c9b9df08daef8 (patch)
tree187d4672e5aec8ab417ca37f72bb15922ef591d2 /net/http
parent69e6f0e744a73856a4e4e90c34b0a857b9b0373f (diff)
downloadchromium_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.cc4
-rw-r--r--net/http/http_network_session.cc4
-rw-r--r--net/http/http_network_session.h1
-rw-r--r--net/http/http_network_transaction.cc15
-rw-r--r--net/http/http_network_transaction_unittest.cc25
-rw-r--r--net/http/http_server_properties.cc7
-rw-r--r--net/http/http_server_properties.h26
-rw-r--r--net/http/http_server_properties_impl.cc40
-rw-r--r--net/http/http_server_properties_impl.h12
-rw-r--r--net/http/http_server_properties_impl_unittest.cc88
-rw-r--r--net/http/http_stream_factory.cc82
-rw-r--r--net/http/http_stream_factory.h2
-rw-r--r--net/http/http_stream_factory_impl.cc15
-rw-r--r--net/http/http_stream_factory_impl.h2
-rw-r--r--net/http/http_stream_factory_impl_job.cc2
-rw-r--r--net/http/http_stream_factory_impl_job.h2
-rw-r--r--net/http/http_stream_factory_impl_unittest.cc3
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;