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

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: more cleanup around ValidateFileSystemRoot Created 9 years 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) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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_callback_factory.h" 10 #include "base/memory/scoped_callback_factory.h"
11 #include "base/memory/scoped_ptr.h" 11 #include "base/memory/scoped_ptr.h"
12 #include "base/message_loop.h" 12 #include "base/message_loop.h"
13 #include "base/message_loop_proxy.h" 13 #include "base/message_loop_proxy.h"
14 #include "base/rand_util.h" 14 #include "base/rand_util.h"
15 #include "base/string_util.h" 15 #include "base/string_util.h"
16 #include "base/stringprintf.h" 16 #include "base/stringprintf.h"
17 #include "base/metrics/histogram.h" 17 #include "base/metrics/histogram.h"
18 #include "googleurl/src/gurl.h" 18 #include "googleurl/src/gurl.h"
19 #include "net/base/net_util.h" 19 #include "net/base/net_util.h"
20 #include "webkit/fileapi/file_system_operation.h"
20 #include "webkit/fileapi/file_system_operation_context.h" 21 #include "webkit/fileapi/file_system_operation_context.h"
21 #include "webkit/fileapi/file_system_options.h" 22 #include "webkit/fileapi/file_system_options.h"
22 #include "webkit/fileapi/file_system_types.h" 23 #include "webkit/fileapi/file_system_types.h"
23 #include "webkit/fileapi/file_system_usage_cache.h" 24 #include "webkit/fileapi/file_system_usage_cache.h"
24 #include "webkit/fileapi/file_system_util.h" 25 #include "webkit/fileapi/file_system_util.h"
25 #include "webkit/fileapi/obfuscated_file_util.h" 26 #include "webkit/fileapi/obfuscated_file_util.h"
26 #include "webkit/fileapi/quota_file_util.h" 27 #include "webkit/fileapi/quota_file_util.h"
27 #include "webkit/glue/webkit_glue.h" 28 #include "webkit/glue/webkit_glue.h"
28 #include "webkit/quota/quota_manager.h" 29 #include "webkit/quota/quota_manager.h"
29 30
30 using quota::QuotaManagerProxy; 31 using quota::QuotaManagerProxy;
31 32
33 namespace fileapi {
34
32 namespace { 35 namespace {
33 36
34 const char kChromeScheme[] = "chrome"; 37 const char kChromeScheme[] = "chrome";
35 const char kExtensionScheme[] = "chrome-extension"; 38 const char kExtensionScheme[] = "chrome-extension";
36 39
37 const FilePath::CharType kOldFileSystemUniqueNamePrefix[] = 40 const FilePath::CharType kOldFileSystemUniqueNamePrefix[] =
38 FILE_PATH_LITERAL("chrome-"); 41 FILE_PATH_LITERAL("chrome-");
39 const size_t kOldFileSystemUniqueLength = 16; 42 const size_t kOldFileSystemUniqueLength = 16;
40 const size_t kOldFileSystemUniqueDirectoryNameLength = 43 const size_t kOldFileSystemUniqueDirectoryNameLength =
41 kOldFileSystemUniqueLength + arraysize(kOldFileSystemUniqueNamePrefix) - 1; 44 kOldFileSystemUniqueLength + arraysize(kOldFileSystemUniqueNamePrefix) - 1;
(...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after
250 // done before anyone looks up a filesystem. Most entry points start by trying 253 // done before anyone looks up a filesystem. Most entry points start by trying
251 // to look up the filesystem's root, so we can take care of most of them by 254 // to look up the filesystem's root, so we can take care of most of them by
252 // putting a check there. 255 // putting a check there.
253 void MigrateIfNeeded( 256 void MigrateIfNeeded(
254 fileapi::ObfuscatedFileUtil* file_util, 257 fileapi::ObfuscatedFileUtil* file_util,
255 const FilePath& old_base_path) { 258 const FilePath& old_base_path) {
256 if (file_util::DirectoryExists(old_base_path)) 259 if (file_util::DirectoryExists(old_base_path))
257 MigrateAllOldFileSystems(file_util, old_base_path); 260 MigrateAllOldFileSystems(file_util, old_base_path);
258 } 261 }
259 262
263 template <typename A>
264 void PassPointerByValue(const base::Callback<void(A)>& callback, A* a) {
satorux1 2011/12/27 18:56:37 This looks a bit tricky (or I'm just not good at r
kinuko 2011/12/28 10:59:35 Done.
265 callback.Run(*a);
266 }
267
268 void ValidateRootOnFileThread(ObfuscatedFileUtil* file_util,
269 const GURL& origin_url,
270 FileSystemType type,
271 const FilePath& old_base_path,
272 bool create,
273 base::PlatformFileError* error) {
274 DCHECK(error);
275 MigrateIfNeeded(file_util, old_base_path);
276 FilePath root_path =
277 file_util->GetDirectoryForOriginAndType(origin_url, type, create);
278 if (root_path.empty()) {
279 UMA_HISTOGRAM_ENUMERATION(kOpenFileSystem,
280 kCreateDirectoryError,
281 kFileSystemErrorMax);
282 // TODO(kinuko): We should return appropriate error code.
283 *error = base::PLATFORM_FILE_ERROR_FAILED;
284 } else {
285 UMA_HISTOGRAM_ENUMERATION(kOpenFileSystem, kOK, kFileSystemErrorMax);
286 *error = base::PLATFORM_FILE_OK;
287 }
288 // The reference of file_util will be derefed on the FILE thread
289 // when the storage of this callback gets deleted regardless of whether
290 // this method is called or not.
291 }
292
260 } // anonymous namespace 293 } // anonymous namespace
261 294
262 namespace fileapi {
263
264 const FilePath::CharType SandboxMountPointProvider::kOldFileSystemDirectory[] = 295 const FilePath::CharType SandboxMountPointProvider::kOldFileSystemDirectory[] =
265 FILE_PATH_LITERAL("FileSystem"); 296 FILE_PATH_LITERAL("FileSystem");
266 297
267 const FilePath::CharType SandboxMountPointProvider::kNewFileSystemDirectory[] = 298 const FilePath::CharType SandboxMountPointProvider::kNewFileSystemDirectory[] =
268 FILE_PATH_LITERAL("File System"); 299 FILE_PATH_LITERAL("File System");
269 300
270 const FilePath::CharType 301 const FilePath::CharType
271 SandboxMountPointProvider::kRenamedOldFileSystemDirectory[] = 302 SandboxMountPointProvider::kRenamedOldFileSystemDirectory[] =
272 FILE_PATH_LITERAL("FS.old"); 303 FILE_PATH_LITERAL("FS.old");
273 304
274 class SandboxMountPointProvider::GetFileSystemRootPathTask
275 : public base::RefCountedThreadSafe<
276 SandboxMountPointProvider::GetFileSystemRootPathTask> {
277 public:
278 GetFileSystemRootPathTask(
279 scoped_refptr<base::MessageLoopProxy> file_message_loop,
280 const GURL& origin_url,
281 FileSystemType type,
282 ObfuscatedFileUtil* file_util,
283 const FilePath& old_base_path,
284 const FileSystemMountPointProvider::GetRootPathCallback& callback)
285 : file_message_loop_(file_message_loop),
286 origin_message_loop_proxy_(
287 base::MessageLoopProxy::current()),
288 origin_url_(origin_url),
289 type_(type),
290 file_util_(file_util),
291 old_base_path_(old_base_path),
292 callback_(callback) {
293 }
294
295 virtual ~GetFileSystemRootPathTask() {
296 // Just in case we get deleted without running, make sure to clean up the
297 // file_util_ on the right thread.
298 if (file_util_.get() && !file_message_loop_->BelongsToCurrentThread())
299 file_message_loop_->ReleaseSoon(FROM_HERE, file_util_.release());
300 }
301
302 void Start(bool create) {
303 file_message_loop_->PostTask(
304 FROM_HERE,
305 base::Bind(
306 &GetFileSystemRootPathTask::GetFileSystemRootPathOnFileThread, this,
307 create));
308 }
309
310 private:
311 void GetFileSystemRootPathOnFileThread(bool create) {
312 MigrateIfNeeded(file_util_, old_base_path_);
313 DispatchCallbackOnCallerThread(
314 file_util_->GetDirectoryForOriginAndType(origin_url_, type_, create));
315 // We must clear the reference on the file thread.
316 file_util_ = NULL;
317 }
318
319 void DispatchCallbackOnCallerThread(const FilePath& root_path) {
320 if (root_path.empty()) {
321 UMA_HISTOGRAM_ENUMERATION(kOpenFileSystem,
322 kCreateDirectoryError,
323 kFileSystemErrorMax);
324 }
325 origin_message_loop_proxy_->PostTask(
326 FROM_HERE,
327 base::Bind(&GetFileSystemRootPathTask::DispatchCallback, this,
328 root_path));
329 }
330
331 void DispatchCallback(const FilePath& root_path) {
332 std::string origin_identifier = GetOriginIdentifierFromURL(origin_url_);
333 std::string type_string = GetFileSystemTypeString(type_);
334 DCHECK(!type_string.empty());
335 std::string name = origin_identifier + ":" + type_string;
336
337 if (!root_path.empty())
338 UMA_HISTOGRAM_ENUMERATION(kOpenFileSystem, kOK, kFileSystemErrorMax);
339
340 callback_.Run(!root_path.empty(), root_path, name);
341 callback_.Reset();
342 }
343
344 scoped_refptr<base::MessageLoopProxy> file_message_loop_;
345 scoped_refptr<base::MessageLoopProxy> origin_message_loop_proxy_;
346 GURL origin_url_;
347 FileSystemType type_;
348 scoped_refptr<ObfuscatedFileUtil> file_util_;
349 FilePath old_base_path_;
350 FileSystemMountPointProvider::GetRootPathCallback callback_;
351 };
satorux1 2011/12/27 18:56:37 Wow, a lot of code is removed. Cool!
352
353 SandboxMountPointProvider::SandboxMountPointProvider( 305 SandboxMountPointProvider::SandboxMountPointProvider(
354 scoped_refptr<base::MessageLoopProxy> file_message_loop, 306 scoped_refptr<base::MessageLoopProxy> file_message_loop,
355 const FilePath& profile_path, 307 const FilePath& profile_path,
356 FileSystemOptions* file_system_options) 308 FileSystemOptions* file_system_options)
357 : FileSystemQuotaUtil(file_message_loop), 309 : FileSystemQuotaUtil(file_message_loop),
358 file_message_loop_(file_message_loop), 310 file_message_loop_(file_message_loop),
359 profile_path_(profile_path), 311 profile_path_(profile_path),
360 file_system_options_(file_system_options), 312 file_system_options_(file_system_options),
361 sandbox_file_util_( 313 sandbox_file_util_(
362 new ObfuscatedFileUtil( 314 new ObfuscatedFileUtil(
363 profile_path.Append(kNewFileSystemDirectory), 315 profile_path.Append(kNewFileSystemDirectory),
364 QuotaFileUtil::CreateDefault())) { 316 QuotaFileUtil::CreateDefault())) {
365 DCHECK(file_system_options); 317 DCHECK(file_system_options);
366 } 318 }
367 319
368 SandboxMountPointProvider::~SandboxMountPointProvider() { 320 SandboxMountPointProvider::~SandboxMountPointProvider() {
369 if (!file_message_loop_->BelongsToCurrentThread()) 321 if (!file_message_loop_->BelongsToCurrentThread())
370 file_message_loop_->ReleaseSoon(FROM_HERE, sandbox_file_util_.release()); 322 file_message_loop_->ReleaseSoon(FROM_HERE, sandbox_file_util_.release());
371 } 323 }
372 324
373 bool SandboxMountPointProvider::IsAccessAllowed(const GURL& origin_url, 325 void SandboxMountPointProvider::ValidateFileSystemRoot(
374 FileSystemType type,
375 const FilePath& unused) {
376 if (type != kFileSystemTypeTemporary && type != kFileSystemTypePersistent)
377 return false;
378 // We essentially depend on quota to do our access controls, so here
379 // we only check if the requested scheme is allowed or not.
380 return IsAllowedScheme(origin_url);
381 }
382
383 void SandboxMountPointProvider::ValidateFileSystemRootAndGetURL(
384 const GURL& origin_url, fileapi::FileSystemType type, bool create, 326 const GURL& origin_url, fileapi::FileSystemType type, bool create,
385 const FileSystemMountPointProvider::GetRootPathCallback& callback) { 327 const ValidateFileSystemCallback& callback) {
386 FilePath origin_base_path;
387
388 if (file_system_options_->is_incognito()) { 328 if (file_system_options_->is_incognito()) {
389 // TODO(kinuko): return an isolated temporary directory. 329 // TODO(kinuko): return an isolated temporary directory.
390 callback.Run(false, FilePath(), std::string()); 330 callback.Run(base::PLATFORM_FILE_ERROR_SECURITY);
391 UMA_HISTOGRAM_ENUMERATION(kOpenFileSystem, 331 UMA_HISTOGRAM_ENUMERATION(kOpenFileSystem,
392 kIncognito, 332 kIncognito,
393 kFileSystemErrorMax); 333 kFileSystemErrorMax);
394 return; 334 return;
395 } 335 }
396 336
397 if (!IsAllowedScheme(origin_url)) { 337 if (!IsAllowedScheme(origin_url)) {
398 callback.Run(false, FilePath(), std::string()); 338 callback.Run(base::PLATFORM_FILE_ERROR_SECURITY);
399 UMA_HISTOGRAM_ENUMERATION(kOpenFileSystem, 339 UMA_HISTOGRAM_ENUMERATION(kOpenFileSystem,
400 kInvalidScheme, 340 kInvalidScheme,
401 kFileSystemErrorMax); 341 kFileSystemErrorMax);
402 return; 342 return;
403 } 343 }
404 344
405 scoped_refptr<GetFileSystemRootPathTask> task( 345 base::PlatformFileError* error = new base::PlatformFileError;
406 new GetFileSystemRootPathTask( 346 file_message_loop_->PostTaskAndReply(
407 file_message_loop_, origin_url, type, sandbox_file_util_.get(), 347 FROM_HERE,
408 old_base_path(), callback)); 348 base::Bind(&ValidateRootOnFileThread,
409 task->Start(create); 349 sandbox_file_util_,
350 origin_url, type, old_base_path(), create,
351 base::Unretained(error)),
352 base::Bind(base::Bind(&PassPointerByValue<base::PlatformFileError>,
353 callback),
354 base::Owned(error)));
410 }; 355 };
411 356
412 FilePath 357 FilePath
413 SandboxMountPointProvider::ValidateFileSystemRootAndGetPathOnFileThread( 358 SandboxMountPointProvider::GetFileSystemRootPathOnFileThread(
414 const GURL& origin_url, FileSystemType type, const FilePath& unused, 359 const GURL& origin_url, FileSystemType type, const FilePath& unused,
415 bool create) { 360 bool create) {
416 if (file_system_options_->is_incognito()) 361 if (file_system_options_->is_incognito())
417 // TODO(kinuko): return an isolated temporary directory. 362 // TODO(kinuko): return an isolated temporary directory.
418 return FilePath(); 363 return FilePath();
419 364
420 if (!IsAllowedScheme(origin_url)) 365 if (!IsAllowedScheme(origin_url))
421 return FilePath(); 366 return FilePath();
422 367
423 MigrateIfNeeded(sandbox_file_util_, old_base_path()); 368 MigrateIfNeeded(sandbox_file_util_, old_base_path());
424 369
425 return sandbox_file_util_->GetDirectoryForOriginAndType( 370 return sandbox_file_util_->GetDirectoryForOriginAndType(
426 origin_url, type, create); 371 origin_url, type, create);
427 } 372 }
428 373
374 bool SandboxMountPointProvider::IsAccessAllowed(const GURL& origin_url,
375 FileSystemType type,
376 const FilePath& unused) {
377 if (type != kFileSystemTypeTemporary && type != kFileSystemTypePersistent)
378 return false;
379 // We essentially depend on quota to do our access controls, so here
380 // we only check if the requested scheme is allowed or not.
381 return IsAllowedScheme(origin_url);
382 }
383
429 bool SandboxMountPointProvider::IsRestrictedFileName(const FilePath& filename) 384 bool SandboxMountPointProvider::IsRestrictedFileName(const FilePath& filename)
430 const { 385 const {
431 if (filename.value().empty()) 386 if (filename.value().empty())
432 return false; 387 return false;
433 388
434 for (size_t i = 0; i < arraysize(kRestrictedNames); ++i) { 389 for (size_t i = 0; i < arraysize(kRestrictedNames); ++i) {
435 // Exact match. 390 // Exact match.
436 if (filename.value() == kRestrictedNames[i]) 391 if (filename.value() == kRestrictedNames[i])
437 return true; 392 return true;
438 } 393 }
(...skipping 238 matching lines...) Expand 10 before | Expand all | Expand 10 after
677 i < file_system_options_->additional_allowed_schemes().size(); 632 i < file_system_options_->additional_allowed_schemes().size();
678 ++i) { 633 ++i) {
679 if (url.SchemeIs( 634 if (url.SchemeIs(
680 file_system_options_->additional_allowed_schemes()[i].c_str())) 635 file_system_options_->additional_allowed_schemes()[i].c_str()))
681 return true; 636 return true;
682 } 637 }
683 return false; 638 return false;
684 } 639 }
685 640
686 } // namespace fileapi 641 } // namespace fileapi
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698