Home | History | Annotate | Download | only in service_worker
      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