Index: net/http/http_server_properties_impl.cc |
diff --git a/net/http/http_server_properties_impl.cc b/net/http/http_server_properties_impl.cc |
index 21832b5bd31bcb13ff731ccbb046f01ec3b82bad..5b2c2f12caa00b8c2a0f43b83ef001f5c0e02e5a 100644 |
--- a/net/http/http_server_properties_impl.cc |
+++ b/net/http/http_server_properties_impl.cc |
@@ -17,13 +17,13 @@ namespace net { |
namespace { |
-const uint64 kBrokenAlternateProtocolDelaySecs = 300; |
+const uint64 kBrokenAlternativeProtocolDelaySecs = 300; |
} // namespace |
HttpServerPropertiesImpl::HttpServerPropertiesImpl() |
: spdy_servers_map_(SpdyServerHostPortMap::NO_AUTO_EVICT), |
- alternate_protocol_map_(AlternateProtocolMap::NO_AUTO_EVICT), |
+ alternative_service_map_(AlternativeServiceMap::NO_AUTO_EVICT), |
spdy_settings_map_(SpdySettingsMap::NO_AUTO_EVICT), |
server_network_stats_map_(ServerNetworkStatsMap::NO_AUTO_EVICT), |
alternate_protocol_probability_threshold_(1), |
@@ -49,25 +49,23 @@ void HttpServerPropertiesImpl::InitializeSpdyServers( |
} |
} |
-void HttpServerPropertiesImpl::InitializeAlternateProtocolServers( |
- AlternateProtocolMap* alternate_protocol_map) { |
+void HttpServerPropertiesImpl::InitializeAlternativeServiceServers( |
+ AlternativeServiceMap* alternative_service_map) { |
// Keep all the broken ones since those don't get persisted. |
- for (AlternateProtocolMap::iterator it = alternate_protocol_map_.begin(); |
- it != alternate_protocol_map_.end();) { |
- const AlternativeService alternative_service( |
- it->second.protocol, it->first.host(), it->second.port); |
- if (IsAlternativeServiceBroken(alternative_service)) { |
+ for (AlternativeServiceMap::iterator it = alternative_service_map_.begin(); |
+ it != alternative_service_map_.end();) { |
+ if (IsAlternativeServiceBroken(it->second.alternative_service)) { |
++it; |
} else { |
- it = alternate_protocol_map_.Erase(it); |
+ it = alternative_service_map_.Erase(it); |
} |
} |
// Add the entries from persisted data. |
- for (AlternateProtocolMap::reverse_iterator it = |
- alternate_protocol_map->rbegin(); |
- it != alternate_protocol_map->rend(); ++it) { |
- alternate_protocol_map_.Put(it->first, it->second); |
+ for (AlternativeServiceMap::reverse_iterator it = |
+ alternative_service_map->rbegin(); |
+ it != alternative_service_map->rend(); ++it) { |
+ alternative_service_map_.Put(it->first, it->second); |
} |
// Attempt to find canonical servers. |
@@ -78,15 +76,16 @@ void HttpServerPropertiesImpl::InitializeAlternateProtocolServers( |
HostPortPair canonical_host(canonical_suffix, canonical_ports[j]); |
// If we already have a valid canonical server, we're done. |
if (ContainsKey(canonical_host_to_origin_map_, canonical_host) && |
- (alternate_protocol_map_.Peek(canonical_host_to_origin_map_[ |
- canonical_host]) != alternate_protocol_map_.end())) { |
+ (alternative_service_map_.Peek( |
+ canonical_host_to_origin_map_[canonical_host]) != |
+ alternative_service_map_.end())) { |
continue; |
} |
// Now attempt to find a server which matches this origin and set it as |
- // canonical . |
- for (AlternateProtocolMap::const_iterator it = |
- alternate_protocol_map_.begin(); |
- it != alternate_protocol_map_.end(); ++it) { |
+ // canonical. |
+ for (AlternativeServiceMap::const_iterator it = |
+ alternative_service_map_.begin(); |
+ it != alternative_service_map_.end(); ++it) { |
if (EndsWith(it->first.host(), canonical_suffixes_[i], false)) { |
canonical_host_to_origin_map_[canonical_host] = it->first; |
break; |
@@ -144,7 +143,7 @@ base::WeakPtr<HttpServerProperties> HttpServerPropertiesImpl::GetWeakPtr() { |
void HttpServerPropertiesImpl::Clear() { |
DCHECK(CalledOnValidThread()); |
spdy_servers_map_.Clear(); |
- alternate_protocol_map_.Clear(); |
+ alternative_service_map_.Clear(); |
canonical_host_to_origin_map_.clear(); |
spdy_settings_map_.Clear(); |
last_quic_address_.clear(); |
@@ -224,43 +223,70 @@ std::string HttpServerPropertiesImpl::GetCanonicalSuffix( |
AlternativeService HttpServerPropertiesImpl::GetAlternativeService( |
const HostPortPair& origin) { |
- AlternateProtocolMap::const_iterator it = |
- GetAlternateProtocolIterator(origin); |
- if (it != alternate_protocol_map_.end() && |
- it->second.probability >= alternate_protocol_probability_threshold_) |
- return AlternativeService(it->second.protocol, origin.host(), |
- it->second.port); |
+ AlternativeServiceMap::const_iterator it = |
+ alternative_service_map_.Get(origin); |
+ if (it != alternative_service_map_.end()) { |
+ if (it->second.probability < alternate_protocol_probability_threshold_) { |
+ return AlternativeService(); |
+ } |
+ AlternativeService alternative_service(it->second.alternative_service); |
+ if (alternative_service.host.empty()) { |
+ alternative_service.host = origin.host(); |
+ } |
+ return alternative_service; |
+ } |
- AlternativeService uninitialize_alternative_service; |
- return uninitialize_alternative_service; |
+ CanonicalHostMap::const_iterator canonical = GetCanonicalHost(origin); |
+ if (canonical == canonical_host_to_origin_map_.end()) { |
+ return AlternativeService(); |
+ } |
+ it = alternative_service_map_.Get(canonical->second); |
+ if (it == alternative_service_map_.end()) { |
+ return AlternativeService(); |
+ } |
+ if (it->second.probability < alternate_protocol_probability_threshold_) { |
+ return AlternativeService(); |
+ } |
+ AlternativeService alternative_service(it->second.alternative_service); |
+ if (alternative_service.host.empty()) { |
+ alternative_service.host = canonical->second.host(); |
+ } |
+ if (IsAlternativeServiceBroken(alternative_service)) { |
+ RemoveCanonicalHost(canonical->second); |
+ return AlternativeService(); |
+ } |
+ // Empty hostname: if alternative service for with hostname of canonical host |
+ // is not broken, then return alternative service with hostname of origin. |
+ if (it->second.alternative_service.host.empty()) { |
+ alternative_service.host = origin.host(); |
+ } |
+ return alternative_service; |
} |
void HttpServerPropertiesImpl::SetAlternativeService( |
const HostPortPair& origin, |
const AlternativeService& alternative_service, |
double alternative_probability) { |
- if (IsAlternativeServiceBroken(alternative_service)) { |
+ AlternativeService complete_alternative_service(alternative_service); |
+ if (complete_alternative_service.host.empty()) { |
+ complete_alternative_service.host = origin.host(); |
+ } |
+ if (IsAlternativeServiceBroken(complete_alternative_service)) { |
DVLOG(1) << "Ignore alternative service since it is known to be broken."; |
return; |
} |
- const AlternateProtocolInfo alternate(alternative_service.port, |
- alternative_service.protocol, |
- alternative_probability); |
- AlternateProtocolMap::const_iterator it = |
+ const AlternativeServiceInfo alternative_service_info( |
+ alternative_service, alternative_probability); |
+ AlternativeServiceMap::const_iterator it = |
GetAlternateProtocolIterator(origin); |
- if (it != alternate_protocol_map_.end()) { |
- const AlternateProtocolInfo existing_alternate = it->second; |
- |
- if (!existing_alternate.Equals(alternate)) { |
- LOG(WARNING) << "Changing the alternate protocol for: " |
- << origin.ToString() |
- << " from [Port: " << existing_alternate.port |
- << ", Protocol: " << existing_alternate.protocol |
- << ", Probability: " << existing_alternate.probability |
- << "] to [Port: " << alternative_service.port |
- << ", Protocol: " << alternative_service.protocol |
- << ", Probability: " << alternative_probability << "]."; |
+ if (it != alternative_service_map_.end()) { |
+ const AlternativeServiceInfo existing_alternative_service_info = it->second; |
+ if (existing_alternative_service_info != alternative_service_info) { |
+ LOG(WARNING) << "Changing the alternative service for: " |
+ << origin.ToString() << " from " |
+ << existing_alternative_service_info.ToString() << " to " |
+ << alternative_service_info.ToString() << "."; |
} |
} else { |
if (alternative_probability >= alternate_protocol_probability_threshold_) { |
@@ -271,7 +297,7 @@ void HttpServerPropertiesImpl::SetAlternativeService( |
} |
} |
- alternate_protocol_map_.Put(origin, alternate); |
+ alternative_service_map_.Put(origin, alternative_service_info); |
// If this host ends with a canonical suffix, then set it as the |
// canonical host. |
@@ -293,7 +319,7 @@ void HttpServerPropertiesImpl::MarkAlternativeServiceBroken( |
} |
int count = ++recently_broken_alternative_services_[alternative_service]; |
base::TimeDelta delay = |
- base::TimeDelta::FromSeconds(kBrokenAlternateProtocolDelaySecs); |
+ base::TimeDelta::FromSeconds(kBrokenAlternativeProtocolDelaySecs); |
base::TimeTicks when = base::TimeTicks::Now() + delay * (1 << (count - 1)); |
auto result = broken_alternative_services_.insert( |
std::make_pair(alternative_service, when)); |
@@ -317,6 +343,8 @@ void HttpServerPropertiesImpl::MarkAlternativeServiceRecentlyBroken( |
bool HttpServerPropertiesImpl::IsAlternativeServiceBroken( |
const AlternativeService& alternative_service) { |
+ // Empty host means use host of origin, callers are supposed to substitute. |
+ DCHECK(!alternative_service.host.empty()); |
return ContainsKey(broken_alternative_services_, alternative_service); |
} |
@@ -340,13 +368,15 @@ void HttpServerPropertiesImpl::ClearAlternativeService( |
const HostPortPair& origin) { |
RemoveCanonicalHost(origin); |
- AlternateProtocolMap::iterator it = alternate_protocol_map_.Peek(origin); |
- if (it == alternate_protocol_map_.end()) { |
+ AlternativeServiceMap::iterator it = alternative_service_map_.Peek(origin); |
+ if (it == alternative_service_map_.end()) { |
return; |
} |
- const AlternativeService alternative_service( |
- it->second.protocol, it->first.host(), it->second.port); |
- alternate_protocol_map_.Erase(it); |
+ AlternativeService alternative_service(it->second.alternative_service); |
+ if (alternative_service.host.empty()) { |
+ alternative_service.host = origin.host(); |
+ } |
+ alternative_service_map_.Erase(it); |
// The following is temporary to keep the existing semantics, which is that if |
// there is a broken alternative service in the mapping, then this method |
@@ -356,13 +386,12 @@ void HttpServerPropertiesImpl::ClearAlternativeService( |
// 1. Verify and document the class invariant that no broken alternative |
// service can be in the mapping. |
// 2. Remove the rest of this method as it will be moot. |
- // 3. Provide a SetAlternativeServiceRecentlyBroken if necessary. |
broken_alternative_services_.erase(alternative_service); |
} |
-const AlternateProtocolMap& |
-HttpServerPropertiesImpl::alternate_protocol_map() const { |
- return alternate_protocol_map_; |
+const AlternativeServiceMap& HttpServerPropertiesImpl::alternative_service_map() |
+ const { |
+ return alternative_service_map_; |
} |
const SettingsMap& HttpServerPropertiesImpl::GetSpdySettings( |
@@ -456,32 +485,34 @@ void HttpServerPropertiesImpl::SetAlternateProtocolProbabilityThreshold( |
alternate_protocol_probability_threshold_ = threshold; |
} |
-AlternateProtocolMap::const_iterator |
+AlternativeServiceMap::const_iterator |
HttpServerPropertiesImpl::GetAlternateProtocolIterator( |
const HostPortPair& server) { |
- AlternateProtocolMap::const_iterator it = alternate_protocol_map_.Get(server); |
- if (it != alternate_protocol_map_.end()) |
+ AlternativeServiceMap::const_iterator it = |
+ alternative_service_map_.Get(server); |
+ if (it != alternative_service_map_.end()) |
return it; |
CanonicalHostMap::const_iterator canonical = GetCanonicalHost(server); |
if (canonical == canonical_host_to_origin_map_.end()) { |
- return alternate_protocol_map_.end(); |
+ return alternative_service_map_.end(); |
} |
const HostPortPair canonical_host_port = canonical->second; |
- it = alternate_protocol_map_.Get(canonical_host_port); |
- if (it == alternate_protocol_map_.end()) { |
- return alternate_protocol_map_.end(); |
+ it = alternative_service_map_.Get(canonical_host_port); |
+ if (it == alternative_service_map_.end()) { |
+ return alternative_service_map_.end(); |
} |
const AlternativeService alternative_service( |
- it->second.protocol, canonical_host_port.host(), it->second.port); |
+ it->second.alternative_service.protocol, canonical_host_port.host(), |
+ it->second.alternative_service.port); |
if (!IsAlternativeServiceBroken(alternative_service)) { |
return it; |
} |
RemoveCanonicalHost(canonical_host_port); |
- return alternate_protocol_map_.end(); |
+ return alternative_service_map_.end(); |
} |
HttpServerPropertiesImpl::CanonicalHostMap::const_iterator |
@@ -520,6 +551,7 @@ void HttpServerPropertiesImpl::ExpireBrokenAlternateProtocolMappings() { |
const AlternativeService alternative_service = it->first; |
broken_alternative_services_.erase(it); |
+ // TODO(bnc): Make sure broken alternative services are not in the mapping. |
ClearAlternativeService( |
HostPortPair(alternative_service.host, alternative_service.port)); |
} |