summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorwillchan@chromium.org <willchan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-10-12 07:05:18 +0000
committerwillchan@chromium.org <willchan@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-10-12 07:05:18 +0000
commitde95f929772cb7214efb747f9a5a115b27561336 (patch)
tree3f376123413c93b064eb65baf2643a407f6dfc7e
parent817925aaf716cb623c56e21030650f075e510157 (diff)
downloadchromium_src-de95f929772cb7214efb747f9a5a115b27561336.zip
chromium_src-de95f929772cb7214efb747f9a5a115b27561336.tar.gz
chromium_src-de95f929772cb7214efb747f9a5a115b27561336.tar.bz2
Persist Alternate-Protocol.
Record Alternate-Protocol servers in spdy.alternate_protocol. Don't persist broken Alternate-Protocol so they will retry on next browser session. Also fix listening to notifications when we're the ones setting them. This was leading to unnecessary double updates, where we'd update the cache on the IO thread, and then propagate to the UI thread, where we'd set the prefs, and then observe that change and propagate back to the IO thread to update the cache. BUG=98472 TEST=Observe that spdy.alternate_protocol is empty in your Preferences file. Confirm that there is no alternate-protocol mapping in chrome://net-internals/#spdy. Browse to www.strangeloopnetworks.com. Check chrome://net-internals/#spdy again and notice that it populates with the mapping. Wait some seconds and then check the Preferences file again and note that it got persisted to disk. Restart Chrome and check chrome://net-internals/#spdy and note that the same alternate-protocol mappings reappear. Review URL: http://codereview.chromium.org/8221030 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@105028 0039d316-1c4b-4281-b951-d872f2087c98
-rw-r--r--chrome/browser/net/http_server_properties_manager.cc270
-rw-r--r--chrome/browser/net/http_server_properties_manager.h93
-rw-r--r--chrome/browser/net/http_server_properties_manager_unittest.cc326
-rw-r--r--chrome/browser/profiles/profile_impl_io_data.cc2
-rw-r--r--chrome/common/pref_names.cc3
-rw-r--r--chrome/common/pref_names.h1
-rw-r--r--net/base/host_port_pair.cc19
-rw-r--r--net/base/host_port_pair.h4
-rw-r--r--net/base/host_port_pair_unittest.cc23
-rw-r--r--net/http/http_server_properties.h4
-rw-r--r--net/http/http_server_properties_impl.cc15
-rw-r--r--net/http/http_server_properties_impl.h5
-rw-r--r--net/http/http_server_properties_impl_unittest.cc38
-rw-r--r--net/net.gyp1
14 files changed, 660 insertions, 144 deletions
diff --git a/chrome/browser/net/http_server_properties_manager.cc b/chrome/browser/net/http_server_properties_manager.cc
index 9bcab3c..48c2adc 100644
--- a/chrome/browser/net/http_server_properties_manager.cc
+++ b/chrome/browser/net/http_server_properties_manager.cc
@@ -54,15 +54,21 @@ StringVector* ListValueToStringVector(const base::ListValue* list) {
HttpServerPropertiesManager::HttpServerPropertiesManager(
PrefService* pref_service)
- : ALLOW_THIS_IN_INITIALIZER_LIST(ui_method_factory_(this)),
- pref_service_(pref_service) {
+ : pref_service_(pref_service),
+ setting_spdy_servers_(false),
+ setting_alternate_protocol_servers_(false) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
DCHECK(pref_service);
ui_weak_ptr_factory_.reset(
new base::WeakPtrFactory<HttpServerPropertiesManager>(this));
ui_weak_ptr_ = ui_weak_ptr_factory_->GetWeakPtr();
+ ui_spdy_cache_update_timer_.reset(
+ new base::OneShotTimer<HttpServerPropertiesManager>);
+ ui_alternate_protocol_cache_update_timer_.reset(
+ new base::OneShotTimer<HttpServerPropertiesManager>);
pref_change_registrar_.Init(pref_service_);
pref_change_registrar_.Add(prefs::kSpdyServers, this);
+ pref_change_registrar_.Add(prefs::kAlternateProtocolServers, this);
}
HttpServerPropertiesManager::~HttpServerPropertiesManager() {
@@ -72,20 +78,29 @@ void HttpServerPropertiesManager::InitializeOnIOThread() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
http_server_properties_impl_.reset(new net::HttpServerPropertiesImpl());
- io_method_factory_.reset(
- new ScopedRunnableMethodFactory<HttpServerPropertiesManager>(this));
+ io_spdy_prefs_update_timer_.reset(
+ new base::OneShotTimer<HttpServerPropertiesManager>);
+ io_alternate_protocol_prefs_update_timer_.reset(
+ new base::OneShotTimer<HttpServerPropertiesManager>);
BrowserThread::PostTask(
BrowserThread::UI,
FROM_HERE,
- base::Bind(&HttpServerPropertiesManager::UpdateCacheFromPrefs,
+ base::Bind(&HttpServerPropertiesManager::UpdateSpdyCacheFromPrefs,
ui_weak_ptr_));
+ BrowserThread::PostTask(
+ BrowserThread::UI,
+ FROM_HERE,
+ base::Bind(
+ &HttpServerPropertiesManager::UpdateAlternateProtocolCacheFromPrefs,
+ ui_weak_ptr_));
}
void HttpServerPropertiesManager::ShutdownOnUIThread() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
// Cancel any pending updates, and stop listening for pref change updates.
- ui_method_factory_.RevokeAll();
+ ui_spdy_cache_update_timer_->Stop();
+ ui_alternate_protocol_cache_update_timer_->Stop();
ui_weak_ptr_factory_.reset();
pref_change_registrar_.RemoveAll();
}
@@ -93,13 +108,16 @@ void HttpServerPropertiesManager::ShutdownOnUIThread() {
// static
void HttpServerPropertiesManager::RegisterPrefs(PrefService* prefs) {
prefs->RegisterListPref(prefs::kSpdyServers, PrefService::UNSYNCABLE_PREF);
+ prefs->RegisterDictionaryPref(prefs::kAlternateProtocolServers,
+ PrefService::UNSYNCABLE_PREF);
}
-void HttpServerPropertiesManager::DeleteAll() {
+void HttpServerPropertiesManager::Clear() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- http_server_properties_impl_->DeleteAll();
- ScheduleUpdatePrefsOnIO();
+ http_server_properties_impl_->Clear();
+ ScheduleUpdateSpdyPrefsOnIO();
+ ScheduleUpdateAlternateProtocolPrefsOnIO();
}
bool HttpServerPropertiesManager::SupportsSpdy(
@@ -114,7 +132,7 @@ void HttpServerPropertiesManager::SetSupportsSpdy(
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
http_server_properties_impl_->SetSupportsSpdy(server, support_spdy);
- ScheduleUpdatePrefsOnIO();
+ ScheduleUpdateSpdyPrefsOnIO();
}
bool HttpServerPropertiesManager::HasAlternateProtocol(
@@ -137,12 +155,14 @@ void HttpServerPropertiesManager::SetAlternateProtocol(
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
http_server_properties_impl_->SetAlternateProtocol(
server, alternate_port, alternate_protocol);
+ ScheduleUpdateAlternateProtocolPrefsOnIO();
}
void HttpServerPropertiesManager::SetBrokenAlternateProtocol(
const net::HostPortPair& server) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
http_server_properties_impl_->SetBrokenAlternateProtocol(server);
+ ScheduleUpdateAlternateProtocolPrefsOnIO();
}
const net::AlternateProtocolMap&
@@ -154,22 +174,15 @@ HttpServerPropertiesManager::alternate_protocol_map() const {
//
// Update spdy_servers (the cached data) with data from preferences.
//
-void HttpServerPropertiesManager::ScheduleUpdateCacheOnUI() {
+void HttpServerPropertiesManager::ScheduleUpdateSpdyCacheOnUI() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
// Cancel pending updates, if any.
- ui_method_factory_.RevokeAll();
- PostUpdateTaskOnUI(
- ui_method_factory_.NewRunnableMethod(
- &HttpServerPropertiesManager::UpdateCacheFromPrefs));
+ ui_spdy_cache_update_timer_->Stop();
+ StartSpdyCacheUpdateTimerOnUI(
+ base::TimeDelta::FromMilliseconds(kUpdateCacheDelayMs));
}
-void HttpServerPropertiesManager::PostUpdateTaskOnUI(Task* task) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
- // This is overridden in tests to post the task without the delay.
- MessageLoop::current()->PostDelayedTask(FROM_HERE, task, kUpdateCacheDelayMs);
-}
-
-void HttpServerPropertiesManager::UpdateCacheFromPrefs() {
+void HttpServerPropertiesManager::UpdateSpdyCacheFromPrefs() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
if (!pref_service_->HasPrefPath(prefs::kSpdyServers))
@@ -179,17 +192,14 @@ void HttpServerPropertiesManager::UpdateCacheFromPrefs() {
StringVector* spdy_servers =
ListValueToStringVector(pref_service_->GetList(prefs::kSpdyServers));
- // Go through the IO thread to grab a WeakPtr to |this|. This is safe from
- // here, since this task will always execute before a potential deletion of
- // ProfileIOData on IO.
BrowserThread::PostTask(
BrowserThread::IO,
FROM_HERE,
- base::Bind(&HttpServerPropertiesManager::UpdateCacheFromPrefsOnIO,
+ base::Bind(&HttpServerPropertiesManager::UpdateSpdyCacheFromPrefsOnIO,
base::Unretained(this), spdy_servers, true));
}
-void HttpServerPropertiesManager::UpdateCacheFromPrefsOnIO(
+void HttpServerPropertiesManager::UpdateSpdyCacheFromPrefsOnIO(
StringVector* spdy_servers,
bool support_spdy) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
@@ -204,22 +214,15 @@ void HttpServerPropertiesManager::UpdateCacheFromPrefsOnIO(
//
// Update Preferences with data from spdy_servers (the cached data).
//
-void HttpServerPropertiesManager::ScheduleUpdatePrefsOnIO() {
+void HttpServerPropertiesManager::ScheduleUpdateSpdyPrefsOnIO() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
// Cancel pending updates, if any.
- io_method_factory_->RevokeAll();
- PostUpdateTaskOnIO(
- io_method_factory_->NewRunnableMethod(
- &HttpServerPropertiesManager::UpdatePrefsFromCache));
+ io_spdy_prefs_update_timer_->Stop();
+ StartSpdyPrefsUpdateTimerOnIO(
+ base::TimeDelta::FromMilliseconds(kUpdatePrefsDelayMs));
}
-void HttpServerPropertiesManager::PostUpdateTaskOnIO(Task* task) {
- DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
- // This is overridden in tests to post the task without the delay.
- MessageLoop::current()->PostDelayedTask(FROM_HERE, task, kUpdatePrefsDelayMs);
-}
-
-void HttpServerPropertiesManager::UpdatePrefsFromCache() {
+void HttpServerPropertiesManager::UpdateSpdyPrefsFromCache() {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
scoped_refptr<RefCountedListValue> spdy_server_list =
@@ -237,7 +240,185 @@ void HttpServerPropertiesManager::UpdatePrefsFromCache() {
void HttpServerPropertiesManager::SetSpdyServersInPrefsOnUI(
scoped_refptr<RefCountedListValue> spdy_server_list) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ setting_spdy_servers_ = true;
pref_service_->Set(prefs::kSpdyServers, spdy_server_list->data);
+ setting_spdy_servers_ = false;
+}
+
+void HttpServerPropertiesManager::ScheduleUpdateAlternateProtocolCacheOnUI() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ // Cancel pending updates, if any.
+ ui_alternate_protocol_cache_update_timer_->Stop();
+ StartAlternateProtocolCacheUpdateTimerOnUI(
+ base::TimeDelta::FromMilliseconds(kUpdateCacheDelayMs));
+}
+
+void HttpServerPropertiesManager::UpdateAlternateProtocolCacheFromPrefs() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+
+ if (!pref_service_->HasPrefPath(prefs::kAlternateProtocolServers))
+ return;
+
+ // Parse the preferences into a AlternateProtocolMap.
+ net::AlternateProtocolMap alternate_protocol_map;
+ const base::DictionaryValue& alternate_protocol_servers =
+ *pref_service_->GetDictionary(prefs::kAlternateProtocolServers);
+ for (base::DictionaryValue::key_iterator it =
+ alternate_protocol_servers.begin_keys();
+ it != alternate_protocol_servers.end_keys(); ++it) {
+ const std::string& server_str = *it;
+ net::HostPortPair server = net::HostPortPair::FromString(server_str);
+ if (server.host().empty()) {
+ VLOG(1) << "Malformed Alternate-Protocol server: " << server_str;
+ NOTREACHED();
+ continue;
+ }
+ DCHECK(!ContainsKey(alternate_protocol_map, server));
+
+ base::DictionaryValue* port_alternate_protocol_dict = NULL;
+ if (!alternate_protocol_servers.GetDictionaryWithoutPathExpansion(
+ server_str, &port_alternate_protocol_dict)) {
+ VLOG(1) << "Malformed Alternate-Protocol server: " << server_str;
+ NOTREACHED();
+ continue;
+ }
+
+ int port = 0;
+ if (!port_alternate_protocol_dict->GetIntegerWithoutPathExpansion(
+ "port", &port) || (port > (1 << 16))) {
+ VLOG(1) << "Malformed Alternate-Protocol server: " << server_str;
+ NOTREACHED();
+ continue;
+ }
+ int protocol = 0;
+ if (!port_alternate_protocol_dict->GetIntegerWithoutPathExpansion(
+ "protocol", &protocol) || (protocol < 0) ||
+ (protocol > net::NUM_ALTERNATE_PROTOCOLS)) {
+ VLOG(1) << "Malformed Alternate-Protocol server: " << server_str;
+ NOTREACHED();
+ continue;
+ }
+
+ net::PortAlternateProtocolPair port_alternate_protocol;
+ port_alternate_protocol.port = port;
+ port_alternate_protocol.protocol = static_cast<net::AlternateProtocol>(
+ protocol);
+
+ alternate_protocol_map[server] = port_alternate_protocol;
+ }
+
+ scoped_refptr<RefCountedAlternateProtocolMap> alternate_protocol_map_arg =
+ new RefCountedAlternateProtocolMap;
+ alternate_protocol_map_arg->data.swap(alternate_protocol_map);
+
+ BrowserThread::PostTask(
+ BrowserThread::IO,
+ FROM_HERE,
+ base::Bind(&HttpServerPropertiesManager::
+ UpdateAlternateProtocolCacheFromPrefsOnIO,
+ base::Unretained(this), alternate_protocol_map_arg));
+}
+
+void HttpServerPropertiesManager::UpdateAlternateProtocolCacheFromPrefsOnIO(
+ RefCountedAlternateProtocolMap* alternate_protocol_map) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ // Preferences have the master data because admins might have pushed new
+ // preferences. Clear the cached data and use the new spdy server list from
+ // preferences.
+ http_server_properties_impl_->InitializeAlternateProtocolServers(
+ &alternate_protocol_map->data);
+}
+
+//
+// Update Preferences with data from alternate_protocol_servers (the cached
+// data).
+//
+void HttpServerPropertiesManager::ScheduleUpdateAlternateProtocolPrefsOnIO() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ // Cancel pending updates, if any.
+ io_alternate_protocol_prefs_update_timer_->Stop();
+ StartAlternateProtocolPrefsUpdateTimerOnIO(
+ base::TimeDelta::FromMilliseconds(kUpdatePrefsDelayMs));
+}
+
+void HttpServerPropertiesManager::UpdateAlternateProtocolPrefsFromCache() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+
+ scoped_refptr<RefCountedAlternateProtocolMap> alternate_protocol_map =
+ new RefCountedAlternateProtocolMap;
+ alternate_protocol_map->data =
+ http_server_properties_impl_->alternate_protocol_map();
+
+ // Update the preferences on the UI thread.
+ BrowserThread::PostTask(
+ BrowserThread::UI,
+ FROM_HERE,
+ base::Bind(&HttpServerPropertiesManager::
+ SetAlternateProtocolServersInPrefsOnUI,
+ ui_weak_ptr_, alternate_protocol_map));
+}
+
+void HttpServerPropertiesManager::SetAlternateProtocolServersInPrefsOnUI(
+ RefCountedAlternateProtocolMap* alternate_protocol_map) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ base::DictionaryValue alternate_protocol_dict;
+ for (net::AlternateProtocolMap::const_iterator it =
+ alternate_protocol_map->data.begin();
+ it != alternate_protocol_map->data.end(); ++it) {
+ const net::HostPortPair& server = it->first;
+ const net::PortAlternateProtocolPair& port_alternate_protocol =
+ it->second;
+ if (port_alternate_protocol.protocol < 0 ||
+ port_alternate_protocol.protocol >= net::NUM_ALTERNATE_PROTOCOLS) {
+ continue;
+ }
+ base::DictionaryValue* port_alternate_protocol_dict =
+ new base::DictionaryValue;
+ port_alternate_protocol_dict->SetInteger(
+ "port", port_alternate_protocol.port);
+ port_alternate_protocol_dict->SetInteger(
+ "protocol", port_alternate_protocol.protocol);
+ alternate_protocol_dict.SetWithoutPathExpansion(
+ server.ToString(), port_alternate_protocol_dict);
+ }
+ setting_alternate_protocol_servers_ = true;
+ pref_service_->Set(prefs::kAlternateProtocolServers,
+ alternate_protocol_dict);
+ setting_alternate_protocol_servers_ = false;
+}
+
+void HttpServerPropertiesManager::StartSpdyCacheUpdateTimerOnUI(
+ base::TimeDelta delay) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ ui_spdy_cache_update_timer_->Start(
+ FROM_HERE, delay, this,
+ &HttpServerPropertiesManager::UpdateSpdyCacheFromPrefs);
+}
+
+void HttpServerPropertiesManager::StartSpdyPrefsUpdateTimerOnIO(
+ base::TimeDelta delay) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ // This is overridden in tests to post the task without the delay.
+ io_spdy_prefs_update_timer_->Start(
+ FROM_HERE, delay, this,
+ &HttpServerPropertiesManager::UpdateSpdyPrefsFromCache);
+}
+
+void HttpServerPropertiesManager::StartAlternateProtocolCacheUpdateTimerOnUI(
+ base::TimeDelta delay) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI));
+ ui_alternate_protocol_cache_update_timer_->Start(
+ FROM_HERE, delay, this,
+ &HttpServerPropertiesManager::UpdateAlternateProtocolCacheFromPrefs);
+}
+
+void HttpServerPropertiesManager::StartAlternateProtocolPrefsUpdateTimerOnIO(
+ base::TimeDelta delay) {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
+ // This is overridden in tests to post the task without the delay.
+ io_alternate_protocol_prefs_update_timer_->Start(
+ FROM_HERE, delay, this,
+ &HttpServerPropertiesManager::UpdateAlternateProtocolPrefsFromCache);
}
void HttpServerPropertiesManager::Observe(int type,
@@ -248,8 +429,15 @@ void HttpServerPropertiesManager::Observe(int type,
PrefService* prefs = Source<PrefService>(source).ptr();
DCHECK(prefs == pref_service_);
std::string* pref_name = Details<std::string>(details).ptr();
- DCHECK(*pref_name == prefs::kSpdyServers);
- ScheduleUpdateCacheOnUI();
+ if (*pref_name == prefs::kSpdyServers) {
+ if (!setting_spdy_servers_)
+ ScheduleUpdateSpdyCacheOnUI();
+ } else if (*pref_name == prefs::kAlternateProtocolServers) {
+ if (!setting_alternate_protocol_servers_)
+ ScheduleUpdateAlternateProtocolCacheOnUI();
+ } else {
+ NOTREACHED();
+ }
}
} // namespace chrome_browser_net
diff --git a/chrome/browser/net/http_server_properties_manager.h b/chrome/browser/net/http_server_properties_manager.h
index 572922e..b7d6bf0 100644
--- a/chrome/browser/net/http_server_properties_manager.h
+++ b/chrome/browser/net/http_server_properties_manager.h
@@ -13,7 +13,7 @@
#include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h"
#include "base/memory/weak_ptr.h"
-#include "base/task.h"
+#include "base/timer.h"
#include "base/values.h"
#include "chrome/browser/prefs/pref_change_registrar.h"
#include "content/common/notification_observer.h"
@@ -75,7 +75,7 @@ class HttpServerPropertiesManager
// ----------------------------------
// Deletes all data.
- virtual void DeleteAll() OVERRIDE;
+ virtual void Clear() OVERRIDE;
// Returns true if |server| supports SPDY. Should only be called from IO
// thread.
@@ -111,39 +111,83 @@ class HttpServerPropertiesManager
protected:
typedef base::RefCountedData<base::ListValue> RefCountedListValue;
+ typedef base::RefCountedData<net::AlternateProtocolMap>
+ RefCountedAlternateProtocolMap;
+
+ // --------------------
+ // SPDY related methods
// These are used to delay updating the spdy servers in
// |http_server_properties_impl_| while the preferences are changing, and
// execute only one update per simultaneous prefs changes.
- void ScheduleUpdateCacheOnUI();
+ void ScheduleUpdateSpdyCacheOnUI();
// Update spdy servers (the cached data in |http_server_properties_impl_|)
// with data from preferences. Virtual for testing.
- virtual void UpdateCacheFromPrefs();
+ virtual void UpdateSpdyCacheFromPrefs();
// Starts the |spdy_servers| update on the IO thread. Protected for testing.
- void UpdateCacheFromPrefsOnIO(std::vector<std::string>* spdy_servers,
- bool support_spdy);
+ void UpdateSpdyCacheFromPrefsOnIO(std::vector<std::string>* spdy_servers,
+ bool support_spdy);
// These are used to delay updating the preferences when spdy servers_ are
// changing, and execute only one update per simultaneous spdy server changes.
- void ScheduleUpdatePrefsOnIO();
+ void ScheduleUpdateSpdyPrefsOnIO();
// Update spdy servers in preferences with the cached data from
// |http_server_properties_impl_|. Virtual for testing.
- virtual void UpdatePrefsFromCache(); // Virtual for testing.
+ virtual void UpdateSpdyPrefsFromCache(); // Virtual for testing.
// Update |prefs::kSpdyServers| preferences with |spdy_server_list| on UI
// thread. Protected for testing.
void SetSpdyServersInPrefsOnUI(
scoped_refptr<RefCountedListValue> spdy_server_list);
- private:
- // Post the tasks with the delay. These are overridden in tests to post the
- // task without the delay.
- virtual void PostUpdateTaskOnUI(Task* task); // Virtual for testing.
- virtual void PostUpdateTaskOnIO(Task* task); // Virtual for testing.
+ // Starts the timers to update the cache/prefs. This are overridden in tests
+ // to prevent the delay.
+ virtual void StartSpdyCacheUpdateTimerOnUI(base::TimeDelta delay);
+ virtual void StartSpdyPrefsUpdateTimerOnIO(base::TimeDelta delay);
+
+ // ----------------------------------
+ // Alternate-Protocol related methods
+
+ // These are used to delay updating the Alternate-Protocol servers in
+ // |http_server_properties_impl_| while the preferences are changing, and
+ // execute only one update per simultaneous prefs changes.
+ void ScheduleUpdateAlternateProtocolCacheOnUI();
+
+ // Update Alternate-Protocol servers (the cached data in
+ // |http_server_properties_impl_|) with data from preferences. Virtual for
+ // testing.
+ virtual void UpdateAlternateProtocolCacheFromPrefs();
+
+ // Starts the |alternate_protocol_servers| update on the IO thread. Protected
+ // for testing.
+ void UpdateAlternateProtocolCacheFromPrefsOnIO(
+ RefCountedAlternateProtocolMap* alternate_protocol_map);
+
+ // These are used to delay updating the preferences when Alternate-Protocol
+ // servers_ are changing, and execute only one update per simultaneous
+ // Alternate-Protocol server changes.
+ void ScheduleUpdateAlternateProtocolPrefsOnIO();
+ // Update Alternate-Protocol servers in preferences with the cached data from
+ // |http_server_properties_impl_|. Virtual for testing.
+ virtual void UpdateAlternateProtocolPrefsFromCache(); // Virtual for testing.
+
+ // Update |prefs::kAlternateProtocolServers| preferences with
+ // |alternate_protocol_server_list| on UI thread. Protected for testing.
+ void SetAlternateProtocolServersInPrefsOnUI(
+ RefCountedAlternateProtocolMap* alternate_protocol_map);
+
+ // Starts the timers to update the cache/prefs. This are overridden in tests
+ // to prevent the delay.
+ virtual void StartAlternateProtocolCacheUpdateTimerOnUI(
+ base::TimeDelta delay);
+ virtual void StartAlternateProtocolPrefsUpdateTimerOnIO(
+ base::TimeDelta delay);
+
+ private:
// Callback for preference changes.
virtual void Observe(int type,
const NotificationSource& source,
@@ -153,26 +197,37 @@ class HttpServerPropertiesManager
// UI thread
// ---------
- // Used to post update tasks to the UI thread.
- ScopedRunnableMethodFactory<HttpServerPropertiesManager> ui_method_factory_;
-
// Used to get |weak_ptr_| to self on the UI thread.
scoped_ptr<base::WeakPtrFactory<HttpServerPropertiesManager> >
ui_weak_ptr_factory_;
base::WeakPtr<HttpServerPropertiesManager> ui_weak_ptr_;
+ // Used to post SPDY cache update tasks.
+ scoped_ptr<base::OneShotTimer<HttpServerPropertiesManager> >
+ ui_spdy_cache_update_timer_;
+
+ // Used to post Alternate-Protocol cache update tasks.
+ scoped_ptr<base::OneShotTimer<HttpServerPropertiesManager> >
+ ui_alternate_protocol_cache_update_timer_;
+
// Used to track the spdy servers changes.
PrefChangeRegistrar pref_change_registrar_;
PrefService* pref_service_; // Weak.
+ bool setting_spdy_servers_;
+ bool setting_alternate_protocol_servers_;
// ---------
// IO thread
// ---------
- // Used to post update tasks to the IO thread.
- scoped_ptr<ScopedRunnableMethodFactory<HttpServerPropertiesManager> >
- io_method_factory_;
+ // Used to post SPDY pref update tasks.
+ scoped_ptr<base::OneShotTimer<HttpServerPropertiesManager> >
+ io_spdy_prefs_update_timer_;
+
+ // Used to post Alternate-Protocol pref update tasks.
+ scoped_ptr<base::OneShotTimer<HttpServerPropertiesManager> >
+ io_alternate_protocol_prefs_update_timer_;
scoped_ptr<net::HttpServerPropertiesImpl> http_server_properties_impl_;
diff --git a/chrome/browser/net/http_server_properties_manager_unittest.cc b/chrome/browser/net/http_server_properties_manager_unittest.cc
index 1c95eab..6c23ac3 100644
--- a/chrome/browser/net/http_server_properties_manager_unittest.cc
+++ b/chrome/browser/net/http_server_properties_manager_unittest.cc
@@ -22,6 +22,7 @@ namespace {
using ::testing::_;
using ::testing::Invoke;
using ::testing::Mock;
+using ::testing::StrictMock;
class TestingHttpServerPropertiesManager : public HttpServerPropertiesManager {
public:
@@ -33,55 +34,68 @@ class TestingHttpServerPropertiesManager : public HttpServerPropertiesManager {
virtual ~TestingHttpServerPropertiesManager() {
}
- // Make this method public for testing.
- using HttpServerPropertiesManager::ScheduleUpdateCacheOnUI;
- using HttpServerPropertiesManager::ScheduleUpdatePrefsOnIO;
+ // Make these method public for testing.
+ using HttpServerPropertiesManager::ScheduleUpdateSpdyCacheOnUI;
+ using HttpServerPropertiesManager::ScheduleUpdateSpdyPrefsOnIO;
+ using HttpServerPropertiesManager::ScheduleUpdateAlternateProtocolCacheOnUI;
+ using HttpServerPropertiesManager::ScheduleUpdateAlternateProtocolPrefsOnIO;
// Post tasks without a delay during tests.
- virtual void PostUpdateTaskOnUI(Task* task) OVERRIDE {
- MessageLoop::current()->PostTask(FROM_HERE, task);
+ virtual void StartSpdyPrefsUpdateTimerOnIO(base::TimeDelta delay) OVERRIDE {
+ HttpServerPropertiesManager::StartSpdyPrefsUpdateTimerOnIO(
+ base::TimeDelta());
}
- // Makes a direct call to UpdateCacheFromPrefsOnIO during tests.
- void UpdateCacheFromPrefsOnIO() {
- std::vector<std::string>* spdy_servers = new std::vector<std::string>;
- spdy_servers->push_back("www.google.com:443");
- HttpServerPropertiesManager::UpdateCacheFromPrefsOnIO(spdy_servers, true);
+ // Post tasks without a delay during tests.
+ virtual void StartAlternateProtocolPrefsUpdateTimerOnIO(
+ base::TimeDelta delay) OVERRIDE {
+ HttpServerPropertiesManager::StartAlternateProtocolPrefsUpdateTimerOnIO(
+ base::TimeDelta());
}
- void UpdateCacheFromPrefsConcrete() {
- HttpServerPropertiesManager::UpdateCacheFromPrefs();
+ void UpdateSpdyCacheFromPrefsConcrete() {
+ HttpServerPropertiesManager::UpdateSpdyCacheFromPrefs();
}
- // Post tasks without a delay during tests.
- virtual void PostUpdateTaskOnIO(Task* task) OVERRIDE {
- MessageLoop::current()->PostTask(FROM_HERE, task);
+ void UpdateAlternateProtocolCacheFromPrefsConcrete() {
+ HttpServerPropertiesManager::UpdateAlternateProtocolCacheFromPrefs();
}
- // Makes a direct call to SetSpdyServersInPrefsOnUI during tests.
- void SetSpdyServersInPrefsOnUI() {
- net::HostPortPair spdy_server_mail("mail.google.com", 443);
- std::string spdy_server_m =
- net::HttpServerPropertiesImpl::GetFlattenedSpdyServer(spdy_server_mail);
+ // Post tasks without a delay during tests.
+ virtual void StartSpdyCacheUpdateTimerOnUI(base::TimeDelta delay) OVERRIDE {
+ HttpServerPropertiesManager::StartSpdyCacheUpdateTimerOnUI(
+ base::TimeDelta());
+ }
- scoped_refptr<RefCountedListValue> spdy_server_list =
- new RefCountedListValue();
- spdy_server_list->data.Append(new StringValue(spdy_server_m));
+ // Post tasks without a delay during tests.
+ virtual void StartAlternateProtocolCacheUpdateTimerOnUI(
+ base::TimeDelta delay) OVERRIDE {
+ HttpServerPropertiesManager::StartAlternateProtocolCacheUpdateTimerOnUI(
+ base::TimeDelta());
+ }
- HttpServerPropertiesManager::SetSpdyServersInPrefsOnUI(spdy_server_list);
+ void UpdateSpdyPrefsFromCacheConcrete() {
+ HttpServerPropertiesManager::UpdateSpdyPrefsFromCache();
}
- void UpdatePrefsFromCacheConcrete() {
- HttpServerPropertiesManager::UpdatePrefsFromCache();
+ void UpdateAlternateProtocolPrefsFromCacheConcrete() {
+ HttpServerPropertiesManager::UpdateAlternateProtocolPrefsFromCache();
}
- MOCK_METHOD0(UpdateCacheFromPrefs, void());
- MOCK_METHOD0(UpdatePrefsFromCache, void());
- MOCK_METHOD2(UpdateCacheFromPrefsOnIO,
+ MOCK_METHOD0(UpdateSpdyCacheFromPrefs, void());
+ MOCK_METHOD0(UpdateSpdyPrefsFromCache, void());
+ MOCK_METHOD2(UpdateSpdyCacheFromPrefsOnIO,
void(std::vector<std::string>* spdy_servers, bool support_spdy));
MOCK_METHOD1(SetSpdyServersInPrefsOnUI,
void(scoped_refptr<RefCountedListValue> spdy_server_list));
+ MOCK_METHOD0(UpdateAlternateProtocolCacheFromPrefs, void());
+ MOCK_METHOD0(UpdateAlternateProtocolPrefsFromCache, void());
+ MOCK_METHOD1(UpdateAlternateProtocolCacheFromPrefsOnIO,
+ void(RefCountedAlternateProtocolMap*));
+ MOCK_METHOD1(SetAlternateProtocolServersInPrefsOnUI,
+ void(RefCountedAlternateProtocolMap*));
+
private:
DISALLOW_COPY_AND_ASSIGN(TestingHttpServerPropertiesManager);
};
@@ -95,8 +109,11 @@ class HttpServerPropertiesManagerTest : public testing::Test {
virtual void SetUp() OVERRIDE {
pref_service_.RegisterListPref(prefs::kSpdyServers);
+ pref_service_.RegisterDictionaryPref(prefs::kAlternateProtocolServers);
http_server_props_manager_.reset(
- new TestingHttpServerPropertiesManager(&pref_service_));
+ new StrictMock<TestingHttpServerPropertiesManager>(&pref_service_));
+ ExpectSpdyCacheUpdate();
+ ExpectAlternateProtocolCacheUpdate();
loop_.RunAllPending();
}
@@ -109,18 +126,38 @@ class HttpServerPropertiesManagerTest : public testing::Test {
http_server_props_manager_.reset();
}
- void ExpectCacheUpdate() {
- EXPECT_CALL(*http_server_props_manager_, UpdateCacheFromPrefs())
+ void ExpectSpdyCacheUpdate() {
+ EXPECT_CALL(*http_server_props_manager_, UpdateSpdyCacheFromPrefs())
+ .WillOnce(
+ Invoke(http_server_props_manager_.get(),
+ &TestingHttpServerPropertiesManager::
+ UpdateSpdyCacheFromPrefsConcrete));
+ }
+
+ void ExpectSpdyPrefsUpdate() {
+ EXPECT_CALL(*http_server_props_manager_, UpdateSpdyPrefsFromCache())
.WillOnce(
Invoke(http_server_props_manager_.get(),
- &TestingHttpServerPropertiesManager::UpdateCacheFromPrefsConcrete));
+ &TestingHttpServerPropertiesManager::
+ UpdateSpdyPrefsFromCacheConcrete));
}
- void ExpectPrefsUpdate() {
- EXPECT_CALL(*http_server_props_manager_, UpdatePrefsFromCache())
+ void ExpectAlternateProtocolCacheUpdate() {
+ EXPECT_CALL(*http_server_props_manager_,
+ UpdateAlternateProtocolCacheFromPrefs())
.WillOnce(
Invoke(http_server_props_manager_.get(),
- &TestingHttpServerPropertiesManager::UpdatePrefsFromCacheConcrete));
+ &TestingHttpServerPropertiesManager::
+ UpdateAlternateProtocolCacheFromPrefsConcrete));
+ }
+
+ void ExpectAlternateProtocolPrefsUpdate() {
+ EXPECT_CALL(*http_server_props_manager_,
+ UpdateAlternateProtocolPrefsFromCache())
+ .WillOnce(
+ Invoke(http_server_props_manager_.get(),
+ &TestingHttpServerPropertiesManager::
+ UpdateAlternateProtocolPrefsFromCacheConcrete));
}
MessageLoop loop_;
@@ -134,23 +171,32 @@ class HttpServerPropertiesManagerTest : public testing::Test {
DISALLOW_COPY_AND_ASSIGN(HttpServerPropertiesManagerTest);
};
-TEST_F(HttpServerPropertiesManagerTest, SingleUpdateForTwoPrefChanges) {
- ExpectCacheUpdate();
+TEST_F(HttpServerPropertiesManagerTest, SingleUpdateForTwoSpdyPrefChanges) {
+ ExpectSpdyCacheUpdate();
- ListValue* http_server_props = new ListValue;
- http_server_props->Append(new StringValue("www.google.com:443"));
- http_server_props->Append(new StringValue("mail.google.com:443"));
+ // Set up the pref and then set it twice. Only expect a single cache update.
+ base::ListValue* http_server_props = new base::ListValue;
+ http_server_props->Append(new base::StringValue("www.google.com:443"));
+ pref_service_.SetManagedPref(prefs::kSpdyServers, http_server_props);
+ http_server_props = http_server_props->DeepCopy();
+ http_server_props->Append(new base::StringValue("mail.google.com:443"));
pref_service_.SetManagedPref(prefs::kSpdyServers, http_server_props);
loop_.RunAllPending();
-
Mock::VerifyAndClearExpectations(http_server_props_manager_.get());
+
+ EXPECT_TRUE(http_server_props_manager_->SupportsSpdy(
+ net::HostPortPair::FromString("www.google.com:443")));
+ EXPECT_TRUE(http_server_props_manager_->SupportsSpdy(
+ net::HostPortPair::FromString("mail.google.com:443")));
+ EXPECT_FALSE(http_server_props_manager_->SupportsSpdy(
+ net::HostPortPair::FromString("foo.google.com:1337")));
}
TEST_F(HttpServerPropertiesManagerTest, SupportsSpdy) {
- ExpectPrefsUpdate();
+ ExpectSpdyPrefsUpdate();
// Post an update task to the IO thread. SetSupportsSpdy calls
- // ScheduleUpdatePrefsOnIO.
+ // ScheduleUpdateSpdyPrefsOnIO.
// Add mail.google.com:443 as a supporting spdy server.
net::HostPortPair spdy_server_mail("mail.google.com", 443);
@@ -164,37 +210,174 @@ TEST_F(HttpServerPropertiesManagerTest, SupportsSpdy) {
Mock::VerifyAndClearExpectations(http_server_props_manager_.get());
}
-TEST_F(HttpServerPropertiesManagerTest, DeleteAll) {
- ExpectPrefsUpdate();
+TEST_F(HttpServerPropertiesManagerTest, Clear) {
+ ExpectSpdyPrefsUpdate();
+ ExpectAlternateProtocolPrefsUpdate();
- // Add mail.google.com:443 as a supporting spdy server.
net::HostPortPair spdy_server_mail("mail.google.com", 443);
http_server_props_manager_->SetSupportsSpdy(spdy_server_mail, true);
+ http_server_props_manager_->SetAlternateProtocol(
+ spdy_server_mail, 443, net::NPN_SPDY_2);
// Run the task.
loop_.RunAllPending();
EXPECT_TRUE(http_server_props_manager_->SupportsSpdy(spdy_server_mail));
+ EXPECT_TRUE(
+ http_server_props_manager_->HasAlternateProtocol(spdy_server_mail));
Mock::VerifyAndClearExpectations(http_server_props_manager_.get());
- // DeleteAll http server data.
- http_server_props_manager_->DeleteAll();
+ ExpectSpdyPrefsUpdate();
+ ExpectAlternateProtocolPrefsUpdate();
+ // Clear http server data.
+ http_server_props_manager_->Clear();
// Run the task.
loop_.RunAllPending();
EXPECT_FALSE(http_server_props_manager_->SupportsSpdy(spdy_server_mail));
+ EXPECT_FALSE(
+ http_server_props_manager_->HasAlternateProtocol(spdy_server_mail));
Mock::VerifyAndClearExpectations(http_server_props_manager_.get());
}
+TEST_F(HttpServerPropertiesManagerTest, ShutdownWithPendingUpdateSpdyCache0) {
+ // Post an update task to the UI thread.
+ http_server_props_manager_->ScheduleUpdateSpdyCacheOnUI();
+ // Shutdown comes before the task is executed.
+ http_server_props_manager_->ShutdownOnUIThread();
+ http_server_props_manager_.reset();
+ // Run the task after shutdown and deletion.
+ loop_.RunAllPending();
+}
+
+TEST_F(HttpServerPropertiesManagerTest, ShutdownWithPendingUpdateSpdyCache1) {
+ // Post an update task.
+ http_server_props_manager_->ScheduleUpdateSpdyCacheOnUI();
+ // Shutdown comes before the task is executed.
+ http_server_props_manager_->ShutdownOnUIThread();
+ // Run the task after shutdown, but before deletion.
+ loop_.RunAllPending();
+ Mock::VerifyAndClearExpectations(http_server_props_manager_.get());
+ http_server_props_manager_.reset();
+ loop_.RunAllPending();
+}
+
+TEST_F(HttpServerPropertiesManagerTest, ShutdownWithPendingUpdateSpdyCache2) {
+ http_server_props_manager_->UpdateSpdyCacheFromPrefsConcrete();
+ // Shutdown comes before the task is executed.
+ http_server_props_manager_->ShutdownOnUIThread();
+ // Run the task after shutdown, but before deletion.
+ loop_.RunAllPending();
+ Mock::VerifyAndClearExpectations(http_server_props_manager_.get());
+ http_server_props_manager_.reset();
+ loop_.RunAllPending();
+}
+
//
-// Tests for shutdown when updating cache.
+// Tests for shutdown when updating prefs.
//
-TEST_F(HttpServerPropertiesManagerTest, ShutdownWithPendingUpdateCache0) {
- EXPECT_CALL(*http_server_props_manager_,
- UpdateCacheFromPrefsOnIO(_, _)).Times(0);
+TEST_F(HttpServerPropertiesManagerTest, ShutdownWithPendingUpdateSpdyPrefs0) {
+ // Post an update task to the IO thread.
+ http_server_props_manager_->ScheduleUpdateSpdyPrefsOnIO();
+ // Shutdown comes before the task is executed.
+ http_server_props_manager_->ShutdownOnUIThread();
+ http_server_props_manager_.reset();
+ // Run the task after shutdown and deletion.
+ loop_.RunAllPending();
+}
+
+TEST_F(HttpServerPropertiesManagerTest, ShutdownWithPendingUpdateSpdyPrefs1) {
+ ExpectSpdyPrefsUpdate();
+ // Post an update task.
+ http_server_props_manager_->ScheduleUpdateSpdyPrefsOnIO();
+ // Shutdown comes before the task is executed.
+ http_server_props_manager_->ShutdownOnUIThread();
+ // Run the task after shutdown, but before deletion.
+ loop_.RunAllPending();
+ Mock::VerifyAndClearExpectations(http_server_props_manager_.get());
+ http_server_props_manager_.reset();
+ loop_.RunAllPending();
+}
+
+TEST_F(HttpServerPropertiesManagerTest, ShutdownWithPendingUpdateSpdyPrefs2) {
+ // This posts a task to the UI thread.
+ http_server_props_manager_->UpdateSpdyPrefsFromCacheConcrete();
+ // Shutdown comes before the task is executed.
+ http_server_props_manager_->ShutdownOnUIThread();
+ // Run the task after shutdown, but before deletion.
+ loop_.RunAllPending();
+ Mock::VerifyAndClearExpectations(http_server_props_manager_.get());
+ http_server_props_manager_.reset();
+ loop_.RunAllPending();
+}
+
+TEST_F(HttpServerPropertiesManagerTest,
+ SingleUpdateForTwoAlternateProtocolPrefChanges) {
+ ExpectAlternateProtocolCacheUpdate();
+
+ // Set up the pref and then set it twice. Only expect a single cache update.
+ base::DictionaryValue* alternate_protocol_servers = new base::DictionaryValue;
+ base::DictionaryValue* alternate_protocol = new base::DictionaryValue;
+ alternate_protocol->SetInteger("port", 443);
+ alternate_protocol->SetInteger("protocol", static_cast<int>(net::NPN_SPDY_1));
+ alternate_protocol_servers->SetWithoutPathExpansion(
+ "www.google.com:80", alternate_protocol);
+ alternate_protocol = new base::DictionaryValue;
+ alternate_protocol->SetInteger("port", 444);
+ alternate_protocol->SetInteger("protocol", static_cast<int>(net::NPN_SPDY_2));
+ alternate_protocol_servers->SetWithoutPathExpansion(
+ "mail.google.com:80", alternate_protocol);
+ pref_service_.SetManagedPref(prefs::kAlternateProtocolServers,
+ alternate_protocol_servers);
+ alternate_protocol_servers = alternate_protocol_servers->DeepCopy();
+ pref_service_.SetManagedPref(prefs::kAlternateProtocolServers,
+ alternate_protocol_servers);
+ loop_.RunAllPending();
+
+ Mock::VerifyAndClearExpectations(http_server_props_manager_.get());
+
+ ASSERT_TRUE(http_server_props_manager_->HasAlternateProtocol(
+ net::HostPortPair::FromString("www.google.com:80")));
+ ASSERT_TRUE(http_server_props_manager_->HasAlternateProtocol(
+ net::HostPortPair::FromString("mail.google.com:80")));
+ net::PortAlternateProtocolPair port_alternate_protocol =
+ http_server_props_manager_->GetAlternateProtocol(
+ net::HostPortPair::FromString("www.google.com:80"));
+ EXPECT_EQ(443, port_alternate_protocol.port);
+ EXPECT_EQ(net::NPN_SPDY_1, port_alternate_protocol.protocol);
+ port_alternate_protocol =
+ http_server_props_manager_->GetAlternateProtocol(
+ net::HostPortPair::FromString("mail.google.com:80"));
+ EXPECT_EQ(444, port_alternate_protocol.port);
+ EXPECT_EQ(net::NPN_SPDY_2, port_alternate_protocol.protocol);
+}
+
+TEST_F(HttpServerPropertiesManagerTest, HasAlternateProtocol) {
+ ExpectAlternateProtocolPrefsUpdate();
+
+ net::HostPortPair spdy_server_mail("mail.google.com", 80);
+ EXPECT_FALSE(
+ http_server_props_manager_->HasAlternateProtocol(spdy_server_mail));
+ http_server_props_manager_->SetAlternateProtocol(
+ spdy_server_mail, 443, net::NPN_SPDY_2);
+
+ // Run the task.
+ loop_.RunAllPending();
+ Mock::VerifyAndClearExpectations(http_server_props_manager_.get());
+
+ ASSERT_TRUE(
+ http_server_props_manager_->HasAlternateProtocol(spdy_server_mail));
+ net::PortAlternateProtocolPair port_alternate_protocol =
+ http_server_props_manager_->GetAlternateProtocol(spdy_server_mail);
+ EXPECT_EQ(443, port_alternate_protocol.port);
+ EXPECT_EQ(net::NPN_SPDY_2, port_alternate_protocol.protocol);
+}
+
+TEST_F(HttpServerPropertiesManagerTest,
+ ShutdownWithPendingUpdateAlternateProtocolCache0) {
// Post an update task to the UI thread.
- http_server_props_manager_->ScheduleUpdateCacheOnUI();
+ http_server_props_manager_->ScheduleUpdateAlternateProtocolCacheOnUI();
// Shutdown comes before the task is executed.
http_server_props_manager_->ShutdownOnUIThread();
http_server_props_manager_.reset();
@@ -202,10 +385,10 @@ TEST_F(HttpServerPropertiesManagerTest, ShutdownWithPendingUpdateCache0) {
loop_.RunAllPending();
}
-TEST_F(HttpServerPropertiesManagerTest, ShutdownWithPendingUpdateCache1) {
- EXPECT_CALL(*http_server_props_manager_, UpdateCacheFromPrefs()).Times(0);
+TEST_F(HttpServerPropertiesManagerTest,
+ ShutdownWithPendingUpdateAlternateProtocolCache1) {
// Post an update task.
- http_server_props_manager_->ScheduleUpdateCacheOnUI();
+ http_server_props_manager_->ScheduleUpdateAlternateProtocolCacheOnUI();
// Shutdown comes before the task is executed.
http_server_props_manager_->ShutdownOnUIThread();
// Run the task after shutdown, but before deletion.
@@ -215,10 +398,9 @@ TEST_F(HttpServerPropertiesManagerTest, ShutdownWithPendingUpdateCache1) {
loop_.RunAllPending();
}
-TEST_F(HttpServerPropertiesManagerTest, ShutdownWithPendingUpdateCache2) {
- EXPECT_CALL(*http_server_props_manager_,
- UpdateCacheFromPrefsOnIO(_, _)).Times(0);
- http_server_props_manager_->UpdateCacheFromPrefsConcrete();
+TEST_F(HttpServerPropertiesManagerTest,
+ ShutdownWithPendingUpdateAlternateProtocolCache2) {
+ http_server_props_manager_->UpdateAlternateProtocolCacheFromPrefsConcrete();
// Shutdown comes before the task is executed.
http_server_props_manager_->ShutdownOnUIThread();
// Run the task after shutdown, but before deletion.
@@ -231,11 +413,10 @@ TEST_F(HttpServerPropertiesManagerTest, ShutdownWithPendingUpdateCache2) {
//
// Tests for shutdown when updating prefs.
//
-TEST_F(HttpServerPropertiesManagerTest, ShutdownWithPendingUpdatePrefs0) {
- EXPECT_CALL(*http_server_props_manager_,
- SetSpdyServersInPrefsOnUI(_)).Times(0);
+TEST_F(HttpServerPropertiesManagerTest,
+ ShutdownWithPendingUpdateAlternateProtocolPrefs0) {
// Post an update task to the IO thread.
- http_server_props_manager_->ScheduleUpdatePrefsOnIO();
+ http_server_props_manager_->ScheduleUpdateAlternateProtocolPrefsOnIO();
// Shutdown comes before the task is executed.
http_server_props_manager_->ShutdownOnUIThread();
http_server_props_manager_.reset();
@@ -243,11 +424,11 @@ TEST_F(HttpServerPropertiesManagerTest, ShutdownWithPendingUpdatePrefs0) {
loop_.RunAllPending();
}
-TEST_F(HttpServerPropertiesManagerTest, ShutdownWithPendingUpdatePrefs1) {
- EXPECT_CALL(*http_server_props_manager_,
- SetSpdyServersInPrefsOnUI(_)).Times(0);
+TEST_F(HttpServerPropertiesManagerTest,
+ ShutdownWithPendingUpdateAlternateProtocolPrefs1) {
+ ExpectAlternateProtocolPrefsUpdate();
// Post an update task.
- http_server_props_manager_->ScheduleUpdatePrefsOnIO();
+ http_server_props_manager_->ScheduleUpdateAlternateProtocolPrefsOnIO();
// Shutdown comes before the task is executed.
http_server_props_manager_->ShutdownOnUIThread();
// Run the task after shutdown, but before deletion.
@@ -257,11 +438,10 @@ TEST_F(HttpServerPropertiesManagerTest, ShutdownWithPendingUpdatePrefs1) {
loop_.RunAllPending();
}
-TEST_F(HttpServerPropertiesManagerTest, ShutdownWithPendingUpdatePrefs2) {
- EXPECT_CALL(*http_server_props_manager_,
- SetSpdyServersInPrefsOnUI(_)).Times(0);
+TEST_F(HttpServerPropertiesManagerTest,
+ ShutdownWithPendingUpdateAlternateProtocolPrefs2) {
// This posts a task to the UI thread.
- http_server_props_manager_->UpdatePrefsFromCacheConcrete();
+ http_server_props_manager_->UpdateAlternateProtocolPrefsFromCacheConcrete();
// Shutdown comes before the task is executed.
http_server_props_manager_->ShutdownOnUIThread();
// Run the task after shutdown, but before deletion.
diff --git a/chrome/browser/profiles/profile_impl_io_data.cc b/chrome/browser/profiles/profile_impl_io_data.cc
index 90f3502..591d77e 100644
--- a/chrome/browser/profiles/profile_impl_io_data.cc
+++ b/chrome/browser/profiles/profile_impl_io_data.cc
@@ -36,7 +36,7 @@ void ClearNetworkingHistorySinceOnIOThread(
ProfileImplIOData* io_data, base::Time time) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO));
io_data->transport_security_state()->DeleteSince(time);
- io_data->http_server_properties()->DeleteAll();
+ io_data->http_server_properties()->Clear();
}
} // namespace
diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc
index ce28238..2b949bd 100644
--- a/chrome/common/pref_names.cc
+++ b/chrome/common/pref_names.cc
@@ -330,6 +330,9 @@ const char kDisableSpdy[] = "spdy.disabled";
// Prefs for server names that support SPDY protocol.
const char kSpdyServers[] = "spdy.servers";
+// Prefs for servers that support Alternate-Protocol.
+const char kAlternateProtocolServers[] = "spdy.alternate_protocol";
+
// Disables the listed protocol schemes.
const char kDisabledSchemes[] = "protocol.disabled_schemes";
diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h
index 16f43bd..00d897a8 100644
--- a/chrome/common/pref_names.h
+++ b/chrome/common/pref_names.h
@@ -129,6 +129,7 @@ extern const char kDnsHostReferralList[]; // OBSOLETE
extern const char kDnsPrefetchingHostReferralList[];
extern const char kDisableSpdy[];
extern const char kSpdyServers[];
+extern const char kAlternateProtocolServers[];
extern const char kDisabledSchemes[];
extern const char kUrlBlacklist[];
extern const char kUrlWhitelist[];
diff --git a/net/base/host_port_pair.cc b/net/base/host_port_pair.cc
index 5164fcf..773c7ee 100644
--- a/net/base/host_port_pair.cc
+++ b/net/base/host_port_pair.cc
@@ -1,9 +1,11 @@
-// Copyright (c) 2010 The Chromium Authors. All rights reserved.
+// Copyright (c) 2011 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 "net/base/host_port_pair.h"
+#include "base/string_number_conversions.h"
+#include "base/string_split.h"
#include "base/string_util.h"
#include "base/stringprintf.h"
#include "googleurl/src/gurl.h"
@@ -27,6 +29,21 @@ HostPortPair HostPortPair::FromAddrInfo(const struct addrinfo* ai) {
GetPortFromSockaddr(ai->ai_addr, ai->ai_addrlen));
}
+HostPortPair HostPortPair::FromString(const std::string& str) {
+ std::vector<std::string> key_port;
+ base::SplitString(str, ':', &key_port);
+ if (key_port.size() != 2)
+ return HostPortPair();
+ int port;
+ if (!base::StringToInt(key_port[1], &port))
+ return HostPortPair();
+ DCHECK_LT(port, 1 << 16);
+ HostPortPair host_port_pair;
+ host_port_pair.set_host(key_port[0]);
+ host_port_pair.set_port(port);
+ return host_port_pair;
+}
+
std::string HostPortPair::ToString() const {
return base::StringPrintf("%s:%u", HostForURL().c_str(), port_);
}
diff --git a/net/base/host_port_pair.h b/net/base/host_port_pair.h
index 7f009a9..ea95356 100644
--- a/net/base/host_port_pair.h
+++ b/net/base/host_port_pair.h
@@ -27,6 +27,10 @@ class NET_EXPORT HostPortPair {
// Creates a HostPortPair from an addrinfo struct.
static HostPortPair FromAddrInfo(const struct addrinfo* ai);
+ // Creates a HostPortPair from a string formatted in same manner as
+ // ToString().
+ static HostPortPair FromString(const std::string& str);
+
// TODO(willchan): Define a functor instead.
// Comparator function so this can be placed in a std::map.
bool operator<(const HostPortPair& other) const {
diff --git a/net/base/host_port_pair_unittest.cc b/net/base/host_port_pair_unittest.cc
new file mode 100644
index 0000000..de059904
--- /dev/null
+++ b/net/base/host_port_pair_unittest.cc
@@ -0,0 +1,23 @@
+// Copyright (c) 2011 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 "net/base/host_port_pair.h"
+
+#include "testing/gtest/include/gtest/gtest.h"
+
+namespace net {
+
+namespace {
+
+TEST(HostPortPairTest, Parsing) {
+ HostPortPair foo("foo.com", 10);
+ std::string foo_str = foo.ToString();
+ EXPECT_EQ("foo.com:10", foo_str);
+ HostPortPair bar = HostPortPair::FromString(foo_str);
+ EXPECT_TRUE(foo.Equals(bar));
+}
+
+} // namespace
+
+} // namespace net
diff --git a/net/http/http_server_properties.h b/net/http/http_server_properties.h
index a026458..06166f7 100644
--- a/net/http/http_server_properties.h
+++ b/net/http/http_server_properties.h
@@ -14,7 +14,7 @@
namespace net {
enum AlternateProtocol {
- NPN_SPDY_1,
+ NPN_SPDY_1 = 0,
NPN_SPDY_2,
NUM_ALTERNATE_PROTOCOLS,
ALTERNATE_PROTOCOL_BROKEN, // The alternate protocol is known to be broken.
@@ -47,7 +47,7 @@ class NET_EXPORT HttpServerProperties {
virtual ~HttpServerProperties() {}
// Deletes all data.
- virtual void DeleteAll() = 0;
+ virtual void Clear() = 0;
// Returns true if |server| supports SPDY.
virtual bool SupportsSpdy(const HostPortPair& server) const = 0;
diff --git a/net/http/http_server_properties_impl.cc b/net/http/http_server_properties_impl.cc
index 1226c9c..3ea973c 100644
--- a/net/http/http_server_properties_impl.cc
+++ b/net/http/http_server_properties_impl.cc
@@ -30,6 +30,19 @@ void HttpServerPropertiesImpl::InitializeSpdyServers(
}
}
+void HttpServerPropertiesImpl::InitializeAlternateProtocolServers(
+ AlternateProtocolMap* alternate_protocol_map) {
+ // First swap, and then add back all the ALTERNATE_PROTOCOL_BROKEN ones since
+ // those don't get persisted.
+ alternate_protocol_map_.swap(*alternate_protocol_map);
+ for (AlternateProtocolMap::const_iterator it =
+ alternate_protocol_map->begin();
+ it != alternate_protocol_map->end(); ++it) {
+ if (it->second.protocol == ALTERNATE_PROTOCOL_BROKEN)
+ alternate_protocol_map_[it->first] = it->second;
+ }
+}
+
void HttpServerPropertiesImpl::GetSpdyServerList(
base::ListValue* spdy_server_list) const {
DCHECK(CalledOnValidThread());
@@ -71,7 +84,7 @@ void HttpServerPropertiesImpl::DisableForcedAlternateProtocol() {
g_forced_alternate_protocol = NULL;
}
-void HttpServerPropertiesImpl::DeleteAll() {
+void HttpServerPropertiesImpl::Clear() {
DCHECK(CalledOnValidThread());
spdy_servers_table_.clear();
alternate_protocol_map_.clear();
diff --git a/net/http/http_server_properties_impl.h b/net/http/http_server_properties_impl.h
index 0bdf1f6..177802f 100644
--- a/net/http/http_server_properties_impl.h
+++ b/net/http/http_server_properties_impl.h
@@ -36,6 +36,9 @@ class NET_EXPORT HttpServerPropertiesImpl
void InitializeSpdyServers(std::vector<std::string>* spdy_servers,
bool support_spdy);
+ void InitializeAlternateProtocolServers(
+ AlternateProtocolMap* alternate_protocol_servers);
+
// Get the list of servers (host/port) that support SPDY.
void GetSpdyServerList(base::ListValue* spdy_server_list) const;
@@ -55,7 +58,7 @@ class NET_EXPORT HttpServerPropertiesImpl
// -----------------------------
// Deletes all data.
- virtual void DeleteAll() OVERRIDE;
+ virtual void Clear() OVERRIDE;
// Returns true if |server| supports SPDY.
virtual bool SupportsSpdy(const HostPortPair& server) const OVERRIDE;
diff --git a/net/http/http_server_properties_impl_unittest.cc b/net/http/http_server_properties_impl_unittest.cc
index 3539ef6..ac5d5fc 100644
--- a/net/http/http_server_properties_impl_unittest.cc
+++ b/net/http/http_server_properties_impl_unittest.cc
@@ -30,7 +30,7 @@ class HttpServerPropertiesImplTest : public testing::Test {
typedef HttpServerPropertiesImplTest SpdyServerPropertiesTest;
-TEST_F(SpdyServerPropertiesTest, InitializeTest) {
+TEST_F(SpdyServerPropertiesTest, Initialize) {
HostPortPair spdy_server_google("www.google.com", 443);
std::string spdy_server_g =
HttpServerPropertiesImpl::GetFlattenedSpdyServer(spdy_server_google);
@@ -88,7 +88,7 @@ TEST_F(SpdyServerPropertiesTest, SupportsSpdyTest) {
EXPECT_TRUE(impl_.SupportsSpdy(spdy_server_docs));
}
-TEST_F(SpdyServerPropertiesTest, SetSupportsSpdyTest) {
+TEST_F(SpdyServerPropertiesTest, SetSupportsSpdy) {
HostPortPair spdy_server_empty("", 443);
impl_.SetSupportsSpdy(spdy_server_empty, true);
EXPECT_FALSE(impl_.SupportsSpdy(spdy_server_empty));
@@ -111,7 +111,7 @@ TEST_F(SpdyServerPropertiesTest, SetSupportsSpdyTest) {
EXPECT_FALSE(impl_.SupportsSpdy(spdy_server_google));
}
-TEST_F(SpdyServerPropertiesTest, DeleteAllTest) {
+TEST_F(SpdyServerPropertiesTest, Clear) {
// Add www.google.com:443 and mail.google.com:443 as supporting SPDY.
HostPortPair spdy_server_google("www.google.com", 443);
impl_.SetSupportsSpdy(spdy_server_google, true);
@@ -121,12 +121,12 @@ TEST_F(SpdyServerPropertiesTest, DeleteAllTest) {
EXPECT_TRUE(impl_.SupportsSpdy(spdy_server_google));
EXPECT_TRUE(impl_.SupportsSpdy(spdy_server_mail));
- impl_.DeleteAll();
+ impl_.Clear();
EXPECT_FALSE(impl_.SupportsSpdy(spdy_server_google));
EXPECT_FALSE(impl_.SupportsSpdy(spdy_server_mail));
}
-TEST_F(SpdyServerPropertiesTest, GetSpdyServerListTest) {
+TEST_F(SpdyServerPropertiesTest, GetSpdyServerList) {
base::ListValue spdy_server_list;
// Check there are no spdy_servers.
@@ -197,6 +197,34 @@ TEST_F(AlternateProtocolServerPropertiesTest, Basic) {
impl_.GetAlternateProtocol(test_host_port_pair);
EXPECT_EQ(443, alternate.port);
EXPECT_EQ(NPN_SPDY_1, alternate.protocol);
+
+ impl_.Clear();
+ EXPECT_FALSE(impl_.HasAlternateProtocol(test_host_port_pair));
+}
+
+TEST_F(AlternateProtocolServerPropertiesTest, Initialize) {
+ HostPortPair test_host_port_pair1("foo1", 80);
+ impl_.SetBrokenAlternateProtocol(test_host_port_pair1);
+ HostPortPair test_host_port_pair2("foo2", 80);
+ impl_.SetAlternateProtocol(
+ test_host_port_pair2, 443, NPN_SPDY_1);
+
+ AlternateProtocolMap alternate_protocol_map;
+ PortAlternateProtocolPair port_alternate_protocol_pair;
+ port_alternate_protocol_pair.port = 123;
+ port_alternate_protocol_pair.protocol = NPN_SPDY_2;
+ alternate_protocol_map[test_host_port_pair2] = port_alternate_protocol_pair;
+ impl_.InitializeAlternateProtocolServers(&alternate_protocol_map);
+
+ ASSERT_TRUE(impl_.HasAlternateProtocol(test_host_port_pair1));
+ ASSERT_TRUE(impl_.HasAlternateProtocol(test_host_port_pair2));
+ port_alternate_protocol_pair =
+ impl_.GetAlternateProtocol(test_host_port_pair1);
+ EXPECT_EQ(ALTERNATE_PROTOCOL_BROKEN, port_alternate_protocol_pair.protocol);
+ port_alternate_protocol_pair =
+ impl_.GetAlternateProtocol(test_host_port_pair2);
+ EXPECT_EQ(123, port_alternate_protocol_pair.port);
+ EXPECT_EQ(NPN_SPDY_2, port_alternate_protocol_pair.protocol);
}
TEST_F(AlternateProtocolServerPropertiesTest, SetBroken) {
diff --git a/net/net.gyp b/net/net.gyp
index 9021035..6bc9340 100644
--- a/net/net.gyp
+++ b/net/net.gyp
@@ -942,6 +942,7 @@
'base/gzip_filter_unittest.cc',
'base/host_cache_unittest.cc',
'base/host_mapping_rules_unittest.cc',
+ 'base/host_port_pair_unittest.cc',
'base/host_resolver_impl_unittest.cc',
'base/ip_endpoint_unittest.cc',
'base/keygen_handler_unittest.cc',