Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1135)

Unified Diff: net/http/http_server_properties_impl.cc

Issue 1216703002: Implement multiple alternative services per origin. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Nit. Created 5 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « net/http/http_server_properties_impl.h ('k') | net/http/http_server_properties_impl_unittest.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 535c915477358ae03584c23ef39b8c33f9ef5548..15871b530866b780a6d9914b9272aa86fb83e98d 100644
--- a/net/http/http_server_properties_impl.cc
+++ b/net/http/http_server_properties_impl.cc
@@ -4,6 +4,8 @@
#include "net/http/http_server_properties_impl.h"
+#include <algorithm>
+
#include "base/bind.h"
#include "base/location.h"
#include "base/logging.h"
@@ -53,25 +55,48 @@ void HttpServerPropertiesImpl::InitializeSpdyServers(
void HttpServerPropertiesImpl::InitializeAlternativeServiceServers(
AlternativeServiceMap* alternative_service_map) {
- // Keep all the broken ones since those don't get persisted.
- for (AlternativeServiceMap::iterator it = alternative_service_map_.begin();
- it != alternative_service_map_.end();) {
- AlternativeService alternative_service(it->second.alternative_service);
- if (alternative_service.host.empty()) {
- alternative_service.host = it->first.host();
+ for (AlternativeServiceMap::iterator map_it =
+ alternative_service_map_.begin();
+ map_it != alternative_service_map_.end();) {
+ for (AlternativeServiceInfoVector::iterator it = map_it->second.begin();
+ it != map_it->second.end();) {
+ // Keep all the broken ones since those do not get persisted.
+ AlternativeService alternative_service(it->alternative_service);
+ if (alternative_service.host.empty()) {
+ alternative_service.host = map_it->first.host();
+ }
+ if (IsAlternativeServiceBroken(alternative_service)) {
+ ++it;
+ continue;
+ }
+ it = map_it->second.erase(it);
}
- if (IsAlternativeServiceBroken(alternative_service)) {
- ++it;
- } else {
- it = alternative_service_map_.Erase(it);
+ if (map_it->second.empty()) {
+ RemoveCanonicalHost(map_it->first);
+ map_it = alternative_service_map_.Erase(map_it);
+ continue;
}
+ ++map_it;
}
// Add the entries from persisted data.
- for (AlternativeServiceMap::reverse_iterator it =
+ for (AlternativeServiceMap::reverse_iterator input_it =
alternative_service_map->rbegin();
- it != alternative_service_map->rend(); ++it) {
- alternative_service_map_.Put(it->first, it->second);
+ input_it != alternative_service_map->rend(); ++input_it) {
+ AlternativeServiceMap::iterator output_it =
+ alternative_service_map_.Peek(input_it->first);
+ if (output_it == alternative_service_map_.end()) {
+ // There is no value in alternative_service_map_ for input_it->first:
+ // inserting in AlternativeServiceVectorInfo.
+ alternative_service_map_.Put(input_it->first, input_it->second);
+ continue;
+ }
+ // There are some broken alternative services in alternative_service_map_
+ // for input_it->first: appending AlternativeServiceInfo one by one.
+ for (const AlternativeServiceInfo& alternative_service_info :
+ input_it->second) {
+ output_it->second.push_back(alternative_service_info);
+ }
}
// Attempt to find canonical servers.
@@ -165,9 +190,15 @@ bool HttpServerPropertiesImpl::SupportsRequestPriority(
if (GetSupportsSpdy(host_port_pair))
return true;
- const AlternativeService alternative_service =
- GetAlternativeService(host_port_pair);
- return alternative_service.protocol == QUIC;
+ const AlternativeServiceVector alternative_service_vector =
+ GetAlternativeServices(host_port_pair);
+ for (const AlternativeService& alternative_service :
+ alternative_service_vector) {
+ if (alternative_service.protocol == QUIC) {
+ return true;
+ }
+ }
+ return false;
}
bool HttpServerPropertiesImpl::GetSupportsSpdy(
@@ -236,66 +267,103 @@ std::string HttpServerPropertiesImpl::GetCanonicalSuffix(
return std::string();
}
-AlternativeService HttpServerPropertiesImpl::GetAlternativeService(
+AlternativeServiceVector HttpServerPropertiesImpl::GetAlternativeServices(
const HostPortPair& origin) {
+ // Copy alternative services with probability greater than or equal to the
+ // threshold into |alternative_services_above_threshold|.
+ AlternativeServiceVector alternative_services_above_threshold;
AlternativeServiceMap::const_iterator it =
alternative_service_map_.Get(origin);
if (it != alternative_service_map_.end()) {
- if (it->second.probability < alternative_service_probability_threshold_) {
- return AlternativeService();
- }
- AlternativeService alternative_service(it->second.alternative_service);
- if (alternative_service.host.empty()) {
- alternative_service.host = origin.host();
+ for (const AlternativeServiceInfo& alternative_service_info : it->second) {
+ if (alternative_service_info.probability <
+ alternative_service_probability_threshold_) {
+ continue;
+ }
+ AlternativeService alternative_service(
+ alternative_service_info.alternative_service);
+ if (alternative_service.host.empty()) {
+ alternative_service.host = origin.host();
+ }
+ alternative_services_above_threshold.push_back(alternative_service);
}
- return alternative_service;
+ return alternative_services_above_threshold;
}
CanonicalHostMap::const_iterator canonical = GetCanonicalHost(origin);
if (canonical == canonical_host_to_origin_map_.end()) {
- return AlternativeService();
+ return AlternativeServiceVector();
}
it = alternative_service_map_.Get(canonical->second);
if (it == alternative_service_map_.end()) {
- return AlternativeService();
+ return AlternativeServiceVector();
}
- if (it->second.probability < alternative_service_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();
+ for (const AlternativeServiceInfo& alternative_service_info : it->second) {
+ if (alternative_service_info.probability <
+ alternative_service_probability_threshold_) {
+ continue;
+ }
+ AlternativeService alternative_service(
+ alternative_service_info.alternative_service);
+ if (alternative_service.host.empty()) {
+ alternative_service.host = canonical->second.host();
+ if (IsAlternativeServiceBroken(alternative_service)) {
+ continue;
+ }
+ alternative_service.host = origin.host();
+ } else if (IsAlternativeServiceBroken(alternative_service)) {
+ continue;
+ }
+ alternative_services_above_threshold.push_back(alternative_service);
}
- return alternative_service;
+ return alternative_services_above_threshold;
}
-void HttpServerPropertiesImpl::SetAlternativeService(
+bool HttpServerPropertiesImpl::SetAlternativeService(
const HostPortPair& origin,
const AlternativeService& alternative_service,
double alternative_probability) {
- const AlternativeServiceInfo alternative_service_info(
- alternative_service, alternative_probability);
- AlternativeServiceMap::const_iterator it =
- GetAlternateProtocolIterator(origin);
- if (it == alternative_service_map_.end() &&
- alternative_probability >= alternative_service_probability_threshold_) {
+ return SetAlternativeServices(
+ origin, AlternativeServiceInfoVector(
+ /*size=*/1, AlternativeServiceInfo(alternative_service,
+ alternative_probability)));
+}
+
+bool HttpServerPropertiesImpl::SetAlternativeServices(
+ const HostPortPair& origin,
+ const AlternativeServiceInfoVector& alternative_service_info_vector) {
+ AlternativeServiceMap::iterator it = alternative_service_map_.Peek(origin);
+
+ if (alternative_service_info_vector.empty()) {
+ if (it == alternative_service_map_.end()) {
+ return false;
+ }
+ ClearAlternativeServices(origin);
+ return true;
+ }
+
+ bool changed = true;
+ if (it != alternative_service_map_.end()) {
+ DCHECK(!it->second.empty());
+ if (it->second.size() == alternative_service_info_vector.size()) {
+ changed = !std::equal(it->second.begin(), it->second.end(),
+ alternative_service_info_vector.begin());
+ }
+ }
+
+ const bool previously_no_alternative_services =
+ (GetAlternateProtocolIterator(origin) == alternative_service_map_.end());
+
+ alternative_service_map_.Put(origin, alternative_service_info_vector);
+
+ if (previously_no_alternative_services &&
+ !GetAlternativeServices(origin).empty()) {
// TODO(rch): Consider the case where multiple requests are started
// before the first completes. In this case, only one of the jobs
// would reach this code, whereas all of them should should have.
HistogramAlternateProtocolUsage(ALTERNATE_PROTOCOL_USAGE_MAPPING_MISSING);
}
- alternative_service_map_.Put(origin, alternative_service_info);
-
// If this host ends with a canonical suffix, then set it as the
// canonical host.
for (size_t i = 0; i < canonical_suffixes_.size(); ++i) {
@@ -306,6 +374,8 @@ void HttpServerPropertiesImpl::SetAlternativeService(
break;
}
}
+
+ return changed;
}
void HttpServerPropertiesImpl::MarkAlternativeServiceBroken(
@@ -363,7 +433,7 @@ void HttpServerPropertiesImpl::ConfirmAlternativeService(
recently_broken_alternative_services_.erase(alternative_service);
}
-void HttpServerPropertiesImpl::ClearAlternativeService(
+void HttpServerPropertiesImpl::ClearAlternativeServices(
const HostPortPair& origin) {
RemoveCanonicalHost(origin);
@@ -382,24 +452,31 @@ const AlternativeServiceMap& HttpServerPropertiesImpl::alternative_service_map()
scoped_ptr<base::Value>
HttpServerPropertiesImpl::GetAlternativeServiceInfoAsValue()
const {
- scoped_ptr<base::ListValue> dict_list(new base::ListValue());
+ scoped_ptr<base::ListValue> dict_list(new base::ListValue);
for (const auto& alternative_service_map_item : alternative_service_map_) {
+ scoped_ptr<base::ListValue> alternative_service_list(new base::ListValue);
const HostPortPair& host_port_pair = alternative_service_map_item.first;
- const AlternativeServiceInfo& alternative_service_info =
- alternative_service_map_item.second;
- std::string alternative_service_string(alternative_service_info.ToString());
- AlternativeService alternative_service(
- alternative_service_info.alternative_service);
- if (alternative_service.host.empty()) {
- alternative_service.host = host_port_pair.host();
- }
- if (IsAlternativeServiceBroken(alternative_service)) {
- alternative_service_string.append(" (broken)");
+ for (const AlternativeServiceInfo& alternative_service_info :
+ alternative_service_map_item.second) {
+ std::string alternative_service_string(
+ alternative_service_info.ToString());
+ AlternativeService alternative_service(
+ alternative_service_info.alternative_service);
+ if (alternative_service.host.empty()) {
+ alternative_service.host = host_port_pair.host();
+ }
+ if (IsAlternativeServiceBroken(alternative_service)) {
+ alternative_service_string.append(" (broken)");
+ }
+ alternative_service_list->Append(
+ new base::StringValue(alternative_service_string));
}
-
+ if (alternative_service_list->empty())
+ continue;
scoped_ptr<base::DictionaryValue> dict(new base::DictionaryValue());
dict->SetString("host_port_pair", host_port_pair.ToString());
- dict->SetString("alternative_service", alternative_service_string);
+ dict->Set("alternative_service",
+ scoped_ptr<base::Value>(alternative_service_list.Pass()));
dict_list->Append(dict.Pass());
}
return dict_list.Pass();
@@ -515,11 +592,15 @@ HttpServerPropertiesImpl::GetAlternateProtocolIterator(
return alternative_service_map_.end();
}
- const AlternativeService alternative_service(
- it->second.alternative_service.protocol, canonical_host_port.host(),
- it->second.alternative_service.port);
- if (!IsAlternativeServiceBroken(alternative_service)) {
- return it;
+ for (const AlternativeServiceInfo& alternative_service_info : it->second) {
+ AlternativeService alternative_service(
+ alternative_service_info.alternative_service);
+ if (alternative_service.host.empty()) {
+ alternative_service.host = canonical_host_port.host();
+ }
+ if (!IsAlternativeServiceBroken(alternative_service)) {
+ return it;
+ }
}
RemoveCanonicalHost(canonical_host_port);
@@ -563,7 +644,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(
+ ClearAlternativeServices(
HostPortPair(alternative_service.host, alternative_service.port));
}
ScheduleBrokenAlternateProtocolMappingsExpiration();
« no previous file with comments | « net/http/http_server_properties_impl.h ('k') | net/http/http_server_properties_impl_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698