| Index: chrome/browser/net/chrome_http_server_properties.cc
|
| diff --git a/chrome/browser/net/chrome_http_server_properties.cc b/chrome/browser/net/chrome_http_server_properties.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..6a94e948b13c95de5f8d1b07f9b6b5e7a44a2d5a
|
| --- /dev/null
|
| +++ b/chrome/browser/net/chrome_http_server_properties.cc
|
| @@ -0,0 +1,346 @@
|
| +// Copyright (c) 2012 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include "chrome/browser/net/chrome_http_server_properties.h"
|
| +
|
| +#include "base/bind.h"
|
| +#include "base/metrics/histogram.h"
|
| +#include "base/rand_util.h"
|
| +#include "base/stl_util.h"
|
| +#include "base/strings/string_number_conversions.h"
|
| +#include "base/strings/stringprintf.h"
|
| +#include "base/values.h"
|
| +#include "chrome/browser/chrome_notification_types.h"
|
| +#include "chrome/common/pref_names.h"
|
| +#include "components/pref_registry/pref_registry_syncable.h"
|
| +#include "content/public/browser/browser_thread.h"
|
| +#include "content/public/browser/notification_details.h"
|
| +#include "content/public/browser/notification_source.h"
|
| +
|
| +using content::BrowserThread;
|
| +
|
| +namespace chrome_browser_net {
|
| +
|
| +namespace {
|
| +
|
| +// Time to wait before starting an update the preferences from the
|
| +// http_server_properties_impl_ cache. Scheduling another update during this
|
| +// period will reset the timer.
|
| +const int64 kUpdatePrefsDelayMs = 5000;
|
| +
|
| +// The version number of persisted http_server_properties.
|
| +const int kVersionNumber = 3;
|
| +
|
| +typedef std::vector<std::string> StringVector;
|
| +
|
| +// Persist 1000 MRU AlternateProtocolHostPortPairs.
|
| +const int kMaxAlternateProtocolHostsToPersist = 1000;
|
| +
|
| +// Persist 200 MRU SpdySettingsHostPortPairs.
|
| +const int kMaxSpdySettingsHostsToPersist = 200;
|
| +
|
| +// Persist 300 MRU SupportsSpdyServerHostPortPairs.
|
| +const int kMaxSupportsSpdyServerHostsToPersist = 300;
|
| +
|
| +} // namespace
|
| +
|
| +////////////////////////////////////////////////////////////////////////////////
|
| +// ChromeHttpServerProperties
|
| +
|
| +ChromeHttpServerProperties::ChromeHttpServerProperties(
|
| + UpdateCallback update_callback)
|
| + : http_server_properties_impl_(new net::HttpServerPropertiesImpl()),
|
| + update_callback_(update_callback),
|
| + prefs_update_timer_(new base::OneShotTimer<ChromeHttpServerProperties>),
|
| + weak_ptr_factory_(
|
| + new base::WeakPtrFactory<ChromeHttpServerProperties>(this)) {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| +}
|
| +
|
| +ChromeHttpServerProperties::~ChromeHttpServerProperties() {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| + weak_ptr_factory_.reset();
|
| +}
|
| +
|
| +// static
|
| +void ChromeHttpServerProperties::SetVersion(
|
| + base::DictionaryValue* http_server_properties_dict,
|
| + int version_number) {
|
| + if (version_number < 0)
|
| + version_number = kVersionNumber;
|
| + DCHECK_LE(version_number, kVersionNumber);
|
| + if (version_number <= kVersionNumber)
|
| + http_server_properties_dict->SetInteger("version", version_number);
|
| +}
|
| +
|
| +// This is required for conformance with the HttpServerProperties interface.
|
| +base::WeakPtr<net::HttpServerProperties>
|
| +ChromeHttpServerProperties::GetWeakPtr() {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| + return weak_ptr_factory_->GetWeakPtr();
|
| +}
|
| +
|
| +void ChromeHttpServerProperties::Clear() {
|
| + Clear(base::Closure());
|
| +}
|
| +
|
| +void ChromeHttpServerProperties::Clear(const base::Closure& completion) {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| +
|
| + http_server_properties_impl_->Clear();
|
| + UpdatePrefsFromCacheOnIO(completion);
|
| +}
|
| +
|
| +bool ChromeHttpServerProperties::SupportsSpdy(
|
| + const net::HostPortPair& server) {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| + return http_server_properties_impl_->SupportsSpdy(server);
|
| +}
|
| +
|
| +void ChromeHttpServerProperties::SetSupportsSpdy(
|
| + const net::HostPortPair& server,
|
| + bool support_spdy) {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| +
|
| + http_server_properties_impl_->SetSupportsSpdy(server, support_spdy);
|
| + ScheduleUpdatePrefsOnIO();
|
| +}
|
| +
|
| +bool ChromeHttpServerProperties::HasAlternateProtocol(
|
| + const net::HostPortPair& server) {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| + return http_server_properties_impl_->HasAlternateProtocol(server);
|
| +}
|
| +
|
| +net::PortAlternateProtocolPair
|
| +ChromeHttpServerProperties::GetAlternateProtocol(
|
| + const net::HostPortPair& server) {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| + return http_server_properties_impl_->GetAlternateProtocol(server);
|
| +}
|
| +
|
| +void ChromeHttpServerProperties::SetAlternateProtocol(
|
| + const net::HostPortPair& server,
|
| + uint16 alternate_port,
|
| + net::AlternateProtocol alternate_protocol) {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| + http_server_properties_impl_->SetAlternateProtocol(
|
| + server, alternate_port, alternate_protocol);
|
| + ScheduleUpdatePrefsOnIO();
|
| +}
|
| +
|
| +void ChromeHttpServerProperties::SetBrokenAlternateProtocol(
|
| + const net::HostPortPair& server) {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| + http_server_properties_impl_->SetBrokenAlternateProtocol(server);
|
| + ScheduleUpdatePrefsOnIO();
|
| +}
|
| +
|
| +bool ChromeHttpServerProperties::WasAlternateProtocolRecentlyBroken(
|
| + const net::HostPortPair& server) {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| + return http_server_properties_impl_->WasAlternateProtocolRecentlyBroken(
|
| + server);
|
| +}
|
| +
|
| +void ChromeHttpServerProperties::ConfirmAlternateProtocol(
|
| + const net::HostPortPair& server) {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| + http_server_properties_impl_->ConfirmAlternateProtocol(server);
|
| + ScheduleUpdatePrefsOnIO();
|
| +}
|
| +
|
| +void ChromeHttpServerProperties::ClearAlternateProtocol(
|
| + const net::HostPortPair& server) {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| + http_server_properties_impl_->ClearAlternateProtocol(server);
|
| + ScheduleUpdatePrefsOnIO();
|
| +}
|
| +
|
| +const net::AlternateProtocolMap&
|
| +ChromeHttpServerProperties::alternate_protocol_map() const {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| + return http_server_properties_impl_->alternate_protocol_map();
|
| +}
|
| +
|
| +void ChromeHttpServerProperties::SetAlternateProtocolExperiment(
|
| + net::AlternateProtocolExperiment experiment) {
|
| + http_server_properties_impl_->SetAlternateProtocolExperiment(experiment);
|
| +}
|
| +
|
| +net::AlternateProtocolExperiment
|
| +ChromeHttpServerProperties::GetAlternateProtocolExperiment() const {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| + return http_server_properties_impl_->GetAlternateProtocolExperiment();
|
| +}
|
| +
|
| +const net::SettingsMap&
|
| +ChromeHttpServerProperties::GetSpdySettings(
|
| + const net::HostPortPair& host_port_pair) {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| + return http_server_properties_impl_->GetSpdySettings(host_port_pair);
|
| +}
|
| +
|
| +bool ChromeHttpServerProperties::SetSpdySetting(
|
| + const net::HostPortPair& host_port_pair,
|
| + net::SpdySettingsIds id,
|
| + net::SpdySettingsFlags flags,
|
| + uint32 value) {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| + bool persist = http_server_properties_impl_->SetSpdySetting(
|
| + host_port_pair, id, flags, value);
|
| + if (persist)
|
| + ScheduleUpdatePrefsOnIO();
|
| + return persist;
|
| +}
|
| +
|
| +void ChromeHttpServerProperties::ClearSpdySettings(
|
| + const net::HostPortPair& host_port_pair) {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| + http_server_properties_impl_->ClearSpdySettings(host_port_pair);
|
| + ScheduleUpdatePrefsOnIO();
|
| +}
|
| +
|
| +void ChromeHttpServerProperties::ClearAllSpdySettings() {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| + http_server_properties_impl_->ClearAllSpdySettings();
|
| + ScheduleUpdatePrefsOnIO();
|
| +}
|
| +
|
| +const net::SpdySettingsMap&
|
| +ChromeHttpServerProperties::spdy_settings_map() const {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| + return http_server_properties_impl_->spdy_settings_map();
|
| +}
|
| +
|
| +void ChromeHttpServerProperties::SetServerNetworkStats(
|
| + const net::HostPortPair& host_port_pair,
|
| + NetworkStats stats) {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| + http_server_properties_impl_->SetServerNetworkStats(host_port_pair, stats);
|
| +}
|
| +
|
| +const ChromeHttpServerProperties::NetworkStats*
|
| +ChromeHttpServerProperties::GetServerNetworkStats(
|
| + const net::HostPortPair& host_port_pair) const {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| + return http_server_properties_impl_->GetServerNetworkStats(host_port_pair);
|
| +}
|
| +
|
| +void ChromeHttpServerProperties::UpdateCacheFromPrefsOnIO(
|
| + StringVector* spdy_servers,
|
| + net::SpdySettingsMap* spdy_settings_map,
|
| + net::AlternateProtocolMap* alternate_protocol_map,
|
| + net::AlternateProtocolExperiment alternate_protocol_experiment,
|
| + bool detected_corrupted_prefs) {
|
| + // Preferences have the master data because admins might have pushed new
|
| + // preferences. Update the cached data with new data from preferences.
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| +
|
| + UMA_HISTOGRAM_COUNTS("Net.CountOfSpdyServers", spdy_servers->size());
|
| + http_server_properties_impl_->InitializeSpdyServers(spdy_servers, true);
|
| +
|
| + // Update the cached data and use the new spdy_settings from preferences.
|
| + UMA_HISTOGRAM_COUNTS("Net.CountOfSpdySettings", spdy_settings_map->size());
|
| + http_server_properties_impl_->InitializeSpdySettingsServers(
|
| + spdy_settings_map);
|
| +
|
| + // Update the cached data and use the new Alternate-Protocol server list from
|
| + // preferences.
|
| + UMA_HISTOGRAM_COUNTS("Net.CountOfAlternateProtocolServers",
|
| + alternate_protocol_map->size());
|
| + http_server_properties_impl_->InitializeAlternateProtocolServers(
|
| + alternate_protocol_map);
|
| + http_server_properties_impl_->SetAlternateProtocolExperiment(
|
| + alternate_protocol_experiment);
|
| +
|
| + // Update the prefs with what we have read (delete all corrupted prefs).
|
| + if (detected_corrupted_prefs)
|
| + ScheduleUpdatePrefsOnIO();
|
| +}
|
| +
|
| +
|
| +//
|
| +// Update Preferences with data from the cached data.
|
| +//
|
| +void ChromeHttpServerProperties::ScheduleUpdatePrefsOnIO() {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| + // Cancel pending updates, if any.
|
| + prefs_update_timer_->Stop();
|
| + StartPrefsUpdateTimerOnIO(
|
| + base::TimeDelta::FromMilliseconds(kUpdatePrefsDelayMs));
|
| +}
|
| +
|
| +void ChromeHttpServerProperties::StartPrefsUpdateTimerOnIO(
|
| + base::TimeDelta delay) {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| + // This is overridden in tests to post the task without the delay.
|
| + prefs_update_timer_->Start(
|
| + FROM_HERE, delay, this,
|
| + &ChromeHttpServerProperties::UpdatePrefsFromCacheOnIO);
|
| +}
|
| +
|
| +// This is required so we can set this as the callback for a timer.
|
| +void ChromeHttpServerProperties::UpdatePrefsFromCacheOnIO() {
|
| + UpdatePrefsFromCacheOnIO(base::Closure());
|
| +}
|
| +
|
| +void ChromeHttpServerProperties::UpdatePrefsFromCacheOnIO(
|
| + const base::Closure& completion) {
|
| + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
|
| +
|
| + base::ListValue* spdy_server_list = new base::ListValue;
|
| + http_server_properties_impl_->GetSpdyServerList(
|
| + spdy_server_list, kMaxSupportsSpdyServerHostsToPersist);
|
| +
|
| + net::SpdySettingsMap* spdy_settings_map =
|
| + new net::SpdySettingsMap(kMaxSpdySettingsHostsToPersist);
|
| + const net::SpdySettingsMap& main_map =
|
| + http_server_properties_impl_->spdy_settings_map();
|
| + int count = 0;
|
| + for (net::SpdySettingsMap::const_iterator it = main_map.begin();
|
| + it != main_map.end() && count < kMaxSpdySettingsHostsToPersist;
|
| + ++it, ++count) {
|
| + spdy_settings_map->Put(it->first, it->second);
|
| + }
|
| +
|
| + net::AlternateProtocolMap* alternate_protocol_map =
|
| + new net::AlternateProtocolMap(kMaxAlternateProtocolHostsToPersist);
|
| + const net::AlternateProtocolMap& map =
|
| + http_server_properties_impl_->alternate_protocol_map();
|
| + count = 0;
|
| + typedef std::map<std::string, bool> CanonicalHostPersistedMap;
|
| + CanonicalHostPersistedMap persisted_map;
|
| + for (net::AlternateProtocolMap::const_iterator it = map.begin();
|
| + it != map.end() && count < kMaxAlternateProtocolHostsToPersist;
|
| + ++it) {
|
| + const net::HostPortPair& server = it->first;
|
| + std::string canonical_suffix =
|
| + http_server_properties_impl_->GetCanonicalSuffix(server);
|
| + if (!canonical_suffix.empty()) {
|
| + if (persisted_map.find(canonical_suffix) != persisted_map.end())
|
| + continue;
|
| + persisted_map[canonical_suffix] = true;
|
| + }
|
| + alternate_protocol_map->Put(server, it->second);
|
| + ++count;
|
| + }
|
| +
|
| + /*
|
| + // Update the preferences on the UI thread.
|
| + BrowserThread::PostTask(
|
| + BrowserThread::UI,
|
| + FROM_HERE,
|
| + base::Bind(&ChromeHttpServerProperties::UpdatePrefsOnUI,
|
| + manager_,
|
| + base::Owned(spdy_server_list),
|
| + base::Owned(spdy_settings_map),
|
| + base::Owned(alternate_protocol_map),
|
| + completion));
|
| + */
|
| + update_callback_.Run(spdy_server_list, spdy_settings_map,
|
| + alternate_protocol_map, completion);
|
| +}
|
| +
|
| +} // namespace chrome_browser_net
|
|
|