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.
5 #ifndef STORAGE_BROWSER_FILEAPI_ISOLATED_CONTEXT_H_
6 #define STORAGE_BROWSER_FILEAPI_ISOLATED_CONTEXT_H_
13 #include "base/basictypes.h"
14 #include "base/files/file_path.h"
15 #include "base/lazy_instance.h"
16 #include "base/memory/singleton.h"
17 #include "base/synchronization/lock.h"
18 #include "storage/browser/fileapi/mount_points.h"
19 #include "storage/browser/storage_browser_export.h"
20 #include "storage/common/fileapi/file_system_types.h"
28 // Manages isolated filesystem mount points which have no well-known names
29 // and are identified by a string 'filesystem ID', which usually just looks
31 // This type of filesystem can be created on the fly and may go away when it has
32 // no references from renderers.
33 // Files in an isolated filesystem are registered with corresponding names and
34 // identified by a filesystem URL like:
36 // filesystem:<origin>/isolated/<filesystem_id>/<name>/relative/path
38 // Some methods of this class are virtual just for mocking.
40 class STORAGE_EXPORT IsolatedContext
: public MountPoints
{
42 class STORAGE_EXPORT FileInfoSet
{
47 // Add the given |path| to the set and populates |registered_name| with
48 // the registered name assigned for the path. |path| needs to be
49 // absolute and should not contain parent references.
50 // Return false if the |path| is not valid and could not be added.
51 bool AddPath(const base::FilePath
& path
, std::string
* registered_name
);
53 // Add the given |path| with the |name|.
54 // Return false if the |name| is already registered in the set or
55 // is not valid and could not be added.
56 bool AddPathWithName(const base::FilePath
& path
, const std::string
& name
);
58 const std::set
<MountPointInfo
>& fileset() const { return fileset_
; }
61 std::set
<MountPointInfo
> fileset_
;
64 // The instance is lazily created per browser process.
65 static IsolatedContext
* GetInstance();
67 // Returns true if the given filesystem type is managed by IsolatedContext
68 // (i.e. if the given |type| is Isolated or External).
69 // TODO(kinuko): needs a better function name.
70 static bool IsIsolatedType(FileSystemType type
);
72 // Registers a new isolated filesystem with the given FileInfoSet |files|
73 // and returns the new filesystem_id. The files are registered with their
74 // register_name as their keys so that later we can resolve the full paths
75 // for the given name. We only expose the name and the ID for the
76 // newly created filesystem to the renderer for the sake of security.
78 // The renderer will be sending filesystem requests with a virtual path like
79 // '/<filesystem_id>/<registered_name>/<relative_path_from_the_dropped_path>'
80 // for which we could crack in the browser process by calling
81 // CrackIsolatedPath to get the full path.
83 // For example: if a dropped file has a path like '/a/b/foo' and we register
84 // the path with the name 'foo' in the newly created filesystem.
85 // Later if the context is asked to crack a virtual path like '/<fsid>/foo'
86 // it can properly return the original path '/a/b/foo' by looking up the
87 // internal mapping. Similarly if a dropped entry is a directory and its
88 // path is like '/a/b/dir' a virtual path like '/<fsid>/dir/foo' can be
89 // cracked into '/a/b/dir/foo'.
91 // Note that the path in |fileset| that contains '..' or is not an
92 // absolute path is skipped and is not registered.
93 std::string
RegisterDraggedFileSystem(const FileInfoSet
& files
);
95 // Registers a new isolated filesystem for a given |path| of filesystem
96 // |type| filesystem with |filesystem_id| and returns a new filesystem ID.
97 // |path| must be an absolute path which has no parent references ('..').
98 // If |register_name| is non-null and has non-empty string the path is
99 // registered as the given |register_name|, otherwise it is populated
100 // with the name internally assigned to the path.
101 std::string
RegisterFileSystemForPath(FileSystemType type
,
102 const std::string
& filesystem_id
,
103 const base::FilePath
& path
,
104 std::string
* register_name
);
106 // Registers a virtual filesystem. This is different from
107 // RegisterFileSystemForPath because register_name is required, and
108 // cracked_path_prefix is allowed to be non-absolute.
109 // |register_name| is required, since we cannot infer one from the path.
110 // |cracked_path_prefix| has no parent references, but can be relative.
111 std::string
RegisterFileSystemForVirtualPath(
113 const std::string
& register_name
,
114 const base::FilePath
& cracked_path_prefix
);
116 // Revokes all filesystem(s) registered for the given path.
117 // This is assumed to be called when the registered path becomes
118 // globally invalid, e.g. when a device for the path is detached.
120 // Note that this revokes the filesystem no matter how many references it has.
121 // It is ok to call this for the path that has no associated filesystems.
122 // Note that this only works for the filesystems registered by
123 // |RegisterFileSystemForPath|.
124 void RevokeFileSystemByPath(const base::FilePath
& path
);
126 // Adds a reference to a filesystem specified by the given filesystem_id.
127 void AddReference(const std::string
& filesystem_id
);
129 // Removes a reference to a filesystem specified by the given filesystem_id.
130 // If the reference count reaches 0 the isolated context gets destroyed.
131 // It is OK to call this on the filesystem that has been already deleted
132 // (e.g. by RevokeFileSystemByPath).
133 void RemoveReference(const std::string
& filesystem_id
);
135 // Returns a set of dragged MountPointInfos registered for the
137 // The filesystem_id must be pointing to a dragged file system
138 // (i.e. must be the one registered by RegisterDraggedFileSystem).
139 // Returns false if the |filesystem_id| is not valid.
140 bool GetDraggedFileInfo(const std::string
& filesystem_id
,
141 std::vector
<MountPointInfo
>* files
) const;
143 // MountPoints overrides.
144 bool HandlesFileSystemMountType(FileSystemType type
) const override
;
145 bool RevokeFileSystem(const std::string
& filesystem_id
) override
;
146 bool GetRegisteredPath(const std::string
& filesystem_id
,
147 base::FilePath
* path
) const override
;
148 bool CrackVirtualPath(const base::FilePath
& virtual_path
,
149 std::string
* filesystem_id
,
150 FileSystemType
* type
,
151 std::string
* cracked_id
,
152 base::FilePath
* path
,
153 FileSystemMountOption
* mount_option
) const override
;
154 FileSystemURL
CrackURL(const GURL
& url
) const override
;
155 FileSystemURL
CreateCrackedFileSystemURL(
158 const base::FilePath
& path
) const override
;
160 // Returns the virtual root path that looks like /<filesystem_id>.
161 base::FilePath
CreateVirtualRootPath(const std::string
& filesystem_id
) const;
164 friend struct base::DefaultLazyInstanceTraits
<IsolatedContext
>;
166 // Represents each file system instance (defined in the .cc).
169 typedef std::map
<std::string
, Instance
*> IDToInstance
;
171 // Reverse map from registered path to IDs.
172 typedef std::map
<base::FilePath
, std::set
<std::string
> > PathToID
;
174 // Obtain an instance of this class via GetInstance().
176 ~IsolatedContext() override
;
178 // MountPoints overrides.
179 FileSystemURL
CrackFileSystemURL(const FileSystemURL
& url
) const override
;
181 // Unregisters a file system of given |filesystem_id|. Must be called with
182 // lock_ held. Returns true if the file system is unregistered.
183 bool UnregisterFileSystem(const std::string
& filesystem_id
);
185 // Returns a new filesystem_id. Called with lock.
186 std::string
GetNewFileSystemId() const;
188 // This lock needs to be obtained when accessing the instance_map_.
189 mutable base::Lock lock_
;
191 IDToInstance instance_map_
;
192 PathToID path_to_id_map_
;
194 DISALLOW_COPY_AND_ASSIGN(IsolatedContext
);
197 } // namespace storage
199 #endif // STORAGE_BROWSER_FILEAPI_ISOLATED_CONTEXT_H_