Home | History | Annotate | Download | only in fileapi
      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 "storage/browser/fileapi/external_mount_points.h"
     21 #include "storage/browser/fileapi/file_permission_policy.h"
     22 #include "storage/browser/fileapi/file_system_backend.h"
     23 #include "storage/browser/fileapi/file_system_context.h"
     24 #include "storage/browser/fileapi/file_system_operation_runner.h"
     25 #include "storage/browser/fileapi/file_system_options.h"
     26 #include "storage/browser/quota/quota_manager.h"
     27 #include "url/url_constants.h"
     28 
     29 namespace content {
     30 
     31 namespace {
     32 
     33 using storage::FileSystemOptions;
     34 
     35 FileSystemOptions CreateBrowserFileSystemOptions(bool is_incognito) {
     36   FileSystemOptions::ProfileMode profile_mode =
     37       is_incognito ? FileSystemOptions::PROFILE_MODE_INCOGNITO
     38                    : FileSystemOptions::PROFILE_MODE_NORMAL;
     39   std::vector<std::string> additional_allowed_schemes;
     40   GetContentClient()->browser()->GetAdditionalAllowedSchemesForFileSystem(
     41       &additional_allowed_schemes);
     42   if (CommandLine::ForCurrentProcess()->HasSwitch(
     43           switches::kAllowFileAccessFromFiles)) {
     44     additional_allowed_schemes.push_back(url::kFileScheme);
     45   }
     46   return FileSystemOptions(profile_mode, additional_allowed_schemes, NULL);
     47 }
     48 
     49 }  // namespace
     50 
     51 scoped_refptr<storage::FileSystemContext> CreateFileSystemContext(
     52     BrowserContext* browser_context,
     53     const base::FilePath& profile_path,
     54     bool is_incognito,
     55     storage::QuotaManagerProxy* quota_manager_proxy) {
     56   base::SequencedWorkerPool* pool = BrowserThread::GetBlockingPool();
     57   scoped_refptr<base::SequencedTaskRunner> file_task_runner =
     58       pool->GetSequencedTaskRunnerWithShutdownBehavior(
     59           pool->GetNamedSequenceToken("FileAPI"),
     60           base::SequencedWorkerPool::SKIP_ON_SHUTDOWN);
     61 
     62   // Setting up additional filesystem backends.
     63   ScopedVector<storage::FileSystemBackend> additional_backends;
     64   GetContentClient()->browser()->GetAdditionalFileSystemBackends(
     65       browser_context,
     66       profile_path,
     67       &additional_backends);
     68 
     69   // Set up the auto mount handlers for url requests.
     70   std::vector<storage::URLRequestAutoMountHandler>
     71       url_request_auto_mount_handlers;
     72   GetContentClient()->browser()->GetURLRequestAutoMountHandlers(
     73       &url_request_auto_mount_handlers);
     74 
     75   scoped_refptr<storage::FileSystemContext> file_system_context =
     76       new storage::FileSystemContext(
     77           BrowserThread::GetMessageLoopProxyForThread(BrowserThread::IO).get(),
     78           file_task_runner.get(),
     79           BrowserContext::GetMountPoints(browser_context),
     80           browser_context->GetSpecialStoragePolicy(),
     81           quota_manager_proxy,
     82           additional_backends.Pass(),
     83           url_request_auto_mount_handlers,
     84           profile_path,
     85           CreateBrowserFileSystemOptions(is_incognito));
     86 
     87   std::vector<storage::FileSystemType> types;
     88   file_system_context->GetFileSystemTypes(&types);
     89   for (size_t i = 0; i < types.size(); ++i) {
     90     ChildProcessSecurityPolicyImpl::GetInstance()
     91         ->RegisterFileSystemPermissionPolicy(
     92             types[i],
     93             storage::FileSystemContext::GetPermissionPolicy(types[i]));
     94   }
     95 
     96   return file_system_context;
     97 }
     98 
     99 bool FileSystemURLIsValid(storage::FileSystemContext* context,
    100                           const storage::FileSystemURL& url) {
    101   if (!url.is_valid())
    102     return false;
    103 
    104   return context->GetFileSystemBackend(url.type()) != NULL;
    105 }
    106 
    107 void SyncGetPlatformPath(storage::FileSystemContext* context,
    108                          int process_id,
    109                          const GURL& path,
    110                          base::FilePath* platform_path) {
    111   DCHECK(context->default_file_task_runner()->
    112          RunsTasksOnCurrentThread());
    113   DCHECK(platform_path);
    114   *platform_path = base::FilePath();
    115   storage::FileSystemURL url(context->CrackURL(path));
    116   if (!FileSystemURLIsValid(context, url))
    117     return;
    118 
    119   // Make sure if this file is ok to be read (in the current architecture
    120   // which means roughly same as the renderer is allowed to get the platform
    121   // path to the file).
    122   ChildProcessSecurityPolicyImpl* policy =
    123       ChildProcessSecurityPolicyImpl::GetInstance();
    124   if (!policy->CanReadFileSystemFile(process_id, url))
    125     return;
    126 
    127   context->operation_runner()->SyncGetPlatformPath(url, platform_path);
    128 
    129   // The path is to be attached to URLLoader so we grant read permission
    130   // for the file. (We need to check first because a parent directory may
    131   // already have the permissions and we don't need to grant it to the file.)
    132   if (!policy->CanReadFile(process_id, *platform_path))
    133     policy->GrantReadFile(process_id, *platform_path);
    134 }
    135 
    136 }  // namespace content
    137