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

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

Issue 21116008: FileAPI: Move FileSystemQuotaUtil related functions into SandboxContext (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: clean up Created 7 years, 4 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/browser/fileapi/sandbox_file_system_backend.h" 5 #include "webkit/browser/fileapi/sandbox_file_system_backend.h"
6 6
7 #include "base/bind.h" 7 #include "base/bind.h"
8 #include "base/file_util.h" 8 #include "base/file_util.h"
9 #include "base/logging.h" 9 #include "base/logging.h"
10 #include "base/memory/scoped_ptr.h"
11 #include "base/metrics/histogram.h" 10 #include "base/metrics/histogram.h"
12 #include "base/stl_util.h"
13 #include "base/task_runner_util.h" 11 #include "base/task_runner_util.h"
14 #include "net/base/net_util.h"
15 #include "url/gurl.h" 12 #include "url/gurl.h"
16 #include "webkit/browser/fileapi/async_file_util_adapter.h" 13 #include "webkit/browser/fileapi/async_file_util_adapter.h"
17 #include "webkit/browser/fileapi/copy_or_move_file_validator.h" 14 #include "webkit/browser/fileapi/copy_or_move_file_validator.h"
18 #include "webkit/browser/fileapi/file_system_context.h" 15 #include "webkit/browser/fileapi/file_system_context.h"
19 #include "webkit/browser/fileapi/file_system_file_stream_reader.h" 16 #include "webkit/browser/fileapi/file_system_file_stream_reader.h"
20 #include "webkit/browser/fileapi/file_system_operation_context.h" 17 #include "webkit/browser/fileapi/file_system_operation_context.h"
21 #include "webkit/browser/fileapi/file_system_options.h" 18 #include "webkit/browser/fileapi/file_system_options.h"
22 #include "webkit/browser/fileapi/file_system_task_runners.h" 19 #include "webkit/browser/fileapi/file_system_task_runners.h"
23 #include "webkit/browser/fileapi/file_system_usage_cache.h"
24 #include "webkit/browser/fileapi/local_file_system_operation.h" 20 #include "webkit/browser/fileapi/local_file_system_operation.h"
25 #include "webkit/browser/fileapi/obfuscated_file_util.h" 21 #include "webkit/browser/fileapi/obfuscated_file_util.h"
26 #include "webkit/browser/fileapi/sandbox_context.h" 22 #include "webkit/browser/fileapi/sandbox_context.h"
27 #include "webkit/browser/fileapi/sandbox_file_stream_writer.h" 23 #include "webkit/browser/fileapi/sandbox_file_stream_writer.h"
28 #include "webkit/browser/fileapi/sandbox_quota_observer.h" 24 #include "webkit/browser/fileapi/sandbox_quota_observer.h"
29 #include "webkit/browser/fileapi/syncable/syncable_file_system_operation.h" 25 #include "webkit/browser/fileapi/syncable/syncable_file_system_operation.h"
30 #include "webkit/browser/fileapi/syncable/syncable_file_system_util.h" 26 #include "webkit/browser/fileapi/syncable/syncable_file_system_util.h"
31 #include "webkit/browser/quota/quota_manager.h" 27 #include "webkit/browser/quota/quota_manager.h"
32 #include "webkit/common/fileapi/file_system_types.h" 28 #include "webkit/common/fileapi/file_system_types.h"
33 #include "webkit/common/fileapi/file_system_util.h" 29 #include "webkit/common/fileapi/file_system_util.h"
(...skipping 17 matching lines...) Expand all
51 kInvalidSchemeError, 47 kInvalidSchemeError,
52 kCreateDirectoryError, 48 kCreateDirectoryError,
53 kNotFound, 49 kNotFound,
54 kUnknownError, 50 kUnknownError,
55 kFileSystemErrorMax, 51 kFileSystemErrorMax,
56 }; 52 };
57 53
58 const char kTemporaryOriginsCountLabel[] = "FileSystem.TemporaryOriginsCount"; 54 const char kTemporaryOriginsCountLabel[] = "FileSystem.TemporaryOriginsCount";
59 const char kPersistentOriginsCountLabel[] = "FileSystem.PersistentOriginsCount"; 55 const char kPersistentOriginsCountLabel[] = "FileSystem.PersistentOriginsCount";
60 56
61 // Restricted names.
62 // http://dev.w3.org/2009/dap/file-system/file-dir-sys.html#naming-restrictions
63 const base::FilePath::CharType* const kRestrictedNames[] = {
64 FILE_PATH_LITERAL("."), FILE_PATH_LITERAL(".."),
65 };
66
67 // Restricted chars.
68 const base::FilePath::CharType kRestrictedChars[] = {
69 FILE_PATH_LITERAL('/'), FILE_PATH_LITERAL('\\'),
70 };
71
72 class ObfuscatedOriginEnumerator
73 : public SandboxFileSystemBackend::OriginEnumerator {
74 public:
75 explicit ObfuscatedOriginEnumerator(ObfuscatedFileUtil* file_util) {
76 enum_.reset(file_util->CreateOriginEnumerator());
77 }
78 virtual ~ObfuscatedOriginEnumerator() {}
79
80 virtual GURL Next() OVERRIDE {
81 return enum_->Next();
82 }
83
84 virtual bool HasFileSystemType(fileapi::FileSystemType type) const OVERRIDE {
85 return enum_->HasFileSystemType(type);
86 }
87
88 private:
89 scoped_ptr<ObfuscatedFileUtil::AbstractOriginEnumerator> enum_;
90 };
91
92 void DidOpenFileSystem( 57 void DidOpenFileSystem(
93 base::WeakPtr<SandboxFileSystemBackend> sandbox_backend, 58 base::WeakPtr<SandboxFileSystemBackend> sandbox_backend,
94 const base::Callback<void(base::PlatformFileError error)>& callback, 59 const base::Callback<void(base::PlatformFileError error)>& callback,
95 base::PlatformFileError* error) { 60 base::PlatformFileError* error) {
96 if (sandbox_backend.get()) 61 if (sandbox_backend.get())
97 sandbox_backend.get()->CollectOpenFileSystemMetrics(*error); 62 sandbox_backend.get()->CollectOpenFileSystemMetrics(*error);
98 callback.Run(*error); 63 callback.Run(*error);
99 } 64 }
100 65
101 void OpenFileSystemOnFileThread( 66 void OpenFileSystemOnFileThread(
(...skipping 13 matching lines...) Expand all
115 UMA_HISTOGRAM_ENUMERATION(kOpenFileSystemLabel, kOK, kFileSystemErrorMax); 80 UMA_HISTOGRAM_ENUMERATION(kOpenFileSystemLabel, kOK, kFileSystemErrorMax);
116 } 81 }
117 // The reference of file_util will be derefed on the FILE thread 82 // The reference of file_util will be derefed on the FILE thread
118 // when the storage of this callback gets deleted regardless of whether 83 // when the storage of this callback gets deleted regardless of whether
119 // this method is called or not. 84 // this method is called or not.
120 } 85 }
121 86
122 } // anonymous namespace 87 } // anonymous namespace
123 88
124 SandboxFileSystemBackend::SandboxFileSystemBackend( 89 SandboxFileSystemBackend::SandboxFileSystemBackend(
125 SandboxContext* sandbox_context, 90 SandboxContext* sandbox_context)
126 const FileSystemOptions& file_system_options) 91 : sandbox_context_(sandbox_context),
127 : file_system_options_(file_system_options),
128 sandbox_context_(sandbox_context),
129 enable_temporary_file_system_in_incognito_(false), 92 enable_temporary_file_system_in_incognito_(false),
130 weak_factory_(this) { 93 weak_factory_(this) {
131 } 94 }
132 95
133 SandboxFileSystemBackend::~SandboxFileSystemBackend() { 96 SandboxFileSystemBackend::~SandboxFileSystemBackend() {
134 } 97 }
135 98
136 bool SandboxFileSystemBackend::CanHandleType(FileSystemType type) const { 99 bool SandboxFileSystemBackend::CanHandleType(FileSystemType type) const {
137 return type == kFileSystemTypeTemporary || 100 return type == kFileSystemTypeTemporary ||
138 type == kFileSystemTypePersistent || 101 type == kFileSystemTypePersistent ||
(...skipping 10 matching lines...) Expand all
149 sandbox_context_->quota_observer(), NULL); 112 sandbox_context_->quota_observer(), NULL);
150 113
151 syncable_update_observers_ = update_observers_; 114 syncable_update_observers_ = update_observers_;
152 115
153 if (!sandbox_context_->file_task_runner()->RunsTasksOnCurrentThread()) { 116 if (!sandbox_context_->file_task_runner()->RunsTasksOnCurrentThread()) {
154 // Post prepopulate task only if it's not already running on 117 // Post prepopulate task only if it's not already running on
155 // file_task_runner (which implies running in tests). 118 // file_task_runner (which implies running in tests).
156 sandbox_context_->file_task_runner()->PostTask( 119 sandbox_context_->file_task_runner()->PostTask(
157 FROM_HERE, 120 FROM_HERE,
158 base::Bind(&ObfuscatedFileUtil::MaybePrepopulateDatabase, 121 base::Bind(&ObfuscatedFileUtil::MaybePrepopulateDatabase,
159 base::Unretained(sandbox_sync_file_util()))); 122 base::Unretained(sandbox_context_->sync_file_util())));
160 } 123 }
161 } 124 }
162 125
163 void SandboxFileSystemBackend::OpenFileSystem( 126 void SandboxFileSystemBackend::OpenFileSystem(
164 const GURL& origin_url, 127 const GURL& origin_url,
165 fileapi::FileSystemType type, 128 fileapi::FileSystemType type,
166 OpenFileSystemMode mode, 129 OpenFileSystemMode mode,
167 const OpenFileSystemCallback& callback) { 130 const OpenFileSystemCallback& callback) {
168 if (file_system_options_.is_incognito() && 131 DCHECK(CanHandleType(type));
132 DCHECK(sandbox_context_);
133 if (sandbox_context_->file_system_options().is_incognito() &&
169 !(type == kFileSystemTypeTemporary && 134 !(type == kFileSystemTypeTemporary &&
170 enable_temporary_file_system_in_incognito_)) { 135 enable_temporary_file_system_in_incognito_)) {
171 // TODO(kinuko): return an isolated temporary directory. 136 // TODO(kinuko): return an isolated temporary directory.
172 callback.Run(GURL(), std::string(), base::PLATFORM_FILE_ERROR_SECURITY); 137 callback.Run(GURL(), std::string(), base::PLATFORM_FILE_ERROR_SECURITY);
173 return; 138 return;
174 } 139 }
175 140
176 if (!IsAllowedScheme(origin_url)) { 141 if (!sandbox_context_->IsAllowedScheme(origin_url)) {
177 callback.Run(GURL(), std::string(), base::PLATFORM_FILE_ERROR_SECURITY); 142 callback.Run(GURL(), std::string(), base::PLATFORM_FILE_ERROR_SECURITY);
178 return; 143 return;
179 } 144 }
180 145
181 // TODO(nhiroki): Factor out SyncFS related code to SyncFileSystemBackend we 146 // TODO(nhiroki): Factor out SyncFS related code to SyncFileSystemBackend we
182 // plan to introduce. (http://crbug.com/242422/) 147 // plan to introduce. (http://crbug.com/242422/)
183 GURL root_url = (type == kFileSystemTypeSyncable) 148 GURL root_url = (type == kFileSystemTypeSyncable)
184 ? sync_file_system::GetSyncableFileSystemRootURI(origin_url) 149 ? sync_file_system::GetSyncableFileSystemRootURI(origin_url)
185 : GetFileSystemRootURI(origin_url, type); 150 : GetFileSystemRootURI(origin_url, type);
186 std::string name = GetFileSystemName(origin_url, type); 151 std::string name = GetFileSystemName(origin_url, type);
187 152
188 base::PlatformFileError* error_ptr = new base::PlatformFileError; 153 base::PlatformFileError* error_ptr = new base::PlatformFileError;
189 sandbox_context_->file_task_runner()->PostTaskAndReply( 154 sandbox_context_->file_task_runner()->PostTaskAndReply(
190 FROM_HERE, 155 FROM_HERE,
191 base::Bind(&OpenFileSystemOnFileThread, 156 base::Bind(&OpenFileSystemOnFileThread,
192 sandbox_sync_file_util(), 157 sandbox_context_->sync_file_util(),
193 origin_url, type, mode, 158 origin_url, type, mode,
194 base::Unretained(error_ptr)), 159 base::Unretained(error_ptr)),
195 base::Bind(&DidOpenFileSystem, 160 base::Bind(&DidOpenFileSystem,
196 weak_factory_.GetWeakPtr(), 161 weak_factory_.GetWeakPtr(),
197 base::Bind(callback, root_url, name), 162 base::Bind(callback, root_url, name),
198 base::Owned(error_ptr))); 163 base::Owned(error_ptr)));
199 }; 164 };
200 165
201 FileSystemFileUtil* SandboxFileSystemBackend::GetFileUtil( 166 FileSystemFileUtil* SandboxFileSystemBackend::GetFileUtil(
202 FileSystemType type) { 167 FileSystemType type) {
(...skipping 13 matching lines...) Expand all
216 base::PlatformFileError* error_code) { 181 base::PlatformFileError* error_code) {
217 DCHECK(error_code); 182 DCHECK(error_code);
218 *error_code = base::PLATFORM_FILE_OK; 183 *error_code = base::PLATFORM_FILE_OK;
219 return NULL; 184 return NULL;
220 } 185 }
221 186
222 FileSystemOperation* SandboxFileSystemBackend::CreateFileSystemOperation( 187 FileSystemOperation* SandboxFileSystemBackend::CreateFileSystemOperation(
223 const FileSystemURL& url, 188 const FileSystemURL& url,
224 FileSystemContext* context, 189 FileSystemContext* context,
225 base::PlatformFileError* error_code) const { 190 base::PlatformFileError* error_code) const {
226 if (!IsAccessValid(url)) { 191 DCHECK(CanHandleType(url.type()));
192 DCHECK(sandbox_context_);
193 if (!sandbox_context_->IsAccessValid(url)) {
227 *error_code = base::PLATFORM_FILE_ERROR_SECURITY; 194 *error_code = base::PLATFORM_FILE_ERROR_SECURITY;
228 return NULL; 195 return NULL;
229 } 196 }
230 197
231 scoped_ptr<FileSystemOperationContext> operation_context( 198 scoped_ptr<FileSystemOperationContext> operation_context(
232 new FileSystemOperationContext(context)); 199 new FileSystemOperationContext(context));
233 200
234 // Copy the observer lists (assuming we only have small number of observers). 201 // Copy the observer lists (assuming we only have small number of observers).
235 if (url.type() == kFileSystemTypeSyncable) { 202 if (url.type() == kFileSystemTypeSyncable) {
236 operation_context->set_update_observers(syncable_update_observers_); 203 operation_context->set_update_observers(syncable_update_observers_);
(...skipping 14 matching lines...) Expand all
251 218
252 return new LocalFileSystemOperation(url, context, operation_context.Pass()); 219 return new LocalFileSystemOperation(url, context, operation_context.Pass());
253 } 220 }
254 221
255 scoped_ptr<webkit_blob::FileStreamReader> 222 scoped_ptr<webkit_blob::FileStreamReader>
256 SandboxFileSystemBackend::CreateFileStreamReader( 223 SandboxFileSystemBackend::CreateFileStreamReader(
257 const FileSystemURL& url, 224 const FileSystemURL& url,
258 int64 offset, 225 int64 offset,
259 const base::Time& expected_modification_time, 226 const base::Time& expected_modification_time,
260 FileSystemContext* context) const { 227 FileSystemContext* context) const {
261 if (!IsAccessValid(url)) 228 DCHECK(CanHandleType(url.type()));
229 DCHECK(sandbox_context_);
230 if (!sandbox_context_->IsAccessValid(url))
262 return scoped_ptr<webkit_blob::FileStreamReader>(); 231 return scoped_ptr<webkit_blob::FileStreamReader>();
263 return scoped_ptr<webkit_blob::FileStreamReader>( 232 return scoped_ptr<webkit_blob::FileStreamReader>(
264 new FileSystemFileStreamReader( 233 new FileSystemFileStreamReader(
265 context, url, offset, expected_modification_time)); 234 context, url, offset, expected_modification_time));
266 } 235 }
267 236
268 scoped_ptr<fileapi::FileStreamWriter> 237 scoped_ptr<fileapi::FileStreamWriter>
269 SandboxFileSystemBackend::CreateFileStreamWriter( 238 SandboxFileSystemBackend::CreateFileStreamWriter(
270 const FileSystemURL& url, 239 const FileSystemURL& url,
271 int64 offset, 240 int64 offset,
272 FileSystemContext* context) const { 241 FileSystemContext* context) const {
273 if (!IsAccessValid(url)) 242 DCHECK(CanHandleType(url.type()));
243 DCHECK(sandbox_context_);
244 if (!sandbox_context_->IsAccessValid(url))
274 return scoped_ptr<fileapi::FileStreamWriter>(); 245 return scoped_ptr<fileapi::FileStreamWriter>();
275 return scoped_ptr<fileapi::FileStreamWriter>( 246 return scoped_ptr<fileapi::FileStreamWriter>(
276 new SandboxFileStreamWriter(context, url, offset, update_observers_)); 247 new SandboxFileStreamWriter(context, url, offset, update_observers_));
277 } 248 }
278 249
279 FileSystemQuotaUtil* SandboxFileSystemBackend::GetQuotaUtil() { 250 FileSystemQuotaUtil* SandboxFileSystemBackend::GetQuotaUtil() {
280 return this; 251 return this;
281 } 252 }
282 253
283 SandboxFileSystemBackend::OriginEnumerator* 254 SandboxContext::OriginEnumerator*
284 SandboxFileSystemBackend::CreateOriginEnumerator() { 255 SandboxFileSystemBackend::CreateOriginEnumerator() {
285 return new ObfuscatedOriginEnumerator(sandbox_sync_file_util()); 256 DCHECK(sandbox_context_);
286 } 257 return sandbox_context_->CreateOriginEnumerator();
287
288 base::FilePath SandboxFileSystemBackend::GetBaseDirectoryForOriginAndType(
289 const GURL& origin_url, fileapi::FileSystemType type, bool create) {
290 base::PlatformFileError error = base::PLATFORM_FILE_OK;
291 base::FilePath path = sandbox_sync_file_util()->GetDirectoryForOriginAndType(
292 origin_url, type, create, &error);
293 if (error != base::PLATFORM_FILE_OK)
294 return base::FilePath();
295 return path;
296 } 258 }
297 259
298 base::PlatformFileError 260 base::PlatformFileError
299 SandboxFileSystemBackend::DeleteOriginDataOnFileThread( 261 SandboxFileSystemBackend::DeleteOriginDataOnFileThread(
300 FileSystemContext* file_system_context, 262 FileSystemContext* file_system_context,
301 QuotaManagerProxy* proxy, 263 QuotaManagerProxy* proxy,
302 const GURL& origin_url, 264 const GURL& origin_url,
303 fileapi::FileSystemType type) { 265 fileapi::FileSystemType type) {
304 int64 usage = GetOriginUsageOnFileThread(file_system_context, 266 DCHECK(CanHandleType(type));
305 origin_url, type); 267 DCHECK(sandbox_context_);
306 268 return sandbox_context_->DeleteOriginDataOnFileThread(
307 usage_cache()->CloseCacheFiles(); 269 file_system_context, proxy, origin_url, type);
308 bool result = sandbox_sync_file_util()->DeleteDirectoryForOriginAndType(
309 origin_url, type);
310 if (result && proxy) {
311 proxy->NotifyStorageModified(
312 quota::QuotaClient::kFileSystem,
313 origin_url,
314 FileSystemTypeToQuotaStorageType(type),
315 -usage);
316 }
317
318 if (result)
319 return base::PLATFORM_FILE_OK;
320 return base::PLATFORM_FILE_ERROR_FAILED;
321 } 270 }
322 271
323 void SandboxFileSystemBackend::GetOriginsForTypeOnFileThread( 272 void SandboxFileSystemBackend::GetOriginsForTypeOnFileThread(
324 fileapi::FileSystemType type, std::set<GURL>* origins) { 273 fileapi::FileSystemType type, std::set<GURL>* origins) {
325 DCHECK(CanHandleType(type)); 274 DCHECK(CanHandleType(type));
326 DCHECK(origins); 275 DCHECK(sandbox_context_);
327 scoped_ptr<OriginEnumerator> enumerator(CreateOriginEnumerator()); 276 sandbox_context_->GetOriginsForTypeOnFileThread(type, origins);
328 GURL origin;
329 while (!(origin = enumerator->Next()).is_empty()) {
330 if (enumerator->HasFileSystemType(type))
331 origins->insert(origin);
332 }
333 switch (type) { 277 switch (type) {
334 case kFileSystemTypeTemporary: 278 case kFileSystemTypeTemporary:
335 UMA_HISTOGRAM_COUNTS(kTemporaryOriginsCountLabel, origins->size()); 279 UMA_HISTOGRAM_COUNTS(kTemporaryOriginsCountLabel, origins->size());
336 break; 280 break;
337 case kFileSystemTypePersistent: 281 case kFileSystemTypePersistent:
338 UMA_HISTOGRAM_COUNTS(kPersistentOriginsCountLabel, origins->size()); 282 UMA_HISTOGRAM_COUNTS(kPersistentOriginsCountLabel, origins->size());
339 break; 283 break;
340 default: 284 default:
341 break; 285 break;
342 } 286 }
343 } 287 }
344 288
345 void SandboxFileSystemBackend::GetOriginsForHostOnFileThread( 289 void SandboxFileSystemBackend::GetOriginsForHostOnFileThread(
346 fileapi::FileSystemType type, const std::string& host, 290 fileapi::FileSystemType type, const std::string& host,
347 std::set<GURL>* origins) { 291 std::set<GURL>* origins) {
348 DCHECK(CanHandleType(type)); 292 DCHECK(CanHandleType(type));
349 DCHECK(origins); 293 DCHECK(sandbox_context_);
350 scoped_ptr<OriginEnumerator> enumerator(CreateOriginEnumerator()); 294 sandbox_context_->GetOriginsForHostOnFileThread(type, host, origins);
351 GURL origin;
352 while (!(origin = enumerator->Next()).is_empty()) {
353 if (host == net::GetHostOrSpecFromURL(origin) &&
354 enumerator->HasFileSystemType(type))
355 origins->insert(origin);
356 }
357 } 295 }
358 296
359 int64 SandboxFileSystemBackend::GetOriginUsageOnFileThread( 297 int64 SandboxFileSystemBackend::GetOriginUsageOnFileThread(
360 FileSystemContext* file_system_context, 298 FileSystemContext* file_system_context,
361 const GURL& origin_url, 299 const GURL& origin_url,
362 fileapi::FileSystemType type) { 300 fileapi::FileSystemType type) {
363 DCHECK(CanHandleType(type)); 301 DCHECK(CanHandleType(type));
364 302 DCHECK(sandbox_context_);
365 // Don't use usage cache and return recalculated usage for sticky invalidated 303 return sandbox_context_->GetOriginUsageOnFileThread(
366 // origins. 304 file_system_context, origin_url, type);
367 if (ContainsKey(sticky_dirty_origins_, std::make_pair(origin_url, type)))
368 return RecalculateUsage(file_system_context, origin_url, type);
369
370 base::FilePath base_path =
371 GetBaseDirectoryForOriginAndType(origin_url, type, false);
372 if (base_path.empty() || !base::DirectoryExists(base_path))
373 return 0;
374 base::FilePath usage_file_path =
375 base_path.Append(FileSystemUsageCache::kUsageFileName);
376
377 bool is_valid = usage_cache()->IsValid(usage_file_path);
378 uint32 dirty_status = 0;
379 bool dirty_status_available =
380 usage_cache()->GetDirty(usage_file_path, &dirty_status);
381 bool visited = !visited_origins_.insert(origin_url).second;
382 if (is_valid && (dirty_status == 0 || (dirty_status_available && visited))) {
383 // The usage cache is clean (dirty == 0) or the origin is already
384 // initialized and running. Read the cache file to get the usage.
385 int64 usage = 0;
386 return usage_cache()->GetUsage(usage_file_path, &usage) ? usage : -1;
387 }
388 // The usage cache has not been initialized or the cache is dirty.
389 // Get the directory size now and update the cache.
390 usage_cache()->Delete(usage_file_path);
391
392 int64 usage = RecalculateUsage(file_system_context, origin_url, type);
393
394 // This clears the dirty flag too.
395 usage_cache()->UpdateUsage(usage_file_path, usage);
396 return usage;
397 } 305 }
398 306
399 void SandboxFileSystemBackend::InvalidateUsageCache( 307 void SandboxFileSystemBackend::InvalidateUsageCache(
400 const GURL& origin, 308 const GURL& origin,
401 fileapi::FileSystemType type) { 309 fileapi::FileSystemType type) {
402 DCHECK(CanHandleType(type)); 310 DCHECK(CanHandleType(type));
403 base::PlatformFileError error = base::PLATFORM_FILE_OK; 311 DCHECK(sandbox_context_);
404 base::FilePath usage_file_path = GetUsageCachePathForOriginAndType( 312 sandbox_context_->InvalidateUsageCache(origin, type);
405 sandbox_sync_file_util(), origin, type, &error);
406 if (error != base::PLATFORM_FILE_OK)
407 return;
408 usage_cache()->IncrementDirty(usage_file_path);
409 } 313 }
410 314
411 void SandboxFileSystemBackend::StickyInvalidateUsageCache( 315 void SandboxFileSystemBackend::StickyInvalidateUsageCache(
412 const GURL& origin, 316 const GURL& origin,
413 fileapi::FileSystemType type) { 317 fileapi::FileSystemType type) {
414 DCHECK(CanHandleType(type)); 318 DCHECK(CanHandleType(type));
415 sticky_dirty_origins_.insert(std::make_pair(origin, type)); 319 DCHECK(sandbox_context_);
416 sandbox_context_->quota_observer()->SetUsageCacheEnabled(origin, type, false); 320 sandbox_context_->StickyInvalidateUsageCache(origin, type);
417 InvalidateUsageCache(origin, type);
418 } 321 }
419 322
420 void SandboxFileSystemBackend::AddFileUpdateObserver( 323 void SandboxFileSystemBackend::AddFileUpdateObserver(
421 FileSystemType type, 324 FileSystemType type,
422 FileUpdateObserver* observer, 325 FileUpdateObserver* observer,
423 base::SequencedTaskRunner* task_runner) { 326 base::SequencedTaskRunner* task_runner) {
424 DCHECK(CanHandleType(type)); 327 DCHECK(CanHandleType(type));
425 UpdateObserverList* list = &update_observers_; 328 UpdateObserverList* list = &update_observers_;
426 if (type == kFileSystemTypeSyncable) 329 if (type == kFileSystemTypeSyncable)
427 list = &syncable_update_observers_; 330 list = &syncable_update_observers_;
(...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after
499 REPORT(kNotFound); 402 REPORT(kNotFound);
500 break; 403 break;
501 case base::PLATFORM_FILE_ERROR_FAILED: 404 case base::PLATFORM_FILE_ERROR_FAILED:
502 default: 405 default:
503 REPORT(kUnknownError); 406 REPORT(kUnknownError);
504 break; 407 break;
505 } 408 }
506 #undef REPORT 409 #undef REPORT
507 } 410 }
508 411
509 bool SandboxFileSystemBackend::IsAccessValid(
510 const FileSystemURL& url) const {
511 if (!IsAllowedScheme(url.origin()))
512 return false;
513
514 if (!CanHandleType(url.type()))
515 return false;
516
517 if (url.path().ReferencesParent())
518 return false;
519
520 // Return earlier if the path is '/', because VirtualPath::BaseName()
521 // returns '/' for '/' and we fail the "basename != '/'" check below.
522 // (We exclude '.' because it's disallowed by spec.)
523 if (VirtualPath::IsRootPath(url.path()) &&
524 url.path() != base::FilePath(base::FilePath::kCurrentDirectory))
525 return true;
526
527 // Restricted names specified in
528 // http://dev.w3.org/2009/dap/file-system/file-dir-sys.html#naming-restriction s
529 base::FilePath filename = VirtualPath::BaseName(url.path());
530 // See if the name is allowed to create.
531 for (size_t i = 0; i < arraysize(kRestrictedNames); ++i) {
532 if (filename.value() == kRestrictedNames[i])
533 return false;
534 }
535 for (size_t i = 0; i < arraysize(kRestrictedChars); ++i) {
536 if (filename.value().find(kRestrictedChars[i]) !=
537 base::FilePath::StringType::npos)
538 return false;
539 }
540
541 return true;
542 }
543
544 base::FilePath SandboxFileSystemBackend::GetUsageCachePathForOriginAndType(
545 const GURL& origin_url,
546 FileSystemType type) {
547 base::PlatformFileError error;
548 base::FilePath path = GetUsageCachePathForOriginAndType(
549 sandbox_sync_file_util(), origin_url, type, &error);
550 if (error != base::PLATFORM_FILE_OK)
551 return base::FilePath();
552 return path;
553 }
554
555 // static
556 base::FilePath SandboxFileSystemBackend::GetUsageCachePathForOriginAndType(
557 ObfuscatedFileUtil* sandbox_file_util,
558 const GURL& origin_url,
559 fileapi::FileSystemType type,
560 base::PlatformFileError* error_out) {
561 DCHECK(error_out);
562 *error_out = base::PLATFORM_FILE_OK;
563 base::FilePath base_path = sandbox_file_util->GetDirectoryForOriginAndType(
564 origin_url, type, false /* create */, error_out);
565 if (*error_out != base::PLATFORM_FILE_OK)
566 return base::FilePath();
567 return base_path.Append(FileSystemUsageCache::kUsageFileName);
568 }
569
570 bool SandboxFileSystemBackend::IsAllowedScheme(const GURL& url) const {
571 // Basically we only accept http or https. We allow file:// URLs
572 // only if --allow-file-access-from-files flag is given.
573 if (url.SchemeIs("http") || url.SchemeIs("https"))
574 return true;
575 if (url.SchemeIsFileSystem())
576 return url.inner_url() && IsAllowedScheme(*url.inner_url());
577
578 for (size_t i = 0;
579 i < file_system_options_.additional_allowed_schemes().size();
580 ++i) {
581 if (url.SchemeIs(
582 file_system_options_.additional_allowed_schemes()[i].c_str()))
583 return true;
584 }
585 return false;
586 }
587
588 ObfuscatedFileUtil* SandboxFileSystemBackend::sandbox_sync_file_util() {
589 DCHECK(sandbox_context_);
590 return sandbox_context_->sync_file_util();
591 }
592
593 FileSystemUsageCache* SandboxFileSystemBackend::usage_cache() {
594 DCHECK(sandbox_context_);
595 return sandbox_context_->usage_cache();
596 }
597
598 int64 SandboxFileSystemBackend::RecalculateUsage(FileSystemContext* context,
599 const GURL& origin,
600 FileSystemType type) {
601 FileSystemOperationContext operation_context(context);
602 FileSystemURL url = context->CreateCrackedFileSystemURL(
603 origin, type, base::FilePath());
604 scoped_ptr<FileSystemFileUtil::AbstractFileEnumerator> enumerator(
605 sandbox_sync_file_util()->CreateFileEnumerator(
606 &operation_context, url, true));
607
608 base::FilePath file_path_each;
609 int64 usage = 0;
610
611 while (!(file_path_each = enumerator->Next()).empty()) {
612 usage += enumerator->Size();
613 usage += ObfuscatedFileUtil::ComputeFilePathCost(file_path_each);
614 }
615
616 return usage;
617 }
618
619 } // namespace fileapi 412 } // namespace fileapi
OLDNEW
« no previous file with comments | « webkit/browser/fileapi/sandbox_file_system_backend.h ('k') | webkit/browser/fileapi/sandbox_file_system_backend_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698