browser_file_system_helper.cc revision a36e5920737c6adbddd3e43b760e5de8431db6e0
1// Copyright (c) 2012 The Chromium Authors. All rights reserved. 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#include "content/browser/fileapi/browser_file_system_helper.h" 6 7#include <string> 8#include <vector> 9 10#include "base/command_line.h" 11#include "base/files/file_path.h" 12#include "base/sequenced_task_runner.h" 13#include "base/threading/sequenced_worker_pool.h" 14#include "content/browser/child_process_security_policy_impl.h" 15#include "content/public/browser/browser_context.h" 16#include "content/public/browser/browser_thread.h" 17#include "content/public/browser/content_browser_client.h" 18#include "content/public/common/content_client.h" 19#include "content/public/common/content_switches.h" 20#include "content/public/common/url_constants.h" 21#include "webkit/browser/fileapi/external_mount_points.h" 22#include "webkit/browser/fileapi/file_permission_policy.h" 23#include "webkit/browser/fileapi/file_system_backend.h" 24#include "webkit/browser/fileapi/file_system_operation_runner.h" 25#include "webkit/browser/fileapi/file_system_options.h" 26#include "webkit/browser/quota/quota_manager.h" 27 28namespace content { 29 30namespace { 31 32using fileapi::FileSystemOptions; 33 34FileSystemOptions CreateBrowserFileSystemOptions(bool is_incognito) { 35 FileSystemOptions::ProfileMode profile_mode = 36 is_incognito ? FileSystemOptions::PROFILE_MODE_INCOGNITO 37 : FileSystemOptions::PROFILE_MODE_NORMAL; 38 std::vector<std::string> additional_allowed_schemes; 39 GetContentClient()->browser()->GetAdditionalAllowedSchemesForFileSystem( 40 &additional_allowed_schemes); 41 if (CommandLine::ForCurrentProcess()->HasSwitch( 42 switches::kAllowFileAccessFromFiles)) { 43 additional_allowed_schemes.push_back(chrome::kFileScheme); 44 } 45 return FileSystemOptions(profile_mode, additional_allowed_schemes); 46} 47 48} // namespace 49 50scoped_refptr<fileapi::FileSystemContext> CreateFileSystemContext( 51 BrowserContext* browser_context, 52 const base::FilePath& profile_path, 53 bool is_incognito, 54 quota::QuotaManagerProxy* quota_manager_proxy) { 55 56 base::SequencedWorkerPool* pool = content::BrowserThread::GetBlockingPool(); 57 scoped_refptr<base::SequencedTaskRunner> file_task_runner = 58 pool->GetSequencedTaskRunner(pool->GetNamedSequenceToken("FileAPI")); 59 60 // Setting up additional filesystem backends. 61 ScopedVector<fileapi::FileSystemBackend> additional_backends; 62 GetContentClient()->browser()->GetAdditionalFileSystemBackends( 63 browser_context, 64 profile_path, 65 &additional_backends); 66 67 scoped_refptr<fileapi::FileSystemContext> file_system_context = 68 new fileapi::FileSystemContext( 69 BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO).get(), 70 file_task_runner.get(), 71 BrowserContext::GetMountPoints(browser_context), 72 browser_context->GetSpecialStoragePolicy(), 73 quota_manager_proxy, 74 additional_backends.Pass(), 75 profile_path, 76 CreateBrowserFileSystemOptions(is_incognito)); 77 78 std::vector<fileapi::FileSystemType> types; 79 file_system_context->GetFileSystemTypes(&types); 80 for (size_t i = 0; i < types.size(); ++i) { 81 ChildProcessSecurityPolicyImpl::GetInstance()-> 82 RegisterFileSystemPermissionPolicy( 83 types[i], 84 fileapi::FileSystemContext::GetPermissionPolicy(types[i])); 85 } 86 87 return file_system_context; 88} 89 90bool FileSystemURLIsValid( 91 fileapi::FileSystemContext* context, 92 const fileapi::FileSystemURL& url) { 93 if (!url.is_valid()) 94 return false; 95 96 return context->GetFileSystemBackend(url.type()) != NULL; 97} 98 99bool CheckFileSystemPermissionsForProcess( 100 fileapi::FileSystemContext* context, int process_id, 101 const fileapi::FileSystemURL& url, int permissions, 102 base::PlatformFileError* error) { 103 DCHECK(error); 104 105 if (!FileSystemURLIsValid(context, url)) { 106 *error = base::PLATFORM_FILE_ERROR_INVALID_URL; 107 return false; 108 } 109 110 if (!ChildProcessSecurityPolicyImpl::GetInstance()-> 111 HasPermissionsForFileSystemFile(process_id, url, permissions)) { 112 *error = base::PLATFORM_FILE_ERROR_SECURITY; 113 return false; 114 } 115 116 *error = base::PLATFORM_FILE_OK; 117 return true; 118} 119 120void SyncGetPlatformPath(fileapi::FileSystemContext* context, 121 int process_id, 122 const GURL& path, 123 base::FilePath* platform_path) { 124 DCHECK(context->default_file_task_runner()-> 125 RunsTasksOnCurrentThread()); 126 DCHECK(platform_path); 127 *platform_path = base::FilePath(); 128 fileapi::FileSystemURL url(context->CrackURL(path)); 129 if (!FileSystemURLIsValid(context, url)) 130 return; 131 132 // Make sure if this file is ok to be read (in the current architecture 133 // which means roughly same as the renderer is allowed to get the platform 134 // path to the file). 135 ChildProcessSecurityPolicyImpl* policy = 136 ChildProcessSecurityPolicyImpl::GetInstance(); 137 if (!policy->CanReadFileSystemFile(process_id, url)) 138 return; 139 140 context->operation_runner()->SyncGetPlatformPath(url, platform_path); 141 142 // The path is to be attached to URLLoader so we grant read permission 143 // for the file. (We need to check first because a parent directory may 144 // already have the permissions and we don't need to grant it to the file.) 145 if (!policy->CanReadFile(process_id, *platform_path)) 146 policy->GrantReadFile(process_id, *platform_path); 147} 148 149} // namespace content 150