summaryrefslogtreecommitdiffstats
path: root/webkit/browser/fileapi
diff options
context:
space:
mode:
authorkinuko@chromium.org <kinuko@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-10-21 16:06:54 +0000
committerkinuko@chromium.org <kinuko@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2013-10-21 16:06:54 +0000
commit1d94153935fd881910180707acbf6f15572ccd87 (patch)
treead606e0f0f8f0c1212e70bb14780b83c71168b56 /webkit/browser/fileapi
parent820ba298c9678a54c28747c4645036d547288595 (diff)
downloadchromium_src-1d94153935fd881910180707acbf6f15572ccd87.zip
chromium_src-1d94153935fd881910180707acbf6f15572ccd87.tar.gz
chromium_src-1d94153935fd881910180707acbf6f15572ccd87.tar.bz2
Add PluginPrivate file system backend.
Not yet wired in the production filesystem context. Not yet added any security protection. Deletes site in the cookies tree should delete the data in this filesystem too, but not tested yet. BUG=286240 TEST=PluginPrivateFileSystemBackendTest.* TBR=avi Review URL: https://codereview.chromium.org/27658002 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@229820 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'webkit/browser/fileapi')
-rw-r--r--webkit/browser/fileapi/plugin_private_file_system_backend.cc297
-rw-r--r--webkit/browser/fileapi/plugin_private_file_system_backend.h136
2 files changed, 433 insertions, 0 deletions
diff --git a/webkit/browser/fileapi/plugin_private_file_system_backend.cc b/webkit/browser/fileapi/plugin_private_file_system_backend.cc
new file mode 100644
index 0000000..e7b6214
--- /dev/null
+++ b/webkit/browser/fileapi/plugin_private_file_system_backend.cc
@@ -0,0 +1,297 @@
+// 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/plugin_private_file_system_backend.h"
+
+#include <map>
+
+#include "base/stl_util.h"
+#include "base/synchronization/lock.h"
+#include "base/task_runner_util.h"
+#include "net/base/net_util.h"
+#include "webkit/browser/blob/file_stream_reader.h"
+#include "webkit/browser/fileapi/async_file_util_adapter.h"
+#include "webkit/browser/fileapi/file_stream_writer.h"
+#include "webkit/browser/fileapi/file_system_context.h"
+#include "webkit/browser/fileapi/file_system_operation.h"
+#include "webkit/browser/fileapi/file_system_operation_context.h"
+#include "webkit/browser/fileapi/file_system_options.h"
+#include "webkit/browser/fileapi/isolated_context.h"
+#include "webkit/browser/fileapi/obfuscated_file_util.h"
+#include "webkit/common/fileapi/file_system_util.h"
+
+namespace fileapi {
+
+class PluginPrivateFileSystemBackend::FileSystemIDToPluginMap {
+ public:
+ FileSystemIDToPluginMap(base::SequencedTaskRunner* task_runner)
+ : task_runner_(task_runner) {}
+ ~FileSystemIDToPluginMap() {}
+
+ std::string GetPluginIDForURL(const FileSystemURL& url) {
+ DCHECK(task_runner_->RunsTasksOnCurrentThread());
+ Map::iterator found = map_.find(url.filesystem_id());
+ if (url.type() != kFileSystemTypePluginPrivate || found == map_.end()) {
+ NOTREACHED() << "Unsupported url is given: " << url.DebugString();
+ return std::string();
+ }
+ return found->second;
+ }
+
+ void RegisterFileSystem(const std::string& filesystem_id,
+ const std::string& plugin_id) {
+ DCHECK(task_runner_->RunsTasksOnCurrentThread());
+ DCHECK(!filesystem_id.empty() &&
+ !ContainsKey(map_, filesystem_id)) << filesystem_id;
+ map_[filesystem_id] = plugin_id;
+ }
+
+ void RemoveFileSystem(const std::string& filesystem_id) {
+ DCHECK(task_runner_->RunsTasksOnCurrentThread());
+ map_.erase(filesystem_id);
+ }
+
+ private:
+ typedef std::map<std::string, std::string> Map;
+ scoped_refptr<base::SequencedTaskRunner> task_runner_;
+ Map map_;
+};
+
+namespace {
+
+const base::FilePath::CharType* kFileSystemDirectory =
+ SandboxFileSystemBackendDelegate::kFileSystemDirectory;
+const base::FilePath::CharType* kPluginPrivateDirectory =
+ FILE_PATH_LITERAL("Plugins");
+
+base::PlatformFileError OpenFileSystemOnFileThread(
+ ObfuscatedFileUtil* file_util,
+ PluginPrivateFileSystemBackend::FileSystemIDToPluginMap* plugin_map,
+ const GURL& origin_url,
+ const std::string& filesystem_id,
+ const std::string& plugin_id,
+ OpenFileSystemMode mode) {
+ base::PlatformFileError error = base::PLATFORM_FILE_ERROR_FAILED;
+ const bool create = (mode == OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT);
+ file_util->GetDirectoryForOriginAndType(
+ origin_url, plugin_id, create, &error);
+ if (error != base::PLATFORM_FILE_OK)
+ IsolatedContext::GetInstance()->RevokeFileSystem(filesystem_id);
+ else
+ plugin_map->RegisterFileSystem(filesystem_id, plugin_id);
+ return error;
+}
+
+} // namespace
+
+PluginPrivateFileSystemBackend::PluginPrivateFileSystemBackend(
+ base::SequencedTaskRunner* file_task_runner,
+ const base::FilePath& profile_path,
+ quota::SpecialStoragePolicy* special_storage_policy,
+ const FileSystemOptions& file_system_options)
+ : file_task_runner_(file_task_runner),
+ file_system_options_(file_system_options),
+ base_path_(profile_path.Append(
+ kFileSystemDirectory).Append(kPluginPrivateDirectory)),
+ plugin_map_(new FileSystemIDToPluginMap(file_task_runner)),
+ weak_factory_(this) {
+ file_util_.reset(
+ new AsyncFileUtilAdapter(new ObfuscatedFileUtil(
+ special_storage_policy,
+ base_path_,
+ file_task_runner,
+ base::Bind(&FileSystemIDToPluginMap::GetPluginIDForURL,
+ base::Owned(plugin_map_)),
+ std::set<std::string>())));
+}
+
+PluginPrivateFileSystemBackend::~PluginPrivateFileSystemBackend() {
+ if (!file_task_runner_->RunsTasksOnCurrentThread()) {
+ AsyncFileUtil* file_util = file_util_.release();
+ if (!file_task_runner_->DeleteSoon(FROM_HERE, file_util))
+ delete file_util;
+ }
+}
+
+void PluginPrivateFileSystemBackend::OpenPrivateFileSystem(
+ const GURL& origin_url,
+ FileSystemType type,
+ const std::string& plugin_id,
+ OpenFileSystemMode mode,
+ const OpenFileSystemCallback& callback) {
+ if (!CanHandleType(type) || file_system_options_.is_incognito()) {
+ base::MessageLoopProxy::current()->PostTask(
+ FROM_HERE, base::Bind(callback, GURL(), std::string(),
+ base::PLATFORM_FILE_ERROR_SECURITY));
+ return;
+ }
+
+ // TODO(nhiroki,kinuko): This constant should be somehow shared.
+ const std::string name("PluginPrivate");
+ std::string filesystem_id =
+ IsolatedContext::GetInstance()->RegisterFileSystemForVirtualPath(
+ type, name, base::FilePath());
+
+ PostTaskAndReplyWithResult(
+ file_task_runner_.get(),
+ FROM_HERE,
+ base::Bind(&OpenFileSystemOnFileThread,
+ obfuscated_file_util(), plugin_map_,
+ origin_url, filesystem_id, plugin_id, mode),
+ base::Bind(callback,
+ GURL(GetIsolatedFileSystemRootURIString(
+ origin_url, filesystem_id, name)),
+ GetIsolatedFileSystemName(origin_url, filesystem_id)));
+}
+
+bool PluginPrivateFileSystemBackend::CanHandleType(FileSystemType type) const {
+ return type == kFileSystemTypePluginPrivate;
+}
+
+void PluginPrivateFileSystemBackend::Initialize(FileSystemContext* context) {
+}
+
+void PluginPrivateFileSystemBackend::OpenFileSystem(
+ const GURL& origin_url,
+ FileSystemType type,
+ OpenFileSystemMode mode,
+ const OpenFileSystemCallback& callback) {
+ // We never allow opening a new plugin-private filesystem via usual
+ // OpenFileSystem.
+ base::MessageLoopProxy::current()->PostTask(
+ FROM_HERE,
+ base::Bind(callback, GURL(), std::string(),
+ base::PLATFORM_FILE_ERROR_SECURITY));
+}
+
+AsyncFileUtil*
+PluginPrivateFileSystemBackend::GetAsyncFileUtil(FileSystemType type) {
+ return file_util_.get();
+}
+
+CopyOrMoveFileValidatorFactory*
+PluginPrivateFileSystemBackend::GetCopyOrMoveFileValidatorFactory(
+ FileSystemType type,
+ base::PlatformFileError* error_code) {
+ DCHECK(error_code);
+ *error_code = base::PLATFORM_FILE_OK;
+ return NULL;
+}
+
+FileSystemOperation* PluginPrivateFileSystemBackend::CreateFileSystemOperation(
+ const FileSystemURL& url,
+ FileSystemContext* context,
+ base::PlatformFileError* error_code) const {
+ scoped_ptr<FileSystemOperationContext> operation_context(
+ new FileSystemOperationContext(context));
+ return FileSystemOperation::Create(url, context, operation_context.Pass());
+}
+
+scoped_ptr<webkit_blob::FileStreamReader>
+PluginPrivateFileSystemBackend::CreateFileStreamReader(
+ const FileSystemURL& url,
+ int64 offset,
+ const base::Time& expected_modification_time,
+ FileSystemContext* context) const {
+ return scoped_ptr<webkit_blob::FileStreamReader>();
+}
+
+scoped_ptr<FileStreamWriter>
+PluginPrivateFileSystemBackend::CreateFileStreamWriter(
+ const FileSystemURL& url,
+ int64 offset,
+ FileSystemContext* context) const {
+ return scoped_ptr<FileStreamWriter>();
+}
+
+FileSystemQuotaUtil* PluginPrivateFileSystemBackend::GetQuotaUtil() {
+ return this;
+}
+
+base::PlatformFileError
+PluginPrivateFileSystemBackend::DeleteOriginDataOnFileThread(
+ FileSystemContext* context,
+ quota::QuotaManagerProxy* proxy,
+ const GURL& origin_url,
+ FileSystemType type) {
+ if (!CanHandleType(type))
+ return base::PLATFORM_FILE_ERROR_SECURITY;
+ bool result = obfuscated_file_util()->DeleteDirectoryForOriginAndType(
+ origin_url, std::string());
+ if (result)
+ return base::PLATFORM_FILE_OK;
+ return base::PLATFORM_FILE_ERROR_FAILED;
+}
+
+void PluginPrivateFileSystemBackend::GetOriginsForTypeOnFileThread(
+ FileSystemType type,
+ std::set<GURL>* origins) {
+ if (!CanHandleType(type))
+ return;
+ scoped_ptr<ObfuscatedFileUtil::AbstractOriginEnumerator> enumerator(
+ obfuscated_file_util()->CreateOriginEnumerator());
+ GURL origin;
+ while (!(origin = enumerator->Next()).is_empty())
+ origins->insert(origin);
+}
+
+void PluginPrivateFileSystemBackend::GetOriginsForHostOnFileThread(
+ FileSystemType type,
+ const std::string& host,
+ std::set<GURL>* origins) {
+ if (!CanHandleType(type))
+ return;
+ scoped_ptr<ObfuscatedFileUtil::AbstractOriginEnumerator> enumerator(
+ obfuscated_file_util()->CreateOriginEnumerator());
+ GURL origin;
+ while (!(origin = enumerator->Next()).is_empty()) {
+ if (host == net::GetHostOrSpecFromURL(origin))
+ origins->insert(origin);
+ }
+}
+
+int64 PluginPrivateFileSystemBackend::GetOriginUsageOnFileThread(
+ FileSystemContext* context,
+ const GURL& origin_url,
+ FileSystemType type) {
+ // We don't track usage on this filesystem.
+ return 0;
+}
+
+void PluginPrivateFileSystemBackend::AddFileUpdateObserver(
+ FileSystemType type,
+ FileUpdateObserver* observer,
+ base::SequencedTaskRunner* task_runner) {}
+
+void PluginPrivateFileSystemBackend::AddFileChangeObserver(
+ FileSystemType type,
+ FileChangeObserver* observer,
+ base::SequencedTaskRunner* task_runner) {}
+
+void PluginPrivateFileSystemBackend::AddFileAccessObserver(
+ FileSystemType type,
+ FileAccessObserver* observer,
+ base::SequencedTaskRunner* task_runner) {}
+
+const UpdateObserverList* PluginPrivateFileSystemBackend::GetUpdateObservers(
+ FileSystemType type) const {
+ return NULL;
+}
+
+const ChangeObserverList* PluginPrivateFileSystemBackend::GetChangeObservers(
+ FileSystemType type) const {
+ return NULL;
+}
+
+const AccessObserverList* PluginPrivateFileSystemBackend::GetAccessObservers(
+ FileSystemType type) const {
+ return NULL;
+}
+
+ObfuscatedFileUtil* PluginPrivateFileSystemBackend::obfuscated_file_util() {
+ return static_cast<ObfuscatedFileUtil*>(
+ static_cast<AsyncFileUtilAdapter*>(file_util_.get())->sync_file_util());
+}
+
+} // namespace fileapi
diff --git a/webkit/browser/fileapi/plugin_private_file_system_backend.h b/webkit/browser/fileapi/plugin_private_file_system_backend.h
new file mode 100644
index 0000000..b94d13a
--- /dev/null
+++ b/webkit/browser/fileapi/plugin_private_file_system_backend.h
@@ -0,0 +1,136 @@
+// 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_PLUGIN_PRIVATE_FILE_SYSTEM_BACKEND_H_
+#define WEBKIT_BROWSER_FILEAPI_PLUGIN_PRIVATE_FILE_SYSTEM_BACKEND_H_
+
+#include <set>
+#include <string>
+
+#include "base/memory/ref_counted.h"
+#include "base/memory/weak_ptr.h"
+#include "webkit/browser/fileapi/file_system_backend.h"
+#include "webkit/browser/fileapi/file_system_options.h"
+#include "webkit/browser/fileapi/file_system_quota_util.h"
+
+namespace base {
+class SequencedTaskRunner;
+}
+
+namespace quota {
+class SpecialStoragePolicy;
+}
+
+namespace fileapi {
+
+class ObfuscatedFileUtil;
+
+class WEBKIT_STORAGE_BROWSER_EXPORT PluginPrivateFileSystemBackend
+ : public FileSystemBackend,
+ public FileSystemQuotaUtil {
+ public:
+ class FileSystemIDToPluginMap;
+
+ PluginPrivateFileSystemBackend(
+ base::SequencedTaskRunner* file_task_runner,
+ const base::FilePath& profile_path,
+ quota::SpecialStoragePolicy* special_storage_policy,
+ const FileSystemOptions& file_system_options);
+ virtual ~PluginPrivateFileSystemBackend();
+
+ // This must be used to open 'private' filesystem instead of regular
+ // OpenFileSystem.
+ // |plugin_id| must be an identifier string for per-plugin
+ // isolation, e.g. name, MIME type etc.
+ // NOTE: |plugin_id| must be sanitized ASCII string that doesn't
+ // include *any* dangerous character like '/'.
+ void OpenPrivateFileSystem(
+ const GURL& origin_url,
+ FileSystemType type,
+ const std::string& plugin_id,
+ OpenFileSystemMode mode,
+ const OpenFileSystemCallback& callback);
+
+ // FileSystemBackend overrides.
+ virtual bool CanHandleType(FileSystemType type) const OVERRIDE;
+ virtual void Initialize(FileSystemContext* context) OVERRIDE;
+ virtual void OpenFileSystem(
+ const GURL& origin_url,
+ FileSystemType type,
+ OpenFileSystemMode mode,
+ const OpenFileSystemCallback& callback) OVERRIDE;
+ virtual AsyncFileUtil* GetAsyncFileUtil(FileSystemType type) OVERRIDE;
+ virtual CopyOrMoveFileValidatorFactory* GetCopyOrMoveFileValidatorFactory(
+ FileSystemType type,
+ base::PlatformFileError* error_code) OVERRIDE;
+ virtual FileSystemOperation* CreateFileSystemOperation(
+ const FileSystemURL& url,
+ FileSystemContext* context,
+ base::PlatformFileError* error_code) const OVERRIDE;
+ virtual scoped_ptr<webkit_blob::FileStreamReader> CreateFileStreamReader(
+ const FileSystemURL& url,
+ int64 offset,
+ const base::Time& expected_modification_time,
+ FileSystemContext* context) const OVERRIDE;
+ virtual scoped_ptr<FileStreamWriter> CreateFileStreamWriter(
+ const FileSystemURL& url,
+ int64 offset,
+ FileSystemContext* context) const OVERRIDE;
+ virtual FileSystemQuotaUtil* GetQuotaUtil() OVERRIDE;
+
+ // FileSystemQuotaUtil overrides.
+ virtual base::PlatformFileError DeleteOriginDataOnFileThread(
+ FileSystemContext* context,
+ quota::QuotaManagerProxy* proxy,
+ const GURL& origin_url,
+ FileSystemType type) OVERRIDE;
+ virtual void GetOriginsForTypeOnFileThread(
+ FileSystemType type,
+ std::set<GURL>* origins) OVERRIDE;
+ virtual void GetOriginsForHostOnFileThread(
+ FileSystemType type,
+ const std::string& host,
+ std::set<GURL>* origins) OVERRIDE;
+ virtual int64 GetOriginUsageOnFileThread(
+ FileSystemContext* context,
+ const GURL& origin_url,
+ FileSystemType type) OVERRIDE;
+ virtual void AddFileUpdateObserver(
+ FileSystemType type,
+ FileUpdateObserver* observer,
+ base::SequencedTaskRunner* task_runner) OVERRIDE;
+ virtual void AddFileChangeObserver(
+ FileSystemType type,
+ FileChangeObserver* observer,
+ base::SequencedTaskRunner* task_runner) OVERRIDE;
+ virtual void AddFileAccessObserver(
+ FileSystemType type,
+ FileAccessObserver* observer,
+ base::SequencedTaskRunner* task_runner) OVERRIDE;
+ virtual const UpdateObserverList* GetUpdateObservers(
+ FileSystemType type) const OVERRIDE;
+ virtual const ChangeObserverList* GetChangeObservers(
+ FileSystemType type) const OVERRIDE;
+ virtual const AccessObserverList* GetAccessObservers(
+ FileSystemType type) const OVERRIDE;
+
+ private:
+ friend class PluginPrivateFileSystemBackendTest;
+
+ ObfuscatedFileUtil* obfuscated_file_util();
+ const base::FilePath& base_path() const { return base_path_; }
+
+ scoped_refptr<base::SequencedTaskRunner> file_task_runner_;
+ const FileSystemOptions file_system_options_;
+ const base::FilePath base_path_;
+ scoped_ptr<AsyncFileUtil> file_util_;
+ FileSystemIDToPluginMap* plugin_map_; // Owned by file_util_.
+ base::WeakPtrFactory<PluginPrivateFileSystemBackend> weak_factory_;
+
+ DISALLOW_COPY_AND_ASSIGN(PluginPrivateFileSystemBackend);
+};
+
+} // namespace fileapi
+
+#endif // WEBKIT_BROWSER_FILEAPI_PLUGIN_PRIVATE_FILE_SYSTEM_BACKEND_H_