Commit 0b7fcc16 authored by kinuko@chromium.org's avatar kinuko@chromium.org

Implement special origin database handling for Isolated Apps

- Factor out SandboxOriginDatabase interface to SandboxOriginDatabaseInterface
- Implement SandboxIsolatedOriginDatabase which implements the same interface
  and only handles a single origin without database

BUG=242272
TEST=SandboxIsolatedOriginDatabaseTest.*
TEST=manually tested (launch Chrome w/o change, launch an app which uses HTML5 FS API, write some data -> launch Chrome with change, make sure the same contents appear & origin database's gone)
TBR=tzik@chromium.org

Review URL: https://codereview.chromium.org/16150002

git-svn-id: svn://svn.chromium.org/chrome/trunk/src@203139 0039d316-1c4b-4281-b951-d872f2087c98
parent 1cbf878f
...@@ -453,6 +453,7 @@ ...@@ -453,6 +453,7 @@
'../webkit/browser/fileapi/sandbox_directory_database_unittest.cc', '../webkit/browser/fileapi/sandbox_directory_database_unittest.cc',
'../webkit/browser/fileapi/sandbox_file_system_test_helper.cc', '../webkit/browser/fileapi/sandbox_file_system_test_helper.cc',
'../webkit/browser/fileapi/sandbox_file_system_test_helper.h', '../webkit/browser/fileapi/sandbox_file_system_test_helper.h',
'../webkit/browser/fileapi/sandbox_isolated_origin_database_unittest.cc',
'../webkit/browser/fileapi/sandbox_mount_point_provider_unittest.cc', '../webkit/browser/fileapi/sandbox_mount_point_provider_unittest.cc',
'../webkit/browser/fileapi/sandbox_origin_database_unittest.cc', '../webkit/browser/fileapi/sandbox_origin_database_unittest.cc',
'../webkit/browser/fileapi/syncable/canned_syncable_file_system.cc', '../webkit/browser/fileapi/syncable/canned_syncable_file_system.cc',
......
...@@ -24,7 +24,9 @@ ...@@ -24,7 +24,9 @@
#include "webkit/browser/fileapi/file_system_operation_context.h" #include "webkit/browser/fileapi/file_system_operation_context.h"
#include "webkit/browser/fileapi/file_system_url.h" #include "webkit/browser/fileapi/file_system_url.h"
#include "webkit/browser/fileapi/native_file_util.h" #include "webkit/browser/fileapi/native_file_util.h"
#include "webkit/browser/fileapi/sandbox_isolated_origin_database.h"
#include "webkit/browser/fileapi/sandbox_mount_point_provider.h" #include "webkit/browser/fileapi/sandbox_mount_point_provider.h"
#include "webkit/browser/fileapi/sandbox_origin_database.h"
#include "webkit/browser/fileapi/syncable/syncable_file_system_util.h" #include "webkit/browser/fileapi/syncable/syncable_file_system_util.h"
#include "webkit/browser/quota/quota_manager.h" #include "webkit/browser/quota/quota_manager.h"
#include "webkit/common/fileapi/file_system_util.h" #include "webkit/common/fileapi/file_system_util.h"
...@@ -210,7 +212,7 @@ class ObfuscatedOriginEnumerator ...@@ -210,7 +212,7 @@ class ObfuscatedOriginEnumerator
public: public:
typedef SandboxOriginDatabase::OriginRecord OriginRecord; typedef SandboxOriginDatabase::OriginRecord OriginRecord;
ObfuscatedOriginEnumerator( ObfuscatedOriginEnumerator(
SandboxOriginDatabase* origin_database, SandboxOriginDatabaseInterface* origin_database,
const base::FilePath& base_file_path) const base::FilePath& base_file_path)
: base_file_path_(base_file_path) { : base_file_path_(base_file_path) {
if (origin_database) if (origin_database)
...@@ -240,7 +242,8 @@ class ObfuscatedOriginEnumerator ...@@ -240,7 +242,8 @@ class ObfuscatedOriginEnumerator
NOTREACHED(); NOTREACHED();
return false; return false;
} }
base::FilePath path = base_file_path_.Append(current_.path).Append(type_string); base::FilePath path =
base_file_path_.Append(current_.path).Append(type_string);
return file_util::DirectoryExists(path); return file_util::DirectoryExists(path);
} }
...@@ -251,8 +254,10 @@ class ObfuscatedOriginEnumerator ...@@ -251,8 +254,10 @@ class ObfuscatedOriginEnumerator
}; };
ObfuscatedFileUtil::ObfuscatedFileUtil( ObfuscatedFileUtil::ObfuscatedFileUtil(
quota::SpecialStoragePolicy* special_storage_policy,
const base::FilePath& file_system_directory) const base::FilePath& file_system_directory)
: file_system_directory_(file_system_directory) { : special_storage_policy_(special_storage_policy),
file_system_directory_(file_system_directory) {
} }
ObfuscatedFileUtil::~ObfuscatedFileUtil() { ObfuscatedFileUtil::~ObfuscatedFileUtil() {
...@@ -880,8 +885,8 @@ base::FilePath ObfuscatedFileUtil::GetDirectoryForOriginAndType( ...@@ -880,8 +885,8 @@ base::FilePath ObfuscatedFileUtil::GetDirectoryForOriginAndType(
bool ObfuscatedFileUtil::DeleteDirectoryForOriginAndType( bool ObfuscatedFileUtil::DeleteDirectoryForOriginAndType(
const GURL& origin, FileSystemType type) { const GURL& origin, FileSystemType type) {
base::PlatformFileError error = base::PLATFORM_FILE_OK; base::PlatformFileError error = base::PLATFORM_FILE_OK;
base::FilePath origin_type_path = GetDirectoryForOriginAndType(origin, type, false, base::FilePath origin_type_path = GetDirectoryForOriginAndType(
&error); origin, type, false, &error);
if (origin_type_path.empty()) if (origin_type_path.empty())
return true; return true;
...@@ -974,7 +979,8 @@ bool ObfuscatedFileUtil::DestroyDirectoryDatabase( ...@@ -974,7 +979,8 @@ bool ObfuscatedFileUtil::DestroyDirectoryDatabase(
} }
PlatformFileError error = base::PLATFORM_FILE_OK; PlatformFileError error = base::PLATFORM_FILE_OK;
base::FilePath path = GetDirectoryForOriginAndType(origin, type, false, &error); base::FilePath path = GetDirectoryForOriginAndType(
origin, type, false, &error);
if (path.empty() || error == base::PLATFORM_FILE_ERROR_NOT_FOUND) if (path.empty() || error == base::PLATFORM_FILE_ERROR_NOT_FOUND)
return true; return true;
return SandboxDirectoryDatabase::DestroyDatabase(path); return SandboxDirectoryDatabase::DestroyDatabase(path);
...@@ -1047,8 +1053,8 @@ PlatformFileError ObfuscatedFileUtil::CreateFile( ...@@ -1047,8 +1053,8 @@ PlatformFileError ObfuscatedFileUtil::CreateFile(
dest_origin, dest_type, true); dest_origin, dest_type, true);
PlatformFileError error = base::PLATFORM_FILE_OK; PlatformFileError error = base::PLATFORM_FILE_OK;
base::FilePath root = GetDirectoryForOriginAndType(dest_origin, dest_type, false, base::FilePath root = GetDirectoryForOriginAndType(
&error); dest_origin, dest_type, false, &error);
if (error != base::PLATFORM_FILE_OK) if (error != base::PLATFORM_FILE_OK)
return error; return error;
...@@ -1119,7 +1125,8 @@ PlatformFileError ObfuscatedFileUtil::CreateFile( ...@@ -1119,7 +1125,8 @@ PlatformFileError ObfuscatedFileUtil::CreateFile(
base::FilePath ObfuscatedFileUtil::DataPathToLocalPath( base::FilePath ObfuscatedFileUtil::DataPathToLocalPath(
const GURL& origin, FileSystemType type, const base::FilePath& data_path) { const GURL& origin, FileSystemType type, const base::FilePath& data_path) {
PlatformFileError error = base::PLATFORM_FILE_OK; PlatformFileError error = base::PLATFORM_FILE_OK;
base::FilePath root = GetDirectoryForOriginAndType(origin, type, false, &error); base::FilePath root = GetDirectoryForOriginAndType(
origin, type, false, &error);
if (error != base::PLATFORM_FILE_OK) if (error != base::PLATFORM_FILE_OK)
return base::FilePath(); return base::FilePath();
return root.Append(data_path); return root.Append(data_path);
...@@ -1146,7 +1153,8 @@ SandboxDirectoryDatabase* ObfuscatedFileUtil::GetDirectoryDatabase( ...@@ -1146,7 +1153,8 @@ SandboxDirectoryDatabase* ObfuscatedFileUtil::GetDirectoryDatabase(
} }
PlatformFileError error = base::PLATFORM_FILE_OK; PlatformFileError error = base::PLATFORM_FILE_OK;
base::FilePath path = GetDirectoryForOriginAndType(origin, type, create, &error); base::FilePath path = GetDirectoryForOriginAndType(
origin, type, create, &error);
if (error != base::PLATFORM_FILE_OK) { if (error != base::PLATFORM_FILE_OK) {
LOG(WARNING) << "Failed to get origin+type directory: " << path.value(); LOG(WARNING) << "Failed to get origin+type directory: " << path.value();
return NULL; return NULL;
...@@ -1159,6 +1167,14 @@ SandboxDirectoryDatabase* ObfuscatedFileUtil::GetDirectoryDatabase( ...@@ -1159,6 +1167,14 @@ SandboxDirectoryDatabase* ObfuscatedFileUtil::GetDirectoryDatabase(
base::FilePath ObfuscatedFileUtil::GetDirectoryForOrigin( base::FilePath ObfuscatedFileUtil::GetDirectoryForOrigin(
const GURL& origin, bool create, base::PlatformFileError* error_code) { const GURL& origin, bool create, base::PlatformFileError* error_code) {
if (special_storage_policy_ &&
special_storage_policy_->HasIsolatedStorage(origin)) {
CHECK(isolated_origin_.is_empty() || isolated_origin_ == origin)
<< "multiple origins for an isolated site: "
<< isolated_origin_.spec() << " vs " << origin.spec();
isolated_origin_ = origin;
}
if (!InitOriginDatabase(create)) { if (!InitOriginDatabase(create)) {
if (error_code) { if (error_code) {
*error_code = create ? *error_code = create ?
...@@ -1233,17 +1249,29 @@ void ObfuscatedFileUtil::DropDatabases() { ...@@ -1233,17 +1249,29 @@ void ObfuscatedFileUtil::DropDatabases() {
} }
bool ObfuscatedFileUtil::InitOriginDatabase(bool create) { bool ObfuscatedFileUtil::InitOriginDatabase(bool create) {
if (!origin_database_) { if (origin_database_)
if (!create && !file_util::DirectoryExists(file_system_directory_)) return true;
return false;
if (!file_util::CreateDirectory(file_system_directory_)) { if (!create && !file_util::DirectoryExists(file_system_directory_))
LOG(WARNING) << "Failed to create FileSystem directory: " << return false;
file_system_directory_.value(); if (!file_util::CreateDirectory(file_system_directory_)) {
return false; LOG(WARNING) << "Failed to create FileSystem directory: " <<
} file_system_directory_.value();
return false;
}
if (!isolated_origin_.is_empty()) {
DCHECK(special_storage_policy_->HasIsolatedStorage(isolated_origin_));
origin_database_.reset( origin_database_.reset(
new SandboxOriginDatabase(file_system_directory_)); new SandboxIsolatedOriginDatabase(
UTF16ToUTF8(webkit_base::GetOriginIdentifierFromURL(
isolated_origin_)),
file_system_directory_));
return true;
} }
origin_database_.reset(
new SandboxOriginDatabase(file_system_directory_));
return true; return true;
} }
...@@ -1259,8 +1287,8 @@ PlatformFileError ObfuscatedFileUtil::GenerateNewLocalPath( ...@@ -1259,8 +1287,8 @@ PlatformFileError ObfuscatedFileUtil::GenerateNewLocalPath(
return base::PLATFORM_FILE_ERROR_FAILED; return base::PLATFORM_FILE_ERROR_FAILED;
PlatformFileError error = base::PLATFORM_FILE_OK; PlatformFileError error = base::PLATFORM_FILE_OK;
base::FilePath new_local_path = GetDirectoryForOriginAndType(origin, type, base::FilePath new_local_path = GetDirectoryForOriginAndType(
false, &error); origin, type, false, &error);
if (error != base::PLATFORM_FILE_OK) if (error != base::PLATFORM_FILE_OK)
return base::PLATFORM_FILE_ERROR_FAILED; return base::PLATFORM_FILE_ERROR_FAILED;
......
...@@ -16,7 +16,6 @@ ...@@ -16,7 +16,6 @@
#include "webkit/browser/fileapi/file_system_file_util.h" #include "webkit/browser/fileapi/file_system_file_util.h"
#include "webkit/browser/fileapi/file_system_url.h" #include "webkit/browser/fileapi/file_system_url.h"
#include "webkit/browser/fileapi/sandbox_directory_database.h" #include "webkit/browser/fileapi/sandbox_directory_database.h"
#include "webkit/browser/fileapi/sandbox_origin_database.h"
#include "webkit/common/blob/shareable_file_reference.h" #include "webkit/common/blob/shareable_file_reference.h"
#include "webkit/common/fileapi/file_system_types.h" #include "webkit/common/fileapi/file_system_types.h"
#include "webkit/storage/webkit_storage_export.h" #include "webkit/storage/webkit_storage_export.h"
...@@ -25,11 +24,16 @@ namespace base { ...@@ -25,11 +24,16 @@ namespace base {
class Time; class Time;
} }
namespace quota {
class SpecialStoragePolicy;
}
class GURL; class GURL;
namespace fileapi { namespace fileapi {
class FileSystemOperationContext; class FileSystemOperationContext;
class SandboxOriginDatabaseInterface;
// The overall implementation philosophy of this class is that partial failures // The overall implementation philosophy of this class is that partial failures
// should leave us with an intact database; we'd prefer to leak the occasional // should leave us with an intact database; we'd prefer to leak the occasional
...@@ -55,7 +59,9 @@ class WEBKIT_STORAGE_EXPORT_PRIVATE ObfuscatedFileUtil ...@@ -55,7 +59,9 @@ class WEBKIT_STORAGE_EXPORT_PRIVATE ObfuscatedFileUtil
virtual bool HasFileSystemType(FileSystemType type) const = 0; virtual bool HasFileSystemType(FileSystemType type) const = 0;
}; };
explicit ObfuscatedFileUtil(const base::FilePath& file_system_directory); ObfuscatedFileUtil(
quota::SpecialStoragePolicy* special_storage_policy,
const base::FilePath& file_system_directory);
virtual ~ObfuscatedFileUtil(); virtual ~ObfuscatedFileUtil();
// FileSystemFileUtil overrides. // FileSystemFileUtil overrides.
...@@ -250,10 +256,15 @@ class WEBKIT_STORAGE_EXPORT_PRIVATE ObfuscatedFileUtil ...@@ -250,10 +256,15 @@ class WEBKIT_STORAGE_EXPORT_PRIVATE ObfuscatedFileUtil
typedef std::map<std::string, SandboxDirectoryDatabase*> DirectoryMap; typedef std::map<std::string, SandboxDirectoryDatabase*> DirectoryMap;
DirectoryMap directories_; DirectoryMap directories_;
scoped_ptr<SandboxOriginDatabase> origin_database_; scoped_ptr<SandboxOriginDatabaseInterface> origin_database_;
scoped_refptr<quota::SpecialStoragePolicy> special_storage_policy_;
base::FilePath file_system_directory_; base::FilePath file_system_directory_;
base::OneShotTimer<ObfuscatedFileUtil> timer_; base::OneShotTimer<ObfuscatedFileUtil> timer_;
// If this instance is initialized for an isolated origin, this should
// only see a single origin.
GURL isolated_origin_;
DISALLOW_COPY_AND_ASSIGN(ObfuscatedFileUtil); DISALLOW_COPY_AND_ASSIGN(ObfuscatedFileUtil);
}; };
......
// Copyright 2013 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 "webkit/browser/fileapi/sandbox_isolated_origin_database.h"
#include "base/file_util.h"
#include "base/logging.h"
#include "webkit/browser/fileapi/sandbox_origin_database.h"
namespace fileapi {
// Special directory name for isolated origin.
const base::FilePath::CharType kOriginDirectory[] = FILE_PATH_LITERAL("iso");
SandboxIsolatedOriginDatabase::SandboxIsolatedOriginDatabase(
const std::string& origin,
const base::FilePath& file_system_directory)
: migration_checked_(false),
origin_(origin),
file_system_directory_(file_system_directory) {
}
SandboxIsolatedOriginDatabase::~SandboxIsolatedOriginDatabase() {
}
bool SandboxIsolatedOriginDatabase::HasOriginPath(
const std::string& origin) {
MigrateDatabaseIfNeeded();
return (origin_ == origin);
}
bool SandboxIsolatedOriginDatabase::GetPathForOrigin(
const std::string& origin, base::FilePath* directory) {
MigrateDatabaseIfNeeded();
if (origin != origin_)
return false;
*directory = base::FilePath(kOriginDirectory);
return true;
}
bool SandboxIsolatedOriginDatabase::RemovePathForOrigin(
const std::string& origin) {
return true;
}
bool SandboxIsolatedOriginDatabase::ListAllOrigins(
std::vector<OriginRecord>* origins) {
MigrateDatabaseIfNeeded();
origins->push_back(OriginRecord(origin_, base::FilePath(kOriginDirectory)));
return true;
}
void SandboxIsolatedOriginDatabase::DropDatabase() {
}
void SandboxIsolatedOriginDatabase::MigrateDatabaseIfNeeded() {
if (migration_checked_)
return;
migration_checked_ = true;
// See if we have non-isolated version of sandbox database.
scoped_ptr<SandboxOriginDatabase> database(
new SandboxOriginDatabase(file_system_directory_));
if (!database->HasOriginPath(origin_))
return;
base::FilePath directory_name;
if (database->GetPathForOrigin(origin_, &directory_name) &&
directory_name != base::FilePath(kOriginDirectory)) {
base::FilePath from_path = file_system_directory_.Append(directory_name);
base::FilePath to_path = file_system_directory_.Append(kOriginDirectory);
if (file_util::PathExists(to_path))
file_util::Delete(to_path, true /* recursive */);
file_util::Move(from_path, to_path);
}
database->RemoveDatabase();
}
} // namespace fileapi
// Copyright 2013 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.
#ifndef WEBKIT_BROWSER_FILEAPI_SANDBOX_ISOLATED_ORIGIN_DATABASE_H_
#define WEBKIT_BROWSER_FILEAPI_SANDBOX_ISOLATED_ORIGIN_DATABASE_H_
#include "webkit/browser/fileapi/sandbox_origin_database_interface.h"
namespace fileapi {
class WEBKIT_STORAGE_EXPORT_PRIVATE SandboxIsolatedOriginDatabase
: public SandboxOriginDatabaseInterface {
public:
explicit SandboxIsolatedOriginDatabase(
const std::string& origin,
const base::FilePath& file_system_directory);
virtual ~SandboxIsolatedOriginDatabase();
// SandboxOriginDatabaseInterface overrides.
virtual bool HasOriginPath(const std::string& origin) OVERRIDE;
virtual bool GetPathForOrigin(const std::string& origin,
base::FilePath* directory) OVERRIDE;
virtual bool RemovePathForOrigin(const std::string& origin) OVERRIDE;
virtual bool ListAllOrigins(std::vector<OriginRecord>* origins) OVERRIDE;
virtual void DropDatabase() OVERRIDE;
private:
void MigrateDatabaseIfNeeded();
bool migration_checked_;
const std::string origin_;
const base::FilePath file_system_directory_;
DISALLOW_COPY_AND_ASSIGN(SandboxIsolatedOriginDatabase);
};
} // namespace fileapi
#endif // WEBKIT_BROWSER_FILEAPI_SANDBOX_ISOLATED_ORIGIN_DATABASE_H_
// Copyright 2013 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/basictypes.h"
#include "base/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "webkit/browser/fileapi/sandbox_isolated_origin_database.h"
#include "webkit/browser/fileapi/sandbox_origin_database.h"
namespace fileapi {
TEST(SandboxIsolatedOriginDatabaseTest, BasicTest) {
base::ScopedTempDir dir;
ASSERT_TRUE(dir.CreateUniqueTempDir());
std::string kOrigin("origin");
SandboxIsolatedOriginDatabase database(kOrigin, dir.path());
EXPECT_TRUE(database.HasOriginPath(kOrigin));
base::FilePath path1, path2;
EXPECT_FALSE(database.GetPathForOrigin(std::string(), &path1));
EXPECT_FALSE(database.GetPathForOrigin("foo", &path1));
EXPECT_TRUE(database.HasOriginPath(kOrigin));
EXPECT_TRUE(database.GetPathForOrigin(kOrigin, &path1));
EXPECT_TRUE(database.GetPathForOrigin(kOrigin, &path2));
EXPECT_FALSE(path1.empty());
EXPECT_FALSE(path2.empty());
EXPECT_EQ(path1, path2);
}
TEST(SandboxIsolatedOriginDatabaseTest, MigrationTest) {
base::ScopedTempDir dir;
ASSERT_TRUE(dir.CreateUniqueTempDir());
std::string kOrigin("origin");
std::string kFakeDirectoryData("0123456789");
base::FilePath path;
base::FilePath old_db_path;
// Initialize the directory with one origin using the regular
// SandboxOriginDatabase.
{
SandboxOriginDatabase database_old(dir.path());
old_db_path = database_old.GetDatabasePath();
EXPECT_FALSE(file_util::PathExists(old_db_path));
EXPECT_TRUE(database_old.GetPathForOrigin(kOrigin, &path));
EXPECT_FALSE(path.empty());
EXPECT_TRUE(file_util::DirectoryExists(old_db_path));
// Populate the origin directory with some fake data.
base::FilePath directory_db_path = dir.path().Append(path);
ASSERT_TRUE(file_util::CreateDirectory(directory_db_path));
EXPECT_EQ(static_cast<int>(kFakeDirectoryData.size()),
file_util::WriteFile(directory_db_path.AppendASCII("dummy"),
kFakeDirectoryData.data(),
kFakeDirectoryData.size()));
}
// Re-open the directory using sandboxIsolatedOriginDatabase.
SandboxIsolatedOriginDatabase database(kOrigin, dir.path());
// The database is migrated from the old one, so we should still
// see the same origin.
EXPECT_TRUE(database.HasOriginPath(kOrigin));
EXPECT_TRUE(database.GetPathForOrigin(kOrigin, &path));
EXPECT_FALSE(path.empty());
// The directory content must be kept (or migrated if necessary),
// so we should see the same fake data.
std::string origin_db_data;
base::FilePath directory_db_path = dir.path().Append(path);
EXPECT_TRUE(file_util::DirectoryExists(directory_db_path));
EXPECT_TRUE(file_util::PathExists(directory_db_path.AppendASCII("dummy")));
EXPECT_TRUE(file_util::ReadFileToString(
directory_db_path.AppendASCII("dummy"), &origin_db_data));
EXPECT_EQ(kFakeDirectoryData, origin_db_data);
// After the migration the database must be gone.
EXPECT_FALSE(file_util::PathExists(old_db_path));
}
} // namespace fileapi
...@@ -153,6 +153,7 @@ SandboxMountPointProvider::SandboxMountPointProvider( ...@@ -153,6 +153,7 @@ SandboxMountPointProvider::SandboxMountPointProvider(
sandbox_file_util_( sandbox_file_util_(
new AsyncFileUtilAdapter( new AsyncFileUtilAdapter(
new ObfuscatedFileUtil( new ObfuscatedFileUtil(
special_storage_policy,
profile_path.Append(kFileSystemDirectory)))), profile_path.Append(kFileSystemDirectory)))),
file_system_usage_cache_(new FileSystemUsageCache(file_task_runner)), file_system_usage_cache_(new FileSystemUsageCache(file_task_runner)),
quota_observer_(new SandboxQuotaObserver( quota_observer_(new SandboxQuotaObserver(
......
...@@ -5,6 +5,7 @@ ...@@ -5,6 +5,7 @@
#include "webkit/browser/fileapi/sandbox_origin_database.h" #include "webkit/browser/fileapi/sandbox_origin_database.h"
#include <set> #include <set>
#include <utility>
#include "base/file_util.h" #include "base/file_util.h"
#include "base/format_macros.h" #include "base/format_macros.h"
...@@ -55,17 +56,6 @@ const char* LastPathKey() { ...@@ -55,17 +56,6 @@ const char* LastPathKey() {
namespace fileapi { namespace fileapi {
SandboxOriginDatabase::OriginRecord::OriginRecord() {
}
SandboxOriginDatabase::OriginRecord::OriginRecord(
const std::string& origin_in, const base::FilePath& path_in)
: origin(origin_in), path(path_in) {
}
SandboxOriginDatabase::OriginRecord::~OriginRecord() {
}
SandboxOriginDatabase::SandboxOriginDatabase( SandboxOriginDatabase::SandboxOriginDatabase(
const base::FilePath& file_system_directory) const base::FilePath& file_system_directory)
: file_system_directory_(file_system_directory) { : file_system_directory_(file_system_directory) {
...@@ -74,12 +64,16 @@ SandboxOriginDatabase::SandboxOriginDatabase( ...@@ -74,12 +64,16 @@ SandboxOriginDatabase::SandboxOriginDatabase(
SandboxOriginDatabase::~SandboxOriginDatabase() { SandboxOriginDatabase::~SandboxOriginDatabase() {
} }
bool SandboxOriginDatabase::Init(RecoveryOption recovery_option) { bool SandboxOriginDatabase::Init(InitOption init_option,
RecoveryOption recovery_option) {
if (db_) if (db_)
return true; return true;
std::string path = base::FilePath db_path = GetDatabasePath();
FilePathToString(file_system_directory_.Append(kOriginDatabaseName)); if (init_option == FAIL_IF_NONEXISTENT && !file_util::PathExists(db_path))
return false;
std::string path = FilePathToString(db_path);
leveldb::Options options; leveldb::Options options;
options.create_if_missing = true; options.create_if_missing = true;
leveldb::DB* db; leveldb::DB* db;
...@@ -117,7 +111,7 @@ bool SandboxOriginDatabase::Init(RecoveryOption recovery_option) { ...@@ -117,7 +111,7 @@ bool SandboxOriginDatabase::Init(RecoveryOption recovery_option) {
return false; return false;
if (!file_util::CreateDirectory(file_system_directory_)) if (!file_util::CreateDirectory(file_system_directory_))
return false; return false;
return Init(FAIL_ON_CORRUPTION); return Init(init_option, FAIL_ON_CORRUPTION);
} }
NOTREACHED(); NOTREACHED();
return false; return false;
...@@ -126,7 +120,7 @@ bool SandboxOriginDatabase::Init(RecoveryOption recovery_option) { ...@@ -126,7 +120,7 @@ bool SandboxOriginDatabase::Init(RecoveryOption recovery_option) {
bool SandboxOriginDatabase::RepairDatabase(const std::string& db_path) { bool SandboxOriginDatabase::RepairDatabase(const std::string& db_path) {
DCHECK(!db_.get()); DCHECK(!db_.get());
if (!leveldb::RepairDB(db_path, leveldb::Options()).ok() || if (!leveldb::RepairDB(db_path, leveldb::Options()).ok() ||
!Init(FAIL_ON_CORRUPTION)) { !Init(FAIL_IF_NONEXISTENT, FAIL_ON_CORRUPTION)) {
LOG(WARNING) << "Failed to repair SandboxOriginDatabase."; LOG(WARNING) << "Failed to repair SandboxOriginDatabase.";
return false; return false;
} }
...@@ -214,7 +208,7 @@ void SandboxOriginDatabase::ReportInitStatus(const leveldb::Status& status) { ...@@ -214,7 +208,7 @@ void SandboxOriginDatabase::ReportInitStatus(const leveldb::Status& status) {
} }
bool SandboxOriginDatabase::HasOriginPath(const std::string& origin) { bool SandboxOriginDatabase::HasOriginPath(const std::string& origin) {
if (!Init(REPAIR_ON_CORRUPTION)) if (!Init(FAIL_IF_NONEXISTENT, REPAIR_ON_CORRUPTION))
return false; return false;
if (origin.empty()) if (origin.empty())
return false; return false;
...@@ -231,7 +225,7 @@ bool SandboxOriginDatabase::HasOriginPath(const std::string& origin) { ...@@ -231,7 +225,7 @@ bool SandboxOriginDatabase::HasOriginPath(const std::string& origin) {
bool SandboxOriginDatabase::GetPathForOrigin( bool SandboxOriginDatabase::GetPathForOrigin(
const std::string& origin, base::FilePath* directory) { const std::string& origin, base::FilePath* directory) {
if (!Init(REPAIR_ON_CORRUPTION)) if (!Init(CREATE_IF_NONEXISTENT, REPAIR_ON_CORRUPTION))
return false; return false;
DCHECK(directory); DCHECK(directory);
if (origin.empty()) if (origin.empty())
...@@ -264,7 +258,7 @@ bool SandboxOriginDatabase::GetPathForOrigin( ...@@ -264,7 +258,7 @@ bool SandboxOriginDatabase::GetPathForOrigin(
} }
bool SandboxOriginDatabase::RemovePathForOrigin(const std::string& origin) { bool SandboxOriginDatabase::RemovePathForOrigin(const std::string& origin) {
if (!Init(REPAIR_ON_CORRUPTION)) if (!Init(CREATE_IF_NONEXISTENT, REPAIR_ON_CORRUPTION))
return false; return false;
leveldb::Status status = leveldb::Status status =
db_->Delete(leveldb::WriteOptions(), OriginToOriginKey(origin)); db_->Delete(leveldb::WriteOptions(), OriginToOriginKey(origin));
...@@ -276,9 +270,11 @@ bool SandboxOriginDatabase::RemovePathForOrigin(const std::string& origin) { ...@@ -276,9 +270,11 @@ bool SandboxOriginDatabase::RemovePathForOrigin(const std::string& origin) {
bool SandboxOriginDatabase::ListAllOrigins( bool SandboxOriginDatabase::ListAllOrigins(
std::vector<OriginRecord>* origins) { std::vector<OriginRecord>* origins) {
if (!Init(REPAIR_ON_CORRUPTION))
return false;
DCHECK(origins); DCHECK(origins);
if (!Init(CREATE_IF_NONEXISTENT, REPAIR_ON_CORRUPTION)) {
origins->clear();
return false;
}
scoped_ptr<leveldb::Iterator> iter(db_->NewIterator(leveldb::ReadOptions())); scoped_ptr<leveldb::Iterator> iter(db_->NewIterator(leveldb::ReadOptions()));
std::string origin_key_prefix = OriginToOriginKey(std::string()); std::string origin_key_prefix = OriginToOriginKey(std::string());
iter->Seek(origin_key_prefix); iter->Seek(origin_key_prefix);
...@@ -298,9 +294,17 @@ void SandboxOriginDatabase::DropDatabase() { ...@@ -298,9 +294,17 @@ void SandboxOriginDatabase::DropDatabase() {
db_.reset(); db_.reset();
} }
base::FilePath SandboxOriginDatabase::GetDatabasePath() const {
return file_system_directory_.Append(kOriginDatabaseName);
}
void SandboxOriginDatabase::RemoveDatabase() {
DropDatabase();
file_util::Delete(GetDatabasePath(), true /* recursive */);
}
bool SandboxOriginDatabase::GetLastPathNumber(int* number) { bool SandboxOriginDatabase::GetLastPathNumber(int* number) {
if (!Init(REPAIR_ON_CORRUPTION)) DCHECK(db_);
return false;
DCHECK(number); DCHECK(number);
std::string number_string; std::string number_string;
leveldb::Status status = leveldb::Status status =
......
...@@ -5,14 +5,9 @@ ...@@ -5,14 +5,9 @@
#ifndef WEBKIT_BROWSER_FILEAPI_SANDBOX_ORIGIN_DATABASE_H_ #ifndef WEBKIT_BROWSER_FILEAPI_SANDBOX_ORIGIN_DATABASE_H_
#define WEBKIT_BROWSER_FILEAPI_SANDBOX_ORIGIN_DATABASE_H_ #define WEBKIT_BROWSER_FILEAPI_SANDBOX_ORIGIN_DATABASE_H_
#include <string>
#include <utility>
#include <vector>
#include "base/files/file_path.h"
#include "base/memory/scoped_ptr.h" #include "base/memory/scoped_ptr.h"
#include "base/time.h" #include "base/time.h"
#include "webkit/storage/webkit_storage_export.h" #include "webkit/browser/fileapi/sandbox_origin_database_interface.h"
namespace leveldb { namespace leveldb {
class DB; class DB;
...@@ -27,35 +22,24 @@ namespace fileapi { ...@@ -27,35 +22,24 @@ namespace fileapi {
// All methods of this class other than the constructor may be used only from // All methods of this class other than the constructor may be used only from
// the browser's FILE thread. The constructor may be used on any thread. // the browser's FILE thread. The constructor may be used on any thread.
class WEBKIT_STORAGE_EXPORT_PRIVATE SandboxOriginDatabase { class WEBKIT_STORAGE_EXPORT_PRIVATE SandboxOriginDatabase
: public SandboxOriginDatabaseInterface {
public: public:
struct WEBKIT_STORAGE_EXPORT_PRIVATE OriginRecord {
std::string origin;
base::FilePath path;
OriginRecord();
OriginRecord(const std::string& origin, const base::FilePath& path);
~OriginRecord();
};
// Only one instance of SandboxOriginDatabase should exist for a given path // Only one instance of SandboxOriginDatabase should exist for a given path
// at a given time. // at a given time.
explicit SandboxOriginDatabase(const base::FilePath& file_system_directory); explicit SandboxOriginDatabase(const base::FilePath& file_system_directory);
~SandboxOriginDatabase(); virtual ~SandboxOriginDatabase();
bool HasOriginPath(const std::string& origin);
// This will produce a unique path and add it to its database, if it's not // SandboxOriginDatabaseInterface overrides.
// already present. virtual bool HasOriginPath(const std::string& origin) OVERRIDE;
bool GetPathForOrigin(const std::string& origin, base::FilePath* directory); virtual bool GetPathForOrigin(const std::string& origin,
base::FilePath* directory) OVERRIDE;
virtual bool RemovePathForOrigin(const std::string& origin) OVERRIDE;
virtual bool ListAllOrigins(std::vector<OriginRecord>* origins) OVERRIDE;
virtual void DropDatabase() OVERRIDE;
// Also returns success if the origin is not found. base::FilePath GetDatabasePath() const;
bool RemovePathForOrigin(const std::string& origin); void RemoveDatabase();
bool ListAllOrigins(std::vector<OriginRecord>* origins);
// This will release all database resources in use; call it to save memory.
void DropDatabase();
private: private:
enum RecoveryOption { enum RecoveryOption {
...@@ -64,7 +48,12 @@ class WEBKIT_STORAGE_EXPORT_PRIVATE SandboxOriginDatabase { ...@@ -64,7 +48,12 @@ class WEBKIT_STORAGE_EXPORT_PRIVATE SandboxOriginDatabase {
FAIL_ON_CORRUPTION, FAIL_ON_CORRUPTION,
}; };
bool Init(RecoveryOption recovery_option); enum InitOption {
CREATE_IF_NONEXISTENT,
FAIL_IF_NONEXISTENT,
};
bool Init(InitOption init_option, RecoveryOption recovery_option);
bool RepairDatabase(const std::string& db_path); bool RepairDatabase(const std::string& db_path);
void HandleError(const tracked_objects::Location& from_here, void HandleError(const tracked_objects::Location& from_here,
const leveldb::Status& status); const leveldb::Status& status);
......
// Copyright 2013 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 "webkit/browser/fileapi/sandbox_origin_database_interface.h"
namespace fileapi {
SandboxOriginDatabaseInterface::OriginRecord::OriginRecord() {
}
SandboxOriginDatabaseInterface::OriginRecord::OriginRecord(
const std::string& origin_in, const base::FilePath& path_in)
: origin(origin_in), path(path_in) {
}
SandboxOriginDatabaseInterface::OriginRecord::~OriginRecord() {
}
} // namespace fileapi
// Copyright 2013 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.
#ifndef WEBKIT_BROWSER_FILEAPI_SANDBOX_ORIGIN_DATABASE_INTERFACE_H_
#define WEBKIT_BROWSER_FILEAPI_SANDBOX_ORIGIN_DATABASE_INTERFACE_H_
#include <string>
#include <vector>
#include "base/files/file_path.h"
#include "webkit/storage/webkit_storage_export.h"
namespace fileapi {
class WEBKIT_STORAGE_EXPORT_PRIVATE SandboxOriginDatabaseInterface {
public:
struct WEBKIT_STORAGE_EXPORT_PRIVATE OriginRecord {
std::string origin;
base::FilePath path;
OriginRecord();
OriginRecord(const std::string& origin, const base::FilePath& path);
~OriginRecord();
};
virtual ~SandboxOriginDatabaseInterface() {}
// Returns true if the origin's path is included in this database.
virtual bool HasOriginPath(const std::string& origin) = 0;
// This will produce a unique path and add it to its database, if it's not
// already present.
virtual bool GetPathForOrigin(const std::string& origin,
base::FilePath* directory) = 0;
// Removes the origin's path from the database.
// Returns success if the origin has been successfully removed, or
// the origin is not found.
// (This doesn't remove the actual path).
virtual bool RemovePathForOrigin(const std::string& origin) = 0;
// Lists all origins in this database.
virtual bool ListAllOrigins(std::vector<OriginRecord>* origins) = 0;
// This will release all database resources in use; call it to save memory.
virtual void DropDatabase() = 0;
protected:
SandboxOriginDatabaseInterface() {}
};
} // namespace fileapi
#endif // WEBKIT_BROWSER_FILEAPI_SANDBOX_ORIGIN_DATABASE_INTERFACE_H_
...@@ -74,10 +74,14 @@ ...@@ -74,10 +74,14 @@
'../browser/fileapi/sandbox_directory_database.h', '../browser/fileapi/sandbox_directory_database.h',
'../browser/fileapi/sandbox_file_stream_writer.cc', '../browser/fileapi/sandbox_file_stream_writer.cc',
'../browser/fileapi/sandbox_file_stream_writer.h', '../browser/fileapi/sandbox_file_stream_writer.h',
'../browser/fileapi/sandbox_isolated_origin_database.cc',
'../browser/fileapi/sandbox_isolated_origin_database.h',
'../browser/fileapi/sandbox_mount_point_provider.cc', '../browser/fileapi/sandbox_mount_point_provider.cc',
'../browser/fileapi/sandbox_mount_point_provider.h', '../browser/fileapi/sandbox_mount_point_provider.h',
'../browser/fileapi/sandbox_origin_database.cc', '../browser/fileapi/sandbox_origin_database.cc',
'../browser/fileapi/sandbox_origin_database.h', '../browser/fileapi/sandbox_origin_database.h',
'../browser/fileapi/sandbox_origin_database_interface.cc',
'../browser/fileapi/sandbox_origin_database_interface.h',
'../browser/fileapi/sandbox_quota_observer.cc', '../browser/fileapi/sandbox_quota_observer.cc',
'../browser/fileapi/sandbox_quota_observer.h', '../browser/fileapi/sandbox_quota_observer.h',
'../browser/fileapi/syncable/file_change.cc', '../browser/fileapi/syncable/file_change.cc',
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment