| 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 ffe234a685344fc6f9ab310114f718029f1a4895..70dc3e8577185f6b36886106709e8c2e733198c6 100644
|
| --- a/net/http/http_server_properties_manager.cc
|
| +++ b/net/http/http_server_properties_manager.cc
|
| @@ -35,7 +35,7 @@ const int64_t kUpdatePrefsDelayMs = 60000;
|
| const int kMissingVersion = 0;
|
|
|
| // The version number of persisted http_server_properties.
|
| -const int kVersionNumber = 3;
|
| +const int kVersionNumber = 4;
|
|
|
| // Persist 200 MRU AlternateProtocolHostPortPairs.
|
| const int kMaxAlternateProtocolHostsToPersist = 200;
|
| @@ -445,23 +445,44 @@ void HttpServerPropertiesManager::UpdateCacheFromPrefsOnPrefThread() {
|
| return;
|
| }
|
|
|
| - // The properties for a given server is in
|
| - // http_server_properties_dict["servers"][server].
|
| - // Server data was stored in the following format in alphabetical order.
|
| - //
|
| - // "http_server_properties": {
|
| - // "servers": {
|
| - // "accounts.google.com:443": {...},
|
| - // "accounts.youtube.com:443": {...},
|
| - // "android.clients.google.com:443": {...},
|
| - // ...
|
| - // }, ...
|
| - // },
|
| - const base::DictionaryValue* servers_dict = NULL;
|
| - if (!http_server_properties_dict.GetDictionaryWithoutPathExpansion(
|
| - kServersKey, &servers_dict)) {
|
| - DVLOG(1) << "Malformed http_server_properties for servers.";
|
| - return;
|
| + const base::DictionaryValue* servers_dict = nullptr;
|
| + const base::ListValue* servers_list = nullptr;
|
| + if (version < 4) {
|
| + // The properties for a given server is in
|
| + // http_server_properties_dict["servers"][server].
|
| + // Before Version 4, server data was stored in the following format in
|
| + // alphabetical order.
|
| + //
|
| + // "http_server_properties": {
|
| + // "servers": {
|
| + // "0-edge-chat.facebook.com:443" : {...},
|
| + // "0.client-channel.google.com:443" : {...},
|
| + // "yt3.ggpht.com:443" : {...},
|
| + // ...
|
| + // }, ...
|
| + // },
|
| + if (!http_server_properties_dict.GetDictionaryWithoutPathExpansion(
|
| + kServersKey, &servers_dict)) {
|
| + DVLOG(1) << "Malformed http_server_properties for servers.";
|
| + return;
|
| + }
|
| + } else {
|
| + // From Version 4 onwards, data was stored in the following format.
|
| + // |servers| are saved in MRU order.
|
| + //
|
| + // "http_server_properties": {
|
| + // "servers": [
|
| + // {"yt3.ggpht.com:443" : {...}},
|
| + // {"0.client-channel.google.com:443" : {...}},
|
| + // {"0-edge-chat.facebook.com:443" : {...}},
|
| + // ...
|
| + // ], ...
|
| + // },
|
| + if (!http_server_properties_dict.GetListWithoutPathExpansion(
|
| + kServersKey, &servers_list)) {
|
| + DVLOG(1) << "Malformed http_server_properties for servers list.";
|
| + return;
|
| + }
|
| }
|
|
|
| IPAddressNumber* addr = new IPAddressNumber;
|
| @@ -478,10 +499,26 @@ void HttpServerPropertiesManager::UpdateCacheFromPrefsOnPrefThread() {
|
| scoped_ptr<QuicServerInfoMap> quic_server_info_map(
|
| new QuicServerInfoMap(kMaxQuicServersToPersist));
|
|
|
| - if (!AddServersData(*servers_dict, spdy_servers.get(),
|
| - spdy_settings_map.get(), alternative_service_map.get(),
|
| - server_network_stats_map.get())) {
|
| - detected_corrupted_prefs = true;
|
| + if (version < 4) {
|
| + if (!AddServersData(*servers_dict, spdy_servers.get(),
|
| + spdy_settings_map.get(), alternative_service_map.get(),
|
| + server_network_stats_map.get())) {
|
| + detected_corrupted_prefs = true;
|
| + }
|
| + } else {
|
| + for (base::ListValue::const_iterator it = servers_list->begin();
|
| + it != servers_list->end(); ++it) {
|
| + if (!(*it)->GetAsDictionary(&servers_dict)) {
|
| + DVLOG(1) << "Malformed http_server_properties for servers dictionary.";
|
| + detected_corrupted_prefs = true;
|
| + continue;
|
| + }
|
| + if (!AddServersData(
|
| + *servers_dict, spdy_servers.get(), spdy_settings_map.get(),
|
| + alternative_service_map.get(), server_network_stats_map.get())) {
|
| + detected_corrupted_prefs = true;
|
| + }
|
| + }
|
| }
|
|
|
| if (!AddToQuicServerInfoMap(http_server_properties_dict,
|
| @@ -517,7 +554,7 @@ bool HttpServerPropertiesManager::AddServersData(
|
| return false;
|
| }
|
|
|
| - const base::DictionaryValue* server_pref_dict = NULL;
|
| + const base::DictionaryValue* server_pref_dict = nullptr;
|
| if (!it.value().GetAsDictionary(&server_pref_dict)) {
|
| DVLOG(1) << "Malformed http_server_properties server: " << server_str;
|
| return false;
|
| @@ -546,7 +583,7 @@ void HttpServerPropertiesManager::AddToSpdySettingsMap(
|
| SpdySettingsMap* spdy_settings_map) {
|
| // Get SpdySettings.
|
| DCHECK(spdy_settings_map->Peek(server) == spdy_settings_map->end());
|
| - const base::DictionaryValue* spdy_settings_dict = NULL;
|
| + const base::DictionaryValue* spdy_settings_dict = nullptr;
|
| if (!server_pref_dict.GetDictionaryWithoutPathExpansion(
|
| kSettingsKey, &spdy_settings_dict)) {
|
| return;
|
| @@ -693,7 +730,7 @@ bool HttpServerPropertiesManager::AddToAlternativeServiceMap(
|
| bool HttpServerPropertiesManager::ReadSupportsQuic(
|
| const base::DictionaryValue& http_server_properties_dict,
|
| IPAddressNumber* last_quic_address) {
|
| - const base::DictionaryValue* supports_quic_dict = NULL;
|
| + const base::DictionaryValue* supports_quic_dict = nullptr;
|
| if (!http_server_properties_dict.GetDictionaryWithoutPathExpansion(
|
| kSupportsQuicKey, &supports_quic_dict)) {
|
| return true;
|
| @@ -722,7 +759,7 @@ bool HttpServerPropertiesManager::AddToNetworkStatsMap(
|
| const base::DictionaryValue& server_pref_dict,
|
| ServerNetworkStatsMap* network_stats_map) {
|
| DCHECK(network_stats_map->Peek(server) == network_stats_map->end());
|
| - const base::DictionaryValue* server_network_stats_dict = NULL;
|
| + const base::DictionaryValue* server_network_stats_dict = nullptr;
|
| if (!server_pref_dict.GetDictionaryWithoutPathExpansion(
|
| kNetworkStatsKey, &server_network_stats_dict)) {
|
| return true;
|
| @@ -745,7 +782,7 @@ bool HttpServerPropertiesManager::AddToNetworkStatsMap(
|
| bool HttpServerPropertiesManager::AddToQuicServerInfoMap(
|
| const base::DictionaryValue& http_server_properties_dict,
|
| QuicServerInfoMap* quic_server_info_map) {
|
| - const base::DictionaryValue* quic_servers_dict = NULL;
|
| + const base::DictionaryValue* quic_servers_dict = nullptr;
|
| if (!http_server_properties_dict.GetDictionaryWithoutPathExpansion(
|
| kQuicServers, &quic_servers_dict)) {
|
| DVLOG(1) << "Malformed http_server_properties for quic_servers.";
|
| @@ -765,7 +802,7 @@ bool HttpServerPropertiesManager::AddToQuicServerInfoMap(
|
| continue;
|
| }
|
|
|
| - const base::DictionaryValue* quic_server_pref_dict = NULL;
|
| + const base::DictionaryValue* quic_server_pref_dict = nullptr;
|
| if (!it.value().GetAsDictionary(&quic_server_pref_dict)) {
|
| DVLOG(1) << "Malformed http_server_properties quic server dict: "
|
| << quic_server_id_str;
|
| @@ -861,6 +898,7 @@ void HttpServerPropertiesManager::UpdatePrefsFromCacheOnNetworkThread(
|
| const base::Closure& completion) {
|
| DCHECK(network_task_runner_->RunsTasksOnCurrentThread());
|
|
|
| + // It is in MRU order.
|
| base::ListValue* spdy_server_list = new base::ListValue;
|
| http_server_properties_impl_->GetSpdyServerList(
|
| spdy_server_list, kMaxSupportsSpdyServerHostsToPersist);
|
| @@ -870,8 +908,9 @@ void HttpServerPropertiesManager::UpdatePrefsFromCacheOnNetworkThread(
|
| const SpdySettingsMap& main_map =
|
| http_server_properties_impl_->spdy_settings_map();
|
| int count = 0;
|
| - for (SpdySettingsMap::const_iterator it = main_map.begin();
|
| - it != main_map.end() && count < kMaxSpdySettingsHostsToPersist;
|
| + // Maintain MRU order.
|
| + for (SpdySettingsMap::const_reverse_iterator it = main_map.rbegin();
|
| + it != main_map.rend() && count < kMaxSpdySettingsHostsToPersist;
|
| ++it, ++count) {
|
| spdy_settings_map->Put(it->first, it->second);
|
| }
|
| @@ -885,8 +924,9 @@ void HttpServerPropertiesManager::UpdatePrefsFromCacheOnNetworkThread(
|
| count = 0;
|
| typedef std::map<std::string, bool> CanonicalHostPersistedMap;
|
| CanonicalHostPersistedMap persisted_map;
|
| - for (AlternativeServiceMap::const_iterator it = map.begin();
|
| - it != map.end() && count < kMaxAlternateProtocolHostsToPersist; ++it) {
|
| + // Maintain MRU order.
|
| + for (AlternativeServiceMap::const_reverse_iterator it = map.rbegin();
|
| + it != map.rend() && count < kMaxAlternateProtocolHostsToPersist; ++it) {
|
| const HostPortPair& server = it->first;
|
| AlternativeServiceInfoVector notbroken_alternative_service_info_vector;
|
| for (const AlternativeServiceInfo& alternative_service_info : it->second) {
|
| @@ -928,14 +968,15 @@ void HttpServerPropertiesManager::UpdatePrefsFromCacheOnNetworkThread(
|
| const ServerNetworkStatsMap& network_stats_map =
|
| http_server_properties_impl_->server_network_stats_map();
|
| count = 0;
|
| - for (ServerNetworkStatsMap::const_iterator it = network_stats_map.begin();
|
| - it != network_stats_map.end() &&
|
| + for (ServerNetworkStatsMap::const_reverse_iterator
|
| + it = network_stats_map.rbegin();
|
| + it != network_stats_map.rend() &&
|
| count < kMaxServerNetworkStatsHostsToPersist;
|
| ++it, ++count) {
|
| server_network_stats_map->Put(it->first, it->second);
|
| }
|
|
|
| - QuicServerInfoMap* quic_server_info_map = NULL;
|
| + QuicServerInfoMap* quic_server_info_map = nullptr;
|
| const QuicServerInfoMap& main_quic_server_info_map =
|
| http_server_properties_impl_->quic_server_info_map();
|
| if (main_quic_server_info_map.size() > 0) {
|
| @@ -965,10 +1006,10 @@ void HttpServerPropertiesManager::UpdatePrefsFromCacheOnNetworkThread(
|
| struct ServerPref {
|
| ServerPref()
|
| : supports_spdy(false),
|
| - settings_map(NULL),
|
| - alternative_service_info_vector(NULL),
|
| - supports_quic(NULL),
|
| - server_network_stats(NULL) {}
|
| + settings_map(nullptr),
|
| + alternative_service_info_vector(nullptr),
|
| + supports_quic(nullptr),
|
| + server_network_stats(nullptr) {}
|
| ServerPref(
|
| bool supports_spdy,
|
| const SettingsMap* settings_map,
|
| @@ -987,6 +1028,7 @@ struct ServerPref {
|
| const ServerNetworkStats* server_network_stats;
|
| };
|
|
|
| +// All maps and lists are in MRU order.
|
| void HttpServerPropertiesManager::UpdatePrefsOnPrefThread(
|
| base::ListValue* spdy_server_list,
|
| SpdySettingsMap* spdy_settings_map,
|
| @@ -995,54 +1037,80 @@ void HttpServerPropertiesManager::UpdatePrefsOnPrefThread(
|
| ServerNetworkStatsMap* server_network_stats_map,
|
| QuicServerInfoMap* quic_server_info_map,
|
| const base::Closure& completion) {
|
| - typedef std::map<HostPortPair, ServerPref> ServerPrefMap;
|
| - ServerPrefMap server_pref_map;
|
| + typedef base::MRUCache<HostPortPair, ServerPref> ServerPrefMap;
|
| + ServerPrefMap server_pref_map(ServerPrefMap::NO_AUTO_EVICT);
|
|
|
| DCHECK(pref_task_runner_->RunsTasksOnCurrentThread());
|
|
|
| - // Add servers that support spdy to server_pref_map.
|
| - std::string s;
|
| - for (base::ListValue::const_iterator list_it = spdy_server_list->begin();
|
| - list_it != spdy_server_list->end();
|
| - ++list_it) {
|
| - if ((*list_it)->GetAsString(&s)) {
|
| + // Add servers that support spdy to server_pref_map in the MRU order.
|
| + for (size_t index = spdy_server_list->GetSize(); index > 0; --index) {
|
| + std::string s;
|
| + if (spdy_server_list->GetString(index - 1, &s)) {
|
| HostPortPair server = HostPortPair::FromString(s);
|
| - server_pref_map[server].supports_spdy = true;
|
| + ServerPrefMap::iterator it = server_pref_map.Get(server);
|
| + if (it == server_pref_map.end()) {
|
| + ServerPref server_pref;
|
| + server_pref.supports_spdy = true;
|
| + server_pref_map.Put(server, server_pref);
|
| + } else {
|
| + it->second.supports_spdy = true;
|
| + }
|
| }
|
| }
|
|
|
| - // Add servers that have SpdySettings to server_pref_map.
|
| - for (SpdySettingsMap::iterator map_it = spdy_settings_map->begin();
|
| - map_it != spdy_settings_map->end(); ++map_it) {
|
| + // Add servers that have SpdySettings to server_pref_map in the MRU order.
|
| + for (SpdySettingsMap::reverse_iterator map_it = spdy_settings_map->rbegin();
|
| + map_it != spdy_settings_map->rend(); ++map_it) {
|
| const HostPortPair& server = map_it->first;
|
| - server_pref_map[server].settings_map = &map_it->second;
|
| + ServerPrefMap::iterator it = server_pref_map.Get(server);
|
| + if (it == server_pref_map.end()) {
|
| + ServerPref server_pref;
|
| + server_pref.settings_map = &map_it->second;
|
| + server_pref_map.Put(server, server_pref);
|
| + } else {
|
| + it->second.settings_map = &map_it->second;
|
| + }
|
| }
|
|
|
| - // Add alternative services to server_pref_map.
|
| - for (AlternativeServiceMap::const_iterator map_it =
|
| - alternative_service_map->begin();
|
| - map_it != alternative_service_map->end(); ++map_it) {
|
| - server_pref_map[map_it->first].alternative_service_info_vector =
|
| - &map_it->second;
|
| + // Add alternative services to server_pref_map in the MRU order.
|
| + for (AlternativeServiceMap::const_reverse_iterator map_it =
|
| + alternative_service_map->rbegin();
|
| + map_it != alternative_service_map->rend(); ++map_it) {
|
| + const HostPortPair& server = map_it->first;
|
| + ServerPrefMap::iterator it = server_pref_map.Get(server);
|
| + if (it == server_pref_map.end()) {
|
| + ServerPref server_pref;
|
| + server_pref.alternative_service_info_vector = &map_it->second;
|
| + server_pref_map.Put(server, server_pref);
|
| + } else {
|
| + it->second.alternative_service_info_vector = &map_it->second;
|
| + }
|
| }
|
|
|
| - // Add ServerNetworkStats servers to server_pref_map.
|
| - for (ServerNetworkStatsMap::const_iterator map_it =
|
| - server_network_stats_map->begin();
|
| - map_it != server_network_stats_map->end(); ++map_it) {
|
| + // Add ServerNetworkStats servers to server_pref_map in the MRU order.
|
| + for (ServerNetworkStatsMap::const_reverse_iterator map_it =
|
| + server_network_stats_map->rbegin();
|
| + map_it != server_network_stats_map->rend(); ++map_it) {
|
| const HostPortPair& server = map_it->first;
|
| - server_pref_map[server].server_network_stats = &map_it->second;
|
| + ServerPrefMap::iterator it = server_pref_map.Get(server);
|
| + if (it == server_pref_map.end()) {
|
| + ServerPref server_pref;
|
| + server_pref.server_network_stats = &map_it->second;
|
| + server_pref_map.Put(server, server_pref);
|
| + } else {
|
| + it->second.server_network_stats = &map_it->second;
|
| + }
|
| }
|
|
|
| - // Persist properties to the |path_|.
|
| + // Persist properties to the |path_| in the MRU order.
|
| base::DictionaryValue http_server_properties_dict;
|
| - base::DictionaryValue* servers_dict = new base::DictionaryValue;
|
| - for (ServerPrefMap::const_iterator map_it = server_pref_map.begin();
|
| - map_it != server_pref_map.end();
|
| - ++map_it) {
|
| + base::ListValue* servers_list = new base::ListValue;
|
| + for (ServerPrefMap::const_reverse_iterator map_it = server_pref_map.rbegin();
|
| + map_it != server_pref_map.rend(); ++map_it) {
|
| const HostPortPair& server = map_it->first;
|
| const ServerPref& server_pref = map_it->second;
|
|
|
| + base::DictionaryValue* servers_dict = new base::DictionaryValue;
|
| base::DictionaryValue* server_pref_dict = new base::DictionaryValue;
|
|
|
| // Save supports_spdy.
|
| @@ -1055,10 +1123,12 @@ void HttpServerPropertiesManager::UpdatePrefsOnPrefThread(
|
| server_pref_dict);
|
|
|
| servers_dict->SetWithoutPathExpansion(server.ToString(), server_pref_dict);
|
| + bool value = servers_list->AppendIfNotPresent(servers_dict);
|
| + DCHECK(value); // Should never happen.
|
| }
|
|
|
| http_server_properties_dict.SetWithoutPathExpansion(kServersKey,
|
| - servers_dict);
|
| + servers_list);
|
| SetVersion(&http_server_properties_dict, kVersionNumber);
|
|
|
| SaveSupportsQuicToPrefs(last_quic_address, &http_server_properties_dict);
|
|
|