Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(30)

Side by Side Diff: webkit/fileapi/sandbox_mount_point_provider.cc

Issue 9016020: Cleanup FileSystemOperation for preparing for adding FSO-factory method (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebased Created 8 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "webkit/fileapi/sandbox_mount_point_provider.h" 5 #include "webkit/fileapi/sandbox_mount_point_provider.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/command_line.h" 8 #include "base/command_line.h"
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/memory/scoped_ptr.h" 10 #include "base/memory/scoped_ptr.h"
11 #include "base/message_loop.h" 11 #include "base/message_loop.h"
12 #include "base/message_loop_proxy.h" 12 #include "base/message_loop_proxy.h"
13 #include "base/rand_util.h" 13 #include "base/rand_util.h"
14 #include "base/string_util.h" 14 #include "base/string_util.h"
15 #include "base/stringprintf.h" 15 #include "base/stringprintf.h"
16 #include "base/metrics/histogram.h" 16 #include "base/metrics/histogram.h"
17 #include "googleurl/src/gurl.h" 17 #include "googleurl/src/gurl.h"
18 #include "net/base/net_util.h" 18 #include "net/base/net_util.h"
19 #include "webkit/fileapi/file_system_operation.h"
19 #include "webkit/fileapi/file_system_operation_context.h" 20 #include "webkit/fileapi/file_system_operation_context.h"
20 #include "webkit/fileapi/file_system_options.h" 21 #include "webkit/fileapi/file_system_options.h"
21 #include "webkit/fileapi/file_system_types.h" 22 #include "webkit/fileapi/file_system_types.h"
22 #include "webkit/fileapi/file_system_usage_cache.h" 23 #include "webkit/fileapi/file_system_usage_cache.h"
23 #include "webkit/fileapi/file_system_util.h" 24 #include "webkit/fileapi/file_system_util.h"
24 #include "webkit/fileapi/obfuscated_file_util.h" 25 #include "webkit/fileapi/obfuscated_file_util.h"
25 #include "webkit/fileapi/quota_file_util.h" 26 #include "webkit/fileapi/quota_file_util.h"
26 #include "webkit/glue/webkit_glue.h" 27 #include "webkit/glue/webkit_glue.h"
27 #include "webkit/quota/quota_manager.h" 28 #include "webkit/quota/quota_manager.h"
28 29
29 using quota::QuotaManagerProxy; 30 using quota::QuotaManagerProxy;
30 31
32 namespace fileapi {
33
31 namespace { 34 namespace {
32 35
33 const char kChromeScheme[] = "chrome"; 36 const char kChromeScheme[] = "chrome";
34 const char kExtensionScheme[] = "chrome-extension"; 37 const char kExtensionScheme[] = "chrome-extension";
35 38
36 const FilePath::CharType kOldFileSystemUniqueNamePrefix[] = 39 const FilePath::CharType kOldFileSystemUniqueNamePrefix[] =
37 FILE_PATH_LITERAL("chrome-"); 40 FILE_PATH_LITERAL("chrome-");
38 const size_t kOldFileSystemUniqueLength = 16; 41 const size_t kOldFileSystemUniqueLength = 16;
39 const size_t kOldFileSystemUniqueDirectoryNameLength = 42 const size_t kOldFileSystemUniqueDirectoryNameLength =
40 kOldFileSystemUniqueLength + arraysize(kOldFileSystemUniqueNamePrefix) - 1; 43 kOldFileSystemUniqueLength + arraysize(kOldFileSystemUniqueNamePrefix) - 1;
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
89 } 92 }
90 found = true; 93 found = true;
91 *unique = current; 94 *unique = current;
92 } 95 }
93 if (unique->empty()) 96 if (unique->empty())
94 return base::PLATFORM_FILE_ERROR_NOT_FOUND; 97 return base::PLATFORM_FILE_ERROR_NOT_FOUND;
95 return base::PLATFORM_FILE_OK; 98 return base::PLATFORM_FILE_OK;
96 } 99 }
97 100
98 class ObfuscatedOriginEnumerator 101 class ObfuscatedOriginEnumerator
99 : public fileapi::SandboxMountPointProvider::OriginEnumerator { 102 : public SandboxMountPointProvider::OriginEnumerator {
100 public: 103 public:
101 explicit ObfuscatedOriginEnumerator( 104 explicit ObfuscatedOriginEnumerator(ObfuscatedFileUtil* file_util) {
102 fileapi::ObfuscatedFileUtil* file_util) {
103 enum_.reset(file_util->CreateOriginEnumerator()); 105 enum_.reset(file_util->CreateOriginEnumerator());
104 } 106 }
105 virtual ~ObfuscatedOriginEnumerator() {} 107 virtual ~ObfuscatedOriginEnumerator() {}
106 108
107 virtual GURL Next() OVERRIDE { 109 virtual GURL Next() OVERRIDE {
108 return enum_->Next(); 110 return enum_->Next();
109 } 111 }
110 112
111 virtual bool HasFileSystemType(fileapi::FileSystemType type) const OVERRIDE { 113 virtual bool HasFileSystemType(fileapi::FileSystemType type) const OVERRIDE {
112 return enum_->HasFileSystemType(type); 114 return enum_->HasFileSystemType(type);
113 } 115 }
114 116
115 private: 117 private:
116 scoped_ptr<fileapi::ObfuscatedFileUtil::AbstractOriginEnumerator> enum_; 118 scoped_ptr<ObfuscatedFileUtil::AbstractOriginEnumerator> enum_;
117 }; 119 };
118 120
119 class OldSandboxOriginEnumerator 121 class OldSandboxOriginEnumerator
120 : public fileapi::SandboxMountPointProvider::OriginEnumerator { 122 : public SandboxMountPointProvider::OriginEnumerator {
121 public: 123 public:
122 explicit OldSandboxOriginEnumerator(const FilePath& base_path) 124 explicit OldSandboxOriginEnumerator(const FilePath& base_path)
123 : enumerator_(base_path, false /* recursive */, 125 : enumerator_(base_path, false /* recursive */,
124 file_util::FileEnumerator::DIRECTORIES) {} 126 file_util::FileEnumerator::DIRECTORIES) {}
125 virtual ~OldSandboxOriginEnumerator() {} 127 virtual ~OldSandboxOriginEnumerator() {}
126 128
127 virtual GURL Next() OVERRIDE { 129 virtual GURL Next() OVERRIDE {
128 current_ = enumerator_.Next(); 130 current_ = enumerator_.Next();
129 if (current_.empty()) 131 if (current_.empty())
130 return GURL(); 132 return GURL();
131 return fileapi::GetOriginURLFromIdentifier( 133 return GetOriginURLFromIdentifier(current_.BaseName().MaybeAsASCII());
132 current_.BaseName().MaybeAsASCII());
133 } 134 }
134 135
135 virtual bool HasFileSystemType(fileapi::FileSystemType type) const OVERRIDE { 136 virtual bool HasFileSystemType(fileapi::FileSystemType type) const OVERRIDE {
136 if (current_.empty()) 137 if (current_.empty())
137 return false; 138 return false;
138 std::string directory = GetFileSystemTypeString(type); 139 std::string directory = GetFileSystemTypeString(type);
139 DCHECK(!directory.empty()); 140 DCHECK(!directory.empty());
140 return file_util::DirectoryExists(current_.AppendASCII(directory)); 141 return file_util::DirectoryExists(current_.AppendASCII(directory));
141 } 142 }
142 143
143 private: 144 private:
144 file_util::FileEnumerator enumerator_; 145 file_util::FileEnumerator enumerator_;
145 FilePath current_; 146 FilePath current_;
146 }; 147 };
147 148
148 FilePath OldGetBaseDirectoryForOrigin( 149 FilePath OldGetBaseDirectoryForOrigin(
149 const FilePath& old_base_path, 150 const FilePath& old_base_path,
150 const GURL& origin_url) { 151 const GURL& origin_url) {
151 std::string id = fileapi::GetOriginIdentifierFromURL(origin_url); 152 std::string id = GetOriginIdentifierFromURL(origin_url);
152 if (!id.empty()) 153 if (!id.empty())
153 return old_base_path.AppendASCII(id); 154 return old_base_path.AppendASCII(id);
154 return FilePath(); 155 return FilePath();
155 } 156 }
156 157
157 FilePath OldGetBaseDirectoryForOriginAndType( 158 FilePath OldGetBaseDirectoryForOriginAndType(
158 const FilePath& old_base_path, 159 const FilePath& old_base_path,
159 const GURL& origin_url, fileapi::FileSystemType type) { 160 const GURL& origin_url, fileapi::FileSystemType type) {
160 std::string type_string = GetFileSystemTypeString(type); 161 std::string type_string = GetFileSystemTypeString(type);
161 if (type_string.empty()) { 162 if (type_string.empty()) {
162 NOTREACHED(); 163 NOTREACHED();
163 return FilePath(); 164 return FilePath();
164 } 165 }
165 FilePath base_path = OldGetBaseDirectoryForOrigin( 166 FilePath base_path = OldGetBaseDirectoryForOrigin(
166 old_base_path, origin_url); 167 old_base_path, origin_url);
167 if (base_path.empty()) { 168 if (base_path.empty()) {
168 NOTREACHED(); 169 NOTREACHED();
169 return FilePath(); 170 return FilePath();
170 } 171 }
171 return base_path.AppendASCII(type_string); 172 return base_path.AppendASCII(type_string);
172 } 173 }
173 174
174 bool MigrateOneOldFileSystem( 175 bool MigrateOneOldFileSystem(
175 fileapi::ObfuscatedFileUtil* file_util, 176 ObfuscatedFileUtil* file_util,
176 const FilePath& old_base_path, const GURL& origin, 177 const FilePath& old_base_path, const GURL& origin,
177 fileapi::FileSystemType type) { 178 fileapi::FileSystemType type) {
178 FilePath base_path = OldGetBaseDirectoryForOriginAndType( 179 FilePath base_path = OldGetBaseDirectoryForOriginAndType(
179 old_base_path, origin, type); 180 old_base_path, origin, type);
180 if (base_path.empty()) 181 if (base_path.empty())
181 return false; 182 return false;
182 183
183 FilePath root; 184 FilePath root;
184 base::PlatformFileError result = OldReadOriginDirectory(base_path, &root); 185 base::PlatformFileError result = OldReadOriginDirectory(base_path, &root);
185 if (base::PLATFORM_FILE_ERROR_NOT_FOUND == result) 186 if (base::PLATFORM_FILE_ERROR_NOT_FOUND == result)
186 return true; // There was nothing to migrate; call that a success. 187 return true; // There was nothing to migrate; call that a success.
187 188
188 // If we found more than one filesystem [a problem we don't know how to 189 // If we found more than one filesystem [a problem we don't know how to
189 // solve], the data is already not accessible through Chrome, so it won't do 190 // solve], the data is already not accessible through Chrome, so it won't do
190 // any harm not to migrate it. Just flag it as an error, so that we don't 191 // any harm not to migrate it. Just flag it as an error, so that we don't
191 // delete it. 192 // delete it.
192 if (base::PLATFORM_FILE_OK != result) 193 if (base::PLATFORM_FILE_OK != result)
193 return false; 194 return false;
194 195
195 if (!file_util->MigrateFromOldSandbox(origin, type, root)) { 196 if (!file_util->MigrateFromOldSandbox(origin, type, root)) {
196 LOG(WARNING) << "Failed to migrate filesystem for origin " << origin << 197 LOG(WARNING) << "Failed to migrate filesystem for origin " << origin <<
197 " and type " << type; 198 " and type " << type;
198 return false; 199 return false;
199 } 200 }
200 return true; 201 return true;
201 } 202 }
202 203
203 void MigrateAllOldFileSystems( 204 void MigrateAllOldFileSystems(
204 fileapi::ObfuscatedFileUtil* file_util, 205 ObfuscatedFileUtil* file_util,
205 const FilePath& old_base_path) { 206 const FilePath& old_base_path) {
206 scoped_ptr<OldSandboxOriginEnumerator> old_origins( 207 scoped_ptr<OldSandboxOriginEnumerator> old_origins(
207 new OldSandboxOriginEnumerator(old_base_path)); 208 new OldSandboxOriginEnumerator(old_base_path));
208 GURL origin; 209 GURL origin;
209 int failures = 0; 210 int failures = 0;
210 while (!(origin = old_origins->Next()).is_empty()) { 211 while (!(origin = old_origins->Next()).is_empty()) {
211 int failures_this_origin = 0; 212 int failures_this_origin = 0;
212 if (old_origins->HasFileSystemType(fileapi::kFileSystemTypeTemporary) && 213 if (old_origins->HasFileSystemType(kFileSystemTypeTemporary) &&
213 !MigrateOneOldFileSystem( 214 !MigrateOneOldFileSystem(
214 file_util, old_base_path, origin, 215 file_util, old_base_path, origin,
215 fileapi::kFileSystemTypeTemporary)) 216 kFileSystemTypeTemporary))
216 ++failures_this_origin; 217 ++failures_this_origin;
217 if (old_origins->HasFileSystemType(fileapi::kFileSystemTypePersistent) && 218 if (old_origins->HasFileSystemType(kFileSystemTypePersistent) &&
218 !MigrateOneOldFileSystem( 219 !MigrateOneOldFileSystem(
219 file_util, old_base_path, origin, 220 file_util, old_base_path, origin,
220 fileapi::kFileSystemTypePersistent)) 221 kFileSystemTypePersistent))
221 ++failures_this_origin; 222 ++failures_this_origin;
222 if (!failures_this_origin) { 223 if (!failures_this_origin) {
223 FilePath origin_base_path = 224 FilePath origin_base_path =
224 OldGetBaseDirectoryForOrigin(old_base_path, origin); 225 OldGetBaseDirectoryForOrigin(old_base_path, origin);
225 // Yes, that's an rm -rf. Make sure that path looks valid, just in case. 226 // Yes, that's an rm -rf. Make sure that path looks valid, just in case.
226 if (!origin_base_path.empty()) 227 if (!origin_base_path.empty())
227 file_util::Delete(origin_base_path, true); 228 file_util::Delete(origin_base_path, true);
228 } 229 }
229 failures += failures_this_origin; 230 failures += failures_this_origin;
230 } 231 }
231 if (!failures) 232 if (!failures)
232 file_util::Delete(old_base_path, true); 233 file_util::Delete(old_base_path, true);
233 if (file_util::DirectoryExists(old_base_path)) { 234 if (file_util::DirectoryExists(old_base_path)) {
234 // Move it out of the way so that we won't keep trying to migrate it. You 235 // Move it out of the way so that we won't keep trying to migrate it. You
235 // get only one chance at this; the bits we couldn't do this time, we're 236 // get only one chance at this; the bits we couldn't do this time, we're
236 // unlikely to be able to do in the future. This way you can now use the 237 // unlikely to be able to do in the future. This way you can now use the
237 // new filesystem, but have a way to recover your old files if absolutely 238 // new filesystem, but have a way to recover your old files if absolutely
238 // necessary. 239 // necessary.
239 FilePath new_path = 240 FilePath new_path =
240 old_base_path.DirName().Append( 241 old_base_path.DirName().Append(
241 fileapi::SandboxMountPointProvider::kRenamedOldFileSystemDirectory); 242 SandboxMountPointProvider::kRenamedOldFileSystemDirectory);
242 file_util::ReplaceFile(old_base_path, new_path); 243 file_util::ReplaceFile(old_base_path, new_path);
243 } 244 }
244 } 245 }
245 246
246 // A migration, whether successful or not, will try to move this directory out 247 // A migration, whether successful or not, will try to move this directory out
247 // of the way so that we never try to migrate it again. We need to do this 248 // of the way so that we never try to migrate it again. We need to do this
248 // check on all public entry points in this file, so that it's guaranteed to be 249 // check on all public entry points in this file, so that it's guaranteed to be
249 // done before anyone looks up a filesystem. Most entry points start by trying 250 // done before anyone looks up a filesystem. Most entry points start by trying
250 // to look up the filesystem's root, so we can take care of most of them by 251 // to look up the filesystem's root, so we can take care of most of them by
251 // putting a check there. 252 // putting a check there.
252 void MigrateIfNeeded( 253 void MigrateIfNeeded(
253 fileapi::ObfuscatedFileUtil* file_util, 254 ObfuscatedFileUtil* file_util,
254 const FilePath& old_base_path) { 255 const FilePath& old_base_path) {
255 if (file_util::DirectoryExists(old_base_path)) 256 if (file_util::DirectoryExists(old_base_path))
256 MigrateAllOldFileSystems(file_util, old_base_path); 257 MigrateAllOldFileSystems(file_util, old_base_path);
257 } 258 }
258 259
260 void PassPointerErrorByValue(
261 const base::Callback<void(PlatformFileError)>& callback,
262 PlatformFileError* error_ptr) {
263 DCHECK(error_ptr);
264 callback.Run(*error_ptr);
265 }
266
267 void ValidateRootOnFileThread(ObfuscatedFileUtil* file_util,
268 const GURL& origin_url,
269 FileSystemType type,
270 const FilePath& old_base_path,
271 bool create,
272 base::PlatformFileError* error_ptr) {
273 DCHECK(error_ptr);
274 MigrateIfNeeded(file_util, old_base_path);
275 FilePath root_path =
276 file_util->GetDirectoryForOriginAndType(origin_url, type, create);
277 if (root_path.empty()) {
278 UMA_HISTOGRAM_ENUMERATION(kOpenFileSystem,
279 kCreateDirectoryError,
280 kFileSystemErrorMax);
281 // TODO(kinuko): We should return appropriate error code.
282 *error_ptr = base::PLATFORM_FILE_ERROR_FAILED;
283 } else {
284 UMA_HISTOGRAM_ENUMERATION(kOpenFileSystem, kOK, kFileSystemErrorMax);
285 *error_ptr = base::PLATFORM_FILE_OK;
286 }
287 // The reference of file_util will be derefed on the FILE thread
288 // when the storage of this callback gets deleted regardless of whether
289 // this method is called or not.
290 }
291
259 } // anonymous namespace 292 } // anonymous namespace
260 293
261 namespace fileapi {
262
263 const FilePath::CharType SandboxMountPointProvider::kOldFileSystemDirectory[] = 294 const FilePath::CharType SandboxMountPointProvider::kOldFileSystemDirectory[] =
264 FILE_PATH_LITERAL("FileSystem"); 295 FILE_PATH_LITERAL("FileSystem");
265 296
266 const FilePath::CharType SandboxMountPointProvider::kNewFileSystemDirectory[] = 297 const FilePath::CharType SandboxMountPointProvider::kNewFileSystemDirectory[] =
267 FILE_PATH_LITERAL("File System"); 298 FILE_PATH_LITERAL("File System");
268 299
269 const FilePath::CharType 300 const FilePath::CharType
270 SandboxMountPointProvider::kRenamedOldFileSystemDirectory[] = 301 SandboxMountPointProvider::kRenamedOldFileSystemDirectory[] =
271 FILE_PATH_LITERAL("FS.old"); 302 FILE_PATH_LITERAL("FS.old");
272 303
273 class SandboxMountPointProvider::GetFileSystemRootPathTask
274 : public base::RefCountedThreadSafe<
275 SandboxMountPointProvider::GetFileSystemRootPathTask> {
276 public:
277 GetFileSystemRootPathTask(
278 scoped_refptr<base::MessageLoopProxy> file_message_loop,
279 const GURL& origin_url,
280 FileSystemType type,
281 ObfuscatedFileUtil* file_util,
282 const FilePath& old_base_path,
283 const FileSystemMountPointProvider::GetRootPathCallback& callback)
284 : file_message_loop_(file_message_loop),
285 origin_message_loop_proxy_(
286 base::MessageLoopProxy::current()),
287 origin_url_(origin_url),
288 type_(type),
289 file_util_(file_util),
290 old_base_path_(old_base_path),
291 callback_(callback) {
292 }
293
294 virtual ~GetFileSystemRootPathTask() {
295 // Just in case we get deleted without running, make sure to clean up the
296 // file_util_ on the right thread.
297 if (file_util_.get() && !file_message_loop_->BelongsToCurrentThread())
298 file_message_loop_->ReleaseSoon(FROM_HERE, file_util_.release());
299 }
300
301 void Start(bool create) {
302 file_message_loop_->PostTask(
303 FROM_HERE,
304 base::Bind(
305 &GetFileSystemRootPathTask::GetFileSystemRootPathOnFileThread, this,
306 create));
307 }
308
309 private:
310 void GetFileSystemRootPathOnFileThread(bool create) {
311 MigrateIfNeeded(file_util_, old_base_path_);
312 DispatchCallbackOnCallerThread(
313 file_util_->GetDirectoryForOriginAndType(origin_url_, type_, create));
314 // We must clear the reference on the file thread.
315 file_util_ = NULL;
316 }
317
318 void DispatchCallbackOnCallerThread(const FilePath& root_path) {
319 if (root_path.empty()) {
320 UMA_HISTOGRAM_ENUMERATION(kOpenFileSystem,
321 kCreateDirectoryError,
322 kFileSystemErrorMax);
323 }
324 origin_message_loop_proxy_->PostTask(
325 FROM_HERE,
326 base::Bind(&GetFileSystemRootPathTask::DispatchCallback, this,
327 root_path));
328 }
329
330 void DispatchCallback(const FilePath& root_path) {
331 std::string origin_identifier = GetOriginIdentifierFromURL(origin_url_);
332 std::string type_string = GetFileSystemTypeString(type_);
333 DCHECK(!type_string.empty());
334 std::string name = origin_identifier + ":" + type_string;
335
336 if (!root_path.empty())
337 UMA_HISTOGRAM_ENUMERATION(kOpenFileSystem, kOK, kFileSystemErrorMax);
338
339 callback_.Run(!root_path.empty(), root_path, name);
340 callback_.Reset();
341 }
342
343 scoped_refptr<base::MessageLoopProxy> file_message_loop_;
344 scoped_refptr<base::MessageLoopProxy> origin_message_loop_proxy_;
345 GURL origin_url_;
346 FileSystemType type_;
347 scoped_refptr<ObfuscatedFileUtil> file_util_;
348 FilePath old_base_path_;
349 FileSystemMountPointProvider::GetRootPathCallback callback_;
350 };
351
352 SandboxMountPointProvider::SandboxMountPointProvider( 304 SandboxMountPointProvider::SandboxMountPointProvider(
353 scoped_refptr<base::MessageLoopProxy> file_message_loop, 305 scoped_refptr<base::MessageLoopProxy> file_message_loop,
354 const FilePath& profile_path, 306 const FilePath& profile_path,
355 const FileSystemOptions& file_system_options) 307 const FileSystemOptions& file_system_options)
356 : FileSystemQuotaUtil(file_message_loop), 308 : FileSystemQuotaUtil(file_message_loop),
357 file_message_loop_(file_message_loop), 309 file_message_loop_(file_message_loop),
358 profile_path_(profile_path), 310 profile_path_(profile_path),
359 file_system_options_(file_system_options), 311 file_system_options_(file_system_options),
360 sandbox_file_util_( 312 sandbox_file_util_(
361 new ObfuscatedFileUtil( 313 new ObfuscatedFileUtil(
362 profile_path.Append(kNewFileSystemDirectory), 314 profile_path.Append(kNewFileSystemDirectory),
363 QuotaFileUtil::CreateDefault())) { 315 QuotaFileUtil::CreateDefault())) {
364 } 316 }
365 317
366 SandboxMountPointProvider::~SandboxMountPointProvider() { 318 SandboxMountPointProvider::~SandboxMountPointProvider() {
367 if (!file_message_loop_->BelongsToCurrentThread()) 319 if (!file_message_loop_->BelongsToCurrentThread())
368 file_message_loop_->ReleaseSoon(FROM_HERE, sandbox_file_util_.release()); 320 file_message_loop_->ReleaseSoon(FROM_HERE, sandbox_file_util_.release());
369 } 321 }
370 322
371 bool SandboxMountPointProvider::IsAccessAllowed(const GURL& origin_url, 323 void SandboxMountPointProvider::ValidateFileSystemRoot(
372 FileSystemType type,
373 const FilePath& unused) {
374 if (type != kFileSystemTypeTemporary && type != kFileSystemTypePersistent)
375 return false;
376 // We essentially depend on quota to do our access controls, so here
377 // we only check if the requested scheme is allowed or not.
378 return IsAllowedScheme(origin_url);
379 }
380
381 void SandboxMountPointProvider::ValidateFileSystemRootAndGetURL(
382 const GURL& origin_url, fileapi::FileSystemType type, bool create, 324 const GURL& origin_url, fileapi::FileSystemType type, bool create,
383 const FileSystemMountPointProvider::GetRootPathCallback& callback) { 325 const ValidateFileSystemCallback& callback) {
384 FilePath origin_base_path;
385
386 if (file_system_options_.is_incognito()) { 326 if (file_system_options_.is_incognito()) {
387 // TODO(kinuko): return an isolated temporary directory. 327 // TODO(kinuko): return an isolated temporary directory.
388 callback.Run(false, FilePath(), std::string()); 328 callback.Run(base::PLATFORM_FILE_ERROR_SECURITY);
389 UMA_HISTOGRAM_ENUMERATION(kOpenFileSystem, 329 UMA_HISTOGRAM_ENUMERATION(kOpenFileSystem,
390 kIncognito, 330 kIncognito,
391 kFileSystemErrorMax); 331 kFileSystemErrorMax);
392 return; 332 return;
393 } 333 }
394 334
395 if (!IsAllowedScheme(origin_url)) { 335 if (!IsAllowedScheme(origin_url)) {
396 callback.Run(false, FilePath(), std::string()); 336 callback.Run(base::PLATFORM_FILE_ERROR_SECURITY);
397 UMA_HISTOGRAM_ENUMERATION(kOpenFileSystem, 337 UMA_HISTOGRAM_ENUMERATION(kOpenFileSystem,
398 kInvalidScheme, 338 kInvalidScheme,
399 kFileSystemErrorMax); 339 kFileSystemErrorMax);
400 return; 340 return;
401 } 341 }
402 342
403 scoped_refptr<GetFileSystemRootPathTask> task( 343 base::PlatformFileError* error_ptr = new base::PlatformFileError;
404 new GetFileSystemRootPathTask( 344 file_message_loop_->PostTaskAndReply(
405 file_message_loop_, origin_url, type, sandbox_file_util_.get(), 345 FROM_HERE,
406 old_base_path(), callback)); 346 base::Bind(&ValidateRootOnFileThread,
407 task->Start(create); 347 sandbox_file_util_,
348 origin_url, type, old_base_path(), create,
349 base::Unretained(error_ptr)),
350 base::Bind(base::Bind(&PassPointerErrorByValue, callback),
351 base::Owned(error_ptr)));
408 }; 352 };
409 353
410 FilePath 354 FilePath
411 SandboxMountPointProvider::ValidateFileSystemRootAndGetPathOnFileThread( 355 SandboxMountPointProvider::GetFileSystemRootPathOnFileThread(
412 const GURL& origin_url, FileSystemType type, const FilePath& unused, 356 const GURL& origin_url, FileSystemType type, const FilePath& unused,
413 bool create) { 357 bool create) {
414 if (file_system_options_.is_incognito()) 358 if (file_system_options_.is_incognito())
415 // TODO(kinuko): return an isolated temporary directory. 359 // TODO(kinuko): return an isolated temporary directory.
416 return FilePath(); 360 return FilePath();
417 361
418 if (!IsAllowedScheme(origin_url)) 362 if (!IsAllowedScheme(origin_url))
419 return FilePath(); 363 return FilePath();
420 364
421 MigrateIfNeeded(sandbox_file_util_, old_base_path()); 365 MigrateIfNeeded(sandbox_file_util_, old_base_path());
422 366
423 return sandbox_file_util_->GetDirectoryForOriginAndType( 367 return sandbox_file_util_->GetDirectoryForOriginAndType(
424 origin_url, type, create); 368 origin_url, type, create);
425 } 369 }
426 370
371 bool SandboxMountPointProvider::IsAccessAllowed(const GURL& origin_url,
372 FileSystemType type,
373 const FilePath& unused) {
374 if (type != kFileSystemTypeTemporary && type != kFileSystemTypePersistent)
375 return false;
376 // We essentially depend on quota to do our access controls, so here
377 // we only check if the requested scheme is allowed or not.
378 return IsAllowedScheme(origin_url);
379 }
380
427 bool SandboxMountPointProvider::IsRestrictedFileName(const FilePath& filename) 381 bool SandboxMountPointProvider::IsRestrictedFileName(const FilePath& filename)
428 const { 382 const {
429 if (filename.value().empty()) 383 if (filename.value().empty())
430 return false; 384 return false;
431 385
432 for (size_t i = 0; i < arraysize(kRestrictedNames); ++i) { 386 for (size_t i = 0; i < arraysize(kRestrictedNames); ++i) {
433 // Exact match. 387 // Exact match.
434 if (filename.value() == kRestrictedNames[i]) 388 if (filename.value() == kRestrictedNames[i])
435 return true; 389 return true;
436 } 390 }
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
497 quota::QuotaClient::kFileSystem, 451 quota::QuotaClient::kFileSystem,
498 origin_url, 452 origin_url,
499 FileSystemTypeToQuotaStorageType(type), 453 FileSystemTypeToQuotaStorageType(type),
500 -usage); 454 -usage);
501 } 455 }
502 return result; 456 return result;
503 } 457 }
504 458
505 void SandboxMountPointProvider::GetOriginsForTypeOnFileThread( 459 void SandboxMountPointProvider::GetOriginsForTypeOnFileThread(
506 fileapi::FileSystemType type, std::set<GURL>* origins) { 460 fileapi::FileSystemType type, std::set<GURL>* origins) {
507 DCHECK(type == fileapi::kFileSystemTypeTemporary || 461 DCHECK(type == kFileSystemTypeTemporary ||
508 type == fileapi::kFileSystemTypePersistent); 462 type == kFileSystemTypePersistent);
509 DCHECK(origins); 463 DCHECK(origins);
510 scoped_ptr<OriginEnumerator> enumerator(CreateOriginEnumerator()); 464 scoped_ptr<OriginEnumerator> enumerator(CreateOriginEnumerator());
511 GURL origin; 465 GURL origin;
512 while (!(origin = enumerator->Next()).is_empty()) { 466 while (!(origin = enumerator->Next()).is_empty()) {
513 if (enumerator->HasFileSystemType(type)) 467 if (enumerator->HasFileSystemType(type))
514 origins->insert(origin); 468 origins->insert(origin);
515 } 469 }
516 } 470 }
517 471
518 void SandboxMountPointProvider::GetOriginsForHostOnFileThread( 472 void SandboxMountPointProvider::GetOriginsForHostOnFileThread(
519 fileapi::FileSystemType type, const std::string& host, 473 fileapi::FileSystemType type, const std::string& host,
520 std::set<GURL>* origins) { 474 std::set<GURL>* origins) {
521 DCHECK(type == fileapi::kFileSystemTypeTemporary || 475 DCHECK(type == kFileSystemTypeTemporary ||
522 type == fileapi::kFileSystemTypePersistent); 476 type == kFileSystemTypePersistent);
523 DCHECK(origins); 477 DCHECK(origins);
524 scoped_ptr<OriginEnumerator> enumerator(CreateOriginEnumerator()); 478 scoped_ptr<OriginEnumerator> enumerator(CreateOriginEnumerator());
525 GURL origin; 479 GURL origin;
526 while (!(origin = enumerator->Next()).is_empty()) { 480 while (!(origin = enumerator->Next()).is_empty()) {
527 if (host == net::GetHostOrSpecFromURL(origin) && 481 if (host == net::GetHostOrSpecFromURL(origin) &&
528 enumerator->HasFileSystemType(type)) 482 enumerator->HasFileSystemType(type))
529 origins->insert(origin); 483 origins->insert(origin);
530 } 484 }
531 } 485 }
532 486
533 int64 SandboxMountPointProvider::GetOriginUsageOnFileThread( 487 int64 SandboxMountPointProvider::GetOriginUsageOnFileThread(
534 const GURL& origin_url, fileapi::FileSystemType type) { 488 const GURL& origin_url, fileapi::FileSystemType type) {
535 DCHECK(type == fileapi::kFileSystemTypeTemporary || 489 DCHECK(type == kFileSystemTypeTemporary ||
536 type == fileapi::kFileSystemTypePersistent); 490 type == kFileSystemTypePersistent);
537 FilePath base_path = 491 FilePath base_path =
538 GetBaseDirectoryForOriginAndType(origin_url, type, false); 492 GetBaseDirectoryForOriginAndType(origin_url, type, false);
539 if (base_path.empty() || !file_util::DirectoryExists(base_path)) return 0; 493 if (base_path.empty() || !file_util::DirectoryExists(base_path)) return 0;
540 FilePath usage_file_path = 494 FilePath usage_file_path =
541 base_path.AppendASCII(FileSystemUsageCache::kUsageFileName); 495 base_path.AppendASCII(FileSystemUsageCache::kUsageFileName);
542 496
543 bool is_valid = FileSystemUsageCache::IsValid(usage_file_path); 497 bool is_valid = FileSystemUsageCache::IsValid(usage_file_path);
544 int32 dirty_status = FileSystemUsageCache::GetDirty(usage_file_path); 498 int32 dirty_status = FileSystemUsageCache::GetDirty(usage_file_path);
545 bool visited = (visited_origins_.find(origin_url) != visited_origins_.end()); 499 bool visited = (visited_origins_.find(origin_url) != visited_origins_.end());
546 visited_origins_.insert(origin_url); 500 visited_origins_.insert(origin_url);
(...skipping 22 matching lines...) Expand all
569 usage += ObfuscatedFileUtil::ComputeFilePathCost(file_path_each); 523 usage += ObfuscatedFileUtil::ComputeFilePathCost(file_path_each);
570 } 524 }
571 // This clears the dirty flag too. 525 // This clears the dirty flag too.
572 FileSystemUsageCache::UpdateUsage(usage_file_path, usage); 526 FileSystemUsageCache::UpdateUsage(usage_file_path, usage);
573 return usage; 527 return usage;
574 } 528 }
575 529
576 void SandboxMountPointProvider::NotifyOriginWasAccessedOnIOThread( 530 void SandboxMountPointProvider::NotifyOriginWasAccessedOnIOThread(
577 QuotaManagerProxy* proxy, const GURL& origin_url, 531 QuotaManagerProxy* proxy, const GURL& origin_url,
578 fileapi::FileSystemType type) { 532 fileapi::FileSystemType type) {
579 DCHECK(type == fileapi::kFileSystemTypeTemporary || 533 DCHECK(type == kFileSystemTypeTemporary ||
580 type == fileapi::kFileSystemTypePersistent); 534 type == kFileSystemTypePersistent);
581 if (proxy) { 535 if (proxy) {
582 proxy->NotifyStorageAccessed( 536 proxy->NotifyStorageAccessed(
583 quota::QuotaClient::kFileSystem, 537 quota::QuotaClient::kFileSystem,
584 origin_url, 538 origin_url,
585 FileSystemTypeToQuotaStorageType(type)); 539 FileSystemTypeToQuotaStorageType(type));
586 } 540 }
587 } 541 }
588 542
589 void SandboxMountPointProvider::UpdateOriginUsageOnFileThread( 543 void SandboxMountPointProvider::UpdateOriginUsageOnFileThread(
590 QuotaManagerProxy* proxy, const GURL& origin_url, 544 QuotaManagerProxy* proxy, const GURL& origin_url,
591 fileapi::FileSystemType type, int64 delta) { 545 fileapi::FileSystemType type, int64 delta) {
592 DCHECK(type == fileapi::kFileSystemTypeTemporary || 546 DCHECK(type == kFileSystemTypeTemporary ||
593 type == fileapi::kFileSystemTypePersistent); 547 type == kFileSystemTypePersistent);
594 FilePath usage_file_path = GetUsageCachePathForOriginAndType( 548 FilePath usage_file_path = GetUsageCachePathForOriginAndType(
595 origin_url, type); 549 origin_url, type);
596 DCHECK(!usage_file_path.empty()); 550 DCHECK(!usage_file_path.empty());
597 // TODO(dmikurbe): Make sure that usage_file_path is available. 551 // TODO(dmikurbe): Make sure that usage_file_path is available.
598 FileSystemUsageCache::AtomicUpdateUsageByDelta(usage_file_path, delta); 552 FileSystemUsageCache::AtomicUpdateUsageByDelta(usage_file_path, delta);
599 if (proxy) { 553 if (proxy) {
600 proxy->NotifyStorageModified( 554 proxy->NotifyStorageModified(
601 quota::QuotaClient::kFileSystem, 555 quota::QuotaClient::kFileSystem,
602 origin_url, 556 origin_url,
603 FileSystemTypeToQuotaStorageType(type), 557 FileSystemTypeToQuotaStorageType(type),
604 delta); 558 delta);
605 } 559 }
606 } 560 }
607 561
608 void SandboxMountPointProvider::StartUpdateOriginOnFileThread( 562 void SandboxMountPointProvider::StartUpdateOriginOnFileThread(
609 const GURL& origin_url, fileapi::FileSystemType type) { 563 const GURL& origin_url, fileapi::FileSystemType type) {
610 DCHECK(type == fileapi::kFileSystemTypeTemporary || 564 DCHECK(type == kFileSystemTypeTemporary ||
611 type == fileapi::kFileSystemTypePersistent); 565 type == kFileSystemTypePersistent);
612 FilePath usage_file_path = GetUsageCachePathForOriginAndType( 566 FilePath usage_file_path = GetUsageCachePathForOriginAndType(
613 origin_url, type); 567 origin_url, type);
614 FileSystemUsageCache::IncrementDirty(usage_file_path); 568 FileSystemUsageCache::IncrementDirty(usage_file_path);
615 } 569 }
616 570
617 void SandboxMountPointProvider::EndUpdateOriginOnFileThread( 571 void SandboxMountPointProvider::EndUpdateOriginOnFileThread(
618 const GURL& origin_url, fileapi::FileSystemType type) { 572 const GURL& origin_url, fileapi::FileSystemType type) {
619 DCHECK(type == fileapi::kFileSystemTypeTemporary || 573 DCHECK(type == kFileSystemTypeTemporary ||
620 type == fileapi::kFileSystemTypePersistent); 574 type == kFileSystemTypePersistent);
621 FilePath usage_file_path = GetUsageCachePathForOriginAndType( 575 FilePath usage_file_path = GetUsageCachePathForOriginAndType(
622 origin_url, type); 576 origin_url, type);
623 FileSystemUsageCache::DecrementDirty(usage_file_path); 577 FileSystemUsageCache::DecrementDirty(usage_file_path);
624 } 578 }
625 579
626 void SandboxMountPointProvider::InvalidateUsageCache( 580 void SandboxMountPointProvider::InvalidateUsageCache(
627 const GURL& origin_url, fileapi::FileSystemType type) { 581 const GURL& origin_url, fileapi::FileSystemType type) {
628 DCHECK(type == fileapi::kFileSystemTypeTemporary || 582 DCHECK(type == kFileSystemTypeTemporary ||
629 type == fileapi::kFileSystemTypePersistent); 583 type == kFileSystemTypePersistent);
630 FilePath usage_file_path = GetUsageCachePathForOriginAndType( 584 FilePath usage_file_path = GetUsageCachePathForOriginAndType(
631 origin_url, type); 585 origin_url, type);
632 FileSystemUsageCache::IncrementDirty(usage_file_path); 586 FileSystemUsageCache::IncrementDirty(usage_file_path);
633 } 587 }
634 588
635 FilePath SandboxMountPointProvider::GetUsageCachePathForOriginAndType( 589 FilePath SandboxMountPointProvider::GetUsageCachePathForOriginAndType(
636 const GURL& origin_url, fileapi::FileSystemType type) const { 590 const GURL& origin_url, fileapi::FileSystemType type) const {
637 FilePath base_path = 591 FilePath base_path =
638 GetBaseDirectoryForOriginAndType(origin_url, type, false); 592 GetBaseDirectoryForOriginAndType(origin_url, type, false);
639 if (base_path.empty()) 593 if (base_path.empty())
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
675 i < file_system_options_.additional_allowed_schemes().size(); 629 i < file_system_options_.additional_allowed_schemes().size();
676 ++i) { 630 ++i) {
677 if (url.SchemeIs( 631 if (url.SchemeIs(
678 file_system_options_.additional_allowed_schemes()[i].c_str())) 632 file_system_options_.additional_allowed_schemes()[i].c_str()))
679 return true; 633 return true;
680 } 634 }
681 return false; 635 return false;
682 } 636 }
683 637
684 } // namespace fileapi 638 } // namespace fileapi
OLDNEW
« no previous file with comments | « webkit/fileapi/sandbox_mount_point_provider.h ('k') | webkit/fileapi/sandbox_mount_point_provider_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698