| OLD | NEW |
| 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" | 10 #include "base/memory/scoped_ptr.h" |
| (...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 51 kInvalidSchemeError, | 51 kInvalidSchemeError, |
| 52 kCreateDirectoryError, | 52 kCreateDirectoryError, |
| 53 kNotFound, | 53 kNotFound, |
| 54 kUnknownError, | 54 kUnknownError, |
| 55 kFileSystemErrorMax, | 55 kFileSystemErrorMax, |
| 56 }; | 56 }; |
| 57 | 57 |
| 58 const char kTemporaryOriginsCountLabel[] = "FileSystem.TemporaryOriginsCount"; | 58 const char kTemporaryOriginsCountLabel[] = "FileSystem.TemporaryOriginsCount"; |
| 59 const char kPersistentOriginsCountLabel[] = "FileSystem.PersistentOriginsCount"; | 59 const char kPersistentOriginsCountLabel[] = "FileSystem.PersistentOriginsCount"; |
| 60 | 60 |
| 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( | 61 void DidOpenFileSystem( |
| 93 base::WeakPtr<SandboxFileSystemBackend> sandbox_backend, | 62 base::WeakPtr<SandboxFileSystemBackend> sandbox_backend, |
| 94 const base::Callback<void(base::PlatformFileError error)>& callback, | 63 const base::Callback<void(base::PlatformFileError error)>& callback, |
| 95 base::PlatformFileError* error) { | 64 base::PlatformFileError* error) { |
| 96 if (sandbox_backend.get()) | 65 if (sandbox_backend.get()) |
| 97 sandbox_backend.get()->CollectOpenFileSystemMetrics(*error); | 66 sandbox_backend.get()->CollectOpenFileSystemMetrics(*error); |
| 98 callback.Run(*error); | 67 callback.Run(*error); |
| 99 } | 68 } |
| 100 | 69 |
| 101 void OpenFileSystemOnFileThread( | 70 void OpenFileSystemOnFileThread( |
| (...skipping 13 matching lines...) Expand all Loading... |
| 115 UMA_HISTOGRAM_ENUMERATION(kOpenFileSystemLabel, kOK, kFileSystemErrorMax); | 84 UMA_HISTOGRAM_ENUMERATION(kOpenFileSystemLabel, kOK, kFileSystemErrorMax); |
| 116 } | 85 } |
| 117 // The reference of file_util will be derefed on the FILE thread | 86 // The reference of file_util will be derefed on the FILE thread |
| 118 // when the storage of this callback gets deleted regardless of whether | 87 // when the storage of this callback gets deleted regardless of whether |
| 119 // this method is called or not. | 88 // this method is called or not. |
| 120 } | 89 } |
| 121 | 90 |
| 122 } // anonymous namespace | 91 } // anonymous namespace |
| 123 | 92 |
| 124 SandboxFileSystemBackend::SandboxFileSystemBackend( | 93 SandboxFileSystemBackend::SandboxFileSystemBackend( |
| 125 SandboxContext* sandbox_context, | 94 SandboxContext* sandbox_context) |
| 126 const FileSystemOptions& file_system_options) | 95 : sandbox_context_(sandbox_context), |
| 127 : file_system_options_(file_system_options), | |
| 128 sandbox_context_(sandbox_context), | |
| 129 enable_temporary_file_system_in_incognito_(false), | 96 enable_temporary_file_system_in_incognito_(false), |
| 130 weak_factory_(this) { | 97 weak_factory_(this) { |
| 131 } | 98 } |
| 132 | 99 |
| 133 SandboxFileSystemBackend::~SandboxFileSystemBackend() { | 100 SandboxFileSystemBackend::~SandboxFileSystemBackend() { |
| 134 } | 101 } |
| 135 | 102 |
| 136 bool SandboxFileSystemBackend::CanHandleType(FileSystemType type) const { | 103 bool SandboxFileSystemBackend::CanHandleType(FileSystemType type) const { |
| 137 return type == kFileSystemTypeTemporary || | 104 return type == kFileSystemTypeTemporary || |
| 138 type == kFileSystemTypePersistent || | 105 type == kFileSystemTypePersistent || |
| 139 type == kFileSystemTypeSyncable || | 106 type == kFileSystemTypeSyncable || |
| 140 type == kFileSystemTypeSyncableForInternalSync; | 107 type == kFileSystemTypeSyncableForInternalSync; |
| 141 } | 108 } |
| 142 | 109 |
| 143 void SandboxFileSystemBackend::Initialize(FileSystemContext* context) { | 110 void SandboxFileSystemBackend::Initialize(FileSystemContext* context) { |
| 144 // Set quota observers. | 111 // Set quota observers. |
| 145 if (sandbox_context_->is_usage_tracking_enabled()) { | 112 update_observers_ = update_observers_.AddObserver( |
| 146 update_observers_ = update_observers_.AddObserver( | 113 sandbox_context_->quota_observer(), |
| 147 sandbox_context_->quota_observer(), | 114 sandbox_context_->file_task_runner()); |
| 148 sandbox_context_->file_task_runner()); | 115 access_observers_ = access_observers_.AddObserver( |
| 149 access_observers_ = access_observers_.AddObserver( | 116 sandbox_context_->quota_observer(), NULL); |
| 150 sandbox_context_->quota_observer(), NULL); | |
| 151 } | |
| 152 | 117 |
| 153 syncable_update_observers_ = update_observers_; | 118 syncable_update_observers_ = update_observers_; |
| 154 | 119 |
| 155 if (!sandbox_context_->file_task_runner()->RunsTasksOnCurrentThread()) { | 120 if (!sandbox_context_->file_task_runner()->RunsTasksOnCurrentThread()) { |
| 156 // Post prepopulate task only if it's not already running on | 121 // Post prepopulate task only if it's not already running on |
| 157 // file_task_runner (which implies running in tests). | 122 // file_task_runner (which implies running in tests). |
| 158 sandbox_context_->file_task_runner()->PostTask( | 123 sandbox_context_->file_task_runner()->PostTask( |
| 159 FROM_HERE, | 124 FROM_HERE, |
| 160 base::Bind(&ObfuscatedFileUtil::MaybePrepopulateDatabase, | 125 base::Bind(&ObfuscatedFileUtil::MaybePrepopulateDatabase, |
| 161 base::Unretained(sandbox_sync_file_util()))); | 126 base::Unretained(sandbox_context_->sync_file_util()))); |
| 162 } | 127 } |
| 163 } | 128 } |
| 164 | 129 |
| 165 void SandboxFileSystemBackend::OpenFileSystem( | 130 void SandboxFileSystemBackend::OpenFileSystem( |
| 166 const GURL& origin_url, | 131 const GURL& origin_url, |
| 167 fileapi::FileSystemType type, | 132 fileapi::FileSystemType type, |
| 168 OpenFileSystemMode mode, | 133 OpenFileSystemMode mode, |
| 169 const OpenFileSystemCallback& callback) { | 134 const OpenFileSystemCallback& callback) { |
| 170 if (file_system_options_.is_incognito() && | 135 DCHECK(sandbox_context_); |
| 136 if (sandbox_context_->file_system_options().is_incognito() && |
| 171 !(type == kFileSystemTypeTemporary && | 137 !(type == kFileSystemTypeTemporary && |
| 172 enable_temporary_file_system_in_incognito_)) { | 138 enable_temporary_file_system_in_incognito_)) { |
| 173 // TODO(kinuko): return an isolated temporary directory. | 139 // TODO(kinuko): return an isolated temporary directory. |
| 174 callback.Run(GURL(), std::string(), base::PLATFORM_FILE_ERROR_SECURITY); | 140 callback.Run(GURL(), std::string(), base::PLATFORM_FILE_ERROR_SECURITY); |
| 175 return; | 141 return; |
| 176 } | 142 } |
| 177 | 143 |
| 178 if (!IsAllowedScheme(origin_url)) { | 144 if (!sandbox_context_->IsAllowedScheme(origin_url)) { |
| 179 callback.Run(GURL(), std::string(), base::PLATFORM_FILE_ERROR_SECURITY); | 145 callback.Run(GURL(), std::string(), base::PLATFORM_FILE_ERROR_SECURITY); |
| 180 return; | 146 return; |
| 181 } | 147 } |
| 182 | 148 |
| 183 // TODO(nhiroki): Factor out SyncFS related code to SyncFileSystemBackend we | 149 // TODO(nhiroki): Factor out SyncFS related code to SyncFileSystemBackend we |
| 184 // plan to introduce. (http://crbug.com/242422/) | 150 // plan to introduce. (http://crbug.com/242422/) |
| 185 GURL root_url = (type == kFileSystemTypeSyncable) | 151 GURL root_url = (type == kFileSystemTypeSyncable) |
| 186 ? sync_file_system::GetSyncableFileSystemRootURI(origin_url) | 152 ? sync_file_system::GetSyncableFileSystemRootURI(origin_url) |
| 187 : GetFileSystemRootURI(origin_url, type); | 153 : GetFileSystemRootURI(origin_url, type); |
| 188 std::string name = GetFileSystemName(origin_url, type); | 154 std::string name = GetFileSystemName(origin_url, type); |
| 189 | 155 |
| 190 base::PlatformFileError* error_ptr = new base::PlatformFileError; | 156 base::PlatformFileError* error_ptr = new base::PlatformFileError; |
| 191 sandbox_context_->file_task_runner()->PostTaskAndReply( | 157 sandbox_context_->file_task_runner()->PostTaskAndReply( |
| 192 FROM_HERE, | 158 FROM_HERE, |
| 193 base::Bind(&OpenFileSystemOnFileThread, | 159 base::Bind(&OpenFileSystemOnFileThread, |
| 194 sandbox_sync_file_util(), | 160 sandbox_context_->sync_file_util(), |
| 195 origin_url, type, mode, | 161 origin_url, type, mode, |
| 196 base::Unretained(error_ptr)), | 162 base::Unretained(error_ptr)), |
| 197 base::Bind(&DidOpenFileSystem, | 163 base::Bind(&DidOpenFileSystem, |
| 198 weak_factory_.GetWeakPtr(), | 164 weak_factory_.GetWeakPtr(), |
| 199 base::Bind(callback, root_url, name), | 165 base::Bind(callback, root_url, name), |
| 200 base::Owned(error_ptr))); | 166 base::Owned(error_ptr))); |
| 201 | |
| 202 if (sandbox_context_->is_usage_tracking_enabled()) | |
| 203 return; | |
| 204 | |
| 205 // Schedule full usage recalculation on the next launch without | |
| 206 // --disable-file-system-usage-tracking. | |
| 207 sandbox_context_->file_task_runner()->PostTask( | |
| 208 FROM_HERE, | |
| 209 base::Bind(&SandboxFileSystemBackend::InvalidateUsageCacheOnFileThread, | |
| 210 sandbox_sync_file_util(), origin_url, type, usage_cache())); | |
| 211 }; | 167 }; |
| 212 | 168 |
| 213 FileSystemFileUtil* SandboxFileSystemBackend::GetFileUtil( | 169 FileSystemFileUtil* SandboxFileSystemBackend::GetFileUtil( |
| 214 FileSystemType type) { | 170 FileSystemType type) { |
| 215 DCHECK(sandbox_context_); | |
| 216 return sandbox_context_->sync_file_util(); | 171 return sandbox_context_->sync_file_util(); |
| 217 } | 172 } |
| 218 | 173 |
| 219 AsyncFileUtil* SandboxFileSystemBackend::GetAsyncFileUtil( | 174 AsyncFileUtil* SandboxFileSystemBackend::GetAsyncFileUtil( |
| 220 FileSystemType type) { | 175 FileSystemType type) { |
| 221 DCHECK(sandbox_context_); | 176 DCHECK(sandbox_context_); |
| 222 return sandbox_context_->file_util(); | 177 return sandbox_context_->file_util(); |
| 223 } | 178 } |
| 224 | 179 |
| 225 CopyOrMoveFileValidatorFactory* | 180 CopyOrMoveFileValidatorFactory* |
| 226 SandboxFileSystemBackend::GetCopyOrMoveFileValidatorFactory( | 181 SandboxFileSystemBackend::GetCopyOrMoveFileValidatorFactory( |
| 227 FileSystemType type, | 182 FileSystemType type, |
| 228 base::PlatformFileError* error_code) { | 183 base::PlatformFileError* error_code) { |
| 229 DCHECK(error_code); | 184 DCHECK(error_code); |
| 230 *error_code = base::PLATFORM_FILE_OK; | 185 *error_code = base::PLATFORM_FILE_OK; |
| 231 return NULL; | 186 return NULL; |
| 232 } | 187 } |
| 233 | 188 |
| 234 FileSystemOperation* SandboxFileSystemBackend::CreateFileSystemOperation( | 189 FileSystemOperation* SandboxFileSystemBackend::CreateFileSystemOperation( |
| 235 const FileSystemURL& url, | 190 const FileSystemURL& url, |
| 236 FileSystemContext* context, | 191 FileSystemContext* context, |
| 237 base::PlatformFileError* error_code) const { | 192 base::PlatformFileError* error_code) const { |
| 238 if (!IsAccessValid(url)) { | 193 DCHECK(CanHandleType(url.type())); |
| 194 DCHECK(sandbox_context_); |
| 195 if (!sandbox_context_->IsAccessValid(url)) { |
| 239 *error_code = base::PLATFORM_FILE_ERROR_SECURITY; | 196 *error_code = base::PLATFORM_FILE_ERROR_SECURITY; |
| 240 return NULL; | 197 return NULL; |
| 241 } | 198 } |
| 242 | 199 |
| 243 scoped_ptr<FileSystemOperationContext> operation_context( | 200 scoped_ptr<FileSystemOperationContext> operation_context( |
| 244 new FileSystemOperationContext(context)); | 201 new FileSystemOperationContext(context)); |
| 245 | 202 |
| 246 // Copy the observer lists (assuming we only have small number of observers). | 203 // Copy the observer lists (assuming we only have small number of observers). |
| 247 if (url.type() == kFileSystemTypeSyncable) { | 204 if (url.type() == kFileSystemTypeSyncable) { |
| 248 operation_context->set_update_observers(syncable_update_observers_); | 205 operation_context->set_update_observers(syncable_update_observers_); |
| (...skipping 14 matching lines...) Expand all Loading... |
| 263 | 220 |
| 264 return new LocalFileSystemOperation(url, context, operation_context.Pass()); | 221 return new LocalFileSystemOperation(url, context, operation_context.Pass()); |
| 265 } | 222 } |
| 266 | 223 |
| 267 scoped_ptr<webkit_blob::FileStreamReader> | 224 scoped_ptr<webkit_blob::FileStreamReader> |
| 268 SandboxFileSystemBackend::CreateFileStreamReader( | 225 SandboxFileSystemBackend::CreateFileStreamReader( |
| 269 const FileSystemURL& url, | 226 const FileSystemURL& url, |
| 270 int64 offset, | 227 int64 offset, |
| 271 const base::Time& expected_modification_time, | 228 const base::Time& expected_modification_time, |
| 272 FileSystemContext* context) const { | 229 FileSystemContext* context) const { |
| 273 if (!IsAccessValid(url)) | 230 DCHECK(CanHandleType(url.type())); |
| 231 DCHECK(sandbox_context_); |
| 232 if (!sandbox_context_->IsAccessValid(url)) |
| 274 return scoped_ptr<webkit_blob::FileStreamReader>(); | 233 return scoped_ptr<webkit_blob::FileStreamReader>(); |
| 275 return scoped_ptr<webkit_blob::FileStreamReader>( | 234 return scoped_ptr<webkit_blob::FileStreamReader>( |
| 276 new FileSystemFileStreamReader( | 235 new FileSystemFileStreamReader( |
| 277 context, url, offset, expected_modification_time)); | 236 context, url, offset, expected_modification_time)); |
| 278 } | 237 } |
| 279 | 238 |
| 280 scoped_ptr<fileapi::FileStreamWriter> | 239 scoped_ptr<fileapi::FileStreamWriter> |
| 281 SandboxFileSystemBackend::CreateFileStreamWriter( | 240 SandboxFileSystemBackend::CreateFileStreamWriter( |
| 282 const FileSystemURL& url, | 241 const FileSystemURL& url, |
| 283 int64 offset, | 242 int64 offset, |
| 284 FileSystemContext* context) const { | 243 FileSystemContext* context) const { |
| 285 if (!IsAccessValid(url)) | 244 DCHECK(CanHandleType(url.type())); |
| 245 DCHECK(sandbox_context_); |
| 246 if (!sandbox_context_->IsAccessValid(url)) |
| 286 return scoped_ptr<fileapi::FileStreamWriter>(); | 247 return scoped_ptr<fileapi::FileStreamWriter>(); |
| 287 return scoped_ptr<fileapi::FileStreamWriter>( | 248 return scoped_ptr<fileapi::FileStreamWriter>( |
| 288 new SandboxFileStreamWriter(context, url, offset, update_observers_)); | 249 new SandboxFileStreamWriter(context, url, offset, update_observers_)); |
| 289 } | 250 } |
| 290 | 251 |
| 291 FileSystemQuotaUtil* SandboxFileSystemBackend::GetQuotaUtil() { | 252 FileSystemQuotaUtil* SandboxFileSystemBackend::GetQuotaUtil() { |
| 292 return this; | 253 return this; |
| 293 } | 254 } |
| 294 | 255 |
| 295 SandboxFileSystemBackend::OriginEnumerator* | 256 SandboxContext::OriginEnumerator* |
| 296 SandboxFileSystemBackend::CreateOriginEnumerator() { | 257 SandboxFileSystemBackend::CreateOriginEnumerator() { |
| 297 return new ObfuscatedOriginEnumerator(sandbox_sync_file_util()); | 258 DCHECK(sandbox_context_); |
| 298 } | 259 return sandbox_context_->CreateOriginEnumerator(); |
| 299 | |
| 300 base::FilePath SandboxFileSystemBackend::GetBaseDirectoryForOriginAndType( | |
| 301 const GURL& origin_url, fileapi::FileSystemType type, bool create) { | |
| 302 base::PlatformFileError error = base::PLATFORM_FILE_OK; | |
| 303 base::FilePath path = sandbox_sync_file_util()->GetDirectoryForOriginAndType( | |
| 304 origin_url, type, create, &error); | |
| 305 if (error != base::PLATFORM_FILE_OK) | |
| 306 return base::FilePath(); | |
| 307 return path; | |
| 308 } | 260 } |
| 309 | 261 |
| 310 base::PlatformFileError | 262 base::PlatformFileError |
| 311 SandboxFileSystemBackend::DeleteOriginDataOnFileThread( | 263 SandboxFileSystemBackend::DeleteOriginDataOnFileThread( |
| 312 FileSystemContext* file_system_context, | 264 FileSystemContext* file_system_context, |
| 313 QuotaManagerProxy* proxy, | 265 QuotaManagerProxy* proxy, |
| 314 const GURL& origin_url, | 266 const GURL& origin_url, |
| 315 fileapi::FileSystemType type) { | 267 fileapi::FileSystemType type) { |
| 316 int64 usage = GetOriginUsageOnFileThread(file_system_context, | 268 DCHECK(CanHandleType(type)); |
| 317 origin_url, type); | 269 DCHECK(sandbox_context_); |
| 318 | 270 return sandbox_context_->DeleteOriginDataOnFileThreadImpl( |
| 319 usage_cache()->CloseCacheFiles(); | 271 file_system_context, proxy, origin_url, type); |
| 320 bool result = sandbox_sync_file_util()->DeleteDirectoryForOriginAndType( | |
| 321 origin_url, type); | |
| 322 if (result && proxy) { | |
| 323 proxy->NotifyStorageModified( | |
| 324 quota::QuotaClient::kFileSystem, | |
| 325 origin_url, | |
| 326 FileSystemTypeToQuotaStorageType(type), | |
| 327 -usage); | |
| 328 } | |
| 329 | |
| 330 if (result) | |
| 331 return base::PLATFORM_FILE_OK; | |
| 332 return base::PLATFORM_FILE_ERROR_FAILED; | |
| 333 } | 272 } |
| 334 | 273 |
| 335 void SandboxFileSystemBackend::GetOriginsForTypeOnFileThread( | 274 void SandboxFileSystemBackend::GetOriginsForTypeOnFileThread( |
| 336 fileapi::FileSystemType type, std::set<GURL>* origins) { | 275 fileapi::FileSystemType type, std::set<GURL>* origins) { |
| 337 DCHECK(CanHandleType(type)); | 276 DCHECK(CanHandleType(type)); |
| 338 DCHECK(origins); | 277 DCHECK(sandbox_context_); |
| 339 scoped_ptr<OriginEnumerator> enumerator(CreateOriginEnumerator()); | 278 sandbox_context_->GetOriginsForTypeOnFileThreadImpl(type, origins); |
| 340 GURL origin; | |
| 341 while (!(origin = enumerator->Next()).is_empty()) { | |
| 342 if (enumerator->HasFileSystemType(type)) | |
| 343 origins->insert(origin); | |
| 344 } | |
| 345 switch (type) { | 279 switch (type) { |
| 346 case kFileSystemTypeTemporary: | 280 case kFileSystemTypeTemporary: |
| 347 UMA_HISTOGRAM_COUNTS(kTemporaryOriginsCountLabel, origins->size()); | 281 UMA_HISTOGRAM_COUNTS(kTemporaryOriginsCountLabel, origins->size()); |
| 348 break; | 282 break; |
| 349 case kFileSystemTypePersistent: | 283 case kFileSystemTypePersistent: |
| 350 UMA_HISTOGRAM_COUNTS(kPersistentOriginsCountLabel, origins->size()); | 284 UMA_HISTOGRAM_COUNTS(kPersistentOriginsCountLabel, origins->size()); |
| 351 break; | 285 break; |
| 352 default: | 286 default: |
| 353 break; | 287 break; |
| 354 } | 288 } |
| 355 } | 289 } |
| 356 | 290 |
| 357 void SandboxFileSystemBackend::GetOriginsForHostOnFileThread( | 291 void SandboxFileSystemBackend::GetOriginsForHostOnFileThread( |
| 358 fileapi::FileSystemType type, const std::string& host, | 292 fileapi::FileSystemType type, const std::string& host, |
| 359 std::set<GURL>* origins) { | 293 std::set<GURL>* origins) { |
| 360 DCHECK(CanHandleType(type)); | 294 DCHECK(CanHandleType(type)); |
| 361 DCHECK(origins); | 295 DCHECK(sandbox_context_); |
| 362 scoped_ptr<OriginEnumerator> enumerator(CreateOriginEnumerator()); | 296 sandbox_context_->GetOriginsForHostOnFileThreadImpl(type, host, origins); |
| 363 GURL origin; | |
| 364 while (!(origin = enumerator->Next()).is_empty()) { | |
| 365 if (host == net::GetHostOrSpecFromURL(origin) && | |
| 366 enumerator->HasFileSystemType(type)) | |
| 367 origins->insert(origin); | |
| 368 } | |
| 369 } | 297 } |
| 370 | 298 |
| 371 int64 SandboxFileSystemBackend::GetOriginUsageOnFileThread( | 299 int64 SandboxFileSystemBackend::GetOriginUsageOnFileThread( |
| 372 FileSystemContext* file_system_context, | 300 FileSystemContext* file_system_context, |
| 373 const GURL& origin_url, | 301 const GURL& origin_url, |
| 374 fileapi::FileSystemType type) { | 302 fileapi::FileSystemType type) { |
| 375 DCHECK(CanHandleType(type)); | 303 DCHECK(CanHandleType(type)); |
| 376 if (!sandbox_context_->is_usage_tracking_enabled()) | 304 DCHECK(sandbox_context_); |
| 377 return 0; | 305 return sandbox_context_->GetOriginUsageOnFileThreadImpl( |
| 378 | 306 file_system_context, origin_url, type); |
| 379 // Don't use usage cache and return recalculated usage for sticky invalidated | |
| 380 // origins. | |
| 381 if (ContainsKey(sticky_dirty_origins_, std::make_pair(origin_url, type))) | |
| 382 return RecalculateUsage(file_system_context, origin_url, type); | |
| 383 | |
| 384 base::FilePath base_path = | |
| 385 GetBaseDirectoryForOriginAndType(origin_url, type, false); | |
| 386 if (base_path.empty() || !base::DirectoryExists(base_path)) | |
| 387 return 0; | |
| 388 base::FilePath usage_file_path = | |
| 389 base_path.Append(FileSystemUsageCache::kUsageFileName); | |
| 390 | |
| 391 bool is_valid = usage_cache()->IsValid(usage_file_path); | |
| 392 uint32 dirty_status = 0; | |
| 393 bool dirty_status_available = | |
| 394 usage_cache()->GetDirty(usage_file_path, &dirty_status); | |
| 395 bool visited = !visited_origins_.insert(origin_url).second; | |
| 396 if (is_valid && (dirty_status == 0 || (dirty_status_available && visited))) { | |
| 397 // The usage cache is clean (dirty == 0) or the origin is already | |
| 398 // initialized and running. Read the cache file to get the usage. | |
| 399 int64 usage = 0; | |
| 400 return usage_cache()->GetUsage(usage_file_path, &usage) ? usage : -1; | |
| 401 } | |
| 402 // The usage cache has not been initialized or the cache is dirty. | |
| 403 // Get the directory size now and update the cache. | |
| 404 usage_cache()->Delete(usage_file_path); | |
| 405 | |
| 406 int64 usage = RecalculateUsage(file_system_context, origin_url, type); | |
| 407 | |
| 408 // This clears the dirty flag too. | |
| 409 usage_cache()->UpdateUsage(usage_file_path, usage); | |
| 410 return usage; | |
| 411 } | 307 } |
| 412 | 308 |
| 413 void SandboxFileSystemBackend::InvalidateUsageCache( | 309 void SandboxFileSystemBackend::InvalidateUsageCache( |
| 414 const GURL& origin, | 310 const GURL& origin, |
| 415 fileapi::FileSystemType type) { | 311 fileapi::FileSystemType type) { |
| 416 DCHECK(CanHandleType(type)); | 312 DCHECK(CanHandleType(type)); |
| 417 base::PlatformFileError error = base::PLATFORM_FILE_OK; | 313 DCHECK(sandbox_context_); |
| 418 base::FilePath usage_file_path = GetUsageCachePathForOriginAndType( | 314 sandbox_context_->InvalidateUsageCacheImpl(origin, type); |
| 419 sandbox_sync_file_util(), origin, type, &error); | |
| 420 if (error != base::PLATFORM_FILE_OK) | |
| 421 return; | |
| 422 usage_cache()->IncrementDirty(usage_file_path); | |
| 423 } | 315 } |
| 424 | 316 |
| 425 void SandboxFileSystemBackend::StickyInvalidateUsageCache( | 317 void SandboxFileSystemBackend::StickyInvalidateUsageCache( |
| 426 const GURL& origin, | 318 const GURL& origin, |
| 427 fileapi::FileSystemType type) { | 319 fileapi::FileSystemType type) { |
| 428 DCHECK(CanHandleType(type)); | 320 DCHECK(CanHandleType(type)); |
| 429 sticky_dirty_origins_.insert(std::make_pair(origin, type)); | 321 DCHECK(sandbox_context_); |
| 430 sandbox_context_->quota_observer()->SetUsageCacheEnabled(origin, type, false); | 322 sandbox_context_->StickyInvalidateUsageCacheImpl(origin, type); |
| 431 InvalidateUsageCache(origin, type); | |
| 432 } | 323 } |
| 433 | 324 |
| 434 void SandboxFileSystemBackend::AddFileUpdateObserver( | 325 void SandboxFileSystemBackend::AddFileUpdateObserver( |
| 435 FileSystemType type, | 326 FileSystemType type, |
| 436 FileUpdateObserver* observer, | 327 FileUpdateObserver* observer, |
| 437 base::SequencedTaskRunner* task_runner) { | 328 base::SequencedTaskRunner* task_runner) { |
| 438 DCHECK(CanHandleType(type)); | 329 DCHECK(CanHandleType(type)); |
| 439 UpdateObserverList* list = &update_observers_; | 330 UpdateObserverList* list = &update_observers_; |
| 440 if (type == kFileSystemTypeSyncable) | 331 if (type == kFileSystemTypeSyncable) |
| 441 list = &syncable_update_observers_; | 332 list = &syncable_update_observers_; |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 513 REPORT(kNotFound); | 404 REPORT(kNotFound); |
| 514 break; | 405 break; |
| 515 case base::PLATFORM_FILE_ERROR_FAILED: | 406 case base::PLATFORM_FILE_ERROR_FAILED: |
| 516 default: | 407 default: |
| 517 REPORT(kUnknownError); | 408 REPORT(kUnknownError); |
| 518 break; | 409 break; |
| 519 } | 410 } |
| 520 #undef REPORT | 411 #undef REPORT |
| 521 } | 412 } |
| 522 | 413 |
| 523 bool SandboxFileSystemBackend::IsAccessValid( | |
| 524 const FileSystemURL& url) const { | |
| 525 if (!IsAllowedScheme(url.origin())) | |
| 526 return false; | |
| 527 | |
| 528 if (!CanHandleType(url.type())) | |
| 529 return false; | |
| 530 | |
| 531 if (url.path().ReferencesParent()) | |
| 532 return false; | |
| 533 | |
| 534 // Return earlier if the path is '/', because VirtualPath::BaseName() | |
| 535 // returns '/' for '/' and we fail the "basename != '/'" check below. | |
| 536 // (We exclude '.' because it's disallowed by spec.) | |
| 537 if (VirtualPath::IsRootPath(url.path()) && | |
| 538 url.path() != base::FilePath(base::FilePath::kCurrentDirectory)) | |
| 539 return true; | |
| 540 | |
| 541 // Restricted names specified in | |
| 542 // http://dev.w3.org/2009/dap/file-system/file-dir-sys.html#naming-restriction
s | |
| 543 base::FilePath filename = VirtualPath::BaseName(url.path()); | |
| 544 // See if the name is allowed to create. | |
| 545 for (size_t i = 0; i < arraysize(kRestrictedNames); ++i) { | |
| 546 if (filename.value() == kRestrictedNames[i]) | |
| 547 return false; | |
| 548 } | |
| 549 for (size_t i = 0; i < arraysize(kRestrictedChars); ++i) { | |
| 550 if (filename.value().find(kRestrictedChars[i]) != | |
| 551 base::FilePath::StringType::npos) | |
| 552 return false; | |
| 553 } | |
| 554 | |
| 555 return true; | |
| 556 } | |
| 557 | |
| 558 base::FilePath SandboxFileSystemBackend::GetUsageCachePathForOriginAndType( | |
| 559 const GURL& origin_url, | |
| 560 FileSystemType type) { | |
| 561 base::PlatformFileError error; | |
| 562 base::FilePath path = GetUsageCachePathForOriginAndType( | |
| 563 sandbox_sync_file_util(), origin_url, type, &error); | |
| 564 if (error != base::PLATFORM_FILE_OK) | |
| 565 return base::FilePath(); | |
| 566 return path; | |
| 567 } | |
| 568 | |
| 569 // static | |
| 570 base::FilePath SandboxFileSystemBackend::GetUsageCachePathForOriginAndType( | |
| 571 ObfuscatedFileUtil* sandbox_file_util, | |
| 572 const GURL& origin_url, | |
| 573 fileapi::FileSystemType type, | |
| 574 base::PlatformFileError* error_out) { | |
| 575 DCHECK(error_out); | |
| 576 *error_out = base::PLATFORM_FILE_OK; | |
| 577 base::FilePath base_path = sandbox_file_util->GetDirectoryForOriginAndType( | |
| 578 origin_url, type, false /* create */, error_out); | |
| 579 if (*error_out != base::PLATFORM_FILE_OK) | |
| 580 return base::FilePath(); | |
| 581 return base_path.Append(FileSystemUsageCache::kUsageFileName); | |
| 582 } | |
| 583 | |
| 584 bool SandboxFileSystemBackend::IsAllowedScheme(const GURL& url) const { | |
| 585 // Basically we only accept http or https. We allow file:// URLs | |
| 586 // only if --allow-file-access-from-files flag is given. | |
| 587 if (url.SchemeIs("http") || url.SchemeIs("https")) | |
| 588 return true; | |
| 589 if (url.SchemeIsFileSystem()) | |
| 590 return url.inner_url() && IsAllowedScheme(*url.inner_url()); | |
| 591 | |
| 592 for (size_t i = 0; | |
| 593 i < file_system_options_.additional_allowed_schemes().size(); | |
| 594 ++i) { | |
| 595 if (url.SchemeIs( | |
| 596 file_system_options_.additional_allowed_schemes()[i].c_str())) | |
| 597 return true; | |
| 598 } | |
| 599 return false; | |
| 600 } | |
| 601 | |
| 602 ObfuscatedFileUtil* SandboxFileSystemBackend::sandbox_sync_file_util() { | |
| 603 DCHECK(sandbox_context_); | |
| 604 return sandbox_context_->sync_file_util(); | |
| 605 } | |
| 606 | |
| 607 FileSystemUsageCache* SandboxFileSystemBackend::usage_cache() { | |
| 608 DCHECK(sandbox_context_); | |
| 609 return sandbox_context_->usage_cache(); | |
| 610 } | |
| 611 | |
| 612 // static | |
| 613 void SandboxFileSystemBackend::InvalidateUsageCacheOnFileThread( | |
| 614 ObfuscatedFileUtil* file_util, | |
| 615 const GURL& origin, | |
| 616 FileSystemType type, | |
| 617 FileSystemUsageCache* usage_cache) { | |
| 618 base::PlatformFileError error = base::PLATFORM_FILE_OK; | |
| 619 base::FilePath usage_cache_path = GetUsageCachePathForOriginAndType( | |
| 620 file_util, origin, type, &error); | |
| 621 if (error == base::PLATFORM_FILE_OK) | |
| 622 usage_cache->IncrementDirty(usage_cache_path); | |
| 623 } | |
| 624 | |
| 625 int64 SandboxFileSystemBackend::RecalculateUsage(FileSystemContext* context, | |
| 626 const GURL& origin, | |
| 627 FileSystemType type) { | |
| 628 FileSystemOperationContext operation_context(context); | |
| 629 FileSystemURL url = context->CreateCrackedFileSystemURL( | |
| 630 origin, type, base::FilePath()); | |
| 631 scoped_ptr<FileSystemFileUtil::AbstractFileEnumerator> enumerator( | |
| 632 sandbox_sync_file_util()->CreateFileEnumerator( | |
| 633 &operation_context, url, true)); | |
| 634 | |
| 635 base::FilePath file_path_each; | |
| 636 int64 usage = 0; | |
| 637 | |
| 638 while (!(file_path_each = enumerator->Next()).empty()) { | |
| 639 usage += enumerator->Size(); | |
| 640 usage += ObfuscatedFileUtil::ComputeFilePathCost(file_path_each); | |
| 641 } | |
| 642 | |
| 643 return usage; | |
| 644 } | |
| 645 | |
| 646 } // namespace fileapi | 414 } // namespace fileapi |
| OLD | NEW |