| // Copyright (c) 2012 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 "content/browser/fileapi/browser_file_system_helper.h" |
| |
| #include <stddef.h> |
| #include <string> |
| #include <utility> |
| #include <vector> |
| |
| #include "base/command_line.h" |
| #include "base/files/file_path.h" |
| #include "base/sequenced_task_runner.h" |
| #include "base/threading/sequenced_worker_pool.h" |
| #include "content/browser/child_process_security_policy_impl.h" |
| #include "content/public/browser/browser_context.h" |
| #include "content/public/browser/browser_thread.h" |
| #include "content/public/browser/content_browser_client.h" |
| #include "content/public/common/content_client.h" |
| #include "content/public/common/content_switches.h" |
| #include "storage/browser/fileapi/external_mount_points.h" |
| #include "storage/browser/fileapi/file_permission_policy.h" |
| #include "storage/browser/fileapi/file_system_backend.h" |
| #include "storage/browser/fileapi/file_system_context.h" |
| #include "storage/browser/fileapi/file_system_operation_runner.h" |
| #include "storage/browser/fileapi/file_system_options.h" |
| #include "storage/browser/quota/quota_manager.h" |
| #include "url/url_constants.h" |
| |
| namespace content { |
| |
| namespace { |
| |
| using storage::FileSystemOptions; |
| |
| FileSystemOptions CreateBrowserFileSystemOptions(bool is_incognito) { |
| FileSystemOptions::ProfileMode profile_mode = |
| is_incognito ? FileSystemOptions::PROFILE_MODE_INCOGNITO |
| : FileSystemOptions::PROFILE_MODE_NORMAL; |
| std::vector<std::string> additional_allowed_schemes; |
| GetContentClient()->browser()->GetAdditionalAllowedSchemesForFileSystem( |
| &additional_allowed_schemes); |
| if (base::CommandLine::ForCurrentProcess()->HasSwitch( |
| switches::kAllowFileAccessFromFiles)) { |
| additional_allowed_schemes.push_back(url::kFileScheme); |
| } |
| return FileSystemOptions(profile_mode, additional_allowed_schemes, NULL); |
| } |
| |
| } // namespace |
| |
| scoped_refptr<storage::FileSystemContext> CreateFileSystemContext( |
| BrowserContext* browser_context, |
| const base::FilePath& profile_path, |
| bool is_incognito, |
| storage::QuotaManagerProxy* quota_manager_proxy) { |
| base::SequencedWorkerPool* pool = BrowserThread::GetBlockingPool(); |
| scoped_refptr<base::SequencedTaskRunner> file_task_runner = |
| pool->GetSequencedTaskRunnerWithShutdownBehavior( |
| pool->GetNamedSequenceToken("FileAPI"), |
| base::SequencedWorkerPool::SKIP_ON_SHUTDOWN); |
| |
| // Setting up additional filesystem backends. |
| ScopedVector<storage::FileSystemBackend> additional_backends; |
| GetContentClient()->browser()->GetAdditionalFileSystemBackends( |
| browser_context, |
| profile_path, |
| &additional_backends); |
| |
| // Set up the auto mount handlers for url requests. |
| std::vector<storage::URLRequestAutoMountHandler> |
| url_request_auto_mount_handlers; |
| GetContentClient()->browser()->GetURLRequestAutoMountHandlers( |
| &url_request_auto_mount_handlers); |
| |
| scoped_refptr<storage::FileSystemContext> file_system_context = |
| new storage::FileSystemContext( |
| BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO).get(), |
| file_task_runner.get(), |
| BrowserContext::GetMountPoints(browser_context), |
| browser_context->GetSpecialStoragePolicy(), quota_manager_proxy, |
| std::move(additional_backends), url_request_auto_mount_handlers, |
| profile_path, CreateBrowserFileSystemOptions(is_incognito)); |
| |
| std::vector<storage::FileSystemType> types; |
| file_system_context->GetFileSystemTypes(&types); |
| for (size_t i = 0; i < types.size(); ++i) { |
| ChildProcessSecurityPolicyImpl::GetInstance() |
| ->RegisterFileSystemPermissionPolicy( |
| types[i], |
| storage::FileSystemContext::GetPermissionPolicy(types[i])); |
| } |
| |
| return file_system_context; |
| } |
| |
| bool FileSystemURLIsValid(storage::FileSystemContext* context, |
| const storage::FileSystemURL& url) { |
| if (!url.is_valid()) |
| return false; |
| |
| return context->GetFileSystemBackend(url.type()) != NULL; |
| } |
| |
| void SyncGetPlatformPath(storage::FileSystemContext* context, |
| int process_id, |
| const GURL& path, |
| base::FilePath* platform_path) { |
| DCHECK(context->default_file_task_runner()-> |
| RunsTasksOnCurrentThread()); |
| DCHECK(platform_path); |
| *platform_path = base::FilePath(); |
| storage::FileSystemURL url(context->CrackURL(path)); |
| if (!FileSystemURLIsValid(context, url)) |
| return; |
| |
| // Make sure if this file is ok to be read (in the current architecture |
| // which means roughly same as the renderer is allowed to get the platform |
| // path to the file). |
| ChildProcessSecurityPolicyImpl* policy = |
| ChildProcessSecurityPolicyImpl::GetInstance(); |
| if (!policy->CanReadFileSystemFile(process_id, url)) |
| return; |
| |
| context->operation_runner()->SyncGetPlatformPath(url, platform_path); |
| |
| // The path is to be attached to URLLoader so we grant read permission |
| // for the file. (We need to check first because a parent directory may |
| // already have the permissions and we don't need to grant it to the file.) |
| if (!policy->CanReadFile(process_id, *platform_path)) |
| policy->GrantReadFile(process_id, *platform_path); |
| } |
| |
| } // namespace content |