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 3 // found in the LICENSE file. 4 5 #include "content/browser/service_worker/service_worker_cache_storage_manager.h" 6 7 #include <map> 8 #include <string> 9 10 #include "base/bind.h" 11 #include "base/id_map.h" 12 #include "base/sha1.h" 13 #include "base/strings/string_number_conversions.h" 14 #include "base/strings/string_util.h" 15 #include "content/browser/service_worker/service_worker_cache_storage.h" 16 #include "content/browser/service_worker/service_worker_context_core.h" 17 #include "content/public/browser/browser_thread.h" 18 #include "url/gurl.h" 19 20 namespace { 21 22 base::FilePath ConstructOriginPath(const base::FilePath& root_path, 23 const GURL& origin) { 24 std::string origin_hash = base::SHA1HashString(origin.spec()); 25 std::string origin_hash_hex = base::StringToLowerASCII( 26 base::HexEncode(origin_hash.c_str(), origin_hash.length())); 27 return root_path.AppendASCII(origin_hash_hex); 28 } 29 30 } // namespace 31 32 namespace content { 33 34 // static 35 scoped_ptr<ServiceWorkerCacheStorageManager> 36 ServiceWorkerCacheStorageManager::Create( 37 const base::FilePath& path, 38 const scoped_refptr<base::SequencedTaskRunner>& cache_task_runner) { 39 base::FilePath root_path = path; 40 if (!path.empty()) { 41 root_path = path.Append(ServiceWorkerContextCore::kServiceWorkerDirectory) 42 .AppendASCII("CacheStorage"); 43 } 44 45 return make_scoped_ptr( 46 new ServiceWorkerCacheStorageManager(root_path, cache_task_runner)); 47 } 48 49 // static 50 scoped_ptr<ServiceWorkerCacheStorageManager> 51 ServiceWorkerCacheStorageManager::Create( 52 ServiceWorkerCacheStorageManager* old_manager) { 53 scoped_ptr<ServiceWorkerCacheStorageManager> manager( 54 new ServiceWorkerCacheStorageManager(old_manager->root_path(), 55 old_manager->cache_task_runner())); 56 // These values may be NULL, in which case this will be called again later by 57 // the dispatcher host per usual. 58 manager->SetBlobParametersForCache(old_manager->url_request_context(), 59 old_manager->blob_storage_context()); 60 return manager.Pass(); 61 } 62 63 ServiceWorkerCacheStorageManager::~ServiceWorkerCacheStorageManager() { 64 for (ServiceWorkerCacheStorageMap::iterator it = cache_storage_map_.begin(); 65 it != cache_storage_map_.end(); 66 ++it) { 67 delete it->second; 68 } 69 } 70 71 void ServiceWorkerCacheStorageManager::CreateCache( 72 const GURL& origin, 73 const std::string& cache_name, 74 const ServiceWorkerCacheStorage::CacheAndErrorCallback& callback) { 75 DCHECK_CURRENTLY_ON(BrowserThread::IO); 76 77 ServiceWorkerCacheStorage* cache_storage = 78 FindOrCreateServiceWorkerCacheManager(origin); 79 80 cache_storage->CreateCache(cache_name, callback); 81 } 82 83 void ServiceWorkerCacheStorageManager::GetCache( 84 const GURL& origin, 85 const std::string& cache_name, 86 const ServiceWorkerCacheStorage::CacheAndErrorCallback& callback) { 87 DCHECK_CURRENTLY_ON(BrowserThread::IO); 88 89 ServiceWorkerCacheStorage* cache_storage = 90 FindOrCreateServiceWorkerCacheManager(origin); 91 92 cache_storage->GetCache(cache_name, callback); 93 } 94 95 void ServiceWorkerCacheStorageManager::HasCache( 96 const GURL& origin, 97 const std::string& cache_name, 98 const ServiceWorkerCacheStorage::BoolAndErrorCallback& callback) { 99 DCHECK_CURRENTLY_ON(BrowserThread::IO); 100 101 ServiceWorkerCacheStorage* cache_storage = 102 FindOrCreateServiceWorkerCacheManager(origin); 103 cache_storage->HasCache(cache_name, callback); 104 } 105 106 void ServiceWorkerCacheStorageManager::DeleteCache( 107 const GURL& origin, 108 const std::string& cache_name, 109 const ServiceWorkerCacheStorage::BoolAndErrorCallback& callback) { 110 DCHECK_CURRENTLY_ON(BrowserThread::IO); 111 112 ServiceWorkerCacheStorage* cache_storage = 113 FindOrCreateServiceWorkerCacheManager(origin); 114 cache_storage->DeleteCache(cache_name, callback); 115 } 116 117 void ServiceWorkerCacheStorageManager::EnumerateCaches( 118 const GURL& origin, 119 const ServiceWorkerCacheStorage::StringsAndErrorCallback& callback) { 120 DCHECK_CURRENTLY_ON(BrowserThread::IO); 121 122 ServiceWorkerCacheStorage* cache_storage = 123 FindOrCreateServiceWorkerCacheManager(origin); 124 125 cache_storage->EnumerateCaches(callback); 126 } 127 128 void ServiceWorkerCacheStorageManager::SetBlobParametersForCache( 129 net::URLRequestContext* request_context, 130 base::WeakPtr<storage::BlobStorageContext> blob_storage_context) { 131 DCHECK_CURRENTLY_ON(BrowserThread::IO); 132 DCHECK(cache_storage_map_.empty()); 133 DCHECK(!request_context_ || request_context_ == request_context); 134 DCHECK(!blob_context_ || blob_context_.get() == blob_storage_context.get()); 135 request_context_ = request_context; 136 blob_context_ = blob_storage_context; 137 } 138 139 ServiceWorkerCacheStorageManager::ServiceWorkerCacheStorageManager( 140 const base::FilePath& path, 141 const scoped_refptr<base::SequencedTaskRunner>& cache_task_runner) 142 : root_path_(path), 143 cache_task_runner_(cache_task_runner), 144 request_context_(NULL) { 145 } 146 147 ServiceWorkerCacheStorage* 148 ServiceWorkerCacheStorageManager::FindOrCreateServiceWorkerCacheManager( 149 const GURL& origin) { 150 DCHECK_CURRENTLY_ON(BrowserThread::IO); 151 DCHECK(request_context_); 152 153 ServiceWorkerCacheStorageMap::const_iterator it = 154 cache_storage_map_.find(origin); 155 if (it == cache_storage_map_.end()) { 156 bool memory_only = root_path_.empty(); 157 ServiceWorkerCacheStorage* cache_storage = 158 new ServiceWorkerCacheStorage(ConstructOriginPath(root_path_, origin), 159 memory_only, 160 cache_task_runner_.get(), 161 request_context_, 162 blob_context_); 163 // The map owns fetch_stores. 164 cache_storage_map_.insert(std::make_pair(origin, cache_storage)); 165 return cache_storage; 166 } 167 return it->second; 168 } 169 170 } // namespace content 171