| OLD | NEW |
| 1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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 "content/browser/cache_storage/cache_storage.h" | 5 #include "content/browser/cache_storage/cache_storage.h" |
| 6 | 6 |
| 7 #include <string> | 7 #include <string> |
| 8 | 8 |
| 9 #include "base/barrier_closure.h" | 9 #include "base/barrier_closure.h" |
| 10 #include "base/files/file_util.h" | 10 #include "base/files/file_util.h" |
| 11 #include "base/files/memory_mapped_file.h" | 11 #include "base/files/memory_mapped_file.h" |
| 12 #include "base/guid.h" |
| 12 #include "base/location.h" | 13 #include "base/location.h" |
| 13 #include "base/memory/ref_counted.h" | 14 #include "base/memory/ref_counted.h" |
| 14 #include "base/metrics/histogram_macros.h" | 15 #include "base/metrics/histogram_macros.h" |
| 15 #include "base/numerics/safe_conversions.h" | 16 #include "base/numerics/safe_conversions.h" |
| 16 #include "base/sha1.h" | 17 #include "base/sha1.h" |
| 17 #include "base/single_thread_task_runner.h" | 18 #include "base/single_thread_task_runner.h" |
| 18 #include "base/stl_util.h" | 19 #include "base/stl_util.h" |
| 19 #include "base/strings/string_number_conversions.h" | 20 #include "base/strings/string_number_conversions.h" |
| 20 #include "base/strings/string_util.h" | 21 #include "base/strings/string_util.h" |
| 21 #include "base/thread_task_runner_handle.h" | 22 #include "base/thread_task_runner_handle.h" |
| 22 #include "content/browser/cache_storage/cache_storage.pb.h" | 23 #include "content/browser/cache_storage/cache_storage.pb.h" |
| 23 #include "content/browser/cache_storage/cache_storage_cache.h" | 24 #include "content/browser/cache_storage/cache_storage_cache.h" |
| 24 #include "content/browser/cache_storage/cache_storage_scheduler.h" | 25 #include "content/browser/cache_storage/cache_storage_scheduler.h" |
| 25 #include "content/public/browser/browser_thread.h" | 26 #include "content/public/browser/browser_thread.h" |
| 26 #include "net/base/directory_lister.h" | 27 #include "net/base/directory_lister.h" |
| 27 #include "net/base/net_errors.h" | 28 #include "net/base/net_errors.h" |
| 28 #include "net/url_request/url_request_context_getter.h" | 29 #include "net/url_request/url_request_context_getter.h" |
| 29 #include "storage/browser/blob/blob_storage_context.h" | 30 #include "storage/browser/blob/blob_storage_context.h" |
| 30 #include "storage/browser/quota/quota_manager_proxy.h" | 31 #include "storage/browser/quota/quota_manager_proxy.h" |
| 31 | 32 |
| 32 namespace content { | 33 namespace content { |
| 33 | 34 |
| 34 namespace { | 35 namespace { |
| 35 | 36 |
| 37 std::string HexedHash(const std::string& value) { |
| 38 std::string value_hash = base::SHA1HashString(value); |
| 39 std::string valued_hexed_hash = base::ToLowerASCII( |
| 40 base::HexEncode(value_hash.c_str(), value_hash.length())); |
| 41 return valued_hexed_hash; |
| 42 } |
| 43 |
| 36 void CloseAllCachesDidCloseCache(const scoped_refptr<CacheStorageCache>& cache, | 44 void CloseAllCachesDidCloseCache(const scoped_refptr<CacheStorageCache>& cache, |
| 37 const base::Closure& barrier_closure) { | 45 const base::Closure& barrier_closure) { |
| 38 barrier_closure.Run(); | 46 barrier_closure.Run(); |
| 39 } | 47 } |
| 40 | 48 |
| 41 } // namespace | 49 } // namespace |
| 42 | 50 |
| 43 const char CacheStorage::kIndexFileName[] = "index.txt"; | 51 const char CacheStorage::kIndexFileName[] = "index.txt"; |
| 44 | 52 |
| 45 // Handles the loading and clean up of CacheStorageCache objects. The | 53 // Handles the loading and clean up of CacheStorageCache objects. |
| 46 // callback of every public method is guaranteed to be called. | |
| 47 class CacheStorage::CacheLoader { | 54 class CacheStorage::CacheLoader { |
| 48 public: | 55 public: |
| 49 typedef base::Callback<void(const scoped_refptr<CacheStorageCache>&)> | 56 typedef base::Callback<void(const scoped_refptr<CacheStorageCache>&)> |
| 50 CacheCallback; | 57 CacheCallback; |
| 51 typedef base::Callback<void(bool)> BoolCallback; | 58 typedef base::Callback<void(bool)> BoolCallback; |
| 52 typedef base::Callback<void(scoped_ptr<std::vector<std::string>>)> | 59 typedef base::Callback<void(scoped_ptr<std::vector<std::string>>)> |
| 53 StringVectorCallback; | 60 StringVectorCallback; |
| 54 | 61 |
| 55 CacheLoader( | 62 CacheLoader( |
| 56 base::SequencedTaskRunner* cache_task_runner, | 63 base::SequencedTaskRunner* cache_task_runner, |
| (...skipping 10 matching lines...) Expand all Loading... |
| 67 } | 74 } |
| 68 | 75 |
| 69 virtual ~CacheLoader() {} | 76 virtual ~CacheLoader() {} |
| 70 | 77 |
| 71 // Creates a CacheStorageCache with the given name. It does not attempt to | 78 // Creates a CacheStorageCache with the given name. It does not attempt to |
| 72 // load the backend, that happens lazily when the cache is used. | 79 // load the backend, that happens lazily when the cache is used. |
| 73 virtual scoped_refptr<CacheStorageCache> CreateCache( | 80 virtual scoped_refptr<CacheStorageCache> CreateCache( |
| 74 const std::string& cache_name) = 0; | 81 const std::string& cache_name) = 0; |
| 75 | 82 |
| 76 // Deletes any pre-existing cache of the same name and then loads it. | 83 // Deletes any pre-existing cache of the same name and then loads it. |
| 77 virtual void CreateCache(const std::string& cache_name, | 84 virtual void PrepareNewCacheDestination(const std::string& cache_name, |
| 78 const CacheCallback& callback) = 0; | 85 const CacheCallback& callback) = 0; |
| 79 | 86 |
| 80 // After the backend has been deleted, do any extra house keeping such as | 87 // After the backend has been deleted, do any extra house keeping such as |
| 81 // removing the cache's directory. | 88 // removing the cache's directory. |
| 82 virtual void CleanUpDeletedCache(const std::string& key, | 89 virtual void CleanUpDeletedCache(const std::string& key, |
| 83 const BoolCallback& callback) = 0; | 90 const BoolCallback& callback) = 0; |
| 84 | 91 |
| 85 // Writes the cache names (and sizes) to disk if applicable. | 92 // Writes the cache names (and sizes) to disk if applicable. |
| 86 virtual void WriteIndex(const StringVector& cache_names, | 93 virtual void WriteIndex(const StringVector& cache_names, |
| 87 const BoolCallback& callback) = 0; | 94 const BoolCallback& callback) = 0; |
| 88 | 95 |
| (...skipping 26 matching lines...) Expand all Loading... |
| 115 quota_manager_proxy, | 122 quota_manager_proxy, |
| 116 blob_context, | 123 blob_context, |
| 117 origin) {} | 124 origin) {} |
| 118 | 125 |
| 119 scoped_refptr<CacheStorageCache> CreateCache( | 126 scoped_refptr<CacheStorageCache> CreateCache( |
| 120 const std::string& cache_name) override { | 127 const std::string& cache_name) override { |
| 121 return CacheStorageCache::CreateMemoryCache( | 128 return CacheStorageCache::CreateMemoryCache( |
| 122 origin_, request_context_getter_, quota_manager_proxy_, blob_context_); | 129 origin_, request_context_getter_, quota_manager_proxy_, blob_context_); |
| 123 } | 130 } |
| 124 | 131 |
| 125 void CreateCache(const std::string& cache_name, | 132 void PrepareNewCacheDestination(const std::string& cache_name, |
| 126 const CacheCallback& callback) override { | 133 const CacheCallback& callback) override { |
| 127 scoped_refptr<CacheStorageCache> cache = CreateCache(cache_name); | 134 scoped_refptr<CacheStorageCache> cache = CreateCache(cache_name); |
| 128 cache_refs_.insert(std::make_pair(cache_name, cache)); | 135 cache_refs_.insert(std::make_pair(cache_name, cache)); |
| 129 callback.Run(cache); | 136 callback.Run(cache); |
| 130 } | 137 } |
| 131 | 138 |
| 132 void CleanUpDeletedCache(const std::string& cache_name, | 139 void CleanUpDeletedCache(const std::string& cache_name, |
| 133 const BoolCallback& callback) override { | 140 const BoolCallback& callback) override { |
| 134 CacheRefMap::iterator it = cache_refs_.find(cache_name); | 141 CacheRefMap::iterator it = cache_refs_.find(cache_name); |
| 135 DCHECK(it != cache_refs_.end()); | 142 DCHECK(it != cache_refs_.end()); |
| 136 cache_refs_.erase(it); | 143 cache_refs_.erase(it); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 170 request_context, | 177 request_context, |
| 171 quota_manager_proxy, | 178 quota_manager_proxy, |
| 172 blob_context, | 179 blob_context, |
| 173 origin), | 180 origin), |
| 174 origin_path_(origin_path), | 181 origin_path_(origin_path), |
| 175 weak_ptr_factory_(this) {} | 182 weak_ptr_factory_(this) {} |
| 176 | 183 |
| 177 scoped_refptr<CacheStorageCache> CreateCache( | 184 scoped_refptr<CacheStorageCache> CreateCache( |
| 178 const std::string& cache_name) override { | 185 const std::string& cache_name) override { |
| 179 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 186 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 187 DCHECK(ContainsKey(cache_name_to_cache_dir_, cache_name)); |
| 180 | 188 |
| 189 std::string cache_dir = cache_name_to_cache_dir_[cache_name]; |
| 190 base::FilePath cache_path = origin_path_.AppendASCII(cache_dir); |
| 181 return CacheStorageCache::CreatePersistentCache( | 191 return CacheStorageCache::CreatePersistentCache( |
| 182 origin_, CreatePersistentCachePath(origin_path_, cache_name), | 192 origin_, cache_path, request_context_getter_, quota_manager_proxy_, |
| 183 request_context_getter_, quota_manager_proxy_, blob_context_); | 193 blob_context_); |
| 184 } | 194 } |
| 185 | 195 |
| 186 void CreateCache(const std::string& cache_name, | 196 void PrepareNewCacheDestination(const std::string& cache_name, |
| 187 const CacheCallback& callback) override { | 197 const CacheCallback& callback) override { |
| 188 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 198 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 189 | 199 |
| 190 // 1. Delete the cache's directory if it exists. | |
| 191 // (CreateCacheDeleteFilesInPool) | |
| 192 // 2. Load the cache. (LoadCreateDirectoryInPool) | |
| 193 | |
| 194 base::FilePath cache_path = | |
| 195 CreatePersistentCachePath(origin_path_, cache_name); | |
| 196 | |
| 197 PostTaskAndReplyWithResult( | 200 PostTaskAndReplyWithResult( |
| 198 cache_task_runner_.get(), FROM_HERE, | 201 cache_task_runner_.get(), FROM_HERE, |
| 199 base::Bind(&SimpleCacheLoader::CreateCachePrepDirInPool, cache_path), | 202 base::Bind(&SimpleCacheLoader::PrepareNewCacheDirectoryInPool, |
| 200 base::Bind(&SimpleCacheLoader::CreateCachePreppedDir, cache_name, | 203 origin_path_), |
| 201 callback, weak_ptr_factory_.GetWeakPtr())); | 204 base::Bind(&SimpleCacheLoader::PrepareNewCacheCreateCache, |
| 205 weak_ptr_factory_.GetWeakPtr(), cache_name, callback)); |
| 202 } | 206 } |
| 203 | 207 |
| 204 static bool CreateCachePrepDirInPool(const base::FilePath& cache_path) { | 208 // Runs on the cache_task_runner_. |
| 205 if (base::PathExists(cache_path)) | 209 static std::string PrepareNewCacheDirectoryInPool( |
| 206 base::DeleteFile(cache_path, /* recursive */ true); | 210 const base::FilePath& origin_path) { |
| 207 return base::CreateDirectory(cache_path); | 211 std::string cache_dir; |
| 212 base::FilePath cache_path; |
| 213 do { |
| 214 cache_dir = base::GenerateGUID(); |
| 215 cache_path = origin_path.AppendASCII(cache_dir); |
| 216 } while (base::PathExists(cache_path)); |
| 217 |
| 218 return base::CreateDirectory(cache_path) ? cache_dir : ""; |
| 208 } | 219 } |
| 209 | 220 |
| 210 static void CreateCachePreppedDir(const std::string& cache_name, | 221 void PrepareNewCacheCreateCache(const std::string& cache_name, |
| 211 const CacheCallback& callback, | 222 const CacheCallback& callback, |
| 212 base::WeakPtr<SimpleCacheLoader> loader, | 223 const std::string& cache_dir) { |
| 213 bool success) { | 224 if (cache_dir.empty()) { |
| 214 if (!success || !loader) { | |
| 215 callback.Run(scoped_refptr<CacheStorageCache>()); | 225 callback.Run(scoped_refptr<CacheStorageCache>()); |
| 216 return; | 226 return; |
| 217 } | 227 } |
| 218 | 228 |
| 219 callback.Run(loader->CreateCache(cache_name)); | 229 cache_name_to_cache_dir_[cache_name] = cache_dir; |
| 230 callback.Run(CreateCache(cache_name)); |
| 220 } | 231 } |
| 221 | 232 |
| 222 void CleanUpDeletedCache(const std::string& cache_name, | 233 void CleanUpDeletedCache(const std::string& cache_name, |
| 223 const BoolCallback& callback) override { | 234 const BoolCallback& callback) override { |
| 224 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 235 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 225 | 236 DCHECK(ContainsKey(cache_name_to_cache_dir_, cache_name)); |
| 226 // 1. Delete the cache's directory. (CleanUpDeleteCacheDirInPool) | |
| 227 | 237 |
| 228 base::FilePath cache_path = | 238 base::FilePath cache_path = |
| 229 CreatePersistentCachePath(origin_path_, cache_name); | 239 origin_path_.AppendASCII(cache_name_to_cache_dir_[cache_name]); |
| 240 cache_name_to_cache_dir_.erase(cache_name); |
| 241 |
| 230 cache_task_runner_->PostTask( | 242 cache_task_runner_->PostTask( |
| 231 FROM_HERE, | 243 FROM_HERE, |
| 232 base::Bind(&SimpleCacheLoader::CleanUpDeleteCacheDirInPool, cache_path, | 244 base::Bind(&SimpleCacheLoader::CleanUpDeleteCacheDirInPool, cache_path, |
| 233 callback, base::ThreadTaskRunnerHandle::Get())); | 245 callback, base::ThreadTaskRunnerHandle::Get())); |
| 234 } | 246 } |
| 235 | 247 |
| 236 static void CleanUpDeleteCacheDirInPool( | 248 static void CleanUpDeleteCacheDirInPool( |
| 237 const base::FilePath& cache_path, | 249 const base::FilePath& cache_path, |
| 238 const BoolCallback& callback, | 250 const BoolCallback& callback, |
| 239 const scoped_refptr<base::SingleThreadTaskRunner>& original_task_runner) { | 251 const scoped_refptr<base::SingleThreadTaskRunner>& original_task_runner) { |
| 240 bool rv = base::DeleteFile(cache_path, true); | 252 bool rv = base::DeleteFile(cache_path, true); |
| 241 original_task_runner->PostTask(FROM_HERE, base::Bind(callback, rv)); | 253 original_task_runner->PostTask(FROM_HERE, base::Bind(callback, rv)); |
| 242 } | 254 } |
| 243 | 255 |
| 244 void WriteIndex(const StringVector& cache_names, | 256 void WriteIndex(const StringVector& cache_names, |
| 245 const BoolCallback& callback) override { | 257 const BoolCallback& callback) override { |
| 246 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 258 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 247 | 259 |
| 248 // 1. Create the index file as a string. (WriteIndex) | 260 // 1. Create the index file as a string. (WriteIndex) |
| 249 // 2. Write the file to disk. (WriteIndexWriteToFileInPool) | 261 // 2. Write the file to disk. (WriteIndexWriteToFileInPool) |
| 250 | 262 |
| 251 CacheStorageIndex index; | 263 CacheStorageIndex index; |
| 252 index.set_origin(origin_.spec()); | 264 index.set_origin(origin_.spec()); |
| 253 | 265 |
| 254 for (size_t i = 0u, max = cache_names.size(); i < max; ++i) { | 266 for (size_t i = 0u, max = cache_names.size(); i < max; ++i) { |
| 267 DCHECK(ContainsKey(cache_name_to_cache_dir_, cache_names[i])); |
| 268 |
| 255 CacheStorageIndex::Cache* index_cache = index.add_cache(); | 269 CacheStorageIndex::Cache* index_cache = index.add_cache(); |
| 256 index_cache->set_name(cache_names[i]); | 270 index_cache->set_name(cache_names[i]); |
| 271 index_cache->set_cache_dir(cache_name_to_cache_dir_[cache_names[i]]); |
| 257 } | 272 } |
| 258 | 273 |
| 259 std::string serialized; | 274 std::string serialized; |
| 260 bool success = index.SerializeToString(&serialized); | 275 bool success = index.SerializeToString(&serialized); |
| 261 DCHECK(success); | 276 DCHECK(success); |
| 262 | 277 |
| 263 base::FilePath tmp_path = origin_path_.AppendASCII("index.txt.tmp"); | 278 base::FilePath tmp_path = origin_path_.AppendASCII("index.txt.tmp"); |
| 264 base::FilePath index_path = | 279 base::FilePath index_path = |
| 265 origin_path_.AppendASCII(CacheStorage::kIndexFileName); | 280 origin_path_.AppendASCII(CacheStorage::kIndexFileName); |
| 266 | 281 |
| (...skipping 23 matching lines...) Expand all Loading... |
| 290 void LoadIndex(scoped_ptr<std::vector<std::string>> names, | 305 void LoadIndex(scoped_ptr<std::vector<std::string>> names, |
| 291 const StringVectorCallback& callback) override { | 306 const StringVectorCallback& callback) override { |
| 292 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 307 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 293 | 308 |
| 294 // 1. Read the file from disk. (LoadIndexReadFileInPool) | 309 // 1. Read the file from disk. (LoadIndexReadFileInPool) |
| 295 // 2. Parse file and return the names of the caches (LoadIndexDidReadFile) | 310 // 2. Parse file and return the names of the caches (LoadIndexDidReadFile) |
| 296 | 311 |
| 297 base::FilePath index_path = | 312 base::FilePath index_path = |
| 298 origin_path_.AppendASCII(CacheStorage::kIndexFileName); | 313 origin_path_.AppendASCII(CacheStorage::kIndexFileName); |
| 299 | 314 |
| 300 cache_task_runner_->PostTask( | 315 PostTaskAndReplyWithResult( |
| 301 FROM_HERE, base::Bind(&SimpleCacheLoader::LoadIndexReadFileInPool, | 316 cache_task_runner_.get(), FROM_HERE, |
| 302 index_path, base::Passed(names.Pass()), callback, | 317 base::Bind(&SimpleCacheLoader::ReadAndMigrateIndexInPool, index_path), |
| 303 base::ThreadTaskRunnerHandle::Get())); | 318 base::Bind(&SimpleCacheLoader::LoadIndexDidReadFile, |
| 319 weak_ptr_factory_.GetWeakPtr(), base::Passed(&names), |
| 320 callback)); |
| 304 } | 321 } |
| 305 | 322 |
| 306 static void LoadIndexReadFileInPool( | 323 void LoadIndexDidReadFile(scoped_ptr<std::vector<std::string>> names, |
| 307 const base::FilePath& index_path, | 324 const StringVectorCallback& callback, |
| 308 scoped_ptr<std::vector<std::string>> names, | 325 const std::string& serialized) { |
| 309 const StringVectorCallback& callback, | |
| 310 const scoped_refptr<base::SingleThreadTaskRunner>& original_task_runner) { | |
| 311 std::string body; | |
| 312 base::ReadFileToString(index_path, &body); | |
| 313 | |
| 314 original_task_runner->PostTask( | |
| 315 FROM_HERE, base::Bind(&SimpleCacheLoader::LoadIndexDidReadFile, | |
| 316 base::Passed(names.Pass()), callback, body)); | |
| 317 } | |
| 318 | |
| 319 static void LoadIndexDidReadFile(scoped_ptr<std::vector<std::string>> names, | |
| 320 const StringVectorCallback& callback, | |
| 321 const std::string& serialized) { | |
| 322 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 326 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 323 | 327 |
| 324 CacheStorageIndex index; | 328 CacheStorageIndex index; |
| 325 if (index.ParseFromString(serialized)) { | 329 if (index.ParseFromString(serialized)) { |
| 326 for (int i = 0, max = index.cache_size(); i < max; ++i) { | 330 for (int i = 0, max = index.cache_size(); i < max; ++i) { |
| 327 const CacheStorageIndex::Cache& cache = index.cache(i); | 331 const CacheStorageIndex::Cache& cache = index.cache(i); |
| 332 DCHECK(cache.has_cache_dir()); |
| 328 names->push_back(cache.name()); | 333 names->push_back(cache.name()); |
| 334 cache_name_to_cache_dir_[cache.name()] = cache.cache_dir(); |
| 329 } | 335 } |
| 330 } | 336 } |
| 331 | 337 |
| 332 // TODO(jkarlin): Delete caches that are in the directory and not returned | 338 // TODO(jkarlin): Delete caches that are in the directory and not returned |
| 333 // in LoadIndex. | 339 // in LoadIndex. |
| 334 callback.Run(names.Pass()); | 340 callback.Run(names.Pass()); |
| 335 } | 341 } |
| 336 | 342 |
| 337 private: | 343 private: |
| 344 friend class MigratedLegacyCacheDirectoryNameTest; |
| 338 ~SimpleCacheLoader() override {} | 345 ~SimpleCacheLoader() override {} |
| 339 | 346 |
| 340 static std::string HexedHash(const std::string& value) { | 347 // Runs on cache_task_runner_ |
| 341 std::string value_hash = base::SHA1HashString(value); | 348 static std::string MigrateCachesIfNecessaryInPool( |
| 342 std::string valued_hexed_hash = base::ToLowerASCII( | 349 const std::string& body, |
| 343 base::HexEncode(value_hash.c_str(), value_hash.length())); | 350 const base::FilePath& index_path) { |
| 344 return valued_hexed_hash; | 351 CacheStorageIndex index; |
| 352 if (!index.ParseFromString(body)) |
| 353 return body; |
| 354 |
| 355 base::FilePath origin_path = index_path.DirName(); |
| 356 bool index_is_dirty = false; |
| 357 const std::string kBadIndexState(""); |
| 358 |
| 359 // Look for caches that have no cache_dir. Give any such caches a directory |
| 360 // with a random name and move them there. Then, rewrite the index file. |
| 361 for (int i = 0, max = index.cache_size(); i < max; ++i) { |
| 362 const CacheStorageIndex::Cache& cache = index.cache(i); |
| 363 if (!cache.has_cache_dir()) { |
| 364 // Find a new home for the cache. |
| 365 base::FilePath legacy_cache_path = |
| 366 origin_path.AppendASCII(HexedHash(cache.name())); |
| 367 std::string cache_dir; |
| 368 base::FilePath cache_path; |
| 369 do { |
| 370 cache_dir = base::GenerateGUID(); |
| 371 cache_path = origin_path.AppendASCII(cache_dir); |
| 372 } while (base::PathExists(cache_path)); |
| 373 |
| 374 if (!base::Move(legacy_cache_path, cache_path)) { |
| 375 // If the move fails then the cache is in a bad state. Return an empty |
| 376 // index so that the CacheStorage can start fresh. The unreferenced |
| 377 // caches will be discarded later in initialization. |
| 378 return kBadIndexState; |
| 379 } |
| 380 |
| 381 index.mutable_cache(0)->set_cache_dir(cache_dir); |
| 382 index_is_dirty = true; |
| 383 } |
| 384 } |
| 385 |
| 386 if (index_is_dirty) { |
| 387 std::string new_body; |
| 388 if (!index.SerializeToString(&new_body)) |
| 389 return kBadIndexState; |
| 390 if (base::WriteFile(index_path, new_body.c_str(), new_body.size()) != |
| 391 base::checked_cast<int>(new_body.size())) |
| 392 return kBadIndexState; |
| 393 return new_body; |
| 394 } |
| 395 |
| 396 return body; |
| 345 } | 397 } |
| 346 | 398 |
| 347 static base::FilePath CreatePersistentCachePath( | 399 // Runs on cache_task_runner_ |
| 348 const base::FilePath& origin_path, | 400 static std::string ReadAndMigrateIndexInPool( |
| 349 const std::string& cache_name) { | 401 const base::FilePath& index_path) { |
| 350 return origin_path.AppendASCII(HexedHash(cache_name)); | 402 std::string body; |
| 403 base::ReadFileToString(index_path, &body); |
| 404 |
| 405 return MigrateCachesIfNecessaryInPool(body, index_path); |
| 351 } | 406 } |
| 352 | 407 |
| 353 const base::FilePath origin_path_; | 408 const base::FilePath origin_path_; |
| 409 std::map<std::string, std::string> cache_name_to_cache_dir_; |
| 354 | 410 |
| 355 base::WeakPtrFactory<SimpleCacheLoader> weak_ptr_factory_; | 411 base::WeakPtrFactory<SimpleCacheLoader> weak_ptr_factory_; |
| 356 }; | 412 }; |
| 357 | 413 |
| 358 CacheStorage::CacheStorage( | 414 CacheStorage::CacheStorage( |
| 359 const base::FilePath& path, | 415 const base::FilePath& path, |
| 360 bool memory_only, | 416 bool memory_only, |
| 361 base::SequencedTaskRunner* cache_task_runner, | 417 base::SequencedTaskRunner* cache_task_runner, |
| 362 const scoped_refptr<net::URLRequestContextGetter>& request_context, | 418 const scoped_refptr<net::URLRequestContextGetter>& request_context, |
| 363 const scoped_refptr<storage::QuotaManagerProxy>& quota_manager_proxy, | 419 const scoped_refptr<storage::QuotaManagerProxy>& quota_manager_proxy, |
| (...skipping 198 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 562 } | 618 } |
| 563 | 619 |
| 564 void CacheStorage::OpenCacheImpl(const std::string& cache_name, | 620 void CacheStorage::OpenCacheImpl(const std::string& cache_name, |
| 565 const CacheAndErrorCallback& callback) { | 621 const CacheAndErrorCallback& callback) { |
| 566 scoped_refptr<CacheStorageCache> cache = GetLoadedCache(cache_name); | 622 scoped_refptr<CacheStorageCache> cache = GetLoadedCache(cache_name); |
| 567 if (cache.get()) { | 623 if (cache.get()) { |
| 568 callback.Run(cache, CACHE_STORAGE_OK); | 624 callback.Run(cache, CACHE_STORAGE_OK); |
| 569 return; | 625 return; |
| 570 } | 626 } |
| 571 | 627 |
| 572 cache_loader_->CreateCache( | 628 cache_loader_->PrepareNewCacheDestination( |
| 573 cache_name, base::Bind(&CacheStorage::CreateCacheDidCreateCache, | 629 cache_name, base::Bind(&CacheStorage::CreateCacheDidCreateCache, |
| 574 weak_factory_.GetWeakPtr(), cache_name, callback)); | 630 weak_factory_.GetWeakPtr(), cache_name, callback)); |
| 575 } | 631 } |
| 576 | 632 |
| 577 void CacheStorage::CreateCacheDidCreateCache( | 633 void CacheStorage::CreateCacheDidCreateCache( |
| 578 const std::string& cache_name, | 634 const std::string& cache_name, |
| 579 const CacheAndErrorCallback& callback, | 635 const CacheAndErrorCallback& callback, |
| 580 const scoped_refptr<CacheStorageCache>& cache) { | 636 const scoped_refptr<CacheStorageCache>& cache) { |
| 581 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 637 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 582 | 638 |
| (...skipping 22 matching lines...) Expand all Loading... |
| 605 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 661 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| 606 DCHECK(cache.get()); | 662 DCHECK(cache.get()); |
| 607 | 663 |
| 608 // TODO(jkarlin): Handle !success. | 664 // TODO(jkarlin): Handle !success. |
| 609 | 665 |
| 610 callback.Run(cache, CACHE_STORAGE_OK); | 666 callback.Run(cache, CACHE_STORAGE_OK); |
| 611 } | 667 } |
| 612 | 668 |
| 613 void CacheStorage::HasCacheImpl(const std::string& cache_name, | 669 void CacheStorage::HasCacheImpl(const std::string& cache_name, |
| 614 const BoolAndErrorCallback& callback) { | 670 const BoolAndErrorCallback& callback) { |
| 615 bool has_cache = cache_map_.find(cache_name) != cache_map_.end(); | 671 bool has_cache = ContainsKey(cache_map_, cache_name); |
| 616 | |
| 617 callback.Run(has_cache, CACHE_STORAGE_OK); | 672 callback.Run(has_cache, CACHE_STORAGE_OK); |
| 618 } | 673 } |
| 619 | 674 |
| 620 void CacheStorage::DeleteCacheImpl(const std::string& cache_name, | 675 void CacheStorage::DeleteCacheImpl(const std::string& cache_name, |
| 621 const BoolAndErrorCallback& callback) { | 676 const BoolAndErrorCallback& callback) { |
| 622 CacheMap::iterator it = cache_map_.find(cache_name); | 677 CacheMap::iterator it = cache_map_.find(cache_name); |
| 623 if (it == cache_map_.end()) { | 678 if (it == cache_map_.end()) { |
| 624 callback.Run(false, CACHE_STORAGE_ERROR_NOT_FOUND); | 679 callback.Run(false, CACHE_STORAGE_ERROR_NOT_FOUND); |
| 625 return; | 680 return; |
| 626 } | 681 } |
| (...skipping 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 856 scoped_ptr<ServiceWorkerResponse> response, | 911 scoped_ptr<ServiceWorkerResponse> response, |
| 857 scoped_ptr<storage::BlobDataHandle> blob_data_handle) { | 912 scoped_ptr<storage::BlobDataHandle> blob_data_handle) { |
| 858 base::WeakPtr<CacheStorage> cache_storage = weak_factory_.GetWeakPtr(); | 913 base::WeakPtr<CacheStorage> cache_storage = weak_factory_.GetWeakPtr(); |
| 859 | 914 |
| 860 callback.Run(error, response.Pass(), blob_data_handle.Pass()); | 915 callback.Run(error, response.Pass(), blob_data_handle.Pass()); |
| 861 if (cache_storage) | 916 if (cache_storage) |
| 862 scheduler_->CompleteOperationAndRunNext(); | 917 scheduler_->CompleteOperationAndRunNext(); |
| 863 } | 918 } |
| 864 | 919 |
| 865 } // namespace content | 920 } // namespace content |
| OLD | NEW |