Index: net/http/http_stream_factory_impl.cc |
diff --git a/net/http/http_stream_factory_impl.cc b/net/http/http_stream_factory_impl.cc |
index 517f10fa3e5341422152707a7168f78f0ccb332b..624bdced9b46e7d0a19f3bd5fd03123fde29aa57 100644 |
--- a/net/http/http_stream_factory_impl.cc |
+++ b/net/http/http_stream_factory_impl.cc |
@@ -93,9 +93,12 @@ HttpStreamRequest* HttpStreamFactoryImpl::RequestStreamInternal( |
proxy_ssl_config, net_log.net_log()); |
request->AttachJob(job); |
- AlternativeService alternative_service = |
- GetAlternativeServiceFor(request_info.url); |
- if (alternative_service.protocol != UNINITIALIZED_ALTERNATE_PROTOCOL) { |
+ const AlternativeServiceVector alternative_service_vector = |
+ GetAlternativeServicesFor(request_info.url); |
+ if (!alternative_service_vector.empty()) { |
+ // TODO(bnc): Pass on multiple alternative services to Job. |
+ const AlternativeService& alternative_service = |
+ alternative_service_vector[0]; |
// Never share connection with other jobs for FTP requests. |
DCHECK(!request_info.url.SchemeIs("ftp")); |
@@ -125,8 +128,13 @@ void HttpStreamFactoryImpl::PreconnectStreams( |
const SSLConfig& server_ssl_config, |
const SSLConfig& proxy_ssl_config) { |
DCHECK(!for_websockets_); |
- AlternativeService alternative_service = |
- GetAlternativeServiceFor(request_info.url); |
+ AlternativeService alternative_service; |
+ AlternativeServiceVector alternative_service_vector = |
+ GetAlternativeServicesFor(request_info.url); |
+ if (!alternative_service_vector.empty()) { |
+ // TODO(bnc): Pass on multiple alternative services to Job. |
+ alternative_service = alternative_service_vector[0]; |
+ } |
Job* job = |
new Job(this, session_, request_info, priority, server_ssl_config, |
proxy_ssl_config, alternative_service, session_->net_log()); |
@@ -138,70 +146,72 @@ const HostMappingRules* HttpStreamFactoryImpl::GetHostMappingRules() const { |
return session_->params().host_mapping_rules; |
} |
-AlternativeService HttpStreamFactoryImpl::GetAlternativeServiceFor( |
+AlternativeServiceVector HttpStreamFactoryImpl::GetAlternativeServicesFor( |
const GURL& original_url) { |
- const AlternativeService kNoAlternativeService; |
- |
if (!session_->params().use_alternate_protocols) |
- return kNoAlternativeService; |
+ return AlternativeServiceVector(); |
if (original_url.SchemeIs("ftp")) |
- return kNoAlternativeService; |
+ return AlternativeServiceVector(); |
HostPortPair origin = HostPortPair::FromURL(original_url); |
HttpServerProperties& http_server_properties = |
*session_->http_server_properties(); |
- const AlternativeService alternative_service = |
- http_server_properties.GetAlternativeService(origin); |
- |
- if (alternative_service.protocol == UNINITIALIZED_ALTERNATE_PROTOCOL) |
- return kNoAlternativeService; |
- if (http_server_properties.IsAlternativeServiceBroken(alternative_service)) { |
- HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_BROKEN); |
- return kNoAlternativeService; |
- } |
- if (!IsAlternateProtocolValid(alternative_service.protocol)) { |
- NOTREACHED(); |
- return kNoAlternativeService; |
- } |
+ const AlternativeServiceVector alternative_service_vector = |
+ http_server_properties.GetAlternativeServices(origin); |
+ if (alternative_service_vector.empty()) |
+ return AlternativeServiceVector(); |
+ |
+ AlternativeServiceVector enabled_alternative_service_vector; |
+ for (const AlternativeService& alternative_service : |
+ alternative_service_vector) { |
+ DCHECK(IsAlternateProtocolValid(alternative_service.protocol)); |
+ if (http_server_properties.IsAlternativeServiceBroken( |
+ alternative_service)) { |
+ HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_BROKEN); |
+ continue; |
+ } |
- // Some shared unix systems may have user home directories (like |
- // http://foo.com/~mike) which allow users to emit headers. This is a bad |
- // idea already, but with Alternate-Protocol, it provides the ability for a |
- // single user on a multi-user system to hijack the alternate protocol. |
- // These systems also enforce ports <1024 as restricted ports. So don't |
- // allow protocol upgrades to user-controllable ports. |
- const int kUnrestrictedPort = 1024; |
- if (!session_->params().enable_user_alternate_protocol_ports && |
- (alternative_service.port >= kUnrestrictedPort && |
- origin.port() < kUnrestrictedPort)) |
- return kNoAlternativeService; |
- |
- origin.set_port(alternative_service.port); |
- if (alternative_service.protocol >= NPN_SPDY_MINIMUM_VERSION && |
- alternative_service.protocol <= NPN_SPDY_MAXIMUM_VERSION) { |
- if (!HttpStreamFactory::spdy_enabled()) |
- return kNoAlternativeService; |
- |
- if (session_->HasSpdyExclusion(origin)) |
- return kNoAlternativeService; |
- |
- return alternative_service; |
- } |
+ // Some shared unix systems may have user home directories (like |
+ // http://foo.com/~mike) which allow users to emit headers. This is a bad |
+ // idea already, but with Alternate-Protocol, it provides the ability for a |
+ // single user on a multi-user system to hijack the alternate protocol. |
+ // These systems also enforce ports <1024 as restricted ports. So don't |
+ // allow protocol upgrades to user-controllable ports. |
+ const int kUnrestrictedPort = 1024; |
+ if (!session_->params().enable_user_alternate_protocol_ports && |
+ (alternative_service.port >= kUnrestrictedPort && |
+ origin.port() < kUnrestrictedPort)) |
+ continue; |
+ |
+ origin.set_port(alternative_service.port); |
+ if (alternative_service.protocol >= NPN_SPDY_MINIMUM_VERSION && |
+ alternative_service.protocol <= NPN_SPDY_MAXIMUM_VERSION) { |
+ if (!HttpStreamFactory::spdy_enabled()) |
+ continue; |
+ |
+ if (session_->HasSpdyExclusion(origin)) |
+ continue; |
+ |
+ enabled_alternative_service_vector.push_back(alternative_service); |
+ continue; |
+ } |
- DCHECK_EQ(QUIC, alternative_service.protocol); |
- if (!session_->params().enable_quic) |
- return kNoAlternativeService; |
+ DCHECK_EQ(QUIC, alternative_service.protocol); |
+ if (!session_->params().enable_quic) |
+ continue; |
- if (session_->quic_stream_factory()->IsQuicDisabled(origin.port())) |
- return kNoAlternativeService; |
+ if (session_->quic_stream_factory()->IsQuicDisabled(origin.port())) |
+ continue; |
- if (session_->params().disable_insecure_quic && |
- !original_url.SchemeIs("https")) { |
- return kNoAlternativeService; |
- } |
+ if (session_->params().disable_insecure_quic && |
+ !original_url.SchemeIs("https")) { |
+ continue; |
+ } |
- return alternative_service; |
+ enabled_alternative_service_vector.push_back(alternative_service); |
+ } |
+ return enabled_alternative_service_vector; |
} |
void HttpStreamFactoryImpl::OrphanJob(Job* job, const Request* request) { |