| Index: webkit/fileapi/sandbox_mount_point_provider.cc
|
| diff --git a/webkit/fileapi/sandbox_mount_point_provider.cc b/webkit/fileapi/sandbox_mount_point_provider.cc
|
| index 95edc813ca631c4977433dbfefb8fce17f5af6a3..c0b65f2a1087e70dca05a83d5b837553cf47e973 100644
|
| --- a/webkit/fileapi/sandbox_mount_point_provider.cc
|
| +++ b/webkit/fileapi/sandbox_mount_point_provider.cc
|
| @@ -16,6 +16,7 @@
|
| #include "base/metrics/histogram.h"
|
| #include "googleurl/src/gurl.h"
|
| #include "net/base/net_util.h"
|
| +#include "webkit/fileapi/file_system_operation.h"
|
| #include "webkit/fileapi/file_system_operation_context.h"
|
| #include "webkit/fileapi/file_system_options.h"
|
| #include "webkit/fileapi/file_system_types.h"
|
| @@ -28,6 +29,8 @@
|
|
|
| using quota::QuotaManagerProxy;
|
|
|
| +namespace fileapi {
|
| +
|
| namespace {
|
|
|
| const char kChromeScheme[] = "chrome";
|
| @@ -96,10 +99,9 @@ base::PlatformFileError OldReadOriginDirectory(const FilePath& base_path,
|
| }
|
|
|
| class ObfuscatedOriginEnumerator
|
| - : public fileapi::SandboxMountPointProvider::OriginEnumerator {
|
| + : public SandboxMountPointProvider::OriginEnumerator {
|
| public:
|
| - explicit ObfuscatedOriginEnumerator(
|
| - fileapi::ObfuscatedFileUtil* file_util) {
|
| + explicit ObfuscatedOriginEnumerator(ObfuscatedFileUtil* file_util) {
|
| enum_.reset(file_util->CreateOriginEnumerator());
|
| }
|
| virtual ~ObfuscatedOriginEnumerator() {}
|
| @@ -113,11 +115,11 @@ class ObfuscatedOriginEnumerator
|
| }
|
|
|
| private:
|
| - scoped_ptr<fileapi::ObfuscatedFileUtil::AbstractOriginEnumerator> enum_;
|
| + scoped_ptr<ObfuscatedFileUtil::AbstractOriginEnumerator> enum_;
|
| };
|
|
|
| class OldSandboxOriginEnumerator
|
| - : public fileapi::SandboxMountPointProvider::OriginEnumerator {
|
| + : public SandboxMountPointProvider::OriginEnumerator {
|
| public:
|
| explicit OldSandboxOriginEnumerator(const FilePath& base_path)
|
| : enumerator_(base_path, false /* recursive */,
|
| @@ -128,8 +130,7 @@ class OldSandboxOriginEnumerator
|
| current_ = enumerator_.Next();
|
| if (current_.empty())
|
| return GURL();
|
| - return fileapi::GetOriginURLFromIdentifier(
|
| - current_.BaseName().MaybeAsASCII());
|
| + return GetOriginURLFromIdentifier(current_.BaseName().MaybeAsASCII());
|
| }
|
|
|
| virtual bool HasFileSystemType(fileapi::FileSystemType type) const OVERRIDE {
|
| @@ -148,7 +149,7 @@ class OldSandboxOriginEnumerator
|
| FilePath OldGetBaseDirectoryForOrigin(
|
| const FilePath& old_base_path,
|
| const GURL& origin_url) {
|
| - std::string id = fileapi::GetOriginIdentifierFromURL(origin_url);
|
| + std::string id = GetOriginIdentifierFromURL(origin_url);
|
| if (!id.empty())
|
| return old_base_path.AppendASCII(id);
|
| return FilePath();
|
| @@ -172,7 +173,7 @@ FilePath OldGetBaseDirectoryForOriginAndType(
|
| }
|
|
|
| bool MigrateOneOldFileSystem(
|
| - fileapi::ObfuscatedFileUtil* file_util,
|
| + ObfuscatedFileUtil* file_util,
|
| const FilePath& old_base_path, const GURL& origin,
|
| fileapi::FileSystemType type) {
|
| FilePath base_path = OldGetBaseDirectoryForOriginAndType(
|
| @@ -201,7 +202,7 @@ bool MigrateOneOldFileSystem(
|
| }
|
|
|
| void MigrateAllOldFileSystems(
|
| - fileapi::ObfuscatedFileUtil* file_util,
|
| + ObfuscatedFileUtil* file_util,
|
| const FilePath& old_base_path) {
|
| scoped_ptr<OldSandboxOriginEnumerator> old_origins(
|
| new OldSandboxOriginEnumerator(old_base_path));
|
| @@ -209,15 +210,15 @@ void MigrateAllOldFileSystems(
|
| int failures = 0;
|
| while (!(origin = old_origins->Next()).is_empty()) {
|
| int failures_this_origin = 0;
|
| - if (old_origins->HasFileSystemType(fileapi::kFileSystemTypeTemporary) &&
|
| + if (old_origins->HasFileSystemType(kFileSystemTypeTemporary) &&
|
| !MigrateOneOldFileSystem(
|
| file_util, old_base_path, origin,
|
| - fileapi::kFileSystemTypeTemporary))
|
| + kFileSystemTypeTemporary))
|
| ++failures_this_origin;
|
| - if (old_origins->HasFileSystemType(fileapi::kFileSystemTypePersistent) &&
|
| + if (old_origins->HasFileSystemType(kFileSystemTypePersistent) &&
|
| !MigrateOneOldFileSystem(
|
| file_util, old_base_path, origin,
|
| - fileapi::kFileSystemTypePersistent))
|
| + kFileSystemTypePersistent))
|
| ++failures_this_origin;
|
| if (!failures_this_origin) {
|
| FilePath origin_base_path =
|
| @@ -238,7 +239,7 @@ void MigrateAllOldFileSystems(
|
| // necessary.
|
| FilePath new_path =
|
| old_base_path.DirName().Append(
|
| - fileapi::SandboxMountPointProvider::kRenamedOldFileSystemDirectory);
|
| + SandboxMountPointProvider::kRenamedOldFileSystemDirectory);
|
| file_util::ReplaceFile(old_base_path, new_path);
|
| }
|
| }
|
| @@ -250,15 +251,45 @@ void MigrateAllOldFileSystems(
|
| // to look up the filesystem's root, so we can take care of most of them by
|
| // putting a check there.
|
| void MigrateIfNeeded(
|
| - fileapi::ObfuscatedFileUtil* file_util,
|
| + ObfuscatedFileUtil* file_util,
|
| const FilePath& old_base_path) {
|
| if (file_util::DirectoryExists(old_base_path))
|
| MigrateAllOldFileSystems(file_util, old_base_path);
|
| }
|
|
|
| -} // anonymous namespace
|
| +void PassPointerErrorByValue(
|
| + const base::Callback<void(PlatformFileError)>& callback,
|
| + PlatformFileError* error_ptr) {
|
| + DCHECK(error_ptr);
|
| + callback.Run(*error_ptr);
|
| +}
|
|
|
| -namespace fileapi {
|
| +void ValidateRootOnFileThread(ObfuscatedFileUtil* file_util,
|
| + const GURL& origin_url,
|
| + FileSystemType type,
|
| + const FilePath& old_base_path,
|
| + bool create,
|
| + base::PlatformFileError* error_ptr) {
|
| + DCHECK(error_ptr);
|
| + MigrateIfNeeded(file_util, old_base_path);
|
| + FilePath root_path =
|
| + file_util->GetDirectoryForOriginAndType(origin_url, type, create);
|
| + if (root_path.empty()) {
|
| + UMA_HISTOGRAM_ENUMERATION(kOpenFileSystem,
|
| + kCreateDirectoryError,
|
| + kFileSystemErrorMax);
|
| + // TODO(kinuko): We should return appropriate error code.
|
| + *error_ptr = base::PLATFORM_FILE_ERROR_FAILED;
|
| + } else {
|
| + UMA_HISTOGRAM_ENUMERATION(kOpenFileSystem, kOK, kFileSystemErrorMax);
|
| + *error_ptr = base::PLATFORM_FILE_OK;
|
| + }
|
| + // The reference of file_util will be derefed on the FILE thread
|
| + // when the storage of this callback gets deleted regardless of whether
|
| + // this method is called or not.
|
| +}
|
| +
|
| +} // anonymous namespace
|
|
|
| const FilePath::CharType SandboxMountPointProvider::kOldFileSystemDirectory[] =
|
| FILE_PATH_LITERAL("FileSystem");
|
| @@ -270,85 +301,6 @@ const FilePath::CharType
|
| SandboxMountPointProvider::kRenamedOldFileSystemDirectory[] =
|
| FILE_PATH_LITERAL("FS.old");
|
|
|
| -class SandboxMountPointProvider::GetFileSystemRootPathTask
|
| - : public base::RefCountedThreadSafe<
|
| - SandboxMountPointProvider::GetFileSystemRootPathTask> {
|
| - public:
|
| - GetFileSystemRootPathTask(
|
| - scoped_refptr<base::MessageLoopProxy> file_message_loop,
|
| - const GURL& origin_url,
|
| - FileSystemType type,
|
| - ObfuscatedFileUtil* file_util,
|
| - const FilePath& old_base_path,
|
| - const FileSystemMountPointProvider::GetRootPathCallback& callback)
|
| - : file_message_loop_(file_message_loop),
|
| - origin_message_loop_proxy_(
|
| - base::MessageLoopProxy::current()),
|
| - origin_url_(origin_url),
|
| - type_(type),
|
| - file_util_(file_util),
|
| - old_base_path_(old_base_path),
|
| - callback_(callback) {
|
| - }
|
| -
|
| - virtual ~GetFileSystemRootPathTask() {
|
| - // Just in case we get deleted without running, make sure to clean up the
|
| - // file_util_ on the right thread.
|
| - if (file_util_.get() && !file_message_loop_->BelongsToCurrentThread())
|
| - file_message_loop_->ReleaseSoon(FROM_HERE, file_util_.release());
|
| - }
|
| -
|
| - void Start(bool create) {
|
| - file_message_loop_->PostTask(
|
| - FROM_HERE,
|
| - base::Bind(
|
| - &GetFileSystemRootPathTask::GetFileSystemRootPathOnFileThread, this,
|
| - create));
|
| - }
|
| -
|
| - private:
|
| - void GetFileSystemRootPathOnFileThread(bool create) {
|
| - MigrateIfNeeded(file_util_, old_base_path_);
|
| - DispatchCallbackOnCallerThread(
|
| - file_util_->GetDirectoryForOriginAndType(origin_url_, type_, create));
|
| - // We must clear the reference on the file thread.
|
| - file_util_ = NULL;
|
| - }
|
| -
|
| - void DispatchCallbackOnCallerThread(const FilePath& root_path) {
|
| - if (root_path.empty()) {
|
| - UMA_HISTOGRAM_ENUMERATION(kOpenFileSystem,
|
| - kCreateDirectoryError,
|
| - kFileSystemErrorMax);
|
| - }
|
| - origin_message_loop_proxy_->PostTask(
|
| - FROM_HERE,
|
| - base::Bind(&GetFileSystemRootPathTask::DispatchCallback, this,
|
| - root_path));
|
| - }
|
| -
|
| - void DispatchCallback(const FilePath& root_path) {
|
| - std::string origin_identifier = GetOriginIdentifierFromURL(origin_url_);
|
| - std::string type_string = GetFileSystemTypeString(type_);
|
| - DCHECK(!type_string.empty());
|
| - std::string name = origin_identifier + ":" + type_string;
|
| -
|
| - if (!root_path.empty())
|
| - UMA_HISTOGRAM_ENUMERATION(kOpenFileSystem, kOK, kFileSystemErrorMax);
|
| -
|
| - callback_.Run(!root_path.empty(), root_path, name);
|
| - callback_.Reset();
|
| - }
|
| -
|
| - scoped_refptr<base::MessageLoopProxy> file_message_loop_;
|
| - scoped_refptr<base::MessageLoopProxy> origin_message_loop_proxy_;
|
| - GURL origin_url_;
|
| - FileSystemType type_;
|
| - scoped_refptr<ObfuscatedFileUtil> file_util_;
|
| - FilePath old_base_path_;
|
| - FileSystemMountPointProvider::GetRootPathCallback callback_;
|
| -};
|
| -
|
| SandboxMountPointProvider::SandboxMountPointProvider(
|
| scoped_refptr<base::MessageLoopProxy> file_message_loop,
|
| const FilePath& profile_path,
|
| @@ -368,24 +320,12 @@ SandboxMountPointProvider::~SandboxMountPointProvider() {
|
| file_message_loop_->ReleaseSoon(FROM_HERE, sandbox_file_util_.release());
|
| }
|
|
|
| -bool SandboxMountPointProvider::IsAccessAllowed(const GURL& origin_url,
|
| - FileSystemType type,
|
| - const FilePath& unused) {
|
| - if (type != kFileSystemTypeTemporary && type != kFileSystemTypePersistent)
|
| - return false;
|
| - // We essentially depend on quota to do our access controls, so here
|
| - // we only check if the requested scheme is allowed or not.
|
| - return IsAllowedScheme(origin_url);
|
| -}
|
| -
|
| -void SandboxMountPointProvider::ValidateFileSystemRootAndGetURL(
|
| +void SandboxMountPointProvider::ValidateFileSystemRoot(
|
| const GURL& origin_url, fileapi::FileSystemType type, bool create,
|
| - const FileSystemMountPointProvider::GetRootPathCallback& callback) {
|
| - FilePath origin_base_path;
|
| -
|
| + const ValidateFileSystemCallback& callback) {
|
| if (file_system_options_.is_incognito()) {
|
| // TODO(kinuko): return an isolated temporary directory.
|
| - callback.Run(false, FilePath(), std::string());
|
| + callback.Run(base::PLATFORM_FILE_ERROR_SECURITY);
|
| UMA_HISTOGRAM_ENUMERATION(kOpenFileSystem,
|
| kIncognito,
|
| kFileSystemErrorMax);
|
| @@ -393,22 +333,26 @@ void SandboxMountPointProvider::ValidateFileSystemRootAndGetURL(
|
| }
|
|
|
| if (!IsAllowedScheme(origin_url)) {
|
| - callback.Run(false, FilePath(), std::string());
|
| + callback.Run(base::PLATFORM_FILE_ERROR_SECURITY);
|
| UMA_HISTOGRAM_ENUMERATION(kOpenFileSystem,
|
| kInvalidScheme,
|
| kFileSystemErrorMax);
|
| return;
|
| }
|
|
|
| - scoped_refptr<GetFileSystemRootPathTask> task(
|
| - new GetFileSystemRootPathTask(
|
| - file_message_loop_, origin_url, type, sandbox_file_util_.get(),
|
| - old_base_path(), callback));
|
| - task->Start(create);
|
| + base::PlatformFileError* error_ptr = new base::PlatformFileError;
|
| + file_message_loop_->PostTaskAndReply(
|
| + FROM_HERE,
|
| + base::Bind(&ValidateRootOnFileThread,
|
| + sandbox_file_util_,
|
| + origin_url, type, old_base_path(), create,
|
| + base::Unretained(error_ptr)),
|
| + base::Bind(base::Bind(&PassPointerErrorByValue, callback),
|
| + base::Owned(error_ptr)));
|
| };
|
|
|
| FilePath
|
| -SandboxMountPointProvider::ValidateFileSystemRootAndGetPathOnFileThread(
|
| +SandboxMountPointProvider::GetFileSystemRootPathOnFileThread(
|
| const GURL& origin_url, FileSystemType type, const FilePath& unused,
|
| bool create) {
|
| if (file_system_options_.is_incognito())
|
| @@ -424,6 +368,16 @@ SandboxMountPointProvider::ValidateFileSystemRootAndGetPathOnFileThread(
|
| origin_url, type, create);
|
| }
|
|
|
| +bool SandboxMountPointProvider::IsAccessAllowed(const GURL& origin_url,
|
| + FileSystemType type,
|
| + const FilePath& unused) {
|
| + if (type != kFileSystemTypeTemporary && type != kFileSystemTypePersistent)
|
| + return false;
|
| + // We essentially depend on quota to do our access controls, so here
|
| + // we only check if the requested scheme is allowed or not.
|
| + return IsAllowedScheme(origin_url);
|
| +}
|
| +
|
| bool SandboxMountPointProvider::IsRestrictedFileName(const FilePath& filename)
|
| const {
|
| if (filename.value().empty())
|
| @@ -504,8 +458,8 @@ bool SandboxMountPointProvider::DeleteOriginDataOnFileThread(
|
|
|
| void SandboxMountPointProvider::GetOriginsForTypeOnFileThread(
|
| fileapi::FileSystemType type, std::set<GURL>* origins) {
|
| - DCHECK(type == fileapi::kFileSystemTypeTemporary ||
|
| - type == fileapi::kFileSystemTypePersistent);
|
| + DCHECK(type == kFileSystemTypeTemporary ||
|
| + type == kFileSystemTypePersistent);
|
| DCHECK(origins);
|
| scoped_ptr<OriginEnumerator> enumerator(CreateOriginEnumerator());
|
| GURL origin;
|
| @@ -518,8 +472,8 @@ void SandboxMountPointProvider::GetOriginsForTypeOnFileThread(
|
| void SandboxMountPointProvider::GetOriginsForHostOnFileThread(
|
| fileapi::FileSystemType type, const std::string& host,
|
| std::set<GURL>* origins) {
|
| - DCHECK(type == fileapi::kFileSystemTypeTemporary ||
|
| - type == fileapi::kFileSystemTypePersistent);
|
| + DCHECK(type == kFileSystemTypeTemporary ||
|
| + type == kFileSystemTypePersistent);
|
| DCHECK(origins);
|
| scoped_ptr<OriginEnumerator> enumerator(CreateOriginEnumerator());
|
| GURL origin;
|
| @@ -532,8 +486,8 @@ void SandboxMountPointProvider::GetOriginsForHostOnFileThread(
|
|
|
| int64 SandboxMountPointProvider::GetOriginUsageOnFileThread(
|
| const GURL& origin_url, fileapi::FileSystemType type) {
|
| - DCHECK(type == fileapi::kFileSystemTypeTemporary ||
|
| - type == fileapi::kFileSystemTypePersistent);
|
| + DCHECK(type == kFileSystemTypeTemporary ||
|
| + type == kFileSystemTypePersistent);
|
| FilePath base_path =
|
| GetBaseDirectoryForOriginAndType(origin_url, type, false);
|
| if (base_path.empty() || !file_util::DirectoryExists(base_path)) return 0;
|
| @@ -576,8 +530,8 @@ int64 SandboxMountPointProvider::GetOriginUsageOnFileThread(
|
| void SandboxMountPointProvider::NotifyOriginWasAccessedOnIOThread(
|
| QuotaManagerProxy* proxy, const GURL& origin_url,
|
| fileapi::FileSystemType type) {
|
| - DCHECK(type == fileapi::kFileSystemTypeTemporary ||
|
| - type == fileapi::kFileSystemTypePersistent);
|
| + DCHECK(type == kFileSystemTypeTemporary ||
|
| + type == kFileSystemTypePersistent);
|
| if (proxy) {
|
| proxy->NotifyStorageAccessed(
|
| quota::QuotaClient::kFileSystem,
|
| @@ -589,8 +543,8 @@ void SandboxMountPointProvider::NotifyOriginWasAccessedOnIOThread(
|
| void SandboxMountPointProvider::UpdateOriginUsageOnFileThread(
|
| QuotaManagerProxy* proxy, const GURL& origin_url,
|
| fileapi::FileSystemType type, int64 delta) {
|
| - DCHECK(type == fileapi::kFileSystemTypeTemporary ||
|
| - type == fileapi::kFileSystemTypePersistent);
|
| + DCHECK(type == kFileSystemTypeTemporary ||
|
| + type == kFileSystemTypePersistent);
|
| FilePath usage_file_path = GetUsageCachePathForOriginAndType(
|
| origin_url, type);
|
| DCHECK(!usage_file_path.empty());
|
| @@ -607,8 +561,8 @@ void SandboxMountPointProvider::UpdateOriginUsageOnFileThread(
|
|
|
| void SandboxMountPointProvider::StartUpdateOriginOnFileThread(
|
| const GURL& origin_url, fileapi::FileSystemType type) {
|
| - DCHECK(type == fileapi::kFileSystemTypeTemporary ||
|
| - type == fileapi::kFileSystemTypePersistent);
|
| + DCHECK(type == kFileSystemTypeTemporary ||
|
| + type == kFileSystemTypePersistent);
|
| FilePath usage_file_path = GetUsageCachePathForOriginAndType(
|
| origin_url, type);
|
| FileSystemUsageCache::IncrementDirty(usage_file_path);
|
| @@ -616,8 +570,8 @@ void SandboxMountPointProvider::StartUpdateOriginOnFileThread(
|
|
|
| void SandboxMountPointProvider::EndUpdateOriginOnFileThread(
|
| const GURL& origin_url, fileapi::FileSystemType type) {
|
| - DCHECK(type == fileapi::kFileSystemTypeTemporary ||
|
| - type == fileapi::kFileSystemTypePersistent);
|
| + DCHECK(type == kFileSystemTypeTemporary ||
|
| + type == kFileSystemTypePersistent);
|
| FilePath usage_file_path = GetUsageCachePathForOriginAndType(
|
| origin_url, type);
|
| FileSystemUsageCache::DecrementDirty(usage_file_path);
|
| @@ -625,8 +579,8 @@ void SandboxMountPointProvider::EndUpdateOriginOnFileThread(
|
|
|
| void SandboxMountPointProvider::InvalidateUsageCache(
|
| const GURL& origin_url, fileapi::FileSystemType type) {
|
| - DCHECK(type == fileapi::kFileSystemTypeTemporary ||
|
| - type == fileapi::kFileSystemTypePersistent);
|
| + DCHECK(type == kFileSystemTypeTemporary ||
|
| + type == kFileSystemTypePersistent);
|
| FilePath usage_file_path = GetUsageCachePathForOriginAndType(
|
| origin_url, type);
|
| FileSystemUsageCache::IncrementDirty(usage_file_path);
|
|
|