diff options
-rw-r--r-- | chrome/browser/net/http_server_properties_manager.cc | 31 | ||||
-rw-r--r-- | chrome/browser/net/http_server_properties_manager.h | 5 | ||||
-rw-r--r-- | net/http/http_network_transaction_unittest.cc | 2 | ||||
-rw-r--r-- | net/http/http_server_properties.h | 8 | ||||
-rw-r--r-- | net/http/http_server_properties_impl.cc | 56 | ||||
-rw-r--r-- | net/http/http_server_properties_impl.h | 4 | ||||
-rw-r--r-- | net/http/http_server_properties_impl_unittest.cc | 61 | ||||
-rw-r--r-- | net/http/http_stream_factory_impl.cc | 4 | ||||
-rw-r--r-- | net/http/http_stream_factory_impl.h | 2 |
9 files changed, 129 insertions, 44 deletions
diff --git a/chrome/browser/net/http_server_properties_manager.cc b/chrome/browser/net/http_server_properties_manager.cc index 08f8ee2d..c24e588 100644 --- a/chrome/browser/net/http_server_properties_manager.cc +++ b/chrome/browser/net/http_server_properties_manager.cc @@ -43,6 +43,9 @@ const int kVersionNumber = 2; typedef std::vector<std::string> StringVector; +// Persist 200 MRU AlternateProtocolHostPortPairs. +const int kMaxAlternateProtocolHostsToPersist = 200; + } // namespace //////////////////////////////////////////////////////////////////////////////// @@ -148,14 +151,14 @@ void HttpServerPropertiesManager::SetSupportsSpdy( } bool HttpServerPropertiesManager::HasAlternateProtocol( - const net::HostPortPair& server) const { + const net::HostPortPair& server) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); return http_server_properties_impl_->HasAlternateProtocol(server); } net::PortAlternateProtocolPair HttpServerPropertiesManager::GetAlternateProtocol( - const net::HostPortPair& server) const { + const net::HostPortPair& server) { DCHECK(BrowserThread::CurrentlyOn(BrowserThread::IO)); return http_server_properties_impl_->GetAlternateProtocol(server); } @@ -327,7 +330,7 @@ void HttpServerPropertiesManager::UpdateCacheFromPrefsOnUI() { scoped_ptr<net::PipelineCapabilityMap> pipeline_capability_map( new net::PipelineCapabilityMap); scoped_ptr<net::AlternateProtocolMap> alternate_protocol_map( - new net::AlternateProtocolMap); + new net::AlternateProtocolMap(kMaxAlternateProtocolHostsToPersist)); for (base::DictionaryValue::Iterator it(*servers_dict); !it.IsAtEnd(); it.Advance()) { @@ -393,7 +396,8 @@ void HttpServerPropertiesManager::UpdateCacheFromPrefsOnUI() { } // Get alternate_protocol server. - DCHECK(!ContainsKey(*alternate_protocol_map, server)); + DCHECK(alternate_protocol_map->Peek(server) == + alternate_protocol_map->end()); const base::DictionaryValue* port_alternate_protocol_dict = NULL; if (!server_pref_dict->GetDictionaryWithoutPathExpansion( "alternate_protocol", &port_alternate_protocol_dict)) { @@ -427,7 +431,7 @@ void HttpServerPropertiesManager::UpdateCacheFromPrefsOnUI() { port_alternate_protocol.port = port; port_alternate_protocol.protocol = protocol; - (*alternate_protocol_map)[server] = port_alternate_protocol; + alternate_protocol_map->Put(server, port_alternate_protocol); } while (false); } @@ -516,9 +520,15 @@ void HttpServerPropertiesManager::UpdatePrefsFromCacheOnIO( *spdy_settings_map = http_server_properties_impl_->spdy_settings_map(); net::AlternateProtocolMap* alternate_protocol_map = - new net::AlternateProtocolMap; - *alternate_protocol_map = + new net::AlternateProtocolMap(kMaxAlternateProtocolHostsToPersist); + const net::AlternateProtocolMap& map = http_server_properties_impl_->alternate_protocol_map(); + int count = 0; + for (net::AlternateProtocolMap::const_iterator it = map.begin(); + it != map.end() && count < kMaxAlternateProtocolHostsToPersist; + ++it, ++count) { + alternate_protocol_map->Put(it->first, it->second); + } net::PipelineCapabilityMap* pipeline_capability_map = new net::PipelineCapabilityMap; @@ -569,6 +579,8 @@ void HttpServerPropertiesManager::UpdatePrefsOnUI( net::PipelineCapabilityMap* pipeline_capability_map, const base::Closure& completion) { + // TODO(rtenneti): Fix ServerPrefMap to preserve MRU order of + // alternate_protocol_map and pipeline_capability_map. typedef std::map<net::HostPortPair, ServerPref> ServerPrefMap; ServerPrefMap server_pref_map; @@ -592,8 +604,7 @@ void HttpServerPropertiesManager::UpdatePrefsOnUI( } // Add servers that have SpdySettings to server_pref_map. - for (net::SpdySettingsMap::iterator map_it = - spdy_settings_map->begin(); + 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; @@ -608,7 +619,7 @@ void HttpServerPropertiesManager::UpdatePrefsOnUI( // Add AlternateProtocol servers to server_pref_map. for (net::AlternateProtocolMap::const_iterator map_it = - alternate_protocol_map->begin(); + 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 = diff --git a/chrome/browser/net/http_server_properties_manager.h b/chrome/browser/net/http_server_properties_manager.h index 8ac9377..c397bb7 100644 --- a/chrome/browser/net/http_server_properties_manager.h +++ b/chrome/browser/net/http_server_properties_manager.h @@ -97,13 +97,12 @@ class HttpServerPropertiesManager bool support_spdy) OVERRIDE; // Returns true if |server| has an Alternate-Protocol header. - virtual bool HasAlternateProtocol( - const net::HostPortPair& server) const OVERRIDE; + virtual bool HasAlternateProtocol(const net::HostPortPair& server) OVERRIDE; // Returns the Alternate-Protocol and port for |server|. // HasAlternateProtocol(server) must be true. virtual net::PortAlternateProtocolPair GetAlternateProtocol( - const net::HostPortPair& server) const OVERRIDE; + const net::HostPortPair& server) OVERRIDE; // Sets the Alternate-Protocol for |server|. virtual void SetAlternateProtocol( diff --git a/net/http/http_network_transaction_unittest.cc b/net/http/http_network_transaction_unittest.cc index e4edbb9..b6113b0 100644 --- a/net/http/http_network_transaction_unittest.cc +++ b/net/http/http_network_transaction_unittest.cc @@ -8144,7 +8144,7 @@ TEST_P(HttpNetworkTransactionTest, HonorAlternateProtocolHeader) { EXPECT_EQ(ERR_IO_PENDING, rv); HostPortPair http_host_port_pair("www.google.com", 80); - const HttpServerProperties& http_server_properties = + HttpServerProperties& http_server_properties = *session->http_server_properties(); EXPECT_FALSE( http_server_properties.HasAlternateProtocol(http_host_port_pair)); diff --git a/net/http/http_server_properties.h b/net/http/http_server_properties.h index ee788b4..3524dbd 100644 --- a/net/http/http_server_properties.h +++ b/net/http/http_server_properties.h @@ -8,6 +8,7 @@ #include <map> #include <string> #include "base/basictypes.h" +#include "base/containers/mru_cache.h" #include "base/memory/weak_ptr.h" #include "base/time/time.h" #include "net/base/host_port_pair.h" @@ -62,7 +63,8 @@ struct NET_EXPORT PortAlternateProtocolPair { AlternateProtocol protocol; }; -typedef std::map<HostPortPair, PortAlternateProtocolPair> AlternateProtocolMap; +typedef base::MRUCache< + HostPortPair, PortAlternateProtocolPair> AlternateProtocolMap; typedef std::map<HostPortPair, SettingsMap> SpdySettingsMap; typedef std::map<HostPortPair, HttpPipelinedHostCapability> PipelineCapabilityMap; @@ -99,12 +101,12 @@ class NET_EXPORT HttpServerProperties { bool support_spdy) = 0; // Returns true if |server| has an Alternate-Protocol header. - virtual bool HasAlternateProtocol(const HostPortPair& server) const = 0; + virtual bool HasAlternateProtocol(const HostPortPair& server) = 0; // Returns the Alternate-Protocol and port for |server|. // HasAlternateProtocol(server) must be true. virtual PortAlternateProtocolPair GetAlternateProtocol( - const HostPortPair& server) const = 0; + const HostPortPair& server) = 0; // Sets the Alternate-Protocol for |server|. virtual void SetAlternateProtocol(const HostPortPair& server, diff --git a/net/http/http_server_properties_impl.cc b/net/http/http_server_properties_impl.cc index ef6d1ed..2b72b58 100644 --- a/net/http/http_server_properties_impl.cc +++ b/net/http/http_server_properties_impl.cc @@ -19,7 +19,8 @@ namespace net { static const int kDefaultNumHostsToRemember = 200; HttpServerPropertiesImpl::HttpServerPropertiesImpl() - : pipeline_capability_map_( + : alternate_protocol_map_(AlternateProtocolMap::NO_AUTO_EVICT), + pipeline_capability_map_( new CachedPipelineCapabilityMap(kDefaultNumHostsToRemember)), weak_ptr_factory_(this) { canoncial_suffixes_.push_back(".c.youtube.com"); @@ -44,15 +45,24 @@ void HttpServerPropertiesImpl::InitializeSpdyServers( void HttpServerPropertiesImpl::InitializeAlternateProtocolServers( AlternateProtocolMap* alternate_protocol_map) { - // First swap, and then add back all the ALTERNATE_PROTOCOL_BROKEN ones since - // those don't get persisted. - alternate_protocol_map_.swap(*alternate_protocol_map); - for (AlternateProtocolMap::const_iterator it = - alternate_protocol_map->begin(); - it != alternate_protocol_map->end(); ++it) { - if (it->second.protocol == ALTERNATE_PROTOCOL_BROKEN) - alternate_protocol_map_[it->first] = it->second; + // Keep all the ALTERNATE_PROTOCOL_BROKEN ones since those don't + // get persisted. + for (AlternateProtocolMap::iterator it = alternate_protocol_map_.begin(); + it != alternate_protocol_map_.end();) { + AlternateProtocolMap::iterator old_it = it; + ++it; + if (old_it->second.protocol != ALTERNATE_PROTOCOL_BROKEN) { + alternate_protocol_map_.Erase(old_it); + } + } + + // Add the entries from persisted data. + for (AlternateProtocolMap::reverse_iterator it = + alternate_protocol_map->rbegin(); + it != alternate_protocol_map->rend(); ++it) { + alternate_protocol_map_.Put(it->first, it->second); } + // Attempt to find canonical servers. int canonical_ports[] = { 80, 443 }; for (size_t i = 0; i < canoncial_suffixes_.size(); ++i) { @@ -61,8 +71,8 @@ void HttpServerPropertiesImpl::InitializeAlternateProtocolServers( HostPortPair canonical_host(canonical_suffix, canonical_ports[j]); // If we already have a valid canonical server, we're done. if (ContainsKey(canonical_host_to_origin_map_, canonical_host) && - ContainsKey(alternate_protocol_map_, - canonical_host_to_origin_map_[canonical_host])) { + (alternate_protocol_map_.Peek(canonical_host_to_origin_map_[ + canonical_host]) != alternate_protocol_map_.end())) { continue; } // Now attempt to find a server which matches this origin and set it as @@ -147,7 +157,7 @@ base::WeakPtr<HttpServerProperties> HttpServerPropertiesImpl::GetWeakPtr() { void HttpServerPropertiesImpl::Clear() { DCHECK(CalledOnValidThread()); spdy_servers_table_.clear(); - alternate_protocol_map_.clear(); + alternate_protocol_map_.Clear(); spdy_settings_map_.clear(); pipeline_capability_map_->Clear(); } @@ -185,8 +195,8 @@ void HttpServerPropertiesImpl::SetSupportsSpdy( } bool HttpServerPropertiesImpl::HasAlternateProtocol( - const HostPortPair& server) const { - if (ContainsKey(alternate_protocol_map_, server) || + const HostPortPair& server) { + if (alternate_protocol_map_.Get(server) != alternate_protocol_map_.end() || g_forced_alternate_protocol) return true; @@ -195,19 +205,18 @@ bool HttpServerPropertiesImpl::HasAlternateProtocol( PortAlternateProtocolPair HttpServerPropertiesImpl::GetAlternateProtocol( - const HostPortPair& server) const { + const HostPortPair& server) { DCHECK(HasAlternateProtocol(server)); // First check the map. - AlternateProtocolMap::const_iterator it = - alternate_protocol_map_.find(server); + AlternateProtocolMap::iterator it = alternate_protocol_map_.Get(server); if (it != alternate_protocol_map_.end()) return it->second; // Next check the canonical host. CanonicalHostMap::const_iterator canonical_host = GetCanonicalHost(server); if (canonical_host != canonical_host_to_origin_map_.end()) - return alternate_protocol_map_.find(canonical_host->second)->second; + return alternate_protocol_map_.Get(canonical_host->second)->second; // We must be forcing an alternate. DCHECK(g_forced_alternate_protocol); @@ -247,7 +256,7 @@ void HttpServerPropertiesImpl::SetAlternateProtocol( } } - alternate_protocol_map_[server] = alternate; + alternate_protocol_map_.Put(server, alternate); // If this host ends with a canonical suffix, then set it as the // canonical host. @@ -263,7 +272,14 @@ void HttpServerPropertiesImpl::SetAlternateProtocol( void HttpServerPropertiesImpl::SetBrokenAlternateProtocol( const HostPortPair& server) { - alternate_protocol_map_[server].protocol = ALTERNATE_PROTOCOL_BROKEN; + AlternateProtocolMap::iterator it = alternate_protocol_map_.Get(server); + if (it != alternate_protocol_map_.end()) { + it->second.protocol = ALTERNATE_PROTOCOL_BROKEN; + return; + } + PortAlternateProtocolPair alternate; + alternate.protocol = ALTERNATE_PROTOCOL_BROKEN; + alternate_protocol_map_.Put(server, alternate); } void HttpServerPropertiesImpl::ClearAlternateProtocol( diff --git a/net/http/http_server_properties_impl.h b/net/http/http_server_properties_impl.h index 60fd562..2bc4792 100644 --- a/net/http/http_server_properties_impl.h +++ b/net/http/http_server_properties_impl.h @@ -87,12 +87,12 @@ class NET_EXPORT HttpServerPropertiesImpl bool support_spdy) OVERRIDE; // Returns true if |server| has an Alternate-Protocol header. - virtual bool HasAlternateProtocol(const HostPortPair& server) const OVERRIDE; + virtual bool HasAlternateProtocol(const HostPortPair& server) OVERRIDE; // Returns the Alternate-Protocol and port for |server|. // HasAlternateProtocol(server) must be true. virtual PortAlternateProtocolPair GetAlternateProtocol( - const HostPortPair& server) const OVERRIDE; + const HostPortPair& server) OVERRIDE; // Sets the Alternate-Protocol for |server|. virtual void SetAlternateProtocol( diff --git a/net/http/http_server_properties_impl_unittest.cc b/net/http/http_server_properties_impl_unittest.cc index 0ab132d..abd48b8 100644 --- a/net/http/http_server_properties_impl_unittest.cc +++ b/net/http/http_server_properties_impl_unittest.cc @@ -206,13 +206,27 @@ TEST_F(AlternateProtocolServerPropertiesTest, Initialize) { HostPortPair test_host_port_pair2("foo2", 80); impl_.SetAlternateProtocol(test_host_port_pair2, 443, NPN_SPDY_3); - AlternateProtocolMap alternate_protocol_map; + AlternateProtocolMap alternate_protocol_map( + AlternateProtocolMap::NO_AUTO_EVICT); PortAlternateProtocolPair port_alternate_protocol_pair; port_alternate_protocol_pair.port = 123; port_alternate_protocol_pair.protocol = NPN_SPDY_3; - alternate_protocol_map[test_host_port_pair2] = port_alternate_protocol_pair; + alternate_protocol_map.Put(test_host_port_pair2, + port_alternate_protocol_pair); + HostPortPair test_host_port_pair3("foo3", 80); + port_alternate_protocol_pair.port = 1234; + alternate_protocol_map.Put(test_host_port_pair3, + port_alternate_protocol_pair); impl_.InitializeAlternateProtocolServers(&alternate_protocol_map); + // Verify test_host_port_pair3 is the MRU server. + const net::AlternateProtocolMap& map = impl_.alternate_protocol_map(); + net::AlternateProtocolMap::const_iterator it = map.begin(); + it = map.begin(); + EXPECT_TRUE(it->first.Equals(test_host_port_pair3)); + EXPECT_EQ(1234, it->second.port); + EXPECT_EQ(NPN_SPDY_3, it->second.protocol); + ASSERT_TRUE(impl_.HasAlternateProtocol(test_host_port_pair1)); ASSERT_TRUE(impl_.HasAlternateProtocol(test_host_port_pair2)); port_alternate_protocol_pair = @@ -224,6 +238,49 @@ TEST_F(AlternateProtocolServerPropertiesTest, Initialize) { EXPECT_EQ(NPN_SPDY_3, port_alternate_protocol_pair.protocol); } +TEST_F(AlternateProtocolServerPropertiesTest, MRUOfHasAlternateProtocol) { + HostPortPair test_host_port_pair1("foo1", 80); + impl_.SetAlternateProtocol(test_host_port_pair1, 443, NPN_SPDY_3); + HostPortPair test_host_port_pair2("foo2", 80); + impl_.SetAlternateProtocol(test_host_port_pair2, 1234, NPN_SPDY_3); + + const net::AlternateProtocolMap& map = impl_.alternate_protocol_map(); + net::AlternateProtocolMap::const_iterator it = map.begin(); + EXPECT_TRUE(it->first.Equals(test_host_port_pair2)); + EXPECT_EQ(1234, it->second.port); + EXPECT_EQ(NPN_SPDY_3, it->second.protocol); + + // HasAlternateProtocol should reoder the AlternateProtocol map. + ASSERT_TRUE(impl_.HasAlternateProtocol(test_host_port_pair1)); + it = map.begin(); + EXPECT_TRUE(it->first.Equals(test_host_port_pair1)); + EXPECT_EQ(443, it->second.port); + EXPECT_EQ(NPN_SPDY_3, it->second.protocol); +} + +TEST_F(AlternateProtocolServerPropertiesTest, MRUOfGetAlternateProtocol) { + HostPortPair test_host_port_pair1("foo1", 80); + impl_.SetAlternateProtocol(test_host_port_pair1, 443, NPN_SPDY_3); + HostPortPair test_host_port_pair2("foo2", 80); + impl_.SetAlternateProtocol(test_host_port_pair2, 1234, NPN_SPDY_3); + + const net::AlternateProtocolMap& map = impl_.alternate_protocol_map(); + net::AlternateProtocolMap::const_iterator it = map.begin(); + EXPECT_TRUE(it->first.Equals(test_host_port_pair2)); + EXPECT_EQ(1234, it->second.port); + EXPECT_EQ(NPN_SPDY_3, it->second.protocol); + + // GetAlternateProtocol should reoder the AlternateProtocol map. + PortAlternateProtocolPair alternate = + impl_.GetAlternateProtocol(test_host_port_pair1); + EXPECT_EQ(443, alternate.port); + EXPECT_EQ(NPN_SPDY_3, alternate.protocol); + it = map.begin(); + EXPECT_TRUE(it->first.Equals(test_host_port_pair1)); + EXPECT_EQ(443, it->second.port); + EXPECT_EQ(NPN_SPDY_3, it->second.protocol); +} + TEST_F(AlternateProtocolServerPropertiesTest, SetBroken) { HostPortPair test_host_port_pair("foo", 80); impl_.SetBrokenAlternateProtocol(test_host_port_pair); diff --git a/net/http/http_stream_factory_impl.cc b/net/http/http_stream_factory_impl.cc index 81dcec0..991e469 100644 --- a/net/http/http_stream_factory_impl.cc +++ b/net/http/http_stream_factory_impl.cc @@ -189,7 +189,7 @@ const HostMappingRules* HttpStreamFactoryImpl::GetHostMappingRules() const { PortAlternateProtocolPair HttpStreamFactoryImpl::GetAlternateProtocolRequestFor( const GURL& original_url, - GURL* alternate_url) const { + GURL* alternate_url) { if (!use_alternate_protocols()) return kNoAlternateProtocol; @@ -199,7 +199,7 @@ PortAlternateProtocolPair HttpStreamFactoryImpl::GetAlternateProtocolRequestFor( HostPortPair origin = HostPortPair(original_url.HostNoBrackets(), original_url.EffectiveIntPort()); - const HttpServerProperties& http_server_properties = + HttpServerProperties& http_server_properties = *session_->http_server_properties(); if (!http_server_properties.HasAlternateProtocol(origin)) return kNoAlternateProtocol; diff --git a/net/http/http_stream_factory_impl.h b/net/http/http_stream_factory_impl.h index 4824dec..db1e00c 100644 --- a/net/http/http_stream_factory_impl.h +++ b/net/http/http_stream_factory_impl.h @@ -90,7 +90,7 @@ class NET_EXPORT_PRIVATE HttpStreamFactoryImpl : PortAlternateProtocolPair GetAlternateProtocolRequestFor( const GURL& original_url, - GURL* alternate_url) const; + GURL* alternate_url); // Detaches |job| from |request|. void OrphanJob(Job* job, const Request* request); |