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

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

Issue 18344013: fileapi: Rename FileSystemMountProvider to FileSystemBackend (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: rebase Created 7 years, 5 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
(Empty)
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 "webkit/browser/fileapi/sandbox_mount_point_provider.h"
6
7 #include "base/bind.h"
8 #include "base/command_line.h"
9 #include "base/file_util.h"
10 #include "base/logging.h"
11 #include "base/memory/scoped_ptr.h"
12 #include "base/metrics/histogram.h"
13 #include "base/stl_util.h"
14 #include "base/task_runner_util.h"
15 #include "net/base/net_util.h"
16 #include "url/gurl.h"
17 #include "webkit/browser/fileapi/async_file_util_adapter.h"
18 #include "webkit/browser/fileapi/copy_or_move_file_validator.h"
19 #include "webkit/browser/fileapi/file_system_context.h"
20 #include "webkit/browser/fileapi/file_system_file_stream_reader.h"
21 #include "webkit/browser/fileapi/file_system_operation_context.h"
22 #include "webkit/browser/fileapi/file_system_options.h"
23 #include "webkit/browser/fileapi/file_system_task_runners.h"
24 #include "webkit/browser/fileapi/file_system_usage_cache.h"
25 #include "webkit/browser/fileapi/local_file_system_operation.h"
26 #include "webkit/browser/fileapi/obfuscated_file_util.h"
27 #include "webkit/browser/fileapi/sandbox_file_stream_writer.h"
28 #include "webkit/browser/fileapi/sandbox_quota_observer.h"
29 #include "webkit/browser/fileapi/syncable/syncable_file_system_operation.h"
30 #include "webkit/browser/quota/quota_manager.h"
31 #include "webkit/common/fileapi/file_system_types.h"
32 #include "webkit/common/fileapi/file_system_util.h"
33
34 using quota::QuotaManagerProxy;
35
36 namespace fileapi {
37
38 namespace {
39
40 const char kChromeScheme[] = "chrome";
41 const char kExtensionScheme[] = "chrome-extension";
42
43 const char kOpenFileSystemLabel[] = "FileSystem.OpenFileSystem";
44 const char kOpenFileSystemDetailLabel[] = "FileSystem.OpenFileSystemDetail";
45 const char kOpenFileSystemDetailNonThrottledLabel[] =
46 "FileSystem.OpenFileSystemDetailNonthrottled";
47 int64 kMinimumStatsCollectionIntervalHours = 1;
48
49 // A command line switch to disable usage tracking.
50 const char kDisableUsageTracking[] = "disable-file-system-usage-tracking";
51
52 enum FileSystemError {
53 kOK = 0,
54 kIncognito,
55 kInvalidSchemeError,
56 kCreateDirectoryError,
57 kNotFound,
58 kUnknownError,
59 kFileSystemErrorMax,
60 };
61
62 const char kTemporaryOriginsCountLabel[] = "FileSystem.TemporaryOriginsCount";
63 const char kPersistentOriginsCountLabel[] = "FileSystem.PersistentOriginsCount";
64 const char kSyncableOriginsCountLabel[] = "FileSystem.SyncableOriginsCount";
65
66 // Restricted names.
67 // http://dev.w3.org/2009/dap/file-system/file-dir-sys.html#naming-restrictions
68 const base::FilePath::CharType* const kRestrictedNames[] = {
69 FILE_PATH_LITERAL("."), FILE_PATH_LITERAL(".."),
70 };
71
72 // Restricted chars.
73 const base::FilePath::CharType kRestrictedChars[] = {
74 FILE_PATH_LITERAL('/'), FILE_PATH_LITERAL('\\'),
75 };
76
77 class ObfuscatedOriginEnumerator
78 : public SandboxMountPointProvider::OriginEnumerator {
79 public:
80 explicit ObfuscatedOriginEnumerator(ObfuscatedFileUtil* file_util) {
81 enum_.reset(file_util->CreateOriginEnumerator());
82 }
83 virtual ~ObfuscatedOriginEnumerator() {}
84
85 virtual GURL Next() OVERRIDE {
86 return enum_->Next();
87 }
88
89 virtual bool HasFileSystemType(fileapi::FileSystemType type) const OVERRIDE {
90 return enum_->HasFileSystemType(type);
91 }
92
93 private:
94 scoped_ptr<ObfuscatedFileUtil::AbstractOriginEnumerator> enum_;
95 };
96
97 void DidOpenFileSystem(
98 base::WeakPtr<SandboxMountPointProvider> mount_point_provider,
99 const FileSystemMountPointProvider::OpenFileSystemCallback& callback,
100 base::PlatformFileError* error) {
101 if (mount_point_provider.get())
102 mount_point_provider.get()->CollectOpenFileSystemMetrics(*error);
103 callback.Run(*error);
104 }
105
106 void OpenFileSystemOnFileThread(
107 ObfuscatedFileUtil* file_util,
108 const GURL& origin_url,
109 FileSystemType type,
110 OpenFileSystemMode mode,
111 base::PlatformFileError* error_ptr) {
112 DCHECK(error_ptr);
113
114 const bool create = (mode == OPEN_FILE_SYSTEM_CREATE_IF_NONEXISTENT);
115 base::FilePath root_path =
116 file_util->GetDirectoryForOriginAndType(
117 origin_url, type, create, error_ptr);
118 if (*error_ptr != base::PLATFORM_FILE_OK) {
119 UMA_HISTOGRAM_ENUMERATION(kOpenFileSystemLabel,
120 kCreateDirectoryError,
121 kFileSystemErrorMax);
122 } else {
123 UMA_HISTOGRAM_ENUMERATION(kOpenFileSystemLabel, kOK, kFileSystemErrorMax);
124 }
125 // The reference of file_util will be derefed on the FILE thread
126 // when the storage of this callback gets deleted regardless of whether
127 // this method is called or not.
128 }
129
130 } // anonymous namespace
131
132 const base::FilePath::CharType
133 SandboxMountPointProvider::kFileSystemDirectory[] =
134 FILE_PATH_LITERAL("File System");
135
136 SandboxMountPointProvider::SandboxMountPointProvider(
137 quota::QuotaManagerProxy* quota_manager_proxy,
138 base::SequencedTaskRunner* file_task_runner,
139 const base::FilePath& profile_path,
140 const FileSystemOptions& file_system_options,
141 quota::SpecialStoragePolicy* special_storage_policy)
142 : file_task_runner_(file_task_runner),
143 profile_path_(profile_path),
144 file_system_options_(file_system_options),
145 enable_temporary_file_system_in_incognito_(false),
146 sandbox_file_util_(
147 new AsyncFileUtilAdapter(
148 new ObfuscatedFileUtil(
149 special_storage_policy,
150 profile_path.Append(kFileSystemDirectory),
151 file_task_runner))),
152 file_system_usage_cache_(new FileSystemUsageCache(file_task_runner)),
153 quota_observer_(new SandboxQuotaObserver(
154 quota_manager_proxy,
155 file_task_runner,
156 sandbox_sync_file_util(),
157 file_system_usage_cache_.get())),
158 enable_usage_tracking_(
159 !CommandLine::ForCurrentProcess()->HasSwitch(
160 kDisableUsageTracking)),
161 special_storage_policy_(special_storage_policy),
162 weak_factory_(this) {
163 // Set quota observers.
164 UpdateObserverList::Source update_observers_src;
165 AccessObserverList::Source access_observers_src;
166
167 if (enable_usage_tracking_) {
168 update_observers_src.AddObserver(quota_observer_.get(),
169 file_task_runner_.get());
170 access_observers_src.AddObserver(quota_observer_.get(), NULL);
171 }
172
173 update_observers_ = UpdateObserverList(update_observers_src);
174 access_observers_ = AccessObserverList(access_observers_src);
175 syncable_update_observers_ = UpdateObserverList(update_observers_src);
176
177 if (!file_task_runner_->RunsTasksOnCurrentThread()) {
178 // Post prepopulate task only if it's not already running on
179 // file_task_runner (which implies running in tests).
180 file_task_runner_->PostTask(
181 FROM_HERE,
182 base::Bind(&ObfuscatedFileUtil::MaybePrepopulateDatabase,
183 base::Unretained(sandbox_sync_file_util())));
184 }
185 }
186
187 SandboxMountPointProvider::~SandboxMountPointProvider() {
188 if (!file_task_runner_->RunsTasksOnCurrentThread()) {
189 AsyncFileUtilAdapter* sandbox_file_util = sandbox_file_util_.release();
190 SandboxQuotaObserver* quota_observer = quota_observer_.release();
191 FileSystemUsageCache* file_system_usage_cache =
192 file_system_usage_cache_.release();
193 if (!file_task_runner_->DeleteSoon(FROM_HERE, sandbox_file_util))
194 delete sandbox_file_util;
195 if (!file_task_runner_->DeleteSoon(FROM_HERE, quota_observer))
196 delete quota_observer;
197 if (!file_task_runner_->DeleteSoon(FROM_HERE, file_system_usage_cache))
198 delete file_system_usage_cache;
199 }
200 }
201
202 bool SandboxMountPointProvider::CanHandleType(FileSystemType type) const {
203 return type == kFileSystemTypeTemporary ||
204 type == kFileSystemTypePersistent ||
205 type == kFileSystemTypeSyncable ||
206 type == kFileSystemTypeSyncableForInternalSync;
207 }
208
209 void SandboxMountPointProvider::OpenFileSystem(
210 const GURL& origin_url, fileapi::FileSystemType type,
211 OpenFileSystemMode mode,
212 const OpenFileSystemCallback& callback) {
213 if (file_system_options_.is_incognito() &&
214 !(type == kFileSystemTypeTemporary &&
215 enable_temporary_file_system_in_incognito_)) {
216 // TODO(kinuko): return an isolated temporary directory.
217 callback.Run(base::PLATFORM_FILE_ERROR_SECURITY);
218 UMA_HISTOGRAM_ENUMERATION(kOpenFileSystemLabel,
219 kIncognito,
220 kFileSystemErrorMax);
221 return;
222 }
223
224 if (!IsAllowedScheme(origin_url)) {
225 callback.Run(base::PLATFORM_FILE_ERROR_SECURITY);
226 UMA_HISTOGRAM_ENUMERATION(kOpenFileSystemLabel,
227 kInvalidSchemeError,
228 kFileSystemErrorMax);
229 return;
230 }
231
232 base::PlatformFileError* error_ptr = new base::PlatformFileError;
233 file_task_runner_->PostTaskAndReply(
234 FROM_HERE,
235 base::Bind(&OpenFileSystemOnFileThread,
236 sandbox_sync_file_util(),
237 origin_url, type, mode,
238 base::Unretained(error_ptr)),
239 base::Bind(&DidOpenFileSystem,
240 weak_factory_.GetWeakPtr(),
241 callback, base::Owned(error_ptr)));
242
243 if (enable_usage_tracking_)
244 return;
245
246 // Schedule full usage recalculation on the next launch without
247 // --disable-file-system-usage-tracking.
248 file_task_runner_->PostTask(
249 FROM_HERE,
250 base::Bind(&SandboxMountPointProvider::InvalidateUsageCacheOnFileThread,
251 sandbox_sync_file_util(), origin_url, type,
252 file_system_usage_cache_.get()));
253 };
254
255 FileSystemFileUtil* SandboxMountPointProvider::GetFileUtil(
256 FileSystemType type) {
257 DCHECK(sandbox_file_util_.get());
258 return sandbox_file_util_->sync_file_util();
259 }
260
261 AsyncFileUtil* SandboxMountPointProvider::GetAsyncFileUtil(
262 FileSystemType type) {
263 return sandbox_file_util_.get();
264 }
265
266 CopyOrMoveFileValidatorFactory*
267 SandboxMountPointProvider::GetCopyOrMoveFileValidatorFactory(
268 FileSystemType type,
269 base::PlatformFileError* error_code) {
270 DCHECK(error_code);
271 *error_code = base::PLATFORM_FILE_OK;
272 return NULL;
273 }
274
275 FileSystemOperation* SandboxMountPointProvider::CreateFileSystemOperation(
276 const FileSystemURL& url,
277 FileSystemContext* context,
278 base::PlatformFileError* error_code) const {
279 if (!IsAccessValid(url)) {
280 *error_code = base::PLATFORM_FILE_ERROR_SECURITY;
281 return NULL;
282 }
283
284 scoped_ptr<FileSystemOperationContext> operation_context(
285 new FileSystemOperationContext(context));
286
287 // Copy the observer lists (assuming we only have small number of observers).
288 if (url.type() == kFileSystemTypeSyncable) {
289 operation_context->set_update_observers(syncable_update_observers_);
290 operation_context->set_change_observers(syncable_change_observers_);
291 return new sync_file_system::SyncableFileSystemOperation(
292 url, context, operation_context.Pass());
293 }
294
295 // For regular sandboxed types.
296 operation_context->set_update_observers(update_observers_);
297 operation_context->set_change_observers(change_observers_);
298
299 if (special_storage_policy_.get() &&
300 special_storage_policy_->IsStorageUnlimited(url.origin())) {
301 operation_context->set_quota_limit_type(quota::kQuotaLimitTypeUnlimited);
302 } else {
303 operation_context->set_quota_limit_type(quota::kQuotaLimitTypeLimited);
304 }
305
306 return new LocalFileSystemOperation(url, context, operation_context.Pass());
307 }
308
309 scoped_ptr<webkit_blob::FileStreamReader>
310 SandboxMountPointProvider::CreateFileStreamReader(
311 const FileSystemURL& url,
312 int64 offset,
313 const base::Time& expected_modification_time,
314 FileSystemContext* context) const {
315 if (!IsAccessValid(url))
316 return scoped_ptr<webkit_blob::FileStreamReader>();
317 return scoped_ptr<webkit_blob::FileStreamReader>(
318 new FileSystemFileStreamReader(
319 context, url, offset, expected_modification_time));
320 }
321
322 scoped_ptr<fileapi::FileStreamWriter>
323 SandboxMountPointProvider::CreateFileStreamWriter(
324 const FileSystemURL& url,
325 int64 offset,
326 FileSystemContext* context) const {
327 if (!IsAccessValid(url))
328 return scoped_ptr<fileapi::FileStreamWriter>();
329 return scoped_ptr<fileapi::FileStreamWriter>(
330 new SandboxFileStreamWriter(context, url, offset, update_observers_));
331 }
332
333 FileSystemQuotaUtil* SandboxMountPointProvider::GetQuotaUtil() {
334 return this;
335 }
336
337 SandboxMountPointProvider::OriginEnumerator*
338 SandboxMountPointProvider::CreateOriginEnumerator() {
339 return new ObfuscatedOriginEnumerator(sandbox_sync_file_util());
340 }
341
342 base::FilePath SandboxMountPointProvider::GetBaseDirectoryForOriginAndType(
343 const GURL& origin_url, fileapi::FileSystemType type, bool create) {
344
345 base::PlatformFileError error = base::PLATFORM_FILE_OK;
346 base::FilePath path = sandbox_sync_file_util()->GetDirectoryForOriginAndType(
347 origin_url, type, create, &error);
348 if (error != base::PLATFORM_FILE_OK)
349 return base::FilePath();
350 return path;
351 }
352
353 base::PlatformFileError
354 SandboxMountPointProvider::DeleteOriginDataOnFileThread(
355 FileSystemContext* file_system_context,
356 QuotaManagerProxy* proxy,
357 const GURL& origin_url,
358 fileapi::FileSystemType type) {
359
360 int64 usage = GetOriginUsageOnFileThread(file_system_context,
361 origin_url, type);
362
363 file_system_usage_cache_->CloseCacheFiles();
364 bool result = sandbox_sync_file_util()->DeleteDirectoryForOriginAndType(
365 origin_url, type);
366 if (result && proxy) {
367 proxy->NotifyStorageModified(
368 quota::QuotaClient::kFileSystem,
369 origin_url,
370 FileSystemTypeToQuotaStorageType(type),
371 -usage);
372 }
373
374 if (result)
375 return base::PLATFORM_FILE_OK;
376 return base::PLATFORM_FILE_ERROR_FAILED;
377 }
378
379 void SandboxMountPointProvider::GetOriginsForTypeOnFileThread(
380 fileapi::FileSystemType type, std::set<GURL>* origins) {
381 DCHECK(CanHandleType(type));
382 DCHECK(origins);
383 scoped_ptr<OriginEnumerator> enumerator(CreateOriginEnumerator());
384 GURL origin;
385 while (!(origin = enumerator->Next()).is_empty()) {
386 if (enumerator->HasFileSystemType(type))
387 origins->insert(origin);
388 }
389 switch (type) {
390 case kFileSystemTypeTemporary:
391 UMA_HISTOGRAM_COUNTS(kTemporaryOriginsCountLabel, origins->size());
392 break;
393 case kFileSystemTypePersistent:
394 UMA_HISTOGRAM_COUNTS(kPersistentOriginsCountLabel, origins->size());
395 break;
396 case kFileSystemTypeSyncable:
397 UMA_HISTOGRAM_COUNTS(kSyncableOriginsCountLabel, origins->size());
398 break;
399 default:
400 break;
401 }
402 }
403
404 void SandboxMountPointProvider::GetOriginsForHostOnFileThread(
405 fileapi::FileSystemType type, const std::string& host,
406 std::set<GURL>* origins) {
407 DCHECK(CanHandleType(type));
408 DCHECK(origins);
409 scoped_ptr<OriginEnumerator> enumerator(CreateOriginEnumerator());
410 GURL origin;
411 while (!(origin = enumerator->Next()).is_empty()) {
412 if (host == net::GetHostOrSpecFromURL(origin) &&
413 enumerator->HasFileSystemType(type))
414 origins->insert(origin);
415 }
416 }
417
418 int64 SandboxMountPointProvider::GetOriginUsageOnFileThread(
419 FileSystemContext* file_system_context,
420 const GURL& origin_url,
421 fileapi::FileSystemType type) {
422 DCHECK(CanHandleType(type));
423 if (!enable_usage_tracking_)
424 return 0;
425
426 // Don't use usage cache and return recalculated usage for sticky invalidated
427 // origins.
428 if (ContainsKey(sticky_dirty_origins_, std::make_pair(origin_url, type)))
429 return RecalculateUsage(file_system_context, origin_url, type);
430
431 base::FilePath base_path =
432 GetBaseDirectoryForOriginAndType(origin_url, type, false);
433 if (base_path.empty() || !file_util::DirectoryExists(base_path))
434 return 0;
435 base::FilePath usage_file_path =
436 base_path.Append(FileSystemUsageCache::kUsageFileName);
437
438 bool is_valid = file_system_usage_cache_->IsValid(usage_file_path);
439 uint32 dirty_status = 0;
440 bool dirty_status_available =
441 file_system_usage_cache_->GetDirty(usage_file_path, &dirty_status);
442 bool visited = !visited_origins_.insert(origin_url).second;
443 if (is_valid && (dirty_status == 0 || (dirty_status_available && visited))) {
444 // The usage cache is clean (dirty == 0) or the origin is already
445 // initialized and running. Read the cache file to get the usage.
446 int64 usage = 0;
447 return file_system_usage_cache_->GetUsage(usage_file_path, &usage) ?
448 usage : -1;
449 }
450 // The usage cache has not been initialized or the cache is dirty.
451 // Get the directory size now and update the cache.
452 file_system_usage_cache_->Delete(usage_file_path);
453
454 int64 usage = RecalculateUsage(file_system_context, origin_url, type);
455
456 // This clears the dirty flag too.
457 file_system_usage_cache_->UpdateUsage(usage_file_path, usage);
458 return usage;
459 }
460
461 void SandboxMountPointProvider::InvalidateUsageCache(
462 const GURL& origin,
463 fileapi::FileSystemType type) {
464 DCHECK(CanHandleType(type));
465 base::PlatformFileError error = base::PLATFORM_FILE_OK;
466 base::FilePath usage_file_path = GetUsageCachePathForOriginAndType(
467 sandbox_sync_file_util(), origin, type, &error);
468 if (error != base::PLATFORM_FILE_OK)
469 return;
470 file_system_usage_cache_->IncrementDirty(usage_file_path);
471 }
472
473 void SandboxMountPointProvider::StickyInvalidateUsageCache(
474 const GURL& origin,
475 fileapi::FileSystemType type) {
476 DCHECK(CanHandleType(type));
477 sticky_dirty_origins_.insert(std::make_pair(origin, type));
478 quota_observer_->SetUsageCacheEnabled(origin, type, false);
479 InvalidateUsageCache(origin, type);
480 }
481
482 void SandboxMountPointProvider::CollectOpenFileSystemMetrics(
483 base::PlatformFileError error_code) {
484 base::Time now = base::Time::Now();
485 bool throttled = now < next_release_time_for_open_filesystem_stat_;
486 if (!throttled) {
487 next_release_time_for_open_filesystem_stat_ =
488 now + base::TimeDelta::FromHours(kMinimumStatsCollectionIntervalHours);
489 }
490
491 #define REPORT(report_value) \
492 UMA_HISTOGRAM_ENUMERATION(kOpenFileSystemDetailLabel, \
493 (report_value), \
494 kFileSystemErrorMax); \
495 if (!throttled) { \
496 UMA_HISTOGRAM_ENUMERATION(kOpenFileSystemDetailNonThrottledLabel, \
497 (report_value), \
498 kFileSystemErrorMax); \
499 }
500
501 switch (error_code) {
502 case base::PLATFORM_FILE_OK:
503 REPORT(kOK);
504 break;
505 case base::PLATFORM_FILE_ERROR_INVALID_URL:
506 REPORT(kInvalidSchemeError);
507 break;
508 case base::PLATFORM_FILE_ERROR_NOT_FOUND:
509 REPORT(kNotFound);
510 break;
511 case base::PLATFORM_FILE_ERROR_FAILED:
512 default:
513 REPORT(kUnknownError);
514 break;
515 }
516 #undef REPORT
517 }
518
519 const UpdateObserverList* SandboxMountPointProvider::GetUpdateObservers(
520 FileSystemType type) const {
521 DCHECK(CanHandleType(type));
522 if (type == kFileSystemTypeSyncable)
523 return &syncable_update_observers_;
524 return &update_observers_;
525 }
526
527 const AccessObserverList* SandboxMountPointProvider::GetAccessObservers(
528 FileSystemType type) const {
529 DCHECK(CanHandleType(type));
530 return &access_observers_;
531 }
532
533 void SandboxMountPointProvider::AddFileUpdateObserver(
534 FileSystemType type,
535 FileUpdateObserver* observer,
536 base::SequencedTaskRunner* task_runner) {
537 DCHECK(CanHandleType(type));
538 UpdateObserverList* list = &update_observers_;
539 if (type == kFileSystemTypeSyncable)
540 list = &syncable_update_observers_;
541 UpdateObserverList::Source observer_source = list->source();
542 observer_source.AddObserver(observer, task_runner);
543 *list = UpdateObserverList(observer_source);
544 }
545
546 void SandboxMountPointProvider::AddFileChangeObserver(
547 FileSystemType type,
548 FileChangeObserver* observer,
549 base::SequencedTaskRunner* task_runner) {
550 ChangeObserverList* list = &change_observers_;
551 if (type == kFileSystemTypeSyncable)
552 list = &syncable_change_observers_;
553 ChangeObserverList::Source observer_source = list->source();
554 observer_source.AddObserver(observer, task_runner);
555 *list = ChangeObserverList(observer_source);
556 }
557
558 bool SandboxMountPointProvider::IsAccessValid(
559 const FileSystemURL& url) const {
560 if (!IsAllowedScheme(url.origin()))
561 return false;
562
563 if (!CanHandleType(url.type()))
564 return false;
565
566 if (url.path().ReferencesParent())
567 return false;
568
569 // Return earlier if the path is '/', because VirtualPath::BaseName()
570 // returns '/' for '/' and we fail the "basename != '/'" check below.
571 // (We exclude '.' because it's disallowed by spec.)
572 if (VirtualPath::IsRootPath(url.path()) &&
573 url.path() != base::FilePath(base::FilePath::kCurrentDirectory))
574 return true;
575
576 // Restricted names specified in
577 // http://dev.w3.org/2009/dap/file-system/file-dir-sys.html#naming-restriction s
578 base::FilePath filename = VirtualPath::BaseName(url.path());
579 // See if the name is allowed to create.
580 for (size_t i = 0; i < arraysize(kRestrictedNames); ++i) {
581 if (filename.value() == kRestrictedNames[i])
582 return false;
583 }
584 for (size_t i = 0; i < arraysize(kRestrictedChars); ++i) {
585 if (filename.value().find(kRestrictedChars[i]) !=
586 base::FilePath::StringType::npos)
587 return false;
588 }
589
590 return true;
591 }
592
593 base::FilePath SandboxMountPointProvider::GetUsageCachePathForOriginAndType(
594 const GURL& origin_url,
595 FileSystemType type) {
596 base::PlatformFileError error;
597 base::FilePath path = GetUsageCachePathForOriginAndType(
598 sandbox_sync_file_util(), origin_url, type, &error);
599 if (error != base::PLATFORM_FILE_OK)
600 return base::FilePath();
601 return path;
602 }
603
604 // static
605 base::FilePath SandboxMountPointProvider::GetUsageCachePathForOriginAndType(
606 ObfuscatedFileUtil* sandbox_file_util,
607 const GURL& origin_url,
608 fileapi::FileSystemType type,
609 base::PlatformFileError* error_out) {
610 DCHECK(error_out);
611 *error_out = base::PLATFORM_FILE_OK;
612 base::FilePath base_path = sandbox_file_util->GetDirectoryForOriginAndType(
613 origin_url, type, false /* create */, error_out);
614 if (*error_out != base::PLATFORM_FILE_OK)
615 return base::FilePath();
616 return base_path.Append(FileSystemUsageCache::kUsageFileName);
617 }
618
619 bool SandboxMountPointProvider::IsAllowedScheme(const GURL& url) const {
620 // Basically we only accept http or https. We allow file:// URLs
621 // only if --allow-file-access-from-files flag is given.
622 if (url.SchemeIs("http") || url.SchemeIs("https"))
623 return true;
624 if (url.SchemeIsFileSystem())
625 return url.inner_url() && IsAllowedScheme(*url.inner_url());
626
627 for (size_t i = 0;
628 i < file_system_options_.additional_allowed_schemes().size();
629 ++i) {
630 if (url.SchemeIs(
631 file_system_options_.additional_allowed_schemes()[i].c_str()))
632 return true;
633 }
634 return false;
635 }
636
637 ObfuscatedFileUtil* SandboxMountPointProvider::sandbox_sync_file_util() {
638 DCHECK(sandbox_file_util_.get());
639 return static_cast<ObfuscatedFileUtil*>(sandbox_file_util_->sync_file_util());
640 }
641
642 // static
643 void SandboxMountPointProvider::InvalidateUsageCacheOnFileThread(
644 ObfuscatedFileUtil* file_util,
645 const GURL& origin,
646 FileSystemType type,
647 FileSystemUsageCache* usage_cache) {
648 base::PlatformFileError error = base::PLATFORM_FILE_OK;
649 base::FilePath usage_cache_path = GetUsageCachePathForOriginAndType(
650 file_util, origin, type, &error);
651 if (error == base::PLATFORM_FILE_OK)
652 usage_cache->IncrementDirty(usage_cache_path);
653 }
654
655 int64 SandboxMountPointProvider::RecalculateUsage(FileSystemContext* context,
656 const GURL& origin,
657 FileSystemType type) {
658 FileSystemOperationContext operation_context(context);
659 FileSystemURL url = context->CreateCrackedFileSystemURL(
660 origin, type, base::FilePath());
661 scoped_ptr<FileSystemFileUtil::AbstractFileEnumerator> enumerator(
662 sandbox_sync_file_util()->CreateFileEnumerator(
663 &operation_context, url, true));
664
665 base::FilePath file_path_each;
666 int64 usage = 0;
667
668 while (!(file_path_each = enumerator->Next()).empty()) {
669 usage += enumerator->Size();
670 usage += ObfuscatedFileUtil::ComputeFilePathCost(file_path_each);
671 }
672
673 return usage;
674 }
675
676 } // namespace fileapi
OLDNEW
« no previous file with comments | « webkit/browser/fileapi/sandbox_mount_point_provider.h ('k') | webkit/browser/fileapi/sandbox_mount_point_provider_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698