Index: net/http/http_server_properties_manager.cc |
diff --git a/net/http/http_server_properties_manager.cc b/net/http/http_server_properties_manager.cc |
index d6bfb38cce1ecbf584ea098a4c1a40fe1f8f5ec7..15719654016aab173432a79082ebf8f9c078ac3b 100644 |
--- a/net/http/http_server_properties_manager.cc |
+++ b/net/http/http_server_properties_manager.cc |
@@ -58,7 +58,9 @@ const char kSupportsQuicKey[] = "supports_quic"; |
const char kUsedQuicKey[] = "used_quic"; |
const char kAddressKey[] = "address"; |
const char kAlternateProtocolKey[] = "alternate_protocol"; |
+const char kAlternativeServicesKey[] = "alternative_services"; |
const char kPortKey[] = "port"; |
+const char kHostKey[] = "host"; |
const char kProtocolKey[] = "protocol_str"; |
const char kProbabilityKey[] = "probability"; |
const char kNetworkStatsKey[] = "network_stats"; |
@@ -180,48 +182,69 @@ void HttpServerPropertiesManager::MaybeForceHTTP11(const HostPortPair& server, |
http_server_properties_impl_->MaybeForceHTTP11(server, ssl_config); |
} |
-AlternateProtocolInfo HttpServerPropertiesManager::GetAlternateProtocol( |
+AlternateProtocols HttpServerPropertiesManager::GetAlternateProtocols( |
const HostPortPair& server) { |
DCHECK(network_task_runner_->RunsTasksOnCurrentThread()); |
- return http_server_properties_impl_->GetAlternateProtocol(server); |
+ return http_server_properties_impl_->GetAlternateProtocols(server); |
} |
-void HttpServerPropertiesManager::SetAlternateProtocol( |
+void HttpServerPropertiesManager::AddAlternateProtocol( |
const HostPortPair& server, |
uint16 alternate_port, |
AlternateProtocol alternate_protocol, |
double alternate_probability) { |
DCHECK(network_task_runner_->RunsTasksOnCurrentThread()); |
- http_server_properties_impl_->SetAlternateProtocol( |
+ http_server_properties_impl_->AddAlternateProtocol( |
server, alternate_port, alternate_protocol, alternate_probability); |
ScheduleUpdatePrefsOnNetworkThread(); |
} |
void HttpServerPropertiesManager::SetBrokenAlternateProtocol( |
- const HostPortPair& server) { |
+ const HostPortPair& server, |
+ const AlternateProtocolInfo& broken_alternate_protocol) { |
DCHECK(network_task_runner_->RunsTasksOnCurrentThread()); |
- http_server_properties_impl_->SetBrokenAlternateProtocol(server); |
+ http_server_properties_impl_->SetBrokenAlternateProtocol( |
+ server, broken_alternate_protocol); |
ScheduleUpdatePrefsOnNetworkThread(); |
} |
bool HttpServerPropertiesManager::WasAlternateProtocolRecentlyBroken( |
- const HostPortPair& server) { |
+ const HostPortPair& server, |
+ const AlternateProtocolInfo& alternate_protocol) const { |
DCHECK(network_task_runner_->RunsTasksOnCurrentThread()); |
return http_server_properties_impl_->WasAlternateProtocolRecentlyBroken( |
- server); |
+ server, alternate_protocol); |
} |
void HttpServerPropertiesManager::ConfirmAlternateProtocol( |
+ const HostPortPair& server, |
+ const AlternateProtocolInfo& alternate_protocol) { |
+ DCHECK(network_task_runner_->RunsTasksOnCurrentThread()); |
+ http_server_properties_impl_->ConfirmAlternateProtocol(server, |
+ alternate_protocol); |
+ ScheduleUpdatePrefsOnNetworkThread(); |
+} |
+ |
+void HttpServerPropertiesManager::ClearAlternateProtocols( |
const HostPortPair& server) { |
DCHECK(network_task_runner_->RunsTasksOnCurrentThread()); |
- http_server_properties_impl_->ConfirmAlternateProtocol(server); |
+ http_server_properties_impl_->ClearAlternateProtocols(server); |
ScheduleUpdatePrefsOnNetworkThread(); |
} |
-void HttpServerPropertiesManager::ClearAlternateProtocol( |
+void HttpServerPropertiesManager::ClearNonBrokenAlternateProtocols( |
const HostPortPair& server) { |
DCHECK(network_task_runner_->RunsTasksOnCurrentThread()); |
- http_server_properties_impl_->ClearAlternateProtocol(server); |
+ http_server_properties_impl_->ClearNonBrokenAlternateProtocols(server); |
+ ScheduleUpdatePrefsOnNetworkThread(); |
+} |
+ |
+void HttpServerPropertiesManager::RemoveAlternateProtocol( |
+ const HostPortPair& server, |
+ const AlternateProtocolInfo& alternate_protocol) { |
+ DCHECK(network_task_runner_->RunsTasksOnCurrentThread()); |
+ http_server_properties_impl_->RemoveAlternateProtocol(server, |
+ alternate_protocol); |
ScheduleUpdatePrefsOnNetworkThread(); |
} |
@@ -491,18 +514,45 @@ bool HttpServerPropertiesManager::AddToAlternateProtocolMap( |
const HostPortPair& server, |
const base::DictionaryValue& server_pref_dict, |
AlternateProtocolMap* alternate_protocol_map) { |
- // Get alternate_protocol server. |
DCHECK(alternate_protocol_map->Peek(server) == alternate_protocol_map->end()); |
- const base::DictionaryValue* alternate_protocol_dict = NULL; |
+ // Get alternative_services... |
+ const base::ListValue* alternate_protocol_list = NULL; |
+ if (server_pref_dict.GetListWithoutPathExpansion(kAlternativeServicesKey, |
+ &alternate_protocol_list) && |
+ !alternate_protocol_list->empty()) { |
+ AlternateProtocols alternate_protocols; |
+ for (base::Value* const alternate_protocol_list_item : |
+ *alternate_protocol_list) { |
+ base::DictionaryValue* alternate_protocol_dict; |
+ if (!alternate_protocol_list_item->GetAsDictionary( |
+ &alternate_protocol_dict)) |
+ return false; |
+ AlternateProtocolInfo alternate_protocol = ParseAlternateProtocolDict( |
+ *alternate_protocol_dict, server.ToString()); |
+ if (alternate_protocol.protocol == UNINITIALIZED_ALTERNATE_PROTOCOL) { |
+ return false; |
+ } |
+ alternate_protocols.push_back(alternate_protocol); |
+ } |
+ alternate_protocol_map->Put(server, alternate_protocols); |
+ return true; |
+ } |
+ |
+ // ...or alternate_protocol. |
+ // TODO(bnc): Remove this in M45. (Saving to kAlternativeServicesKey is |
+ // targeted to M43, and we do not need preference migration for long.) |
+ const base::DictionaryValue* alternate_protocol_dict; |
if (!server_pref_dict.GetDictionaryWithoutPathExpansion( |
kAlternateProtocolKey, &alternate_protocol_dict)) { |
return true; |
} |
AlternateProtocolInfo alternate_protocol = |
ParseAlternateProtocolDict(*alternate_protocol_dict, server.ToString()); |
- if (alternate_protocol.protocol == UNINITIALIZED_ALTERNATE_PROTOCOL) |
+ if (alternate_protocol.protocol == UNINITIALIZED_ALTERNATE_PROTOCOL) { |
return false; |
- alternate_protocol_map->Put(server, alternate_protocol); |
+ } |
+ alternate_protocol_map->Put( |
+ server, AlternateProtocols(/*size=*/1, alternate_protocol)); |
return true; |
} |
@@ -684,28 +734,28 @@ void HttpServerPropertiesManager::UpdatePrefsFromCacheOnNetworkThread( |
} |
// A local or temporary data structure to hold |supports_spdy|, SpdySettings, |
-// AlternateProtocolInfo and SupportsQuic preferences for a server. This is used |
+// AlternateProtocols and SupportsQuic preferences for a server. This is used |
// only in UpdatePrefsOnPrefThread. |
struct ServerPref { |
ServerPref() |
: supports_spdy(false), |
settings_map(NULL), |
- alternate_protocol(NULL), |
+ alternate_protocols(NULL), |
supports_quic(NULL), |
server_network_stats(NULL) {} |
ServerPref(bool supports_spdy, |
const SettingsMap* settings_map, |
- const AlternateProtocolInfo* alternate_protocol, |
+ const AlternateProtocols* alternate_protocols, |
const SupportsQuic* supports_quic, |
const ServerNetworkStats* server_network_stats) |
: supports_spdy(supports_spdy), |
settings_map(settings_map), |
- alternate_protocol(alternate_protocol), |
+ alternate_protocols(alternate_protocols), |
supports_quic(supports_quic), |
server_network_stats(server_network_stats) {} |
bool supports_spdy; |
const SettingsMap* settings_map; |
- const AlternateProtocolInfo* alternate_protocol; |
+ const AlternateProtocols* alternate_protocols; |
const SupportsQuic* supports_quic; |
const ServerNetworkStats* server_network_stats; |
}; |
@@ -745,11 +795,13 @@ void HttpServerPropertiesManager::UpdatePrefsOnPrefThread( |
alternate_protocol_map->begin(); |
map_it != alternate_protocol_map->end(); ++map_it) { |
const HostPortPair& server = map_it->first; |
- const AlternateProtocolInfo& port_alternate_protocol = map_it->second; |
- if (!IsAlternateProtocolValid(port_alternate_protocol.protocol)) { |
- continue; |
+ ServerPrefMap::iterator it = server_pref_map.find(server); |
+ if (it == server_pref_map.end()) { |
+ ServerPref server_pref(false, NULL, &map_it->second, NULL, NULL); |
+ server_pref_map[server] = server_pref; |
+ } else { |
+ it->second.alternate_protocols = &map_it->second; |
} |
- server_pref_map[server].alternate_protocol = &map_it->second; |
} |
// Add ServerNetworkStats servers to server_pref_map. |
@@ -775,8 +827,8 @@ void HttpServerPropertiesManager::UpdatePrefsOnPrefThread( |
if (server_pref.supports_spdy) |
server_pref_dict->SetBoolean(kSupportsSpdyKey, server_pref.supports_spdy); |
SaveSpdySettingsToServerPrefs(server_pref.settings_map, server_pref_dict); |
- SaveAlternateProtocolToServerPrefs(server_pref.alternate_protocol, |
- server_pref_dict); |
+ SaveAlternateProtocolToServerPrefs(server_pref.alternate_protocols, |
+ server_pref_dict, server); |
SaveNetworkStatsToServerPrefs(server_pref.server_network_stats, |
server_pref_dict); |
@@ -819,22 +871,29 @@ void HttpServerPropertiesManager::SaveSpdySettingsToServerPrefs( |
} |
void HttpServerPropertiesManager::SaveAlternateProtocolToServerPrefs( |
- const AlternateProtocolInfo* port_alternate_protocol, |
- base::DictionaryValue* server_pref_dict) { |
- if (!port_alternate_protocol || port_alternate_protocol->is_broken) |
+ const AlternateProtocols* alternate_protocols, |
+ base::DictionaryValue* server_pref_dict, |
+ const HostPortPair& server) { |
+ if (!alternate_protocols || alternate_protocols->size() == 0) |
return; |
- |
- base::DictionaryValue* port_alternate_protocol_dict = |
- new base::DictionaryValue; |
- port_alternate_protocol_dict->SetInteger(kPortKey, |
- port_alternate_protocol->port); |
- const char* protocol_str = |
- AlternateProtocolToString(port_alternate_protocol->protocol); |
- port_alternate_protocol_dict->SetString(kProtocolKey, protocol_str); |
- port_alternate_protocol_dict->SetDouble(kProbabilityKey, |
- port_alternate_protocol->probability); |
- server_pref_dict->SetWithoutPathExpansion(kAlternateProtocolKey, |
- port_alternate_protocol_dict); |
+ base::ListValue* alternate_protocols_list = new base::ListValue; |
+ for (const AlternateProtocolInfo& alternate_protocol : *alternate_protocols) { |
+ if (alternate_protocol.is_broken) |
+ continue; |
+ DCHECK(IsAlternateProtocolValid(alternate_protocol.protocol)); |
+ base::DictionaryValue* alternate_protocol_dict = new base::DictionaryValue; |
+ alternate_protocol_dict->SetInteger(kPortKey, alternate_protocol.port); |
+ alternate_protocol_dict->SetString(kHostKey, server.host()); |
+ alternate_protocol_dict->SetString( |
+ kProtocolKey, AlternateProtocolToString(alternate_protocol.protocol)); |
+ alternate_protocol_dict->SetDouble(kProbabilityKey, |
+ alternate_protocol.probability); |
+ alternate_protocols_list->Append(alternate_protocol_dict); |
+ } |
+ if (alternate_protocols_list->GetSize() == 0) |
+ return; |
+ server_pref_dict->SetWithoutPathExpansion(kAlternativeServicesKey, |
+ alternate_protocols_list); |
} |
void HttpServerPropertiesManager::SaveSupportsQuicToPrefs( |