summaryrefslogtreecommitdiffstats
path: root/webkit/appcache
diff options
context:
space:
mode:
authormichaeln@chromium.org <michaeln@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-11-19 03:12:12 +0000
committermichaeln@chromium.org <michaeln@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2010-11-19 03:12:12 +0000
commit0b52f1c47868cb6d7b132a15bd7c0a94df08de79 (patch)
tree7ecce97440c40f357f65672305d8597b51775faa /webkit/appcache
parentc112093004963fb24639127d4a7ce3b2fdfda508 (diff)
downloadchromium_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.cc24
-rw-r--r--webkit/appcache/appcache.h5
-rw-r--r--webkit/appcache/appcache_storage_impl.cc47
-rw-r--r--webkit/appcache/appcache_storage_impl_unittest.cc42
-rw-r--r--webkit/appcache/appcache_unittest.cc23
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