diff options
author | rtenneti@chromium.org <rtenneti@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-11-15 19:20:31 +0000 |
---|---|---|
committer | rtenneti@chromium.org <rtenneti@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-11-15 19:20:31 +0000 |
commit | 53bfa31ccee6580c7e79d9024721817a07227801 (patch) | |
tree | 376c45efc814c8f31236a581eab56cb44fb4abb4 | |
parent | 2753d493f7fa77bf376eaca4a922596424d8a896 (diff) | |
download | chromium_src-53bfa31ccee6580c7e79d9024721817a07227801.zip chromium_src-53bfa31ccee6580c7e79d9024721817a07227801.tar.gz chromium_src-53bfa31ccee6580c7e79d9024721817a07227801.tar.bz2 |
Persist dynamically learned SPDY settings (like CWND).
BUG=70652
R=willchan
TEST=network unittests, browser unit tests
Review URL: http://codereview.chromium.org/8423028
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@110143 0039d316-1c4b-4281-b951-d872f2087c98
20 files changed, 889 insertions, 587 deletions
diff --git a/chrome/browser/net/http_server_properties_manager.cc b/chrome/browser/net/http_server_properties_manager.cc index f36b5e3..dad1876 100644 --- a/chrome/browser/net/http_server_properties_manager.cc +++ b/chrome/browser/net/http_server_properties_manager.cc @@ -19,36 +19,18 @@ namespace chrome_browser_net { namespace { -// Time to wait before starting an update the spdy_servers_table_ cache from -// preferences. Scheduling another update during this period will reset the +// Time to wait before starting an update the http_server_properties_impl_ cache +// from preferences. Scheduling another update during this period will reset the // timer. const int64 kUpdateCacheDelayMs = 1000; // Time to wait before starting an update the preferences from the -// spdy_servers cache. Scheduling another update during this period will -// reset the timer. +// http_server_properties_impl_ cache. Scheduling another update during this +// period will reset the timer. const int64 kUpdatePrefsDelayMs = 5000; typedef std::vector<std::string> StringVector; -// String is host/port pair of spdy server. -StringVector* ListValueToStringVector(const base::ListValue* list) { - StringVector* vector = new StringVector; - - if (!list) - return vector; - - vector->reserve(list->GetSize()); - std::string s; - for (base::ListValue::const_iterator it = list->begin(); - it != list->end(); ++it) { - if ((*it)->GetAsString(&s)) - vector->push_back(s); - } - - return vector; -} - } // namespace //////////////////////////////////////////////////////////////////////////////// @@ -57,20 +39,16 @@ StringVector* ListValueToStringVector(const base::ListValue* list) { HttpServerPropertiesManager::HttpServerPropertiesManager( PrefService* pref_service) : pref_service_(pref_service), - setting_spdy_servers_(false), - setting_alternate_protocol_servers_(false) { + setting_prefs_(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( + ui_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); + pref_change_registrar_.Add(prefs::kHttpServerProperties, this); } HttpServerPropertiesManager::~HttpServerPropertiesManager() { @@ -80,37 +58,27 @@ void HttpServerPropertiesManager::InitializeOnIOThread() { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); http_server_properties_impl_.reset(new net::HttpServerPropertiesImpl()); - io_spdy_prefs_update_timer_.reset( - new base::OneShotTimer<HttpServerPropertiesManager>); - io_alternate_protocol_prefs_update_timer_.reset( + io_prefs_update_timer_.reset( new base::OneShotTimer<HttpServerPropertiesManager>); BrowserThread::PostTask( BrowserThread::UI, FROM_HERE, - base::Bind(&HttpServerPropertiesManager::UpdateSpdyCacheFromPrefs, + base::Bind(&HttpServerPropertiesManager::UpdateCacheFromPrefsOnUI, 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_spdy_cache_update_timer_->Stop(); - ui_alternate_protocol_cache_update_timer_->Stop(); + ui_cache_update_timer_->Stop(); ui_weak_ptr_factory_.reset(); pref_change_registrar_.RemoveAll(); } // static void HttpServerPropertiesManager::RegisterPrefs(PrefService* prefs) { - prefs->RegisterListPref(prefs::kSpdyServers, PrefService::UNSYNCABLE_PREF); - prefs->RegisterDictionaryPref(prefs::kAlternateProtocolServers, + prefs->RegisterDictionaryPref(prefs::kHttpServerProperties, PrefService::UNSYNCABLE_PREF); } @@ -118,8 +86,7 @@ void HttpServerPropertiesManager::Clear() { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); http_server_properties_impl_->Clear(); - ScheduleUpdateSpdyPrefsOnIO(); - ScheduleUpdateAlternateProtocolPrefsOnIO(); + ScheduleUpdatePrefsOnIO(); } bool HttpServerPropertiesManager::SupportsSpdy( @@ -134,7 +101,7 @@ void HttpServerPropertiesManager::SetSupportsSpdy( DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); http_server_properties_impl_->SetSupportsSpdy(server, support_spdy); - ScheduleUpdateSpdyPrefsOnIO(); + ScheduleUpdatePrefsOnIO(); } bool HttpServerPropertiesManager::HasAlternateProtocol( @@ -157,14 +124,14 @@ void HttpServerPropertiesManager::SetAlternateProtocol( DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); http_server_properties_impl_->SetAlternateProtocol( server, alternate_port, alternate_protocol); - ScheduleUpdateAlternateProtocolPrefsOnIO(); + ScheduleUpdatePrefsOnIO(); } void HttpServerPropertiesManager::SetBrokenAlternateProtocol( const net::HostPortPair& server) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); http_server_properties_impl_->SetBrokenAlternateProtocol(server); - ScheduleUpdateAlternateProtocolPrefsOnIO(); + ScheduleUpdatePrefsOnIO(); } const net::AlternateProtocolMap& @@ -173,254 +140,392 @@ HttpServerPropertiesManager::alternate_protocol_map() const { return http_server_properties_impl_->alternate_protocol_map(); } -// -// Update spdy_servers (the cached data) with data from preferences. -// -void HttpServerPropertiesManager::ScheduleUpdateSpdyCacheOnUI() { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - // Cancel pending updates, if any. - ui_spdy_cache_update_timer_->Stop(); - StartSpdyCacheUpdateTimerOnUI( - base::TimeDelta::FromMilliseconds(kUpdateCacheDelayMs)); -} - -void HttpServerPropertiesManager::UpdateSpdyCacheFromPrefs() { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - - if (!pref_service_->HasPrefPath(prefs::kSpdyServers)) - return; - - // The preferences can only be read on the UI thread. - StringVector* spdy_servers = - ListValueToStringVector(pref_service_->GetList(prefs::kSpdyServers)); - - BrowserThread::PostTask( - BrowserThread::IO, - FROM_HERE, - base::Bind(&HttpServerPropertiesManager::UpdateSpdyCacheFromPrefsOnIO, - base::Unretained(this), spdy_servers, true)); +const spdy::SpdySettings& +HttpServerPropertiesManager::GetSpdySettings( + const net::HostPortPair& host_port_pair) const { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + return http_server_properties_impl_->GetSpdySettings(host_port_pair); } -void HttpServerPropertiesManager::UpdateSpdyCacheFromPrefsOnIO( - StringVector* spdy_servers, - bool support_spdy) { +// Saves settings for a host. +bool HttpServerPropertiesManager::SetSpdySettings( + const net::HostPortPair& host_port_pair, + const spdy::SpdySettings& settings) { 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. - scoped_ptr<StringVector> scoped_spdy_servers(spdy_servers); - http_server_properties_impl_->InitializeSpdyServers(spdy_servers, - support_spdy); + bool persist = http_server_properties_impl_->SetSpdySettings( + host_port_pair, settings); + if (persist) + ScheduleUpdatePrefsOnIO(); + return persist; } -// -// Update Preferences with data from spdy_servers (the cached data). -// -void HttpServerPropertiesManager::ScheduleUpdateSpdyPrefsOnIO() { +void HttpServerPropertiesManager::ClearSpdySettings() { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - // Cancel pending updates, if any. - io_spdy_prefs_update_timer_->Stop(); - StartSpdyPrefsUpdateTimerOnIO( - base::TimeDelta::FromMilliseconds(kUpdatePrefsDelayMs)); + http_server_properties_impl_->ClearSpdySettings(); + ScheduleUpdatePrefsOnIO(); } -void HttpServerPropertiesManager::UpdateSpdyPrefsFromCache() { +const net::SpdySettingsMap& +HttpServerPropertiesManager::spdy_settings_map() const { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - - scoped_refptr<RefCountedListValue> spdy_server_list = - new RefCountedListValue(); - http_server_properties_impl_->GetSpdyServerList(&spdy_server_list->data); - - // Update the preferences on the UI thread. - BrowserThread::PostTask( - BrowserThread::UI, - FROM_HERE, - base::Bind(&HttpServerPropertiesManager::SetSpdyServersInPrefsOnUI, - ui_weak_ptr_, spdy_server_list)); + return http_server_properties_impl_->spdy_settings_map(); } -void HttpServerPropertiesManager::SetSpdyServersInPrefsOnUI( - scoped_refptr<RefCountedListValue> spdy_server_list) { +// +// Update the HttpServerPropertiesImpl's cache with data from preferences. +// +void HttpServerPropertiesManager::ScheduleUpdateCacheOnUI() { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - setting_spdy_servers_ = true; - pref_service_->Set(prefs::kSpdyServers, spdy_server_list->data); - setting_spdy_servers_ = false; + // Cancel pending updates, if any. + ui_cache_update_timer_->Stop(); + StartCacheUpdateTimerOnUI( + base::TimeDelta::FromMilliseconds(kUpdateCacheDelayMs)); } -void HttpServerPropertiesManager::ScheduleUpdateAlternateProtocolCacheOnUI() { +void HttpServerPropertiesManager::StartCacheUpdateTimerOnUI( + base::TimeDelta delay) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - // Cancel pending updates, if any. - ui_alternate_protocol_cache_update_timer_->Stop(); - StartAlternateProtocolCacheUpdateTimerOnUI( - base::TimeDelta::FromMilliseconds(kUpdateCacheDelayMs)); + ui_cache_update_timer_->Start( + FROM_HERE, delay, this, + &HttpServerPropertiesManager::UpdateCacheFromPrefsOnUI); } -void HttpServerPropertiesManager::UpdateAlternateProtocolCacheFromPrefs() { +void HttpServerPropertiesManager::UpdateCacheFromPrefsOnUI() { + // The preferences can only be read on the UI thread. DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - if (!pref_service_->HasPrefPath(prefs::kAlternateProtocolServers)) + if (!pref_service_->HasPrefPath(prefs::kHttpServerProperties)) return; + // String is host/port pair of spdy server. + StringVector* spdy_servers = new StringVector; + + // Parse the preferences into a SpdySettingsMap. + net::SpdySettingsMap* spdy_settings_map = new net::SpdySettingsMap; + // Parse the preferences into a AlternateProtocolMap. - net::AlternateProtocolMap alternate_protocol_map; - const base::DictionaryValue& alternate_protocol_servers = - *pref_service_->GetDictionary(prefs::kAlternateProtocolServers); + net::AlternateProtocolMap* alternate_protocol_map = + new net::AlternateProtocolMap; + + const base::DictionaryValue& http_server_properties_dict = + *pref_service_->GetDictionary(prefs::kHttpServerProperties); for (base::DictionaryValue::key_iterator it = - alternate_protocol_servers.begin_keys(); - it != alternate_protocol_servers.end_keys(); ++it) { + http_server_properties_dict.begin_keys(); + it != http_server_properties_dict.end_keys(); ++it) { + // Get server's host/pair. 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; + DVLOG(1) << "Malformed http_server_properties for 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; + base::DictionaryValue* server_pref_dict = NULL; + if (!http_server_properties_dict.GetDictionaryWithoutPathExpansion( + server_str, &server_pref_dict)) { + DVLOG(1) << "Malformed http_server_properties 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; + // Get if server supports Spdy. + bool supports_spdy = false; + if ((server_pref_dict->GetBoolean( + "supports_spdy", &supports_spdy)) && supports_spdy) { + spdy_servers->push_back(server_str); } - 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; + + // Get SpdySettings. + DCHECK(!ContainsKey(*spdy_settings_map, server)); + base::ListValue* spdy_settings_list = NULL; + if (server_pref_dict->GetListWithoutPathExpansion( + "settings", &spdy_settings_list)) { + spdy::SpdySettings spdy_settings; + + for (base::ListValue::const_iterator list_it = + spdy_settings_list->begin(); + list_it != spdy_settings_list->end(); ++list_it) { + if ((*list_it)->GetType() != Value::TYPE_DICTIONARY) { + DVLOG(1) << "Malformed SpdySettingsList for server: " << server_str; + NOTREACHED(); + continue; + } + + const base::DictionaryValue* spdy_setting_dict = + static_cast<const base::DictionaryValue*>(*list_it); + + int id = 0; + if (!spdy_setting_dict->GetIntegerWithoutPathExpansion("id", &id)) { + DVLOG(1) << "Malformed id in SpdySettings for server: " << server_str; + NOTREACHED(); + continue; + } + + int value = 0; + if (!spdy_setting_dict->GetIntegerWithoutPathExpansion("value", + &value)) { + DVLOG(1) << "Malformed value in SpdySettings for server: " << + server_str; + NOTREACHED(); + continue; + } + + spdy::SettingsFlagsAndId flags_and_id(0); + flags_and_id.set_id(id); + flags_and_id.set_flags(spdy::SETTINGS_FLAG_PERSISTED); + + spdy_settings.push_back(spdy::SpdySetting(flags_and_id, value)); + } + + (*spdy_settings_map)[server] = spdy_settings; } - net::PortAlternateProtocolPair port_alternate_protocol; - port_alternate_protocol.port = port; - port_alternate_protocol.protocol = static_cast<net::AlternateProtocol>( - protocol); + // Get alternate_protocol server. + DCHECK(!ContainsKey(*alternate_protocol_map, server)); + base::DictionaryValue* port_alternate_protocol_dict = NULL; + if (!server_pref_dict->GetDictionaryWithoutPathExpansion( + "alternate_protocol", &port_alternate_protocol_dict)) { + continue; + } - alternate_protocol_map[server] = port_alternate_protocol; + do { + int port = 0; + if (!port_alternate_protocol_dict->GetIntegerWithoutPathExpansion( + "port", &port) || (port > (1 << 16))) { + DVLOG(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)) { + DVLOG(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; + } while (false); } - 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)); + UpdateCacheFromPrefsOnIO, + base::Unretained(this), + base::Owned(spdy_servers), + base::Owned(spdy_settings_map), + base::Owned(alternate_protocol_map))); } -void HttpServerPropertiesManager::UpdateAlternateProtocolCacheFromPrefsOnIO( - RefCountedAlternateProtocolMap* alternate_protocol_map) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); +void HttpServerPropertiesManager::UpdateCacheFromPrefsOnIO( + StringVector* spdy_servers, + net::SpdySettingsMap* spdy_settings_map, + net::AlternateProtocolMap* alternate_protocol_map) { // 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. Update the cached data with new data from preferences. + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + + http_server_properties_impl_->InitializeSpdyServers(spdy_servers, true); + + // Clear the cached data and use the new spdy_settings from preferences. + http_server_properties_impl_->InitializeSpdySettingsServers( + spdy_settings_map); + + // Clear the cached data and use the new Alternate-Protocol server list from // preferences. http_server_properties_impl_->InitializeAlternateProtocolServers( - &alternate_protocol_map->data); + alternate_protocol_map); } + // -// Update Preferences with data from alternate_protocol_servers (the cached -// data). +// Update Preferences with data from the cached data. // -void HttpServerPropertiesManager::ScheduleUpdateAlternateProtocolPrefsOnIO() { +void HttpServerPropertiesManager::ScheduleUpdatePrefsOnIO() { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); // Cancel pending updates, if any. - io_alternate_protocol_prefs_update_timer_->Stop(); - StartAlternateProtocolPrefsUpdateTimerOnIO( + io_prefs_update_timer_->Stop(); + StartPrefsUpdateTimerOnIO( base::TimeDelta::FromMilliseconds(kUpdatePrefsDelayMs)); } -void HttpServerPropertiesManager::UpdateAlternateProtocolPrefsFromCache() { +void HttpServerPropertiesManager::StartPrefsUpdateTimerOnIO( + base::TimeDelta delay) { + DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); + // This is overridden in tests to post the task without the delay. + io_prefs_update_timer_->Start( + FROM_HERE, delay, this, + &HttpServerPropertiesManager::UpdatePrefsFromCacheOnIO); +} + +void HttpServerPropertiesManager::UpdatePrefsFromCacheOnIO() { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); - scoped_refptr<RefCountedAlternateProtocolMap> alternate_protocol_map = - new RefCountedAlternateProtocolMap; - alternate_protocol_map->data = + base::ListValue* spdy_server_list = new base::ListValue; + http_server_properties_impl_->GetSpdyServerList(spdy_server_list); + + net::SpdySettingsMap* spdy_settings_map = new net::SpdySettingsMap; + *spdy_settings_map = http_server_properties_impl_->spdy_settings_map(); + + net::AlternateProtocolMap* alternate_protocol_map = + new net::AlternateProtocolMap; + *alternate_protocol_map = 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)); + base::Bind(&HttpServerPropertiesManager::UpdatePrefsOnUI, + ui_weak_ptr_, + base::Owned(spdy_server_list), + base::Owned(spdy_settings_map), + base::Owned(alternate_protocol_map))); } -void HttpServerPropertiesManager::SetAlternateProtocolServersInPrefsOnUI( - RefCountedAlternateProtocolMap* alternate_protocol_map) { +// A local or temporary data structure to hold supports_spdy, SpdySettings and +// PortAlternateProtocolPair preferences for a server. This is used only in +// UpdatePrefsOnUI. +struct ServerPref { + ServerPref() + : supports_spdy(false), + settings(NULL), + alternate_protocol(NULL) { + } + ServerPref(bool supports_spdy, + const spdy::SpdySettings* settings, + const net::PortAlternateProtocolPair* alternate_protocol) + : supports_spdy(supports_spdy), + settings(settings), + alternate_protocol(alternate_protocol) { + } + bool supports_spdy; + const spdy::SpdySettings* settings; + const net::PortAlternateProtocolPair* alternate_protocol; +}; + +void HttpServerPropertiesManager::UpdatePrefsOnUI( + base::ListValue* spdy_server_list, + net::SpdySettingsMap* spdy_settings_map, + net::AlternateProtocolMap* alternate_protocol_map) { + + typedef std::map<net::HostPortPair, ServerPref> ServerPrefMap; + ServerPrefMap server_pref_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; + + // 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)) { + net::HostPortPair server = net::HostPortPair::FromString(s); + + ServerPrefMap::iterator it = server_pref_map.find(server); + if (it == server_pref_map.end()) { + ServerPref server_pref(true, NULL, NULL); + server_pref_map[server] = server_pref; + } else { + it->second.supports_spdy = true; + } + } + } + + // Add servers that have SpdySettings to server_pref_map. + for (net::SpdySettingsMap::iterator map_it = + spdy_settings_map->begin(); + map_it != spdy_settings_map->end(); ++map_it) { + const net::HostPortPair& server = map_it->first; + + ServerPrefMap::iterator it = server_pref_map.find(server); + if (it == server_pref_map.end()) { + ServerPref server_pref(false, &map_it->second, NULL); + server_pref_map[server] = server_pref; + } else { + it->second.settings = &map_it->second; + } + } + + // Add AlternateProtocol servers to server_pref_map. + for (net::AlternateProtocolMap::const_iterator map_it = + alternate_protocol_map->begin(); + map_it != alternate_protocol_map->end(); ++map_it) { + const net::HostPortPair& server = map_it->first; const net::PortAlternateProtocolPair& port_alternate_protocol = - it->second; + map_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); -} + ServerPrefMap::iterator it = server_pref_map.find(server); + if (it == server_pref_map.end()) { + ServerPref server_pref(false, NULL, &map_it->second); + server_pref_map[server] = server_pref; + } else { + it->second.alternate_protocol = &map_it->second; + } + } -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); -} + // Persist the prefs::kHttpServerProperties. + base::DictionaryValue http_server_properties_dict; + for (ServerPrefMap::const_iterator map_it = + server_pref_map.begin(); + map_it != server_pref_map.end(); ++map_it) { + const net::HostPortPair& server = map_it->first; + const ServerPref& server_pref = map_it->second; + + base::DictionaryValue* server_pref_dict = new base::DictionaryValue; + + // Save supports_spdy. + server_pref_dict->SetBoolean("supports_spdy", server_pref.supports_spdy); + + // Save SpdySettings. + if (server_pref.settings) { + base::ListValue* spdy_settings_list = new ListValue(); + for (spdy::SpdySettings::const_iterator it = + server_pref.settings->begin(); + it != server_pref.settings->end(); ++it) { + uint32 id = it->first.id(); + uint32 value = it->second; + base::DictionaryValue* spdy_setting_dict = new base::DictionaryValue; + spdy_setting_dict->SetInteger("id", id); + spdy_setting_dict->SetInteger("value", value); + spdy_settings_list->Append(spdy_setting_dict); + } + server_pref_dict->Set("settings", spdy_settings_list); + } -void HttpServerPropertiesManager::StartAlternateProtocolCacheUpdateTimerOnUI( - base::TimeDelta delay) { - DCHECK(BrowserThread::CurrentlyOn(BrowserThread::UI)); - ui_alternate_protocol_cache_update_timer_->Start( - FROM_HERE, delay, this, - &HttpServerPropertiesManager::UpdateAlternateProtocolCacheFromPrefs); -} + // Save alternate_protocol. + if (server_pref.alternate_protocol) { + base::DictionaryValue* port_alternate_protocol_dict = + new base::DictionaryValue; + const net::PortAlternateProtocolPair* port_alternate_protocol = + server_pref.alternate_protocol; + port_alternate_protocol_dict->SetInteger( + "port", port_alternate_protocol->port); + port_alternate_protocol_dict->SetInteger( + "protocol", port_alternate_protocol->protocol); + server_pref_dict->SetWithoutPathExpansion( + "alternate_protocol", port_alternate_protocol_dict); + } + http_server_properties_dict.SetWithoutPathExpansion( + server.ToString(), server_pref_dict); + } -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); + setting_prefs_ = true; + pref_service_->Set(prefs::kHttpServerProperties, + http_server_properties_dict); + setting_prefs_ = false; } void HttpServerPropertiesManager::Observe( @@ -432,12 +537,9 @@ void HttpServerPropertiesManager::Observe( PrefService* prefs = content::Source<PrefService>(source).ptr(); DCHECK(prefs == pref_service_); std::string* pref_name = content::Details<std::string>(details).ptr(); - if (*pref_name == prefs::kSpdyServers) { - if (!setting_spdy_servers_) - ScheduleUpdateSpdyCacheOnUI(); - } else if (*pref_name == prefs::kAlternateProtocolServers) { - if (!setting_alternate_protocol_servers_) - ScheduleUpdateAlternateProtocolCacheOnUI(); + if (*pref_name == prefs::kHttpServerProperties) { + if (!setting_prefs_) + ScheduleUpdateCacheOnUI(); } else { NOTREACHED(); } diff --git a/chrome/browser/net/http_server_properties_manager.h b/chrome/browser/net/http_server_properties_manager.h index a505de5..fa8e526 100644 --- a/chrome/browser/net/http_server_properties_manager.h +++ b/chrome/browser/net/http_server_properties_manager.h @@ -10,7 +10,6 @@ #include <vector> #include "base/basictypes.h" #include "base/compiler_specific.h" -#include "base/memory/ref_counted.h" #include "base/memory/scoped_ptr.h" #include "base/memory/weak_ptr.h" #include "base/timer.h" @@ -107,83 +106,68 @@ class HttpServerPropertiesManager virtual const net::AlternateProtocolMap& alternate_protocol_map() const OVERRIDE; - 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 ScheduleUpdateSpdyCacheOnUI(); + // Gets a reference to the SpdySettings stored for a host. + // If no settings are stored, returns an empty set of settings. + virtual const spdy::SpdySettings& GetSpdySettings( + const net::HostPortPair& host_port_pair) const OVERRIDE; - // Update spdy servers (the cached data in |http_server_properties_impl_|) - // with data from preferences. Virtual for testing. - virtual void UpdateSpdyCacheFromPrefs(); + // Saves settings for a host. Returns true if SpdySettings are persisted. + virtual bool SetSpdySettings( + const net::HostPortPair& host_port_pair, + const spdy::SpdySettings& settings) OVERRIDE; - // Starts the |spdy_servers| update on the IO thread. Protected for testing. - void UpdateSpdyCacheFromPrefsOnIO(std::vector<std::string>* spdy_servers, - bool support_spdy); + // Clears all spdy_settings. + virtual void ClearSpdySettings() OVERRIDE; - // These are used to delay updating the preferences when spdy servers_ are - // changing, and execute only one update per simultaneous spdy server changes. - void ScheduleUpdateSpdyPrefsOnIO(); + // Returns all SpdySettings mappings. + virtual const net::SpdySettingsMap& spdy_settings_map() const OVERRIDE; - // Update spdy servers in preferences with the cached data from - // |http_server_properties_impl_|. 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); - - // 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 + protected: + // -------------------- + // SPDY related methods - // These are used to delay updating the Alternate-Protocol servers in + // These are used to delay updating of the cached data 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. + void ScheduleUpdateCacheOnUI(); - // 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 + // Starts the timers to update the cached prefs. This are overridden in tests // to prevent the delay. - virtual void StartAlternateProtocolCacheUpdateTimerOnUI( - base::TimeDelta delay); - virtual void StartAlternateProtocolPrefsUpdateTimerOnIO( - base::TimeDelta delay); + virtual void StartCacheUpdateTimerOnUI(base::TimeDelta delay); + + // Update cached prefs in |http_server_properties_impl_| with data from + // preferences. It gets the data on UI thread and calls + // UpdateSpdyServersFromPrefsOnIO() to perform the update on IO thread. + virtual void UpdateCacheFromPrefsOnUI(); + + // Starts the update of cached prefs in |http_server_properties_impl_| on the + // IO thread. Protected for testing. + void UpdateCacheFromPrefsOnIO( + std::vector<std::string>* spdy_servers, + net::SpdySettingsMap* spdy_settings_map, + net::AlternateProtocolMap* alternate_protocol_map); + + // These are used to delay updating the preferences when cached data in + // |http_server_properties_impl_| is changing, and execute only one update per + // simultaneous spdy_servers or spdy_settings or alternate_protocol changes. + void ScheduleUpdatePrefsOnIO(); + + // Starts the timers to update the prefs from cache. This are overridden in + // tests to prevent the delay. + virtual void StartPrefsUpdateTimerOnIO(base::TimeDelta delay); + + // Update prefs::kHttpServerProperties in preferences with the cached data + // from |http_server_properties_impl_|. This gets the data on IO thread and + // posts a task (UpdatePrefsOnUI) to update the preferences UI thread. + // Virtual for testing. + virtual void UpdatePrefsFromCacheOnIO(); + + // Update prefs::kHttpServerProperties preferences on UI thread. Protected for + // testing. + void UpdatePrefsOnUI( + base::ListValue* spdy_server_list, + net::SpdySettingsMap* spdy_settings_map, + net::AlternateProtocolMap* alternate_protocol_map); private: // Callback for preference changes. @@ -201,31 +185,22 @@ class HttpServerPropertiesManager 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. + // Used to post cache update tasks. scoped_ptr<base::OneShotTimer<HttpServerPropertiesManager> > - ui_alternate_protocol_cache_update_timer_; + ui_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_; + bool setting_prefs_; // --------- // IO thread // --------- - // 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. + // Used to post |prefs::kHttpServerProperties| pref update tasks. scoped_ptr<base::OneShotTimer<HttpServerPropertiesManager> > - io_alternate_protocol_prefs_update_timer_; + io_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 23fe26d..98cb86b 100644 --- a/chrome/browser/net/http_server_properties_manager_unittest.cc +++ b/chrome/browser/net/http_server_properties_manager_unittest.cc @@ -34,67 +34,40 @@ class TestingHttpServerPropertiesManager : public HttpServerPropertiesManager { virtual ~TestingHttpServerPropertiesManager() { } - // Make these method public for testing. - using HttpServerPropertiesManager::ScheduleUpdateSpdyCacheOnUI; - using HttpServerPropertiesManager::ScheduleUpdateSpdyPrefsOnIO; - using HttpServerPropertiesManager::ScheduleUpdateAlternateProtocolCacheOnUI; - using HttpServerPropertiesManager::ScheduleUpdateAlternateProtocolPrefsOnIO; + // Make these methods public for testing. + using HttpServerPropertiesManager::ScheduleUpdateCacheOnUI; + using HttpServerPropertiesManager::ScheduleUpdatePrefsOnIO; // Post tasks without a delay during tests. - virtual void StartSpdyPrefsUpdateTimerOnIO(base::TimeDelta delay) OVERRIDE { - HttpServerPropertiesManager::StartSpdyPrefsUpdateTimerOnIO( + virtual void StartPrefsUpdateTimerOnIO(base::TimeDelta delay) OVERRIDE { + HttpServerPropertiesManager::StartPrefsUpdateTimerOnIO( base::TimeDelta()); } - // Post tasks without a delay during tests. - virtual void StartAlternateProtocolPrefsUpdateTimerOnIO( - base::TimeDelta delay) OVERRIDE { - HttpServerPropertiesManager::StartAlternateProtocolPrefsUpdateTimerOnIO( - base::TimeDelta()); - } - - void UpdateSpdyCacheFromPrefsConcrete() { - HttpServerPropertiesManager::UpdateSpdyCacheFromPrefs(); - } - - void UpdateAlternateProtocolCacheFromPrefsConcrete() { - HttpServerPropertiesManager::UpdateAlternateProtocolCacheFromPrefs(); + void UpdateCacheFromPrefsOnUIConcrete() { + HttpServerPropertiesManager::UpdateCacheFromPrefsOnUI(); } // Post tasks without a delay during tests. - virtual void StartSpdyCacheUpdateTimerOnUI(base::TimeDelta delay) OVERRIDE { - HttpServerPropertiesManager::StartSpdyCacheUpdateTimerOnUI( + virtual void StartCacheUpdateTimerOnUI(base::TimeDelta delay) OVERRIDE { + HttpServerPropertiesManager::StartCacheUpdateTimerOnUI( base::TimeDelta()); } - // Post tasks without a delay during tests. - virtual void StartAlternateProtocolCacheUpdateTimerOnUI( - base::TimeDelta delay) OVERRIDE { - HttpServerPropertiesManager::StartAlternateProtocolCacheUpdateTimerOnUI( - base::TimeDelta()); - } - - void UpdateSpdyPrefsFromCacheConcrete() { - HttpServerPropertiesManager::UpdateSpdyPrefsFromCache(); - } - - void UpdateAlternateProtocolPrefsFromCacheConcrete() { - HttpServerPropertiesManager::UpdateAlternateProtocolPrefsFromCache(); + void UpdatePrefsFromCacheOnIOConcrete() { + HttpServerPropertiesManager::UpdatePrefsFromCacheOnIO(); } - 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*)); + MOCK_METHOD0(UpdateCacheFromPrefsOnUI, void()); + MOCK_METHOD0(UpdatePrefsFromCacheOnIO, void()); + MOCK_METHOD3(UpdateCacheFromPrefsOnIO, + void(std::vector<std::string>* spdy_servers, + net::SpdySettingsMap* spdy_settings_map, + net::AlternateProtocolMap* alternate_protocol_map)); + MOCK_METHOD3(UpdatePrefsOnUI, + void(base::ListValue* spdy_server_list, + net::SpdySettingsMap* spdy_settings_map, + net::AlternateProtocolMap* alternate_protocol_map)); private: DISALLOW_COPY_AND_ASSIGN(TestingHttpServerPropertiesManager); @@ -108,12 +81,10 @@ class HttpServerPropertiesManagerTest : public testing::Test { } virtual void SetUp() OVERRIDE { - pref_service_.RegisterListPref(prefs::kSpdyServers); - pref_service_.RegisterDictionaryPref(prefs::kAlternateProtocolServers); + pref_service_.RegisterDictionaryPref(prefs::kHttpServerProperties); http_server_props_manager_.reset( new StrictMock<TestingHttpServerPropertiesManager>(&pref_service_)); - ExpectSpdyCacheUpdate(); - ExpectAlternateProtocolCacheUpdate(); + ExpectCacheUpdate(); loop_.RunAllPending(); } @@ -126,38 +97,20 @@ class HttpServerPropertiesManagerTest : public testing::Test { http_server_props_manager_.reset(); } - 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:: - UpdateSpdyPrefsFromCacheConcrete)); - } - - void ExpectAlternateProtocolCacheUpdate() { - EXPECT_CALL(*http_server_props_manager_, - UpdateAlternateProtocolCacheFromPrefs()) + void ExpectCacheUpdate() { + EXPECT_CALL(*http_server_props_manager_, UpdateCacheFromPrefsOnUI()) .WillOnce( Invoke(http_server_props_manager_.get(), &TestingHttpServerPropertiesManager:: - UpdateAlternateProtocolCacheFromPrefsConcrete)); + UpdateCacheFromPrefsOnUIConcrete)); } - void ExpectAlternateProtocolPrefsUpdate() { - EXPECT_CALL(*http_server_props_manager_, - UpdateAlternateProtocolPrefsFromCache()) + void ExpectPrefsUpdate() { + EXPECT_CALL(*http_server_props_manager_, UpdatePrefsFromCacheOnIO()) .WillOnce( Invoke(http_server_props_manager_.get(), &TestingHttpServerPropertiesManager:: - UpdateAlternateProtocolPrefsFromCacheConcrete)); + UpdatePrefsFromCacheOnIOConcrete)); } MessageLoop loop_; @@ -171,32 +124,127 @@ class HttpServerPropertiesManagerTest : public testing::Test { DISALLOW_COPY_AND_ASSIGN(HttpServerPropertiesManagerTest); }; -TEST_F(HttpServerPropertiesManagerTest, SingleUpdateForTwoSpdyPrefChanges) { - ExpectSpdyCacheUpdate(); +TEST_F(HttpServerPropertiesManagerTest, + SingleUpdateForTwoSpdyServerPrefChanges) { + ExpectCacheUpdate(); + + // Set up the prefs for www.google.com:80 and mail.google.com:80 and then set + // it twice. Only expect a single cache update. + + base::DictionaryValue* server_pref_dict = new base::DictionaryValue; + + // Set supports_spdy for www.google.com:80. + server_pref_dict->SetBoolean("supports_spdy", true); + + // Set up the SpdySettings for www.google.com:80. + base::ListValue* spdy_settings_list = new base::ListValue; + base::DictionaryValue* spdy_setting_dict = new base::DictionaryValue; + spdy_setting_dict->SetInteger("flags", spdy::SETTINGS_FLAG_PERSISTED); + spdy_setting_dict->SetInteger("id", 1234); + spdy_setting_dict->SetInteger("value", 31337); + spdy_settings_list->Append(spdy_setting_dict); + server_pref_dict->Set("settings", spdy_settings_list); + + // Set up alternate_protocol for www.google.com:80. + base::DictionaryValue* alternate_protocol = new base::DictionaryValue; + alternate_protocol->SetInteger("port", 443); + alternate_protocol->SetInteger("protocol", static_cast<int>(net::NPN_SPDY_1)); + server_pref_dict->SetWithoutPathExpansion( + "alternate_protocol", alternate_protocol); + + // Set the server preference for www.google.com:80. + base::DictionaryValue* http_server_properties_dict = + new base::DictionaryValue; + http_server_properties_dict->SetWithoutPathExpansion( + "www.google.com:80", server_pref_dict); + + // Set the preference for mail.google.com server. + base::DictionaryValue* server_pref_dict1 = new base::DictionaryValue; + + // Set supports_spdy for mail.google.com:80 + server_pref_dict1->SetBoolean("supports_spdy", true); + + // Set up the SpdySettings for mail.google.com:80 + base::ListValue* spdy_settings_list1 = new base::ListValue; + base::DictionaryValue* spdy_setting_dict1 = new base::DictionaryValue; + spdy_setting_dict1->SetInteger("flags", spdy::SETTINGS_FLAG_PERSISTED); + spdy_setting_dict1->SetInteger("id", 5678); + spdy_setting_dict1->SetInteger("value", 62667); + spdy_settings_list1->Append(spdy_setting_dict1); + server_pref_dict1->Set("settings", spdy_settings_list1); + + // Set up alternate_protocol for mail.google.com:80 + base::DictionaryValue* alternate_protocol1 = new base::DictionaryValue; + alternate_protocol1->SetInteger("port", 444); + alternate_protocol1->SetInteger( + "protocol", static_cast<int>(net::NPN_SPDY_2)); + server_pref_dict1->SetWithoutPathExpansion( + "alternate_protocol", alternate_protocol1); + + // Set the server preference for mail.google.com:80. + http_server_properties_dict->SetWithoutPathExpansion( + "mail.google.com:80", server_pref_dict1); + + // Set the same value for kHttpServerProperties multiple times. + pref_service_.SetManagedPref(prefs::kHttpServerProperties, + http_server_properties_dict); + base::DictionaryValue* http_server_properties_dict2 = + http_server_properties_dict->DeepCopy(); + pref_service_.SetManagedPref(prefs::kHttpServerProperties, + http_server_properties_dict2); - // 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()); + // Verify SupportsSpdy. EXPECT_TRUE(http_server_props_manager_->SupportsSpdy( - net::HostPortPair::FromString("www.google.com:443"))); + net::HostPortPair::FromString("www.google.com:80"))); EXPECT_TRUE(http_server_props_manager_->SupportsSpdy( - net::HostPortPair::FromString("mail.google.com:443"))); + net::HostPortPair::FromString("mail.google.com:80"))); EXPECT_FALSE(http_server_props_manager_->SupportsSpdy( net::HostPortPair::FromString("foo.google.com:1337"))); + + // Verify SpdySettings. + spdy::SpdySettings spdy_settings_ret = + http_server_props_manager_->GetSpdySettings( + net::HostPortPair::FromString("www.google.com:80")); + ASSERT_EQ(1U, spdy_settings_ret.size()); + spdy::SpdySetting spdy_setting1_ret = spdy_settings_ret.front(); + spdy::SettingsFlagsAndId id1_ret(spdy_setting1_ret.first); + EXPECT_EQ(1234U, id1_ret.id()); + EXPECT_EQ(spdy::SETTINGS_FLAG_PERSISTED, id1_ret.flags()); + EXPECT_EQ(31337u, spdy_setting1_ret.second); + spdy_settings_ret = http_server_props_manager_->GetSpdySettings( + net::HostPortPair::FromString("mail.google.com:80")); + ASSERT_EQ(1U, spdy_settings_ret.size()); + spdy_setting1_ret = spdy_settings_ret.front(); + id1_ret = spdy_setting1_ret.first; + EXPECT_EQ(5678U, id1_ret.id()); + EXPECT_EQ(spdy::SETTINGS_FLAG_PERSISTED, id1_ret.flags()); + EXPECT_EQ(62667u, spdy_setting1_ret.second); + + // Verify AlternateProtocol. + 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, SupportsSpdy) { - ExpectSpdyPrefsUpdate(); + ExpectPrefsUpdate(); // Post an update task to the IO thread. SetSupportsSpdy calls - // ScheduleUpdateSpdyPrefsOnIO. + // ScheduleUpdatePrefsOnIO. // Add mail.google.com:443 as a supporting spdy server. net::HostPortPair spdy_server_mail("mail.google.com", 443); @@ -210,174 +258,108 @@ TEST_F(HttpServerPropertiesManagerTest, SupportsSpdy) { Mock::VerifyAndClearExpectations(http_server_props_manager_.get()); } -TEST_F(HttpServerPropertiesManagerTest, Clear) { - ExpectSpdyPrefsUpdate(); - ExpectAlternateProtocolPrefsUpdate(); +TEST_F(HttpServerPropertiesManagerTest, SetSpdySettings) { + ExpectPrefsUpdate(); + // Add SpdySettings for mail.google.com:443. 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); + spdy::SpdySettings spdy_settings; + spdy::SettingsFlagsAndId id1(0); + id1.set_flags(spdy::SETTINGS_FLAG_PLEASE_PERSIST); + id1.set_id(1234); + spdy_settings.push_back(std::make_pair(id1, 31337)); + http_server_props_manager_->SetSpdySettings(spdy_server_mail, spdy_settings); // 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()); + spdy::SpdySettings spdy_settings_ret = + http_server_props_manager_->GetSpdySettings(spdy_server_mail); + ASSERT_EQ(1U, spdy_settings_ret.size()); + spdy::SpdySetting spdy_setting1_ret = spdy_settings_ret.front(); + spdy::SettingsFlagsAndId id1_ret(spdy_setting1_ret.first); + EXPECT_EQ(1234U, id1_ret.id()); + EXPECT_EQ(spdy::SETTINGS_FLAG_PERSISTED, id1_ret.flags()); + EXPECT_EQ(31337U, spdy_setting1_ret.second); - ExpectSpdyPrefsUpdate(); - ExpectAlternateProtocolPrefsUpdate(); - // Clear http server data. - http_server_props_manager_->Clear(); + Mock::VerifyAndClearExpectations(http_server_props_manager_.get()); +} - // Run the task. - loop_.RunAllPending(); +TEST_F(HttpServerPropertiesManagerTest, HasAlternateProtocol) { + ExpectPrefsUpdate(); - EXPECT_FALSE(http_server_props_manager_->SupportsSpdy(spdy_server_mail)); + net::HostPortPair spdy_server_mail("mail.google.com", 80); 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(); -} + http_server_props_manager_->SetAlternateProtocol( + spdy_server_mail, 443, net::NPN_SPDY_2); -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. + // Run the task. 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(); + 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); } -// -// Tests for shutdown when updating prefs. -// -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, Clear) { + ExpectPrefsUpdate(); -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(); -} + 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); -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(); + spdy::SpdySettings spdy_settings; + spdy::SettingsFlagsAndId id1(0); + id1.set_flags(spdy::SETTINGS_FLAG_PLEASE_PERSIST); + id1.set_id(1234); + spdy_settings.push_back(std::make_pair(id1, 31337)); + http_server_props_manager_->SetSpdySettings(spdy_server_mail, spdy_settings); + + // Run the task. loop_.RunAllPending(); -} -TEST_F(HttpServerPropertiesManagerTest, - SingleUpdateForTwoAlternateProtocolPrefChanges) { - ExpectAlternateProtocolCacheUpdate(); + EXPECT_TRUE(http_server_props_manager_->SupportsSpdy(spdy_server_mail)); + EXPECT_TRUE( + http_server_props_manager_->HasAlternateProtocol(spdy_server_mail)); - // 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(); + spdy::SpdySettings spdy_settings_ret = + http_server_props_manager_->GetSpdySettings(spdy_server_mail); + ASSERT_EQ(1U, spdy_settings_ret.size()); + spdy::SpdySetting spdy_setting1_ret = spdy_settings_ret.front(); + spdy::SettingsFlagsAndId id1_ret(spdy_setting1_ret.first); + EXPECT_EQ(1234U, id1_ret.id()); + EXPECT_EQ(spdy::SETTINGS_FLAG_PERSISTED, id1_ret.flags()); + EXPECT_EQ(31337U, spdy_setting1_ret.second); 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); -} + ExpectPrefsUpdate(); + // Clear http server data. + http_server_props_manager_->Clear(); -TEST_F(HttpServerPropertiesManagerTest, HasAlternateProtocol) { - ExpectAlternateProtocolPrefsUpdate(); + // Run the task. + loop_.RunAllPending(); - net::HostPortPair spdy_server_mail("mail.google.com", 80); + EXPECT_FALSE(http_server_props_manager_->SupportsSpdy(spdy_server_mail)); 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()); + spdy::SpdySettings spdy_settings1_ret = + http_server_props_manager_->GetSpdySettings(spdy_server_mail); + EXPECT_EQ(0U, spdy_settings1_ret.size()); - 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); + Mock::VerifyAndClearExpectations(http_server_props_manager_.get()); } -TEST_F(HttpServerPropertiesManagerTest, - ShutdownWithPendingUpdateAlternateProtocolCache0) { +TEST_F(HttpServerPropertiesManagerTest, ShutdownWithPendingUpdateCache0) { // Post an update task to the UI thread. - http_server_props_manager_->ScheduleUpdateAlternateProtocolCacheOnUI(); + http_server_props_manager_->ScheduleUpdateCacheOnUI(); // Shutdown comes before the task is executed. http_server_props_manager_->ShutdownOnUIThread(); http_server_props_manager_.reset(); @@ -385,10 +367,9 @@ TEST_F(HttpServerPropertiesManagerTest, loop_.RunAllPending(); } -TEST_F(HttpServerPropertiesManagerTest, - ShutdownWithPendingUpdateAlternateProtocolCache1) { +TEST_F(HttpServerPropertiesManagerTest, ShutdownWithPendingUpdateCache1) { // Post an update task. - http_server_props_manager_->ScheduleUpdateAlternateProtocolCacheOnUI(); + http_server_props_manager_->ScheduleUpdateCacheOnUI(); // Shutdown comes before the task is executed. http_server_props_manager_->ShutdownOnUIThread(); // Run the task after shutdown, but before deletion. @@ -398,9 +379,8 @@ TEST_F(HttpServerPropertiesManagerTest, loop_.RunAllPending(); } -TEST_F(HttpServerPropertiesManagerTest, - ShutdownWithPendingUpdateAlternateProtocolCache2) { - http_server_props_manager_->UpdateAlternateProtocolCacheFromPrefsConcrete(); +TEST_F(HttpServerPropertiesManagerTest, ShutdownWithPendingUpdateCache2) { + http_server_props_manager_->UpdateCacheFromPrefsOnUIConcrete(); // Shutdown comes before the task is executed. http_server_props_manager_->ShutdownOnUIThread(); // Run the task after shutdown, but before deletion. @@ -413,10 +393,9 @@ TEST_F(HttpServerPropertiesManagerTest, // // Tests for shutdown when updating prefs. // -TEST_F(HttpServerPropertiesManagerTest, - ShutdownWithPendingUpdateAlternateProtocolPrefs0) { +TEST_F(HttpServerPropertiesManagerTest, ShutdownWithPendingUpdatePrefs0) { // Post an update task to the IO thread. - http_server_props_manager_->ScheduleUpdateAlternateProtocolPrefsOnIO(); + http_server_props_manager_->ScheduleUpdatePrefsOnIO(); // Shutdown comes before the task is executed. http_server_props_manager_->ShutdownOnUIThread(); http_server_props_manager_.reset(); @@ -424,11 +403,10 @@ TEST_F(HttpServerPropertiesManagerTest, loop_.RunAllPending(); } -TEST_F(HttpServerPropertiesManagerTest, - ShutdownWithPendingUpdateAlternateProtocolPrefs1) { - ExpectAlternateProtocolPrefsUpdate(); +TEST_F(HttpServerPropertiesManagerTest, ShutdownWithPendingUpdatePrefs1) { + ExpectPrefsUpdate(); // Post an update task. - http_server_props_manager_->ScheduleUpdateAlternateProtocolPrefsOnIO(); + http_server_props_manager_->ScheduleUpdatePrefsOnIO(); // Shutdown comes before the task is executed. http_server_props_manager_->ShutdownOnUIThread(); // Run the task after shutdown, but before deletion. @@ -438,10 +416,9 @@ TEST_F(HttpServerPropertiesManagerTest, loop_.RunAllPending(); } -TEST_F(HttpServerPropertiesManagerTest, - ShutdownWithPendingUpdateAlternateProtocolPrefs2) { +TEST_F(HttpServerPropertiesManagerTest, ShutdownWithPendingUpdatePrefs2) { // This posts a task to the UI thread. - http_server_props_manager_->UpdateAlternateProtocolPrefsFromCacheConcrete(); + http_server_props_manager_->UpdatePrefsFromCacheOnIOConcrete(); // 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/off_the_record_profile_io_data.h b/chrome/browser/profiles/off_the_record_profile_io_data.h index 15f1d93..79334a5 100644 --- a/chrome/browser/profiles/off_the_record_profile_io_data.h +++ b/chrome/browser/profiles/off_the_record_profile_io_data.h @@ -104,11 +104,11 @@ class OffTheRecordProfileIOData : public ProfileIOData { scoped_refptr<ChromeURLRequestContext> main_context, const std::string& app_id) const; + mutable scoped_ptr<net::HttpServerPropertiesImpl> http_server_properties_; + mutable scoped_ptr<net::HttpTransactionFactory> main_http_factory_; mutable scoped_ptr<net::FtpTransactionFactory> ftp_factory_; - mutable scoped_ptr<net::HttpServerPropertiesImpl> http_server_properties_; - DISALLOW_COPY_AND_ASSIGN(OffTheRecordProfileIOData); }; diff --git a/chrome/browser/profiles/profile_impl_io_data.h b/chrome/browser/profiles/profile_impl_io_data.h index 1c13eed..1a8d905 100644 --- a/chrome/browser/profiles/profile_impl_io_data.h +++ b/chrome/browser/profiles/profile_impl_io_data.h @@ -135,6 +135,9 @@ class ProfileImplIOData : public ProfileIOData { // Lazy initialization params. mutable scoped_ptr<LazyParams> lazy_params_; + mutable scoped_ptr<chrome_browser_net::HttpServerPropertiesManager> + http_server_properties_manager_; + mutable scoped_refptr<ChromeURLRequestContext> media_request_context_; mutable scoped_ptr<net::HttpTransactionFactory> main_http_factory_; @@ -142,8 +145,6 @@ class ProfileImplIOData : public ProfileIOData { mutable scoped_ptr<net::FtpTransactionFactory> ftp_factory_; mutable scoped_ptr<chrome_browser_net::Predictor> predictor_; - mutable scoped_ptr<chrome_browser_net::HttpServerPropertiesManager> - http_server_properties_manager_; // Parameters needed for isolated apps. FilePath app_path_; diff --git a/chrome/common/pref_names.cc b/chrome/common/pref_names.cc index aeb79e4..c959d5d 100644 --- a/chrome/common/pref_names.cc +++ b/chrome/common/pref_names.cc @@ -342,6 +342,9 @@ const char kDnsPrefetchingHostReferralList[] = // Disables the SPDY protocol. const char kDisableSpdy[] = "spdy.disabled"; +// Prefs for persisting HttpServerProperties. +const char kHttpServerProperties[] = "net.http_server_properties"; + // Prefs for server names that support SPDY protocol. const char kSpdyServers[] = "spdy.servers"; diff --git a/chrome/common/pref_names.h b/chrome/common/pref_names.h index ebc958a..31ec123 100644 --- a/chrome/common/pref_names.h +++ b/chrome/common/pref_names.h @@ -130,6 +130,7 @@ extern const char kDnsPrefetchingStartupList[]; extern const char kDnsHostReferralList[]; // OBSOLETE extern const char kDnsPrefetchingHostReferralList[]; extern const char kDisableSpdy[]; +extern const char kHttpServerProperties[]; extern const char kSpdyServers[]; extern const char kAlternateProtocolServers[]; extern const char kDisabledSchemes[]; diff --git a/net/base/host_port_pair_unittest.cc b/net/base/host_port_pair_unittest.cc index de059904..1c3b56a 100644 --- a/net/base/host_port_pair_unittest.cc +++ b/net/base/host_port_pair_unittest.cc @@ -18,6 +18,16 @@ TEST(HostPortPairTest, Parsing) { EXPECT_TRUE(foo.Equals(bar)); } +TEST(HostPortPairTest, BadString) { + HostPortPair foo = HostPortPair::FromString("foo.com:2:3"); + EXPECT_TRUE(foo.host().empty()); + EXPECT_EQ(0, foo.port()); + + HostPortPair bar = HostPortPair::FromString("bar.com:two"); + EXPECT_TRUE(bar.host().empty()); + EXPECT_EQ(0, bar.port()); +} + } // namespace } // namespace net diff --git a/net/http/http_network_session.cc b/net/http/http_network_session.cc index 8346573..a957436 100644 --- a/net/http/http_network_session.cc +++ b/net/http/http_network_session.cc @@ -42,7 +42,9 @@ HttpNetworkSession::HttpNetworkSession(const Params& params) params.ssl_host_info_factory, params.proxy_service, params.ssl_config_service), - spdy_session_pool_(params.host_resolver, params.ssl_config_service), + spdy_session_pool_(params.host_resolver, + params.ssl_config_service, + params.http_server_properties), ALLOW_THIS_IN_INITIALIZER_LIST(http_stream_factory_( new HttpStreamFactoryImpl(this))) { DCHECK(proxy_service_); diff --git a/net/http/http_server_properties.h b/net/http/http_server_properties.h index 06166f7..51171c2 100644 --- a/net/http/http_server_properties.h +++ b/net/http/http_server_properties.h @@ -10,6 +10,7 @@ #include "base/basictypes.h" #include "net/base/host_port_pair.h" #include "net/base/net_export.h" +#include "net/spdy/spdy_framer.h" // TODO(willchan): Reconsider this. namespace net { @@ -33,6 +34,7 @@ struct NET_EXPORT PortAlternateProtocolPair { }; typedef std::map<HostPortPair, PortAlternateProtocolPair> AlternateProtocolMap; +typedef std::map<HostPortPair, spdy::SpdySettings> SpdySettingsMap; extern const char kAlternateProtocolHeader[]; extern const char* const kAlternateProtocolStrings[NUM_ALTERNATE_PROTOCOLS]; @@ -41,6 +43,7 @@ extern const char* const kAlternateProtocolStrings[NUM_ALTERNATE_PROTOCOLS]; // Currently, this class manages servers': // * SPDY support (based on NPN results) // * Alternate-Protocol support +// * Spdy Settings (like CWND ID field) class NET_EXPORT HttpServerProperties { public: HttpServerProperties() {} @@ -76,6 +79,22 @@ class NET_EXPORT HttpServerProperties { // Returns all Alternate-Protocol mappings. virtual const AlternateProtocolMap& alternate_protocol_map() const = 0; + // Gets a reference to the SpdySettings stored for a host. + // If no settings are stored, returns an empty set of settings. + virtual const spdy::SpdySettings& GetSpdySettings( + const HostPortPair& host_port_pair) const = 0; + + // Saves settings for a host. Returns true if SpdySettings are to be + // persisted. + virtual bool SetSpdySettings(const HostPortPair& host_port_pair, + const spdy::SpdySettings& settings) = 0; + + // Clears all spdy_settings. + virtual void ClearSpdySettings() = 0; + + // Returns all persistent SpdySettings. + virtual const SpdySettingsMap& spdy_settings_map() const = 0; + private: DISALLOW_COPY_AND_ASSIGN(HttpServerProperties); }; diff --git a/net/http/http_server_properties_impl.cc b/net/http/http_server_properties_impl.cc index 3ea973c..d4e1303 100644 --- a/net/http/http_server_properties_impl.cc +++ b/net/http/http_server_properties_impl.cc @@ -43,6 +43,11 @@ void HttpServerPropertiesImpl::InitializeAlternateProtocolServers( } } +void HttpServerPropertiesImpl::InitializeSpdySettingsServers( + std::map<HostPortPair, spdy::SpdySettings>* spdy_settings_map) { + spdy_settings_map_.swap(*spdy_settings_map); +} + void HttpServerPropertiesImpl::GetSpdyServerList( base::ListValue* spdy_server_list) const { DCHECK(CalledOnValidThread()); @@ -88,6 +93,7 @@ void HttpServerPropertiesImpl::Clear() { DCHECK(CalledOnValidThread()); spdy_servers_table_.clear(); alternate_protocol_map_.clear(); + spdy_settings_map_.clear(); } bool HttpServerPropertiesImpl::SupportsSpdy( @@ -190,4 +196,47 @@ HttpServerPropertiesImpl::alternate_protocol_map() const { return alternate_protocol_map_; } +const spdy::SpdySettings& HttpServerPropertiesImpl::GetSpdySettings( + const HostPortPair& host_port_pair) const { + SpdySettingsMap::const_iterator it = spdy_settings_map_.find(host_port_pair); + if (it == spdy_settings_map_.end()) { + CR_DEFINE_STATIC_LOCAL(spdy::SpdySettings, kEmptySpdySettings, ()); + return kEmptySpdySettings; + } + return it->second; +} + +bool HttpServerPropertiesImpl::SetSpdySettings( + const HostPortPair& host_port_pair, + const spdy::SpdySettings& settings) { + spdy::SpdySettings persistent_settings; + + // Iterate through the list, and only copy those settings which are marked + // for persistence. + spdy::SpdySettings::const_iterator it; + for (it = settings.begin(); it != settings.end(); ++it) { + spdy::SettingsFlagsAndId id = it->first; + if (id.flags() & spdy::SETTINGS_FLAG_PLEASE_PERSIST) { + id.set_flags(spdy::SETTINGS_FLAG_PERSISTED); + persistent_settings.push_back(std::make_pair(id, it->second)); + } + } + + // If we didn't persist anything, then we are done. + if (persistent_settings.empty()) + return false; + + spdy_settings_map_[host_port_pair] = persistent_settings; + return true; +} + +void HttpServerPropertiesImpl::ClearSpdySettings() { + spdy_settings_map_.clear(); +} + +const SpdySettingsMap& +HttpServerPropertiesImpl::spdy_settings_map() const { + return spdy_settings_map_; +} + } // namespace net diff --git a/net/http/http_server_properties_impl.h b/net/http/http_server_properties_impl.h index 177802f..f697848 100644 --- a/net/http/http_server_properties_impl.h +++ b/net/http/http_server_properties_impl.h @@ -5,6 +5,7 @@ #ifndef NET_HTTP_HTTP_SERVER_PROPERTIES_IMPL_H_ #define NET_HTTP_HTTP_SERVER_PROPERTIES_IMPL_H_ +#include <map> #include <string> #include <vector> @@ -39,6 +40,8 @@ class NET_EXPORT HttpServerPropertiesImpl void InitializeAlternateProtocolServers( AlternateProtocolMap* alternate_protocol_servers); + void InitializeSpdySettingsServers(SpdySettingsMap* spdy_settings_map); + // Get the list of servers (host/port) that support SPDY. void GetSpdyServerList(base::ListValue* spdy_server_list) const; @@ -87,6 +90,22 @@ class NET_EXPORT HttpServerPropertiesImpl // Returns all Alternate-Protocol mappings. virtual const AlternateProtocolMap& alternate_protocol_map() const OVERRIDE; + // Gets a reference to the SpdySettings stored for a host. + // If no settings are stored, returns an empty set of settings. + virtual const spdy::SpdySettings& GetSpdySettings( + const HostPortPair& host_port_pair) const OVERRIDE; + + // Saves settings for a host. Returns true if SpdySettings are to be + // persisted because |spdy_settings_map_| has been updated. + virtual bool SetSpdySettings(const HostPortPair& host_port_pair, + const spdy::SpdySettings& settings) OVERRIDE; + + // Clears all spdy_settings. + virtual void ClearSpdySettings() OVERRIDE; + + // Returns all persistent SpdySettings. + virtual const SpdySettingsMap& spdy_settings_map() const OVERRIDE; + private: // |spdy_servers_table_| has flattened representation of servers (host/port // pair) that either support or not support SPDY protocol. @@ -94,6 +113,7 @@ class NET_EXPORT HttpServerPropertiesImpl SpdyServerHostPortTable spdy_servers_table_; AlternateProtocolMap alternate_protocol_map_; + SpdySettingsMap spdy_settings_map_; DISALLOW_COPY_AND_ASSIGN(HttpServerPropertiesImpl); }; diff --git a/net/http/http_server_properties_impl_unittest.cc b/net/http/http_server_properties_impl_unittest.cc index ac5d5fc..a3bb781 100644 --- a/net/http/http_server_properties_impl_unittest.cc +++ b/net/http/http_server_properties_impl_unittest.cc @@ -131,13 +131,13 @@ TEST_F(SpdyServerPropertiesTest, GetSpdyServerList) { // Check there are no spdy_servers. impl_.GetSpdyServerList(&spdy_server_list); - EXPECT_EQ(0u, spdy_server_list.GetSize()); + EXPECT_EQ(0U, spdy_server_list.GetSize()); // Check empty server is not added. HostPortPair spdy_server_empty("", 443); impl_.SetSupportsSpdy(spdy_server_empty, true); impl_.GetSpdyServerList(&spdy_server_list); - EXPECT_EQ(0u, spdy_server_list.GetSize()); + EXPECT_EQ(0U, spdy_server_list.GetSize()); std::string string_value_g; std::string string_value_m; @@ -151,26 +151,26 @@ TEST_F(SpdyServerPropertiesTest, GetSpdyServerList) { // Add www.google.com:443 as not supporting SPDY. impl_.SetSupportsSpdy(spdy_server_google, false); impl_.GetSpdyServerList(&spdy_server_list); - EXPECT_EQ(0u, spdy_server_list.GetSize()); + EXPECT_EQ(0U, spdy_server_list.GetSize()); // Add www.google.com:443 as supporting SPDY. impl_.SetSupportsSpdy(spdy_server_google, true); impl_.GetSpdyServerList(&spdy_server_list); - EXPECT_EQ(1u, spdy_server_list.GetSize()); + ASSERT_EQ(1U, spdy_server_list.GetSize()); ASSERT_TRUE(spdy_server_list.GetString(0, &string_value_g)); ASSERT_EQ(spdy_server_g, string_value_g); // Add mail.google.com:443 as not supporting SPDY. impl_.SetSupportsSpdy(spdy_server_mail, false); impl_.GetSpdyServerList(&spdy_server_list); - EXPECT_EQ(1u, spdy_server_list.GetSize()); + ASSERT_EQ(1U, spdy_server_list.GetSize()); ASSERT_TRUE(spdy_server_list.GetString(0, &string_value_g)); ASSERT_EQ(spdy_server_g, string_value_g); // Add mail.google.com:443 as supporting SPDY. impl_.SetSupportsSpdy(spdy_server_mail, true); impl_.GetSpdyServerList(&spdy_server_list); - EXPECT_EQ(2u, spdy_server_list.GetSize()); + ASSERT_EQ(2U, spdy_server_list.GetSize()); // Verify www.google.com:443 and mail.google.com:443 are in the list. ASSERT_TRUE(spdy_server_list.GetString(0, &string_value_g)); @@ -279,6 +279,124 @@ TEST_F(AlternateProtocolServerPropertiesTest, Forced) { impl_.HasAlternateProtocol(test_host_port_pair2)); } +typedef HttpServerPropertiesImplTest SpdySettingsServerPropertiesTest; + +TEST_F(SpdySettingsServerPropertiesTest, Initialize) { + HostPortPair spdy_server_google("www.google.com", 443); + + // Check by initializing empty spdy settings. + SpdySettingsMap spdy_settings_map; + impl_.InitializeSpdySettingsServers(&spdy_settings_map); + EXPECT_TRUE(impl_.GetSpdySettings(spdy_server_google).empty()); + + // Check by initializing with www.google.com:443 spdy server settings. + spdy::SpdySettings spdy_settings; + spdy::SettingsFlagsAndId spdy_setting(0); + spdy_setting.set_flags(spdy::SETTINGS_FLAG_PERSISTED); + spdy_setting.set_id(1234); + spdy_settings.push_back(std::make_pair(spdy_setting, 31337)); + spdy_settings_map[spdy_server_google] = spdy_settings; + impl_.InitializeSpdySettingsServers(&spdy_settings_map); + spdy::SpdySettings spdy_settings2 = impl_.GetSpdySettings(spdy_server_google); + ASSERT_EQ(1U, spdy_settings2.size()); + spdy::SpdySetting spdy_setting2 = spdy_settings2.front(); + spdy::SettingsFlagsAndId id2_ret(spdy_setting2.first); + EXPECT_EQ(1234U, id2_ret.id()); + EXPECT_EQ(spdy::SETTINGS_FLAG_PERSISTED, id2_ret.flags()); + EXPECT_EQ(31337U, spdy_settings2.front().second); +} + +TEST_F(SpdySettingsServerPropertiesTest, SpdySettingsTest) { + HostPortPair spdy_server_empty("", 443); + spdy::SpdySettings spdy_settings0 = impl_.GetSpdySettings(spdy_server_empty); + EXPECT_EQ(0U, spdy_settings0.size()); // Returns kEmptySpdySettings + + // Add www.google.com:443 as persisting. + HostPortPair spdy_server_google("www.google.com", 443); + spdy::SpdySettings spdy_settings1; + spdy::SettingsFlagsAndId id1(0); + id1.set_flags(spdy::SETTINGS_FLAG_PLEASE_PERSIST); + id1.set_id(1234); + spdy_settings1.push_back(std::make_pair(id1, 31337)); + EXPECT_TRUE(impl_.SetSpdySettings(spdy_server_google, spdy_settings1)); + spdy::SpdySettings spdy_settings1_ret = + impl_.GetSpdySettings(spdy_server_google); + ASSERT_EQ(1U, spdy_settings1_ret.size()); + spdy::SpdySetting spdy_setting1_ret = spdy_settings1_ret.front(); + spdy::SettingsFlagsAndId id1_ret(spdy_setting1_ret.first); + EXPECT_EQ(1234U, id1_ret.id()); + EXPECT_EQ(spdy::SETTINGS_FLAG_PERSISTED, id1_ret.flags()); + EXPECT_EQ(31337U, spdy_setting1_ret.second); + + // Add mail.google.com:443 as not persisting. + HostPortPair spdy_server_mail("mail.google.com", 443); + spdy::SpdySettings spdy_settings2; + spdy::SettingsFlagsAndId id2(0); + id2.set_id(5678); + spdy_settings2.push_back(std::make_pair(id2, 62667)); + EXPECT_FALSE(impl_.SetSpdySettings(spdy_server_mail, spdy_settings2)); + spdy::SpdySettings spdy_settings2_ret = + impl_.GetSpdySettings(spdy_server_mail); + EXPECT_EQ(0U, spdy_settings2_ret.size()); // Returns kEmptySpdySettings + + // Add docs.google.com:443 as persisting + HostPortPair spdy_server_docs("docs.google.com", 443); + spdy::SpdySettings spdy_settings3; + spdy::SettingsFlagsAndId id3(0); + id3.set_flags(spdy::SETTINGS_FLAG_PLEASE_PERSIST); + id3.set_id(9012); + spdy_settings3.push_back(std::make_pair(id3, 93997)); + EXPECT_TRUE(impl_.SetSpdySettings(spdy_server_docs, spdy_settings3)); + spdy::SpdySettings spdy_settings3_ret = + impl_.GetSpdySettings(spdy_server_docs); + ASSERT_EQ(1U, spdy_settings3_ret.size()); + spdy::SpdySetting spdy_setting3_ret = spdy_settings3_ret.front(); + spdy::SettingsFlagsAndId id3_ret(spdy_setting3_ret.first); + EXPECT_EQ(9012U, id3_ret.id()); + EXPECT_EQ(spdy::SETTINGS_FLAG_PERSISTED, id3_ret.flags()); + EXPECT_EQ(93997U, spdy_setting3_ret.second); +} + +TEST_F(SpdySettingsServerPropertiesTest, Clear) { + // Add www.google.com:443 as persisting. + HostPortPair spdy_server_google("www.google.com", 443); + spdy::SpdySettings spdy_settings1; + spdy::SettingsFlagsAndId id1(0); + id1.set_flags(spdy::SETTINGS_FLAG_PLEASE_PERSIST); + id1.set_id(1234); + spdy_settings1.push_back(std::make_pair(id1, 31337)); + EXPECT_TRUE(impl_.SetSpdySettings(spdy_server_google, spdy_settings1)); + spdy::SpdySettings spdy_settings1_ret = + impl_.GetSpdySettings(spdy_server_google); + ASSERT_EQ(1U, spdy_settings1_ret.size()); + spdy::SpdySetting spdy_setting1_ret = spdy_settings1_ret.front(); + spdy::SettingsFlagsAndId id1_ret(spdy_setting1_ret.first); + EXPECT_EQ(1234U, id1_ret.id()); + EXPECT_EQ(spdy::SETTINGS_FLAG_PERSISTED, id1_ret.flags()); + EXPECT_EQ(31337U, spdy_setting1_ret.second); + + // Add docs.google.com:443 as persisting + HostPortPair spdy_server_docs("docs.google.com", 443); + spdy::SpdySettings spdy_settings3; + spdy::SettingsFlagsAndId id3(0); + id3.set_flags(spdy::SETTINGS_FLAG_PLEASE_PERSIST); + id3.set_id(9012); + spdy_settings3.push_back(std::make_pair(id3, 93997)); + EXPECT_TRUE(impl_.SetSpdySettings(spdy_server_docs, spdy_settings3)); + spdy::SpdySettings spdy_settings3_ret = + impl_.GetSpdySettings(spdy_server_docs); + ASSERT_EQ(1U, spdy_settings3_ret.size()); + spdy::SpdySetting spdy_setting3_ret = spdy_settings3_ret.front(); + spdy::SettingsFlagsAndId id3_ret(spdy_setting3_ret.first); + EXPECT_EQ(9012U, id3_ret.id()); + EXPECT_EQ(spdy::SETTINGS_FLAG_PERSISTED, id3_ret.flags()); + EXPECT_EQ(93997U, spdy_setting3_ret.second); + + impl_.Clear(); + EXPECT_EQ(0U, impl_.GetSpdySettings(spdy_server_google).size()); + EXPECT_EQ(0U, impl_.GetSpdySettings(spdy_server_docs).size()); +} + } // namespace } // namespace net diff --git a/net/spdy/spdy_network_transaction_unittest.cc b/net/spdy/spdy_network_transaction_unittest.cc index bcc8201..632649b 100644 --- a/net/spdy/spdy_network_transaction_unittest.cc +++ b/net/spdy/spdy_network_transaction_unittest.cc @@ -4206,7 +4206,8 @@ TEST_P(SpdyNetworkTransactionTest, SettingsSaved) { // Verify that no settings exist initially. HostPortPair host_port_pair("www.google.com", helper.port()); SpdySessionPool* spdy_session_pool = helper.session()->spdy_session_pool(); - EXPECT_TRUE(spdy_session_pool->spdy_settings().Get(host_port_pair).empty()); + EXPECT_TRUE(spdy_session_pool->http_server_properties()->GetSpdySettings( + host_port_pair).empty()); // Construct the request. scoped_ptr<spdy::SpdyFrame> req(ConstructSpdyGet(NULL, 0, false, 1, LOWEST)); @@ -4268,7 +4269,8 @@ TEST_P(SpdyNetworkTransactionTest, SettingsSaved) { { // Verify we had two persisted settings. spdy::SpdySettings saved_settings = - spdy_session_pool->spdy_settings().Get(host_port_pair); + spdy_session_pool->http_server_properties()->GetSpdySettings( + host_port_pair); ASSERT_EQ(2u, saved_settings.size()); // Verify the first persisted setting. @@ -4315,7 +4317,8 @@ TEST_P(SpdyNetworkTransactionTest, SettingsPlayback) { // Verify that no settings exist initially. HostPortPair host_port_pair("www.google.com", helper.port()); SpdySessionPool* spdy_session_pool = helper.session()->spdy_session_pool(); - EXPECT_TRUE(spdy_session_pool->spdy_settings().Get(host_port_pair).empty()); + EXPECT_TRUE(spdy_session_pool->http_server_properties()->GetSpdySettings( + host_port_pair).empty()); unsigned int kSampleId1 = 0x1; unsigned int kSampleValue1 = 0x0a0a0a0a; @@ -4334,14 +4337,17 @@ TEST_P(SpdyNetworkTransactionTest, SettingsPlayback) { setting.set_id(kSampleId2); settings.push_back(std::make_pair(setting, kSampleValue2)); - spdy_session_pool->mutable_spdy_settings()->Set(host_port_pair, settings); + spdy_session_pool->http_server_properties()->SetSpdySettings( + host_port_pair, settings); } - EXPECT_EQ(2u, spdy_session_pool->spdy_settings().Get(host_port_pair).size()); + EXPECT_EQ(2u, spdy_session_pool->http_server_properties()->GetSpdySettings( + host_port_pair).size()); // Construct the SETTINGS frame. const spdy::SpdySettings& settings = - spdy_session_pool->spdy_settings().Get(host_port_pair); + spdy_session_pool->http_server_properties()->GetSpdySettings( + host_port_pair); scoped_ptr<spdy::SpdyFrame> settings_frame(ConstructSpdySettings(settings)); // Construct the request. @@ -4381,7 +4387,8 @@ TEST_P(SpdyNetworkTransactionTest, SettingsPlayback) { { // Verify we had two persisted settings. spdy::SpdySettings saved_settings = - spdy_session_pool->spdy_settings().Get(host_port_pair); + spdy_session_pool->http_server_properties()->GetSpdySettings( + host_port_pair); ASSERT_EQ(2u, saved_settings.size()); // Verify the first persisted setting. diff --git a/net/spdy/spdy_session.cc b/net/spdy/spdy_session.cc index cffbe0f..cdd71dc 100644 --- a/net/spdy/spdy_session.cc +++ b/net/spdy/spdy_session.cc @@ -21,6 +21,7 @@ #include "net/base/net_log.h" #include "net/base/net_util.h" #include "net/http/http_network_session.h" +#include "net/http/http_server_properties.h" #include "net/socket/ssl_client_socket.h" #include "net/spdy/spdy_frame_builder.h" #include "net/spdy/spdy_http_utils.h" @@ -244,7 +245,7 @@ int SpdySession::hung_interval_ms_ = 10000; SpdySession::SpdySession(const HostPortProxyPair& host_port_proxy_pair, SpdySessionPool* spdy_session_pool, - SpdySettingsStorage* spdy_settings, + HttpServerProperties* http_server_properties, bool verify_domain_authentication, NetLog* net_log) : ALLOW_THIS_IN_INITIALIZER_LIST( @@ -254,7 +255,7 @@ SpdySession::SpdySession(const HostPortProxyPair& host_port_proxy_pair, ALLOW_THIS_IN_INITIALIZER_LIST(method_factory_(this)), host_port_proxy_pair_(host_port_proxy_pair), spdy_session_pool_(spdy_session_pool), - spdy_settings_(spdy_settings), + http_server_properties_(http_server_properties), connection_(new ClientSocketHandle), read_buffer_(new IOBuffer(kReadBufferSize)), read_pending_(false), @@ -1412,7 +1413,7 @@ void SpdySession::OnSettings(const spdy::SpdySettingsControlFrame& frame) { spdy::SpdySettings settings; if (spdy_framer_.ParseSettings(&frame, &settings)) { HandleSettings(settings); - spdy_settings_->Set(host_port_pair(), settings); + http_server_properties_->SetSpdySettings(host_port_pair(), settings); } received_settings_ = true; @@ -1493,7 +1494,8 @@ void SpdySession::SendSettings() { // Note: we're copying the settings here, so that we can potentially modify // the settings for the field trial. When removing the field trial, make // this a reference to the const SpdySettings again. - spdy::SpdySettings settings = spdy_settings_->Get(host_port_pair()); + spdy::SpdySettings settings = + http_server_properties_->GetSpdySettings(host_port_pair()); if (settings.empty()) return; @@ -1512,7 +1514,7 @@ void SpdySession::SendSettings() { if (cwnd != val) { i->second = cwnd; i->first.set_flags(spdy::SETTINGS_FLAG_PLEASE_PERSIST); - spdy_settings_->Set(host_port_pair(), settings); + http_server_properties_->SetSpdySettings(host_port_pair(), settings); } break; } @@ -1674,7 +1676,8 @@ void SpdySession::RecordHistograms() { if (received_settings_) { // Enumerate the saved settings, and set histograms for it. - const spdy::SpdySettings& settings = spdy_settings_->Get(host_port_pair()); + const spdy::SpdySettings& settings = + http_server_properties_->GetSpdySettings(host_port_pair()); spdy::SpdySettings::const_iterator it; for (it = settings.begin(); it != settings.end(); ++it) { diff --git a/net/spdy/spdy_session.h b/net/spdy/spdy_session.h index b45b361..8d9b8ae 100644 --- a/net/spdy/spdy_session.h +++ b/net/spdy/spdy_session.h @@ -56,7 +56,7 @@ class NET_EXPORT SpdySession : public base::RefCounted<SpdySession>, // network events to. SpdySession(const HostPortProxyPair& host_port_proxy_pair, SpdySessionPool* spdy_session_pool, - SpdySettingsStorage* spdy_settings, + HttpServerProperties* http_server_properties, bool verify_domain_authentication, NetLog* net_log); @@ -447,7 +447,7 @@ class NET_EXPORT SpdySession : public base::RefCounted<SpdySession>, // |spdy_session_pool_| owns us, therefore its lifetime must exceed ours. We // set this to NULL after we are removed from the pool. SpdySessionPool* spdy_session_pool_; - SpdySettingsStorage* const spdy_settings_; + HttpServerProperties* const http_server_properties_; // The socket handle for this session. scoped_ptr<ClientSocketHandle> connection_; diff --git a/net/spdy/spdy_session_pool.cc b/net/spdy/spdy_session_pool.cc index 7bac3bc..ed490e4 100644 --- a/net/spdy/spdy_session_pool.cc +++ b/net/spdy/spdy_session_pool.cc @@ -10,6 +10,7 @@ #include "net/base/address_list.h" #include "net/base/sys_addrinfo.h" #include "net/http/http_network_session.h" +#include "net/http/http_server_properties.h" #include "net/spdy/spdy_session.h" @@ -40,8 +41,10 @@ bool SpdySessionPool::g_force_single_domain = false; bool SpdySessionPool::g_enable_ip_pooling = true; SpdySessionPool::SpdySessionPool(HostResolver* resolver, - SSLConfigService* ssl_config_service) - : ssl_config_service_(ssl_config_service), + SSLConfigService* ssl_config_service, + HttpServerProperties* http_server_properties) + : http_server_properties_(http_server_properties), + ssl_config_service_(ssl_config_service), resolver_(resolver), verify_domain_authentication_(true) { NetworkChangeNotifier::AddIPAddressObserver(this); @@ -110,7 +113,8 @@ scoped_refptr<SpdySession> SpdySessionPool::GetInternal( DCHECK(!only_use_existing_sessions); - spdy_session = new SpdySession(host_port_proxy_pair, this, &spdy_settings_, + spdy_session = new SpdySession(host_port_proxy_pair, this, + http_server_properties_, verify_domain_authentication_, net_log.net_log()); UMA_HISTOGRAM_ENUMERATION("Net.SpdySessionGet", @@ -136,7 +140,8 @@ net::Error SpdySessionPool::GetSpdySessionFromSocket( IMPORTED_FROM_SOCKET, SPDY_SESSION_GET_MAX); // Create the SPDY session and add it to the pool. - *spdy_session = new SpdySession(host_port_proxy_pair, this, &spdy_settings_, + *spdy_session = new SpdySession(host_port_proxy_pair, this, + http_server_properties_, verify_domain_authentication_, net_log.net_log()); SpdySessionList* list = GetSessionList(host_port_proxy_pair); @@ -207,7 +212,7 @@ Value* SpdySessionPool::SpdySessionPoolInfoToValue() const { void SpdySessionPool::OnIPAddressChanged() { CloseCurrentSessions(); - spdy_settings_.Clear(); + http_server_properties_->ClearSpdySettings(); } void SpdySessionPool::OnSSLConfigChanged() { diff --git a/net/spdy/spdy_session_pool.h b/net/spdy/spdy_session_pool.h index 9da713e..3861481 100644 --- a/net/spdy/spdy_session_pool.h +++ b/net/spdy/spdy_session_pool.h @@ -31,6 +31,7 @@ class AddressList; class BoundNetLog; class ClientSocketHandle; class HostResolver; +class HttpServerProperties; class SpdySession; // This is a very simple pool for open SpdySessions. @@ -40,7 +41,8 @@ class NET_EXPORT SpdySessionPool public CertDatabase::Observer { public: SpdySessionPool(HostResolver* host_resolver, - SSLConfigService* ssl_config_service); + SSLConfigService* ssl_config_service, + HttpServerProperties* http_server_properties); virtual ~SpdySessionPool(); // Either returns an existing SpdySession or creates a new SpdySession for @@ -105,6 +107,10 @@ class NET_EXPORT SpdySessionPool SpdySettingsStorage* mutable_spdy_settings() { return &spdy_settings_; } const SpdySettingsStorage& spdy_settings() const { return spdy_settings_; } + HttpServerProperties* http_server_properties() { + return http_server_properties_; + } + // NetworkChangeNotifier::IPAddressObserver methods: // We flush all idle sessions and release references to the active ones so @@ -171,6 +177,7 @@ class NET_EXPORT SpdySessionPool void RemoveAliases(const HostPortProxyPair& pair); SpdySettingsStorage spdy_settings_; + HttpServerProperties* const http_server_properties_; // This is our weak session pool - one session per domain. SpdySessionsMap sessions_; diff --git a/net/spdy/spdy_session_unittest.cc b/net/spdy/spdy_session_unittest.cc index e9ec4a9..2b012a3 100644 --- a/net/spdy/spdy_session_unittest.cc +++ b/net/spdy/spdy_session_unittest.cc @@ -538,7 +538,7 @@ TEST_F(SpdySessionTest, OnSettings) { spdy::SpdySettings old_settings; id.set_flags(spdy::SETTINGS_FLAG_PLEASE_PERSIST); old_settings.push_back(spdy::SpdySetting(id, 1)); - spdy_session_pool->mutable_spdy_settings()->Set( + spdy_session_pool->http_server_properties()->SetSpdySettings( test_host_port_pair, old_settings); // Create a session. @@ -624,7 +624,7 @@ TEST_F(SpdySessionTest, CancelPendingCreateStream) { id.set_id(spdy::SETTINGS_MAX_CONCURRENT_STREAMS); id.set_flags(spdy::SETTINGS_FLAG_PLEASE_PERSIST); settings.push_back(spdy::SpdySetting(id, 1)); - spdy_session_pool->mutable_spdy_settings()->Set( + spdy_session_pool->http_server_properties()->SetSpdySettings( test_host_port_pair, settings); // Create a session. @@ -726,7 +726,7 @@ TEST_F(SpdySessionTest, SendSettingsOnNewSession) { settings.clear(); settings.push_back(spdy::SpdySetting(id, kBogusSettingValue)); SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool()); - spdy_session_pool->mutable_spdy_settings()->Set( + spdy_session_pool->http_server_properties()->SetSpdySettings( test_host_port_pair, settings); EXPECT_FALSE(spdy_session_pool->HasSession(pair)); scoped_refptr<SpdySession> session = @@ -905,8 +905,8 @@ TEST_F(SpdySessionTest, ClearSettingsStorageOnIPAddressChanged) { SpdySessionDependencies::SpdyCreateSession(&session_deps)); SpdySessionPool* spdy_session_pool(http_session->spdy_session_pool()); - SpdySettingsStorage* test_settings_storage = - spdy_session_pool->mutable_spdy_settings(); + HttpServerProperties* test_http_server_properties = + spdy_session_pool->http_server_properties(); spdy::SettingsFlagsAndId id(0); id.set_id(spdy::SETTINGS_MAX_CONCURRENT_STREAMS); id.set_flags(spdy::SETTINGS_FLAG_PLEASE_PERSIST); @@ -914,10 +914,13 @@ TEST_F(SpdySessionTest, ClearSettingsStorageOnIPAddressChanged) { spdy::SpdySettings test_settings; test_settings.push_back(spdy::SpdySetting(id, max_concurrent_streams)); - test_settings_storage->Set(test_host_port_pair, test_settings); - EXPECT_NE(0u, test_settings_storage->Get(test_host_port_pair).size()); + test_http_server_properties->SetSpdySettings(test_host_port_pair, + test_settings); + EXPECT_NE(0u, test_http_server_properties->GetSpdySettings( + test_host_port_pair).size()); spdy_session_pool->OnIPAddressChanged(); - EXPECT_EQ(0u, test_settings_storage->Get(test_host_port_pair).size()); + EXPECT_EQ(0u, test_http_server_properties->GetSpdySettings( + test_host_port_pair).size()); } } // namespace net diff --git a/net/spdy/spdy_websocket_stream_unittest.cc b/net/spdy/spdy_websocket_stream_unittest.cc index 0644c96..0f050a6 100644 --- a/net/spdy/spdy_websocket_stream_unittest.cc +++ b/net/spdy/spdy_websocket_stream_unittest.cc @@ -255,7 +255,7 @@ class SpdyWebSocketStreamTest : public testing::Test { if (throttling) { // Set max concurrent streams to 1. - spdy_session_pool->mutable_spdy_settings()->Set( + spdy_session_pool->http_server_properties()->SetSpdySettings( host_port_pair_, spdy_settings_to_set_); } |