Chromium Code Reviews| Index: content/browser/cache_storage/cache_storage.cc |
| diff --git a/content/browser/cache_storage/cache_storage.cc b/content/browser/cache_storage/cache_storage.cc |
| index 42f0215b8477c7a4afac97353e844b331c97e3f4..312e1165a0bd65e319e1a8924b43deeca10790e9 100644 |
| --- a/content/browser/cache_storage/cache_storage.cc |
| +++ b/content/browser/cache_storage/cache_storage.cc |
| @@ -9,6 +9,7 @@ |
| #include "base/barrier_closure.h" |
| #include "base/files/file_util.h" |
| #include "base/files/memory_mapped_file.h" |
| +#include "base/guid.h" |
| #include "base/location.h" |
| #include "base/memory/ref_counted.h" |
| #include "base/metrics/histogram_macros.h" |
| @@ -38,12 +39,19 @@ void CloseAllCachesDidCloseCache(const scoped_refptr<CacheStorageCache>& cache, |
| barrier_closure.Run(); |
| } |
| +std::string ReadFile(const base::FilePath& path) { |
| + std::string body; |
| + base::ReadFileToString(path, &body); |
| + return body; |
| +} |
| + |
| } // namespace |
| +class LegacyCacheDirectoryNameTest; |
| + |
| const char CacheStorage::kIndexFileName[] = "index.txt"; |
| -// Handles the loading and clean up of CacheStorageCache objects. The |
| -// callback of every public method is guaranteed to be called. |
| +// Handles the loading and clean up of CacheStorageCache objects. |
| class CacheStorage::CacheLoader { |
| public: |
| typedef base::Callback<void(const scoped_refptr<CacheStorageCache>&)> |
| @@ -74,8 +82,8 @@ class CacheStorage::CacheLoader { |
| const std::string& cache_name) = 0; |
| // Deletes any pre-existing cache of the same name and then loads it. |
| - virtual void CreateCache(const std::string& cache_name, |
| - const CacheCallback& callback) = 0; |
| + virtual void PrepareNewCacheDestination(const std::string& cache_name, |
| + const CacheCallback& callback) = 0; |
| // After the backend has been deleted, do any extra house keeping such as |
| // removing the cache's directory. |
| @@ -122,8 +130,8 @@ class CacheStorage::MemoryLoader : public CacheStorage::CacheLoader { |
| origin_, request_context_getter_, quota_manager_proxy_, blob_context_); |
| } |
| - void CreateCache(const std::string& cache_name, |
| - const CacheCallback& callback) override { |
| + void PrepareNewCacheDestination(const std::string& cache_name, |
| + const CacheCallback& callback) override { |
| scoped_refptr<CacheStorageCache> cache = CreateCache(cache_name); |
| cache_refs_.insert(std::make_pair(cache_name, cache)); |
| callback.Run(cache); |
| @@ -177,56 +185,62 @@ class CacheStorage::SimpleCacheLoader : public CacheStorage::CacheLoader { |
| scoped_refptr<CacheStorageCache> CreateCache( |
| const std::string& cache_name) override { |
| DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| + DCHECK(cache_name_to_cache_dir_.find(cache_name) != |
|
jsbell
2015/10/22 16:38:52
Could use ContainsKey() from base/stl_util
jkarlin
2015/10/23 17:23:09
Done, thanks! Forgot about that function.
|
| + cache_name_to_cache_dir_.end()); |
| + std::string cache_dir = cache_name_to_cache_dir_[cache_name]; |
| + base::FilePath cache_path = origin_path_.AppendASCII(cache_dir); |
| return CacheStorageCache::CreatePersistentCache( |
| - origin_, CreatePersistentCachePath(origin_path_, cache_name), |
| - request_context_getter_, quota_manager_proxy_, blob_context_); |
| + origin_, cache_path, request_context_getter_, quota_manager_proxy_, |
| + blob_context_); |
| } |
| - void CreateCache(const std::string& cache_name, |
| - const CacheCallback& callback) override { |
| + void PrepareNewCacheDestination(const std::string& cache_name, |
| + const CacheCallback& callback) override { |
| DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| - // 1. Delete the cache's directory if it exists. |
| - // (CreateCacheDeleteFilesInPool) |
| - // 2. Load the cache. (LoadCreateDirectoryInPool) |
| - |
| - base::FilePath cache_path = |
| - CreatePersistentCachePath(origin_path_, cache_name); |
| - |
| PostTaskAndReplyWithResult( |
| cache_task_runner_.get(), FROM_HERE, |
| - base::Bind(&SimpleCacheLoader::CreateCachePrepDirInPool, cache_path), |
| - base::Bind(&SimpleCacheLoader::CreateCachePreppedDir, cache_name, |
| - callback, weak_ptr_factory_.GetWeakPtr())); |
| + base::Bind(&SimpleCacheLoader::PrepareNewCacheDirectoryInPool, |
| + origin_path_), |
| + base::Bind(&SimpleCacheLoader::PrepareNewCacheCreateCache, |
| + weak_ptr_factory_.GetWeakPtr(), cache_name, callback)); |
| } |
| - static bool CreateCachePrepDirInPool(const base::FilePath& cache_path) { |
| - if (base::PathExists(cache_path)) |
| - base::DeleteFile(cache_path, /* recursive */ true); |
| - return base::CreateDirectory(cache_path); |
| + static std::string PrepareNewCacheDirectoryInPool( |
|
jsbell
2015/10/22 16:38:52
Add comment that this is run on the cache_task_run
jkarlin
2015/10/23 17:23:09
Done.
|
| + const base::FilePath& origin_path) { |
| + std::string cache_dir; |
| + base::FilePath cache_path; |
| + do { |
| + cache_dir = base::GenerateGUID(); |
| + cache_path = origin_path.AppendASCII(cache_dir); |
| + } while (base::PathExists(cache_path)); |
| + |
| + return base::CreateDirectory(cache_path) ? cache_dir : ""; |
| } |
| - static void CreateCachePreppedDir(const std::string& cache_name, |
| - const CacheCallback& callback, |
| - base::WeakPtr<SimpleCacheLoader> loader, |
| - bool success) { |
| - if (!success || !loader) { |
| + void PrepareNewCacheCreateCache(const std::string& cache_name, |
| + const CacheCallback& callback, |
| + const std::string& cache_dir) { |
| + if (cache_dir.empty()) { |
| callback.Run(scoped_refptr<CacheStorageCache>()); |
| return; |
| } |
| - callback.Run(loader->CreateCache(cache_name)); |
| + cache_name_to_cache_dir_[cache_name] = cache_dir; |
| + callback.Run(CreateCache(cache_name)); |
| } |
| void CleanUpDeletedCache(const std::string& cache_name, |
| const BoolCallback& callback) override { |
| DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| - |
| - // 1. Delete the cache's directory. (CleanUpDeleteCacheDirInPool) |
| + DCHECK(cache_name_to_cache_dir_.find(cache_name) != |
|
jsbell
2015/10/22 16:38:52
Could use ContainsKey()
jkarlin
2015/10/23 17:23:09
Done.
|
| + cache_name_to_cache_dir_.end()); |
| base::FilePath cache_path = |
| - CreatePersistentCachePath(origin_path_, cache_name); |
| + origin_path_.AppendASCII(cache_name_to_cache_dir_[cache_name]); |
| + cache_name_to_cache_dir_.erase(cache_name); |
| + |
| cache_task_runner_->PostTask( |
| FROM_HERE, |
| base::Bind(&SimpleCacheLoader::CleanUpDeleteCacheDirInPool, cache_path, |
| @@ -252,8 +266,12 @@ class CacheStorage::SimpleCacheLoader : public CacheStorage::CacheLoader { |
| index.set_origin(origin_.spec()); |
| for (size_t i = 0u, max = cache_names.size(); i < max; ++i) { |
| + DCHECK(cache_name_to_cache_dir_.find(cache_names[i]) != |
|
jsbell
2015/10/22 16:38:52
ContainsKey()
jkarlin
2015/10/23 17:23:09
Done.
|
| + cache_name_to_cache_dir_.end()); |
| + |
| CacheStorageIndex::Cache* index_cache = index.add_cache(); |
| index_cache->set_name(cache_names[i]); |
| + index_cache->set_cache_dir(cache_name_to_cache_dir_[cache_names[i]]); |
| } |
| std::string serialized; |
| @@ -297,28 +315,16 @@ class CacheStorage::SimpleCacheLoader : public CacheStorage::CacheLoader { |
| base::FilePath index_path = |
| origin_path_.AppendASCII(CacheStorage::kIndexFileName); |
| - cache_task_runner_->PostTask( |
| - FROM_HERE, base::Bind(&SimpleCacheLoader::LoadIndexReadFileInPool, |
| - index_path, base::Passed(names.Pass()), callback, |
| - base::ThreadTaskRunnerHandle::Get())); |
| - } |
| - |
| - static void LoadIndexReadFileInPool( |
| - const base::FilePath& index_path, |
| - scoped_ptr<std::vector<std::string>> names, |
| - const StringVectorCallback& callback, |
| - const scoped_refptr<base::SingleThreadTaskRunner>& original_task_runner) { |
| - std::string body; |
| - base::ReadFileToString(index_path, &body); |
| - |
| - original_task_runner->PostTask( |
| - FROM_HERE, base::Bind(&SimpleCacheLoader::LoadIndexDidReadFile, |
| - base::Passed(names.Pass()), callback, body)); |
| + PostTaskAndReplyWithResult( |
| + cache_task_runner_.get(), FROM_HERE, base::Bind(&ReadFile, index_path), |
| + base::Bind(&SimpleCacheLoader::LoadIndexDidReadFile, |
| + weak_ptr_factory_.GetWeakPtr(), base::Passed(&names), |
| + callback)); |
| } |
| - static void LoadIndexDidReadFile(scoped_ptr<std::vector<std::string>> names, |
| - const StringVectorCallback& callback, |
| - const std::string& serialized) { |
| + void LoadIndexDidReadFile(scoped_ptr<std::vector<std::string>> names, |
| + const StringVectorCallback& callback, |
| + const std::string& serialized) { |
| DCHECK_CURRENTLY_ON(BrowserThread::IO); |
| CacheStorageIndex index; |
| @@ -326,6 +332,13 @@ class CacheStorage::SimpleCacheLoader : public CacheStorage::CacheLoader { |
| for (int i = 0, max = index.cache_size(); i < max; ++i) { |
| const CacheStorageIndex::Cache& cache = index.cache(i); |
| names->push_back(cache.name()); |
| + // Before randomly generated cache directory names were used, the hexed |
| + // hash of the cache name was used. For backwards compatibility, use the |
| + // hexed hash as the directory name for protobufs that don't have a |
| + // directory name. |
| + std::string cache_dir = |
| + cache.has_cache_dir() ? cache.cache_dir() : HexedHash(cache.name()); |
| + cache_name_to_cache_dir_[cache.name()] = cache_dir; |
| } |
| } |
| @@ -335,6 +348,7 @@ class CacheStorage::SimpleCacheLoader : public CacheStorage::CacheLoader { |
| } |
| private: |
| + friend class LegacyCacheDirectoryNameTest; |
| ~SimpleCacheLoader() override {} |
| static std::string HexedHash(const std::string& value) { |
| @@ -344,13 +358,8 @@ class CacheStorage::SimpleCacheLoader : public CacheStorage::CacheLoader { |
| return valued_hexed_hash; |
| } |
| - static base::FilePath CreatePersistentCachePath( |
| - const base::FilePath& origin_path, |
| - const std::string& cache_name) { |
| - return origin_path.AppendASCII(HexedHash(cache_name)); |
| - } |
| - |
| const base::FilePath origin_path_; |
| + std::map<std::string, std::string> cache_name_to_cache_dir_; |
| base::WeakPtrFactory<SimpleCacheLoader> weak_ptr_factory_; |
| }; |
| @@ -569,7 +578,7 @@ void CacheStorage::OpenCacheImpl(const std::string& cache_name, |
| return; |
| } |
| - cache_loader_->CreateCache( |
| + cache_loader_->PrepareNewCacheDestination( |
| cache_name, base::Bind(&CacheStorage::CreateCacheDidCreateCache, |
| weak_factory_.GetWeakPtr(), cache_name, callback)); |
| } |