Chromium Code Reviews| 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 93b85df394c223f1ec0b7644111c55d1aee545c8..e8494436c8941aa28c570c38075e1828a3077909 100644 |
| --- a/net/http/http_stream_factory_impl.cc |
| +++ b/net/http/http_stream_factory_impl.cc |
| @@ -94,13 +94,10 @@ HttpStreamRequest* HttpStreamFactoryImpl::RequestStreamInternal( |
| proxy_ssl_config, net_log.net_log()); |
| request->AttachJob(job); |
| - const AlternativeServiceVector alternative_service_vector = |
| - GetAlternativeServicesFor(request_info.url, delegate); |
| + const AlternativeService alternative_service = |
| + GetAlternativeServiceFor(request_info, delegate); |
| - if (!alternative_service_vector.empty()) { |
| - // TODO(bnc): Pass on multiple alternative services to Job. |
| - const AlternativeService& alternative_service = |
| - alternative_service_vector[0]; |
| + if (alternative_service.protocol != UNINITIALIZED_ALTERNATE_PROTOCOL) { |
| // Never share connection with other jobs for FTP requests. |
| DCHECK(!request_info.url.SchemeIs("ftp")); |
| @@ -129,12 +126,9 @@ void HttpStreamFactoryImpl::PreconnectStreams( |
| const SSLConfig& server_ssl_config, |
| const SSLConfig& proxy_ssl_config) { |
| DCHECK(!for_websockets_); |
| - AlternativeService alternative_service; |
| - AlternativeServiceVector alternative_service_vector = |
| - GetAlternativeServicesFor(request_info.url, nullptr); |
| - if (!alternative_service_vector.empty()) { |
| - // TODO(bnc): Pass on multiple alternative services to Job. |
| - alternative_service = alternative_service_vector[0]; |
| + AlternativeService alternative_service = |
| + GetAlternativeServiceFor(request_info, nullptr); |
| + if (alternative_service.protocol != UNINITIALIZED_ALTERNATE_PROTOCOL) { |
| if (session_->params().quic_disable_preconnect_if_0rtt && |
| alternative_service.protocol == QUIC && |
| session_->quic_stream_factory()->ZeroRTTEnabledFor(QuicServerId( |
| @@ -158,11 +152,13 @@ const HostMappingRules* HttpStreamFactoryImpl::GetHostMappingRules() const { |
| return session_->params().host_mapping_rules; |
| } |
| -AlternativeServiceVector HttpStreamFactoryImpl::GetAlternativeServicesFor( |
| - const GURL& original_url, |
| +AlternativeService HttpStreamFactoryImpl::GetAlternativeServiceFor( |
| + const HttpRequestInfo& request_info, |
| HttpStreamRequest::Delegate* delegate) { |
| + GURL original_url = request_info.url; |
| + |
| if (original_url.SchemeIs("ftp")) |
| - return AlternativeServiceVector(); |
| + return AlternativeService(); |
| HostPortPair origin = HostPortPair::FromURL(original_url); |
| HttpServerProperties& http_server_properties = |
| @@ -170,7 +166,7 @@ AlternativeServiceVector HttpStreamFactoryImpl::GetAlternativeServicesFor( |
| const AlternativeServiceVector alternative_service_vector = |
| http_server_properties.GetAlternativeServices(origin); |
| if (alternative_service_vector.empty()) |
| - return AlternativeServiceVector(); |
| + return AlternativeService(); |
| bool quic_advertised = false; |
| bool quic_all_broken = true; |
| @@ -178,7 +174,8 @@ AlternativeServiceVector HttpStreamFactoryImpl::GetAlternativeServicesFor( |
| const bool enable_different_host = |
| session_->params().use_alternative_services; |
| - AlternativeServiceVector enabled_alternative_service_vector; |
| + AlternativeService preferred_alternative_service; |
| + AlternativeService candidate_alternative_service; |
| for (const AlternativeService& alternative_service : |
| alternative_service_vector) { |
| DCHECK(IsAlternateProtocolValid(alternative_service.protocol)); |
| @@ -214,7 +211,14 @@ AlternativeServiceVector HttpStreamFactoryImpl::GetAlternativeServicesFor( |
| if (session_->HasSpdyExclusion(origin)) |
| continue; |
| - enabled_alternative_service_vector.push_back(alternative_service); |
| + // enabled_alternative_service_vector.push_back(alternative_service); |
| + // Cache the first entry if no preferred Alt-Svc selected yet. |
| + if (candidate_alternative_service.protocol == |
| + UNINITIALIZED_ALTERNATE_PROTOCOL && |
| + preferred_alternative_service.protocol == |
| + UNINITIALIZED_ALTERNATE_PROTOCOL) { |
| + candidate_alternative_service = alternative_service; |
| + } |
| continue; |
| } |
| @@ -229,11 +233,31 @@ AlternativeServiceVector HttpStreamFactoryImpl::GetAlternativeServicesFor( |
| if (!original_url.SchemeIs("https")) |
| continue; |
| - enabled_alternative_service_vector.push_back(alternative_service); |
| + if (preferred_alternative_service.protocol == |
| + UNINITIALIZED_ALTERNATE_PROTOCOL) { |
| + // Check to see whether there's an active session to pool for this QUIC |
| + // alternative service. |
| + HostPortPair destination = alternative_service.host_port_pair(); |
| + StringPiece origin_host = |
| + ApplyHostMappingRules(request_info.url, &destination).host(); |
|
Ryan Hamilton
2015/12/18 17:52:51
Are you sure this is correct? It may well be, but
Zhongyi Shi
2015/12/18 21:59:29
I still leave the origin_host calculation here, bu
|
| + if (session_->quic_stream_factory()->CanPool( |
| + destination, request_info.privacy_mode, origin_host)) |
| + preferred_alternative_service = alternative_service; |
|
Ryan Hamilton
2015/12/18 17:52:51
I'm not sure that I understand the dance here with
Zhongyi Shi
2015/12/18 17:57:23
Candidate is the first entry of the list. While pr
Ryan Hamilton
2015/12/18 19:52:59
Are you specifically thinking about the call to de
Zhongyi Shi
2015/12/18 21:59:29
Ah, thanks for pointing this out! If we are able t
|
| + } |
| + // enabled_alternative_service_vector.push_back(alternative_service); |
| + if (candidate_alternative_service.protocol == |
| + UNINITIALIZED_ALTERNATE_PROTOCOL && |
| + preferred_alternative_service.protocol == |
| + UNINITIALIZED_ALTERNATE_PROTOCOL) { |
| + candidate_alternative_service = alternative_service; |
| + } |
| } |
| if (quic_advertised && quic_all_broken && delegate != nullptr) |
| delegate->OnQuicBroken(); |
| - return enabled_alternative_service_vector; |
| + if (preferred_alternative_service.protocol == |
| + UNINITIALIZED_ALTERNATE_PROTOCOL) |
| + return candidate_alternative_service; |
| + return preferred_alternative_service; |
| } |
| void HttpStreamFactoryImpl::OrphanJob(Job* job, const Request* request) { |