summaryrefslogtreecommitdiffstats
path: root/webkit/browser/fileapi
diff options
context:
space:
mode:
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_