summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/browser/extensions/extension_special_storage_policy.cc14
-rw-r--r--chrome/browser/extensions/extension_special_storage_policy.h6
-rw-r--r--chrome/browser/extensions/extension_special_storage_policy_unittest.cc8
-rw-r--r--chrome/browser/extensions/mock_extension_special_storage_policy.cc9
-rw-r--r--chrome/browser/extensions/mock_extension_special_storage_policy.h7
-rw-r--r--chrome/browser/profiles/profile_impl.cc9
-rw-r--r--chrome/chrome_tests.gypi1
-rw-r--r--chrome/test/base/testing_profile.cc2
-rw-r--r--content/browser/in_process_webkit/dom_storage_context.cc23
-rw-r--r--content/browser/in_process_webkit/dom_storage_context.h9
-rw-r--r--content/browser/in_process_webkit/dom_storage_unittest.cc67
-rw-r--r--content/browser/in_process_webkit/webkit_context.cc10
-rw-r--r--content/browser/in_process_webkit/webkit_context.h4
-rw-r--r--webkit/quota/mock_special_storage_policy.cc4
-rw-r--r--webkit/quota/mock_special_storage_policy.h8
-rw-r--r--webkit/quota/special_storage_policy.h4
16 files changed, 175 insertions, 10 deletions
diff --git a/chrome/browser/extensions/extension_special_storage_policy.cc b/chrome/browser/extensions/extension_special_storage_policy.cc
index 08ff3f2..95a2486 100644
--- a/chrome/browser/extensions/extension_special_storage_policy.cc
+++ b/chrome/browser/extensions/extension_special_storage_policy.cc
@@ -5,11 +5,15 @@
#include "chrome/browser/extensions/extension_special_storage_policy.h"
#include "base/logging.h"
+#include "chrome/browser/content_settings/host_content_settings_map.h"
+#include "chrome/common/content_settings.h"
#include "chrome/common/extensions/extension.h"
#include "chrome/common/url_constants.h"
#include "content/browser/browser_thread.h"
-ExtensionSpecialStoragePolicy::ExtensionSpecialStoragePolicy() {}
+ExtensionSpecialStoragePolicy::ExtensionSpecialStoragePolicy(
+ HostContentSettingsMap* host_content_settings_map)
+ : host_content_settings_map_(host_content_settings_map) {}
ExtensionSpecialStoragePolicy::~ExtensionSpecialStoragePolicy() {}
@@ -25,6 +29,14 @@ bool ExtensionSpecialStoragePolicy::IsStorageUnlimited(const GURL& origin) {
return unlimited_extensions_.Contains(origin);
}
+bool ExtensionSpecialStoragePolicy::IsStorageSessionOnly(const GURL& origin) {
+ if (host_content_settings_map_ == NULL)
+ return false;
+ ContentSetting content_setting = host_content_settings_map_->
+ GetCookieContentSetting(origin, origin, true);
+ return (content_setting == CONTENT_SETTING_SESSION_ONLY);
+}
+
bool ExtensionSpecialStoragePolicy::IsFileHandler(
const std::string& extension_id) {
base::AutoLock locker(lock_);
diff --git a/chrome/browser/extensions/extension_special_storage_policy.h b/chrome/browser/extensions/extension_special_storage_policy.h
index b31407c..8ce9d30 100644
--- a/chrome/browser/extensions/extension_special_storage_policy.h
+++ b/chrome/browser/extensions/extension_special_storage_policy.h
@@ -14,18 +14,21 @@
#include "webkit/quota/special_storage_policy.h"
class Extension;
+class HostContentSettingsMap;
// Special rights are granted to 'extensions' and 'applications'. The
// storage subsystems and the browsing data remover query this interface
// to determine which origins have these rights.
class ExtensionSpecialStoragePolicy : public quota::SpecialStoragePolicy {
public:
- ExtensionSpecialStoragePolicy();
+ explicit ExtensionSpecialStoragePolicy(
+ HostContentSettingsMap* host_content_settings_map);
// SpecialStoragePolicy methods used by storage subsystems and the browsing
// data remover. These methods are safe to call on any thread.
virtual bool IsStorageProtected(const GURL& origin);
virtual bool IsStorageUnlimited(const GURL& origin);
+ virtual bool IsStorageSessionOnly(const GURL& origin);
virtual bool IsFileHandler(const std::string& extension_id);
// Methods used by the ExtensionService to populate this class.
@@ -61,6 +64,7 @@ class ExtensionSpecialStoragePolicy : public quota::SpecialStoragePolicy {
SpecialCollection protected_apps_;
SpecialCollection unlimited_extensions_;
SpecialCollection file_handler_extensions_;
+ scoped_refptr<HostContentSettingsMap> host_content_settings_map_;
};
#endif // CHROME_BROWSER_EXTENSIONS_EXTENSION_SPECIAL_STORAGE_POLICY_H_
diff --git a/chrome/browser/extensions/extension_special_storage_policy_unittest.cc b/chrome/browser/extensions/extension_special_storage_policy_unittest.cc
index cbaf6ed..bd7f274 100644
--- a/chrome/browser/extensions/extension_special_storage_policy_unittest.cc
+++ b/chrome/browser/extensions/extension_special_storage_policy_unittest.cc
@@ -118,7 +118,7 @@ TEST_F(ExtensionSpecialStoragePolicyTest, EmptyPolicy) {
const GURL kExtensionUrl("chrome-extension://bar");
scoped_refptr<ExtensionSpecialStoragePolicy> policy(
- new ExtensionSpecialStoragePolicy);
+ new ExtensionSpecialStoragePolicy(NULL));
ASSERT_FALSE(policy->IsStorageUnlimited(kHttpUrl));
ASSERT_FALSE(policy->IsStorageUnlimited(kHttpUrl)); // test cached result
@@ -133,7 +133,7 @@ TEST_F(ExtensionSpecialStoragePolicyTest, EmptyPolicy) {
TEST_F(ExtensionSpecialStoragePolicyTest, AppWithProtectedStorage) {
scoped_refptr<Extension> extension(CreateProtectedApp());
scoped_refptr<ExtensionSpecialStoragePolicy> policy(
- new ExtensionSpecialStoragePolicy);
+ new ExtensionSpecialStoragePolicy(NULL));
policy->GrantRightsForExtension(extension);
EXPECT_FALSE(policy->IsStorageUnlimited(extension->url()));
EXPECT_FALSE(policy->IsStorageUnlimited(GURL("http://explicit/")));
@@ -152,7 +152,7 @@ TEST_F(ExtensionSpecialStoragePolicyTest, AppWithProtectedStorage) {
TEST_F(ExtensionSpecialStoragePolicyTest, AppWithUnlimitedStorage) {
scoped_refptr<Extension> extension(CreateUnlimitedApp());
scoped_refptr<ExtensionSpecialStoragePolicy> policy(
- new ExtensionSpecialStoragePolicy);
+ new ExtensionSpecialStoragePolicy(NULL));
policy->GrantRightsForExtension(extension);
EXPECT_TRUE(policy->IsStorageProtected(GURL("http://explicit/")));
EXPECT_TRUE(policy->IsStorageProtected(GURL("http://explicit:6000/")));
@@ -181,7 +181,7 @@ TEST_F(ExtensionSpecialStoragePolicyTest, OverlappingApps) {
scoped_refptr<Extension> protected_app(CreateProtectedApp());
scoped_refptr<Extension> unlimited_app(CreateUnlimitedApp());
scoped_refptr<ExtensionSpecialStoragePolicy> policy(
- new ExtensionSpecialStoragePolicy);
+ new ExtensionSpecialStoragePolicy(NULL));
policy->GrantRightsForExtension(protected_app);
policy->GrantRightsForExtension(unlimited_app);
diff --git a/chrome/browser/extensions/mock_extension_special_storage_policy.cc b/chrome/browser/extensions/mock_extension_special_storage_policy.cc
index dddf49f..7cf86cd 100644
--- a/chrome/browser/extensions/mock_extension_special_storage_policy.cc
+++ b/chrome/browser/extensions/mock_extension_special_storage_policy.cc
@@ -4,7 +4,9 @@
#include "chrome/browser/extensions/mock_extension_special_storage_policy.h"
-MockExtensionSpecialStoragePolicy::MockExtensionSpecialStoragePolicy() {}
+MockExtensionSpecialStoragePolicy::MockExtensionSpecialStoragePolicy()
+ : ExtensionSpecialStoragePolicy(NULL) {}
+
MockExtensionSpecialStoragePolicy::~MockExtensionSpecialStoragePolicy() {}
bool MockExtensionSpecialStoragePolicy::IsStorageProtected(const GURL& origin) {
@@ -15,6 +17,11 @@ bool MockExtensionSpecialStoragePolicy::IsStorageUnlimited(const GURL& origin) {
return unlimited_.find(origin) != unlimited_.end();
}
+bool MockExtensionSpecialStoragePolicy::IsStorageSessionOnly(
+ const GURL& origin) {
+ return session_only_.find(origin) != session_only_.end();
+}
+
bool MockExtensionSpecialStoragePolicy::IsFileHandler(
const std::string& extension_id) {
return file_handlers_.find(extension_id) != file_handlers_.end();
diff --git a/chrome/browser/extensions/mock_extension_special_storage_policy.h b/chrome/browser/extensions/mock_extension_special_storage_policy.h
index 0c481f1..b4ce548 100644
--- a/chrome/browser/extensions/mock_extension_special_storage_policy.h
+++ b/chrome/browser/extensions/mock_extension_special_storage_policy.h
@@ -22,6 +22,7 @@ class MockExtensionSpecialStoragePolicy : public ExtensionSpecialStoragePolicy {
virtual bool IsStorageProtected(const GURL& origin);
virtual bool IsStorageUnlimited(const GURL& origin);
+ virtual bool IsStorageSessionOnly(const GURL& origin);
virtual bool IsFileHandler(const std::string& extension_id);
void AddProtected(const GURL& origin) {
@@ -32,6 +33,10 @@ class MockExtensionSpecialStoragePolicy : public ExtensionSpecialStoragePolicy {
unlimited_.insert(origin);
}
+ void AddSessionOnly(const GURL& origin) {
+ session_only_.insert(origin);
+ }
+
void AddFileHandler(const std::string& id) {
file_handlers_.insert(id);
}
@@ -39,12 +44,14 @@ class MockExtensionSpecialStoragePolicy : public ExtensionSpecialStoragePolicy {
void Reset() {
protected_.clear();
unlimited_.clear();
+ session_only_.clear();
file_handlers_.clear();
}
private:
std::set<GURL> protected_;
std::set<GURL> unlimited_;
+ std::set<GURL> session_only_;
std::set<std::string> file_handlers_;
DISALLOW_COPY_AND_ASSIGN(MockExtensionSpecialStoragePolicy);
diff --git a/chrome/browser/profiles/profile_impl.cc b/chrome/browser/profiles/profile_impl.cc
index 7790c47..f838d08 100644
--- a/chrome/browser/profiles/profile_impl.cc
+++ b/chrome/browser/profiles/profile_impl.cc
@@ -663,6 +663,9 @@ ProfileImpl::~ProfileImpl() {
true));
}
+ if (webkit_context_.get())
+ webkit_context_->DeleteSessionOnlyData();
+
StopCreateSessionServiceTimer();
// Remove pref observers
@@ -827,8 +830,10 @@ ExtensionEventRouter* ProfileImpl::GetExtensionEventRouter() {
ExtensionSpecialStoragePolicy*
ProfileImpl::GetExtensionSpecialStoragePolicy() {
- if (!extension_special_storage_policy_.get())
- extension_special_storage_policy_ = new ExtensionSpecialStoragePolicy();
+ if (!extension_special_storage_policy_.get()) {
+ extension_special_storage_policy_ =
+ new ExtensionSpecialStoragePolicy(GetHostContentSettingsMap());
+ }
return extension_special_storage_policy_.get();
}
diff --git a/chrome/chrome_tests.gypi b/chrome/chrome_tests.gypi
index 5aaf31f..181bda7 100644
--- a/chrome/chrome_tests.gypi
+++ b/chrome/chrome_tests.gypi
@@ -2038,6 +2038,7 @@
'../content/browser/geolocation/win7_location_api_unittest_win.cc',
'../content/browser/geolocation/win7_location_provider_unittest_win.cc',
'../content/browser/gpu/gpu_blacklist_unittest.cc',
+ '../content/browser/in_process_webkit/dom_storage_unittest.cc',
'../content/browser/in_process_webkit/indexed_db_quota_client_unittest.cc',
'../content/browser/in_process_webkit/webkit_context_unittest.cc',
'../content/browser/in_process_webkit/webkit_thread_unittest.cc',
diff --git a/chrome/test/base/testing_profile.cc b/chrome/test/base/testing_profile.cc
index 1a7b131..2f3ecfa 100644
--- a/chrome/test/base/testing_profile.cc
+++ b/chrome/test/base/testing_profile.cc
@@ -440,7 +440,7 @@ void TestingProfile::SetExtensionSpecialStoragePolicy(
ExtensionSpecialStoragePolicy*
TestingProfile::GetExtensionSpecialStoragePolicy() {
if (!extension_special_storage_policy_.get())
- extension_special_storage_policy_ = new ExtensionSpecialStoragePolicy();
+ extension_special_storage_policy_ = new ExtensionSpecialStoragePolicy(NULL);
return extension_special_storage_policy_.get();
}
diff --git a/content/browser/in_process_webkit/dom_storage_context.cc b/content/browser/in_process_webkit/dom_storage_context.cc
index 3daa66e..d86b089 100644
--- a/content/browser/in_process_webkit/dom_storage_context.cc
+++ b/content/browser/in_process_webkit/dom_storage_context.cc
@@ -198,6 +198,29 @@ void DOMStorageContext::DeleteDataModifiedSince(const base::Time& cutoff) {
}
}
+void DOMStorageContext::DeleteSessionOnlyData() {
+ DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
+
+ // Make sure that we don't delete a database that's currently being accessed
+ // by unloading all of the databases temporarily.
+ PurgeMemory();
+
+ file_util::FileEnumerator file_enumerator(
+ data_path_.Append(kLocalStorageDirectory), false,
+ file_util::FileEnumerator::FILES);
+ for (FilePath path = file_enumerator.Next(); !path.value().empty();
+ path = file_enumerator.Next()) {
+ GURL origin(WebSecurityOrigin::createFromDatabaseIdentifier(
+ webkit_glue::FilePathToWebString(path.BaseName())).toString());
+ if (!special_storage_policy_->IsStorageSessionOnly(origin))
+ continue;
+ if (special_storage_policy_->IsStorageProtected(origin))
+ continue;
+
+ file_util::Delete(path, false);
+ }
+}
+
void DOMStorageContext::DeleteLocalStorageFile(const FilePath& file_path) {
DCHECK(BrowserThread::CurrentlyOn(BrowserThread::WEBKIT));
diff --git a/content/browser/in_process_webkit/dom_storage_context.h b/content/browser/in_process_webkit/dom_storage_context.h
index 4b5e639..a23dc83 100644
--- a/content/browser/in_process_webkit/dom_storage_context.h
+++ b/content/browser/in_process_webkit/dom_storage_context.h
@@ -10,6 +10,7 @@
#include <set>
#include "base/file_path.h"
+#include "base/gtest_prod_util.h"
#include "base/memory/ref_counted.h"
#include "base/string16.h"
#include "base/time.h"
@@ -80,6 +81,11 @@ class DOMStorageContext {
// are not deleted by this method.
void DeleteDataModifiedSince(const base::Time& cutoff);
+ // Delete any local storage files which are allowed to be stored only until
+ // the end of the session. Protected origins, per the SpecialStoragePolicy,
+ // are not deleted by this method.
+ void DeleteSessionOnlyData();
+
// Deletes a single local storage file.
void DeleteLocalStorageFile(const FilePath& file_path);
@@ -108,6 +114,9 @@ class DOMStorageContext {
#endif
private:
+
+ FRIEND_TEST_ALL_PREFIXES(DOMStorageTest, SessionOnly);
+
// Get the local storage instance. The object is owned by this class.
DOMStorageNamespace* CreateLocalStorage();
diff --git a/content/browser/in_process_webkit/dom_storage_unittest.cc b/content/browser/in_process_webkit/dom_storage_unittest.cc
new file mode 100644
index 0000000..14f5a30
--- /dev/null
+++ b/content/browser/in_process_webkit/dom_storage_unittest.cc
@@ -0,0 +1,67 @@
+// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "base/file_path.h"
+#include "base/file_util.h"
+#include "chrome/test/base/testing_browser_process.h"
+#include "chrome/test/base/testing_browser_process_test.h"
+#include "chrome/test/base/testing_profile.h"
+#include "content/browser/in_process_webkit/webkit_context.h"
+#include "webkit/quota/mock_special_storage_policy.h"
+
+class DOMStorageTest : public TestingBrowserProcessTest {
+ public:
+ DOMStorageTest()
+ : message_loop_(MessageLoop::TYPE_IO),
+ webkit_thread_(BrowserThread::WEBKIT, &message_loop_) {
+ }
+ protected:
+ MessageLoop message_loop_;
+
+ private:
+ BrowserThread webkit_thread_;
+};
+
+TEST_F(DOMStorageTest, SessionOnly) {
+ GURL session_only_origin("http://www.sessiononly.com");
+ scoped_refptr<quota::MockSpecialStoragePolicy> special_storage_policy =
+ new quota::MockSpecialStoragePolicy;
+ special_storage_policy->AddSessionOnly(session_only_origin);
+
+ TestingProfile profile;
+
+ // Create databases for permanent and session-only origins.
+ FilePath domstorage_dir = profile.GetPath().Append(
+ DOMStorageContext::kLocalStorageDirectory);
+ FilePath::StringType session_only_database(
+ FILE_PATH_LITERAL("http_www.sessiononly.com_0"));
+ FilePath::StringType permanent_database(
+ FILE_PATH_LITERAL("http_www.permanent.com_0"));
+ session_only_database.append(DOMStorageContext::kLocalStorageExtension);
+ permanent_database.append(DOMStorageContext::kLocalStorageExtension);
+ FilePath session_only_database_path =
+ domstorage_dir.Append(session_only_database);
+ FilePath permanent_database_path =
+ domstorage_dir.Append(permanent_database);
+
+ ASSERT_TRUE(file_util::CreateDirectory(domstorage_dir));
+
+ ASSERT_EQ(1, file_util::WriteFile(session_only_database_path, ".", 1));
+ ASSERT_EQ(1, file_util::WriteFile(permanent_database_path, ".", 1));
+
+ // Inject MockSpecialStoragePolicy into DOMStorageContext.
+ profile.GetWebKitContext()->dom_storage_context()->special_storage_policy_ =
+ special_storage_policy;
+
+ // Tell the WebKitContext explicitly do clean up the session-only
+ // data. TestingProfile (unlike ProfileImpl) doesn't do it automatically when
+ // destructed. The deletion is done immediately since we're on the WEBKIT
+ // thread (created by the test).
+ profile.GetWebKitContext()->DeleteSessionOnlyData();
+
+ // Expected result: the database file for the permanent storage remains but
+ // the database for the session only storage was deleted.
+ EXPECT_FALSE(file_util::PathExists(session_only_database_path));
+ EXPECT_TRUE(file_util::PathExists(permanent_database_path));
+}
diff --git a/content/browser/in_process_webkit/webkit_context.cc b/content/browser/in_process_webkit/webkit_context.cc
index 6359916..8fd9d11 100644
--- a/content/browser/in_process_webkit/webkit_context.cc
+++ b/content/browser/in_process_webkit/webkit_context.cc
@@ -66,6 +66,16 @@ void WebKitContext::DeleteDataModifiedSince(const base::Time& cutoff) {
dom_storage_context_->DeleteDataModifiedSince(cutoff);
}
+void WebKitContext::DeleteSessionOnlyData() {
+ if (!BrowserThread::CurrentlyOn(BrowserThread::WEBKIT)) {
+ BrowserThread::PostTask(
+ BrowserThread::WEBKIT, FROM_HERE,
+ NewRunnableMethod(this, &WebKitContext::DeleteSessionOnlyData));
+ return;
+ }
+
+ dom_storage_context_->DeleteSessionOnlyData();
+}
void WebKitContext::DeleteSessionStorageNamespace(
int64 session_storage_namespace_id) {
diff --git a/content/browser/in_process_webkit/webkit_context.h b/content/browser/in_process_webkit/webkit_context.h
index 6992d77..8d404ce 100644
--- a/content/browser/in_process_webkit/webkit_context.h
+++ b/content/browser/in_process_webkit/webkit_context.h
@@ -69,6 +69,10 @@ class WebKitContext : public base::RefCountedThreadSafe<WebKitContext> {
// last modified on or after the following time.
void DeleteDataModifiedSince(const base::Time& cutoff);
+ // Tell all children (where applicable) to delete any objects that are allowed
+ // to be stored only until the end of the session.
+ void DeleteSessionOnlyData();
+
// Delete the session storage namespace associated with this id. Can be
// called from any thread.
void DeleteSessionStorageNamespace(int64 session_storage_namespace_id);
diff --git a/webkit/quota/mock_special_storage_policy.cc b/webkit/quota/mock_special_storage_policy.cc
index 8b75073..5787be9 100644
--- a/webkit/quota/mock_special_storage_policy.cc
+++ b/webkit/quota/mock_special_storage_policy.cc
@@ -21,6 +21,10 @@ bool MockSpecialStoragePolicy::IsStorageUnlimited(const GURL& origin) {
return unlimited_.find(origin) != unlimited_.end();
}
+bool MockSpecialStoragePolicy::IsStorageSessionOnly(const GURL& origin) {
+ return session_only_.find(origin) != session_only_.end();
+}
+
bool MockSpecialStoragePolicy::IsFileHandler(const std::string& extension_id) {
return file_handlers_.find(extension_id) != file_handlers_.end();
}
diff --git a/webkit/quota/mock_special_storage_policy.h b/webkit/quota/mock_special_storage_policy.h
index b04d16d..7e54a6e 100644
--- a/webkit/quota/mock_special_storage_policy.h
+++ b/webkit/quota/mock_special_storage_policy.h
@@ -19,6 +19,7 @@ class MockSpecialStoragePolicy : public quota::SpecialStoragePolicy {
virtual bool IsStorageProtected(const GURL& origin);
virtual bool IsStorageUnlimited(const GURL& origin);
+ virtual bool IsStorageSessionOnly(const GURL& origin);
virtual bool IsFileHandler(const std::string& extension_id);
void AddProtected(const GURL& origin) {
@@ -29,6 +30,10 @@ class MockSpecialStoragePolicy : public quota::SpecialStoragePolicy {
unlimited_.insert(origin);
}
+ void AddSessionOnly(const GURL& origin) {
+ session_only_.insert(origin);
+ }
+
void AddFileHandler(const std::string& id) {
file_handlers_.insert(id);
}
@@ -40,7 +45,9 @@ class MockSpecialStoragePolicy : public quota::SpecialStoragePolicy {
void Reset() {
protected_.clear();
unlimited_.clear();
+ session_only_.clear();
file_handlers_.clear();
+ all_unlimited_ = false;
}
void NotifyChanged() {
@@ -50,6 +57,7 @@ class MockSpecialStoragePolicy : public quota::SpecialStoragePolicy {
private:
std::set<GURL> protected_;
std::set<GURL> unlimited_;
+ std::set<GURL> session_only_;
std::set<std::string> file_handlers_;
bool all_unlimited_;
diff --git a/webkit/quota/special_storage_policy.h b/webkit/quota/special_storage_policy.h
index cc1af6b..ed8989c 100644
--- a/webkit/quota/special_storage_policy.h
+++ b/webkit/quota/special_storage_policy.h
@@ -42,6 +42,10 @@ class SpecialStoragePolicy
// file handler.
virtual bool IsFileHandler(const std::string& extension_id) = 0;
+ // Some origins are only allowed to store session-only data which is deleted
+ // when the session ends.
+ virtual bool IsStorageSessionOnly(const GURL& origin) = 0;
+
// Adds/removes an observer, the policy does not take
// ownership of the observer. Should only be called on the IO thread.
void AddObserver(Observer* observer);