diff options
author | michaeln@chromium.org <michaeln@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-19 03:12:12 +0000 |
---|---|---|
committer | michaeln@chromium.org <michaeln@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-11-19 03:12:12 +0000 |
commit | 0b52f1c47868cb6d7b132a15bd7c0a94df08de79 (patch) | |
tree | 7ecce97440c40f357f65672305d8597b51775faa /webkit/appcache | |
parent | c112093004963fb24639127d4a7ce3b2fdfda508 (diff) | |
download | chromium_src-0b52f1c47868cb6d7b132a15bd7c0a94df08de79.zip chromium_src-0b52f1c47868cb6d7b132a15bd7c0a94df08de79.tar.gz chromium_src-0b52f1c47868cb6d7b132a15bd7c0a94df08de79.tar.bz2 |
Alter the relative priorities of network vs fallback namespaces in the appcache. If a resource url is in an appcache's network namespace and fallback namespace, the network namespace wins (with the exception of the special '*' network namespace which does not take priority over the fallback namespace.
BUG=WK49292
TEST=unit test, also a new layout test (not landed yet)
Review URL: http://codereview.chromium.org/4807001
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@66731 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/appcache')
-rw-r--r-- | webkit/appcache/appcache.cc | 24 | ||||
-rw-r--r-- | webkit/appcache/appcache.h | 5 | ||||
-rw-r--r-- | webkit/appcache/appcache_storage_impl.cc | 47 | ||||
-rw-r--r-- | webkit/appcache/appcache_storage_impl_unittest.cc | 42 | ||||
-rw-r--r-- | webkit/appcache/appcache_unittest.cc | 23 |
5 files changed, 125 insertions, 16 deletions
diff --git a/webkit/appcache/appcache.cc b/webkit/appcache/appcache.cc index aeeeb0c..f877576 100644 --- a/webkit/appcache/appcache.cc +++ b/webkit/appcache/appcache.cc @@ -193,12 +193,20 @@ bool AppCache::FindResponseForRequest(const GURL& url, } else { url_no_ref = url; } + + // 6.6.6 Changes to the networking model + AppCacheEntry* entry = GetEntry(url_no_ref); if (entry) { *found_entry = *entry; return true; } + if (*found_network_namespace = + IsInNetworkNamespace(url_no_ref, online_whitelist_namespaces_)) { + return true; + } + FallbackNamespace* fallback_namespace = FindFallbackNamespace(url_no_ref); if (fallback_namespace) { entry = GetEntry(fallback_namespace->second); @@ -208,7 +216,7 @@ bool AppCache::FindResponseForRequest(const GURL& url, return true; } - *found_network_namespace = IsInNetworkNamespace(url_no_ref); + *found_network_namespace = online_whitelist_all_; return *found_network_namespace; } @@ -223,18 +231,16 @@ FallbackNamespace* AppCache::FindFallbackNamespace(const GURL& url) { return NULL; } -bool AppCache::IsInNetworkNamespace(const GURL& url) { - if (online_whitelist_all_) - return true; - +// static +bool AppCache::IsInNetworkNamespace( + const GURL& url, + const std::vector<GURL> &namespaces) { // TODO(michaeln): There are certainly better 'prefix matching' // structures and algorithms that can be applied here and above. - size_t count = online_whitelist_namespaces_.size(); + size_t count = namespaces.size(); for (size_t i = 0; i < count; ++i) { - if (StartsWithASCII( - url.spec(), online_whitelist_namespaces_[i].spec(), true)) { + if (StartsWithASCII(url.spec(), namespaces[i].spec(), true)) return true; - } } return false; } diff --git a/webkit/appcache/appcache.h b/webkit/appcache/appcache.h index 20298a4..8e41973 100644 --- a/webkit/appcache/appcache.h +++ b/webkit/appcache/appcache.h @@ -106,6 +106,10 @@ class AppCache : public base::RefCounted<AppCache> { AppCacheEntry* found_entry, AppCacheEntry* found_fallback_entry, GURL* found_fallback_namespace, bool* found_network_namespace); + static bool IsInNetworkNamespace( + const GURL& url, + const std::vector<GURL> &namespaces); + private: friend class AppCacheGroup; friend class AppCacheHost; @@ -120,7 +124,6 @@ class AppCache : public base::RefCounted<AppCache> { // FindResponseForRequest helpers FallbackNamespace* FindFallbackNamespace(const GURL& url); - bool IsInNetworkNamespace(const GURL& url); // Use AppCacheHost::AssociateCache() to manipulate host association. void AssociateHost(AppCacheHost* host) { diff --git a/webkit/appcache/appcache_storage_impl.cc b/webkit/appcache/appcache_storage_impl.cc index b0aa25a..8d21105 100644 --- a/webkit/appcache/appcache_storage_impl.cc +++ b/webkit/appcache/appcache_storage_impl.cc @@ -558,13 +558,52 @@ class AppCacheStorageImpl::FindMainResponseTask : public DatabaseTask { GURL manifest_url_; }; +// Helpers for FindMainResponseTask::Run() namespace { bool SortByLength( const AppCacheDatabase::FallbackNameSpaceRecord& lhs, const AppCacheDatabase::FallbackNameSpaceRecord& rhs) { return lhs.namespace_url.spec().length() > rhs.namespace_url.spec().length(); } -} + +class NetworkNamespaceHelper { + public: + explicit NetworkNamespaceHelper(AppCacheDatabase* database) + : database_(database) { + } + + bool IsInNetworkNamespace(const GURL& url, int64 cache_id) { + static const std::vector<GURL> kEmptyVector; + typedef std::pair<WhiteListMap::iterator, bool> InsertResult; + InsertResult result = namespaces_map_.insert( + WhiteListMap::value_type(cache_id, kEmptyVector)); + if (result.second) + GetOnlineWhiteListForCache(cache_id, &result.first->second); + return AppCache::IsInNetworkNamespace(url, result.first->second); + } + + private: + void GetOnlineWhiteListForCache( + int64 cache_id, std::vector<GURL>* urls) { + DCHECK(urls && urls->empty()); + typedef std::vector<AppCacheDatabase::OnlineWhiteListRecord> + WhiteListVector; + WhiteListVector records; + if (!database_->FindOnlineWhiteListForCache(cache_id, &records)) + return; + WhiteListVector::const_iterator iter = records.begin(); + while (iter != records.end()) { + urls->push_back(iter->namespace_url); + ++iter; + } + } + + // Key is cache id + typedef std::map<int64, std::vector<GURL> > WhiteListMap; + WhiteListMap namespaces_map_; + AppCacheDatabase* database_; +}; +} // namespace void AppCacheStorageImpl::FindMainResponseTask::Run() { // We have a bias for hits from caches that are in use. @@ -615,7 +654,13 @@ void AppCacheStorageImpl::FindMainResponseTask::Run() { bool has_candidate = false; GURL candidate_fallback_namespace; std::vector<AppCacheDatabase::FallbackNameSpaceRecord>::iterator iter; + NetworkNamespaceHelper network_namespace_helper(database_); for (iter = fallbacks.begin(); iter < fallbacks.end(); ++iter) { + // Skip this fallback namespace if the requested url falls into a network + // namespace of the containing appcache. + if (network_namespace_helper.IsInNetworkNamespace(url_, iter->cache_id)) + continue; + if (has_candidate && (candidate_fallback_namespace.spec().length() > iter->namespace_url.spec().length())) { diff --git a/webkit/appcache/appcache_storage_impl_unittest.cc b/webkit/appcache/appcache_storage_impl_unittest.cc index 116ce47..87df2b0 100644 --- a/webkit/appcache/appcache_storage_impl_unittest.cc +++ b/webkit/appcache/appcache_storage_impl_unittest.cc @@ -31,6 +31,8 @@ const GURL kFallbackNamespace("http://blah/fallback_namespace/"); const GURL kFallbackNamespace2("http://blah/fallback_namespace/longer"); const GURL kFallbackTestUrl("http://blah/fallback_namespace/longer/test"); const GURL kOnlineNamespace("http://blah/online_namespace"); +const GURL kOnlineNamespaceWithinFallback( + "http://blah/fallback_namespace/online/"); // For the duration of this test case, we hijack the AppCacheThread API // calls and implement them in terms of the io and db threads created here. @@ -926,11 +928,19 @@ class AppCacheStorageImplTest : public testing::Test { void FindMainResponseExclusions(bool drop_from_working_set) { // Setup some preconditions. Create a complete cache with a - // foreign entry and an online namespace. + // foreign entry, an online namespace, and a second online + // namespace nested within a fallback namespace. MakeCacheAndGroup(kManifestUrl, 1, 1, true); cache_->AddEntry(kEntryUrl, AppCacheEntry(AppCacheEntry::EXPLICIT | AppCacheEntry::FOREIGN, 1)); cache_->online_whitelist_namespaces_.push_back(kOnlineNamespace); + cache_->AddEntry(kEntryUrl2, AppCacheEntry(AppCacheEntry::FALLBACK, 2)); + cache_->fallback_namespaces_.push_back( + FallbackNamespace(kFallbackNamespace, kEntryUrl2)); + cache_->online_whitelist_namespaces_.push_back(kOnlineNamespace); + cache_->online_whitelist_namespaces_.push_back( + kOnlineNamespaceWithinFallback); + AppCacheDatabase::EntryRecord entry_record; entry_record.cache_id = 1; entry_record.url = kEntryUrl; @@ -941,6 +951,16 @@ class AppCacheStorageImplTest : public testing::Test { whitelist_record.cache_id = 1; whitelist_record.namespace_url = kOnlineNamespace; EXPECT_TRUE(database()->InsertOnlineWhiteList(&whitelist_record)); + AppCacheDatabase::FallbackNameSpaceRecord fallback_namespace_record; + fallback_namespace_record.cache_id = 1; + fallback_namespace_record.fallback_entry_url = kEntryUrl2; + fallback_namespace_record.namespace_url = kFallbackNamespace; + fallback_namespace_record.origin = kManifestUrl.GetOrigin(); + EXPECT_TRUE( + database()->InsertFallbackNameSpace(&fallback_namespace_record)); + whitelist_record.cache_id = 1; + whitelist_record.namespace_url = kOnlineNamespaceWithinFallback; + EXPECT_TRUE(database()->InsertOnlineWhiteList(&whitelist_record)); if (drop_from_working_set) { cache_ = NULL; group_ = NULL; @@ -948,11 +968,12 @@ class AppCacheStorageImplTest : public testing::Test { // We should not find anything for the foreign entry. PushNextTask(NewRunnableMethod( - this, &AppCacheStorageImplTest::Verify_NotFound, kEntryUrl, false)); + this, &AppCacheStorageImplTest::Verify_ExclusionNotFound, + kEntryUrl, 1)); storage()->FindResponseForMainRequest(kEntryUrl, delegate()); } - void Verify_NotFound(GURL expected_url, bool test_finished) { + void Verify_ExclusionNotFound(GURL expected_url, int phase) { EXPECT_EQ(expected_url, delegate()->found_url_); EXPECT_TRUE(delegate()->found_manifest_url_.is_empty()); EXPECT_FALSE(delegate()->found_blocked_by_policy_); @@ -963,13 +984,24 @@ class AppCacheStorageImplTest : public testing::Test { EXPECT_EQ(0, delegate()->found_entry_.types()); EXPECT_EQ(0, delegate()->found_fallback_entry_.types()); - if (!test_finished) { + if (phase == 1) { // We should not find anything for the online namespace. PushNextTask(NewRunnableMethod(this, - &AppCacheStorageImplTest::Verify_NotFound, kOnlineNamespace, true)); + &AppCacheStorageImplTest::Verify_ExclusionNotFound, + kOnlineNamespace, 2)); storage()->FindResponseForMainRequest(kOnlineNamespace, delegate()); return; } + if (phase == 2) { + // We should not find anything for the online namespace nested within + // the fallback namespace. + PushNextTask(NewRunnableMethod(this, + &AppCacheStorageImplTest::Verify_ExclusionNotFound, + kOnlineNamespaceWithinFallback, 3)); + storage()->FindResponseForMainRequest( + kOnlineNamespaceWithinFallback, delegate()); + return; + } TestFinished(); } diff --git a/webkit/appcache/appcache_unittest.cc b/webkit/appcache/appcache_unittest.cc index bdeaa53..5e1de6b 100644 --- a/webkit/appcache/appcache_unittest.cc +++ b/webkit/appcache/appcache_unittest.cc @@ -129,6 +129,8 @@ TEST(AppCacheTest, FindResponseForRequest) { "http://blah/online_namespace/explicit"); const GURL kFallbackTestUrl1("http://blah/fallback_namespace/1"); const GURL kFallbackTestUrl2("http://blah/fallback_namespace/longer2"); + const GURL kOnlineNamespaceWithinFallback( + "http://blah/fallback_namespace/1/online"); const int64 kFallbackResponseId1 = 1; const int64 kFallbackResponseId2 = 2; @@ -138,6 +140,8 @@ TEST(AppCacheTest, FindResponseForRequest) { Manifest manifest; manifest.online_whitelist_namespaces.push_back(kOnlineNamespaceUrl); + manifest.online_whitelist_namespaces.push_back( + kOnlineNamespaceWithinFallback); manifest.fallback_namespaces.push_back( FallbackNamespace(kFallbackNamespaceUrl1, kFallbackEntryUrl1)); manifest.fallback_namespaces.push_back( @@ -232,6 +236,25 @@ TEST(AppCacheTest, FindResponseForRequest) { EXPECT_EQ(kFallbackEntryUrl2, cache->GetFallbackEntryUrl(fallback_namespace)); EXPECT_FALSE(network_namespace); + + fallback_entry = AppCacheEntry(); // reset + + found = cache->FindResponseForRequest(kOnlineNamespaceWithinFallback, + &entry, &fallback_entry, &fallback_namespace, &network_namespace); + EXPECT_TRUE(found); + EXPECT_FALSE(entry.has_response_id()); + EXPECT_FALSE(fallback_entry.has_response_id()); + EXPECT_TRUE(network_namespace); + + fallback_entry = AppCacheEntry(); // reset + + found = cache->FindResponseForRequest( + kOnlineNamespaceWithinFallback.Resolve("online_resource"), + &entry, &fallback_entry, &fallback_namespace, &network_namespace); + EXPECT_TRUE(found); + EXPECT_FALSE(entry.has_response_id()); + EXPECT_FALSE(fallback_entry.has_response_id()); + EXPECT_TRUE(network_namespace); } } // namespace appacache |