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