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/service_worker/service_worker_cache_storage.h" | 5 #include "content/browser/service_worker/service_worker_cache_storage.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 | 8 |
9 #include "base/files/file_util.h" | 9 #include "base/files/file_util.h" |
10 #include "base/files/memory_mapped_file.h" | 10 #include "base/files/memory_mapped_file.h" |
11 #include "base/memory/ref_counted.h" | 11 #include "base/memory/ref_counted.h" |
12 #include "base/sha1.h" | 12 #include "base/sha1.h" |
13 #include "base/stl_util.h" | 13 #include "base/stl_util.h" |
14 #include "base/strings/string_number_conversions.h" | 14 #include "base/strings/string_number_conversions.h" |
15 #include "base/strings/string_util.h" | 15 #include "base/strings/string_util.h" |
16 #include "content/browser/service_worker/service_worker_cache.h" | 16 #include "content/browser/service_worker/service_worker_cache.h" |
17 #include "content/browser/service_worker/service_worker_cache.pb.h" | 17 #include "content/browser/service_worker/service_worker_cache.pb.h" |
18 #include "content/public/browser/browser_thread.h" | 18 #include "content/public/browser/browser_thread.h" |
19 #include "net/base/directory_lister.h" | 19 #include "net/base/directory_lister.h" |
20 #include "net/base/net_errors.h" | 20 #include "net/base/net_errors.h" |
21 #include "storage/browser/blob/blob_storage_context.h" | 21 #include "storage/browser/blob/blob_storage_context.h" |
22 | 22 |
23 namespace content { | 23 namespace content { |
24 | 24 |
25 const char ServiceWorkerCacheStorage::kIndexFileName[] = "index.txt"; | |
26 | 25 |
27 // Handles the loading and clean up of ServiceWorkerCache objects. The | 26 // Handles the loading and clean up of ServiceWorkerCache objects. The |
28 // callback of every public method is guaranteed to be called. | 27 // callback of every public method is guaranteed to be called. |
29 class ServiceWorkerCacheStorage::CacheLoader { | 28 class ServiceWorkerCacheStorage::CacheLoader { |
30 public: | 29 public: |
31 typedef base::Callback<void(const scoped_refptr<ServiceWorkerCache>&)> | 30 typedef base::Callback<void(const scoped_refptr<ServiceWorkerCache>&)> |
32 CacheCallback; | 31 CacheCallback; |
33 typedef base::Callback<void(bool)> BoolCallback; | 32 typedef base::Callback<void(bool)> BoolCallback; |
34 typedef base::Callback<void(scoped_ptr<std::vector<std::string> >)> | 33 typedef base::Callback<void(scoped_ptr<std::vector<std::string> >)> |
35 StringVectorCallback; | 34 StringVectorCallback; |
36 | 35 |
37 CacheLoader(base::SequencedTaskRunner* cache_task_runner, | 36 CacheLoader(base::SequencedTaskRunner* cache_task_runner, |
38 net::URLRequestContext* request_context, | 37 net::URLRequestContext* request_context, |
39 base::WeakPtr<storage::BlobStorageContext> blob_context, | 38 base::WeakPtr<storage::BlobStorageContext> blob_context) |
40 const GURL& origin) | |
41 : cache_task_runner_(cache_task_runner), | 39 : cache_task_runner_(cache_task_runner), |
42 request_context_(request_context), | 40 request_context_(request_context), |
43 blob_context_(blob_context), | 41 blob_context_(blob_context) {} |
44 origin_(origin) { | |
45 DCHECK(!origin_.is_empty()); | |
46 } | |
47 | 42 |
48 virtual ~CacheLoader() {} | 43 virtual ~CacheLoader() {} |
49 | 44 |
50 // Creates a ServiceWorkerCache with the given name. It does not attempt to | 45 // Creates a ServiceWorkerCache with the given name. It does not attempt to |
51 // load the backend, that happens lazily when the cache is used. | 46 // load the backend, that happens lazily when the cache is used. |
52 virtual scoped_refptr<ServiceWorkerCache> CreateServiceWorkerCache( | 47 virtual scoped_refptr<ServiceWorkerCache> CreateServiceWorkerCache( |
53 const std::string& cache_name) = 0; | 48 const std::string& cache_name) = 0; |
54 | 49 |
55 // Deletes any pre-existing cache of the same name and then loads it. | 50 // Deletes any pre-existing cache of the same name and then loads it. |
56 virtual void CreateCache(const std::string& cache_name, | 51 virtual void CreateCache(const std::string& cache_name, |
57 const CacheCallback& callback) = 0; | 52 const CacheCallback& callback) = 0; |
58 | 53 |
59 // After the backend has been deleted, do any extra house keeping such as | 54 // After the backend has been deleted, do any extra house keeping such as |
60 // removing the cache's directory. | 55 // removing the cache's directory. |
61 virtual void CleanUpDeletedCache(const std::string& key, | 56 virtual void CleanUpDeletedCache(const std::string& key, |
62 const BoolCallback& callback) = 0; | 57 const BoolCallback& callback) = 0; |
63 | 58 |
64 // Writes the cache names (and sizes) to disk if applicable. | 59 // Writes the cache names (and sizes) to disk if applicable. |
65 virtual void WriteIndex(const StringVector& cache_names, | 60 virtual void WriteIndex(const StringVector& cache_names, |
66 const BoolCallback& callback) = 0; | 61 const BoolCallback& callback) = 0; |
67 | 62 |
68 // Loads the cache names from disk if applicable. | 63 // Loads the cache names from disk if applicable. |
69 virtual void LoadIndex(scoped_ptr<std::vector<std::string> > cache_names, | 64 virtual void LoadIndex(scoped_ptr<std::vector<std::string> > cache_names, |
70 const StringVectorCallback& callback) = 0; | 65 const StringVectorCallback& callback) = 0; |
71 | 66 |
72 protected: | 67 protected: |
73 scoped_refptr<base::SequencedTaskRunner> cache_task_runner_; | 68 scoped_refptr<base::SequencedTaskRunner> cache_task_runner_; |
74 net::URLRequestContext* request_context_; | 69 net::URLRequestContext* request_context_; |
75 base::WeakPtr<storage::BlobStorageContext> blob_context_; | 70 base::WeakPtr<storage::BlobStorageContext> blob_context_; |
76 GURL origin_; | |
77 }; | 71 }; |
78 | 72 |
79 // Creates memory-only ServiceWorkerCaches. Because these caches have no | 73 // Creates memory-only ServiceWorkerCaches. Because these caches have no |
80 // persistent storage it is not safe to free them from memory if they might be | 74 // persistent storage it is not safe to free them from memory if they might be |
81 // used again. Therefore this class holds a reference to each cache until the | 75 // used again. Therefore this class holds a reference to each cache until the |
82 // cache is deleted. | 76 // cache is deleted. |
83 class ServiceWorkerCacheStorage::MemoryLoader | 77 class ServiceWorkerCacheStorage::MemoryLoader |
84 : public ServiceWorkerCacheStorage::CacheLoader { | 78 : public ServiceWorkerCacheStorage::CacheLoader { |
85 public: | 79 public: |
86 MemoryLoader(base::SequencedTaskRunner* cache_task_runner, | 80 MemoryLoader(base::SequencedTaskRunner* cache_task_runner, |
87 net::URLRequestContext* request_context, | 81 net::URLRequestContext* request_context, |
88 base::WeakPtr<storage::BlobStorageContext> blob_context, | 82 base::WeakPtr<storage::BlobStorageContext> blob_context) |
89 const GURL& origin) | 83 : CacheLoader(cache_task_runner, request_context, blob_context) {} |
90 : CacheLoader(cache_task_runner, request_context, blob_context, origin) {} | |
91 | 84 |
92 virtual scoped_refptr<ServiceWorkerCache> CreateServiceWorkerCache( | 85 virtual scoped_refptr<ServiceWorkerCache> CreateServiceWorkerCache( |
93 const std::string& cache_name) override { | 86 const std::string& cache_name) override { |
94 return ServiceWorkerCache::CreateMemoryCache(request_context_, | 87 return ServiceWorkerCache::CreateMemoryCache(request_context_, |
95 blob_context_); | 88 blob_context_); |
96 } | 89 } |
97 | 90 |
98 virtual void CreateCache(const std::string& cache_name, | 91 virtual void CreateCache(const std::string& cache_name, |
99 const CacheCallback& callback) override { | 92 const CacheCallback& callback) override { |
100 scoped_refptr<ServiceWorkerCache> cache = | 93 scoped_refptr<ServiceWorkerCache> cache = |
(...skipping 29 matching lines...) Expand all Loading... |
130 // freed. | 123 // freed. |
131 CacheRefMap cache_refs_; | 124 CacheRefMap cache_refs_; |
132 }; | 125 }; |
133 | 126 |
134 class ServiceWorkerCacheStorage::SimpleCacheLoader | 127 class ServiceWorkerCacheStorage::SimpleCacheLoader |
135 : public ServiceWorkerCacheStorage::CacheLoader { | 128 : public ServiceWorkerCacheStorage::CacheLoader { |
136 public: | 129 public: |
137 SimpleCacheLoader(const base::FilePath& origin_path, | 130 SimpleCacheLoader(const base::FilePath& origin_path, |
138 base::SequencedTaskRunner* cache_task_runner, | 131 base::SequencedTaskRunner* cache_task_runner, |
139 net::URLRequestContext* request_context, | 132 net::URLRequestContext* request_context, |
140 base::WeakPtr<storage::BlobStorageContext> blob_context, | 133 base::WeakPtr<storage::BlobStorageContext> blob_context) |
141 const GURL& origin) | 134 : CacheLoader(cache_task_runner, request_context, blob_context), |
142 : CacheLoader(cache_task_runner, request_context, blob_context, origin), | |
143 origin_path_(origin_path), | 135 origin_path_(origin_path), |
144 weak_ptr_factory_(this) {} | 136 weak_ptr_factory_(this) {} |
145 | 137 |
146 virtual scoped_refptr<ServiceWorkerCache> CreateServiceWorkerCache( | 138 virtual scoped_refptr<ServiceWorkerCache> CreateServiceWorkerCache( |
147 const std::string& cache_name) override { | 139 const std::string& cache_name) override { |
148 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 140 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
149 | 141 |
150 return ServiceWorkerCache::CreatePersistentCache( | 142 return ServiceWorkerCache::CreatePersistentCache( |
151 CreatePersistentCachePath(origin_path_, cache_name), | 143 CreatePersistentCachePath(origin_path_, cache_name), |
152 request_context_, | 144 request_context_, |
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
217 } | 209 } |
218 | 210 |
219 virtual void WriteIndex(const StringVector& cache_names, | 211 virtual void WriteIndex(const StringVector& cache_names, |
220 const BoolCallback& callback) override { | 212 const BoolCallback& callback) override { |
221 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 213 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
222 | 214 |
223 // 1. Create the index file as a string. (WriteIndex) | 215 // 1. Create the index file as a string. (WriteIndex) |
224 // 2. Write the file to disk. (WriteIndexWriteToFileInPool) | 216 // 2. Write the file to disk. (WriteIndexWriteToFileInPool) |
225 | 217 |
226 ServiceWorkerCacheStorageIndex index; | 218 ServiceWorkerCacheStorageIndex index; |
227 index.set_origin(origin_.spec()); | |
228 | 219 |
229 for (size_t i = 0u, max = cache_names.size(); i < max; ++i) { | 220 for (size_t i = 0u, max = cache_names.size(); i < max; ++i) { |
230 ServiceWorkerCacheStorageIndex::Cache* index_cache = index.add_cache(); | 221 ServiceWorkerCacheStorageIndex::Cache* index_cache = index.add_cache(); |
231 index_cache->set_name(cache_names[i]); | 222 index_cache->set_name(cache_names[i]); |
232 index_cache->set_size(0); // TODO(jkarlin): Make this real. | 223 index_cache->set_size(0); // TODO(jkarlin): Make this real. |
233 } | 224 } |
234 | 225 |
235 std::string serialized; | 226 std::string serialized; |
236 bool success = index.SerializeToString(&serialized); | 227 bool success = index.SerializeToString(&serialized); |
237 DCHECK(success); | 228 DCHECK(success); |
238 | 229 |
239 base::FilePath tmp_path = origin_path_.AppendASCII("index.txt.tmp"); | 230 base::FilePath tmp_path = origin_path_.AppendASCII("index.txt.tmp"); |
240 base::FilePath index_path = | 231 base::FilePath index_path = origin_path_.AppendASCII("index.txt"); |
241 origin_path_.AppendASCII(ServiceWorkerCacheStorage::kIndexFileName); | |
242 | 232 |
243 cache_task_runner_->PostTask( | 233 cache_task_runner_->PostTask( |
244 FROM_HERE, | 234 FROM_HERE, |
245 base::Bind(&SimpleCacheLoader::WriteIndexWriteToFileInPool, | 235 base::Bind(&SimpleCacheLoader::WriteIndexWriteToFileInPool, |
246 tmp_path, | 236 tmp_path, |
247 index_path, | 237 index_path, |
248 serialized, | 238 serialized, |
249 callback, | 239 callback, |
250 base::MessageLoopProxy::current())); | 240 base::MessageLoopProxy::current())); |
251 } | 241 } |
(...skipping 15 matching lines...) Expand all Loading... |
267 original_loop->PostTask(FROM_HERE, base::Bind(callback, rv)); | 257 original_loop->PostTask(FROM_HERE, base::Bind(callback, rv)); |
268 } | 258 } |
269 | 259 |
270 virtual void LoadIndex(scoped_ptr<std::vector<std::string> > names, | 260 virtual void LoadIndex(scoped_ptr<std::vector<std::string> > names, |
271 const StringVectorCallback& callback) override { | 261 const StringVectorCallback& callback) override { |
272 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 262 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
273 | 263 |
274 // 1. Read the file from disk. (LoadIndexReadFileInPool) | 264 // 1. Read the file from disk. (LoadIndexReadFileInPool) |
275 // 2. Parse file and return the names of the caches (LoadIndexDidReadFile) | 265 // 2. Parse file and return the names of the caches (LoadIndexDidReadFile) |
276 | 266 |
277 base::FilePath index_path = | 267 base::FilePath index_path = origin_path_.AppendASCII("index.txt"); |
278 origin_path_.AppendASCII(ServiceWorkerCacheStorage::kIndexFileName); | |
279 | 268 |
280 cache_task_runner_->PostTask( | 269 cache_task_runner_->PostTask( |
281 FROM_HERE, | 270 FROM_HERE, |
282 base::Bind(&SimpleCacheLoader::LoadIndexReadFileInPool, | 271 base::Bind(&SimpleCacheLoader::LoadIndexReadFileInPool, |
283 index_path, | 272 index_path, |
284 base::Passed(names.Pass()), | 273 base::Passed(names.Pass()), |
285 callback, | 274 callback, |
286 base::MessageLoopProxy::current())); | 275 base::MessageLoopProxy::current())); |
287 } | 276 } |
288 | 277 |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
338 const base::FilePath origin_path_; | 327 const base::FilePath origin_path_; |
339 | 328 |
340 base::WeakPtrFactory<SimpleCacheLoader> weak_ptr_factory_; | 329 base::WeakPtrFactory<SimpleCacheLoader> weak_ptr_factory_; |
341 }; | 330 }; |
342 | 331 |
343 ServiceWorkerCacheStorage::ServiceWorkerCacheStorage( | 332 ServiceWorkerCacheStorage::ServiceWorkerCacheStorage( |
344 const base::FilePath& path, | 333 const base::FilePath& path, |
345 bool memory_only, | 334 bool memory_only, |
346 base::SequencedTaskRunner* cache_task_runner, | 335 base::SequencedTaskRunner* cache_task_runner, |
347 net::URLRequestContext* request_context, | 336 net::URLRequestContext* request_context, |
348 base::WeakPtr<storage::BlobStorageContext> blob_context, | 337 base::WeakPtr<storage::BlobStorageContext> blob_context) |
349 const GURL& origin) | |
350 : initialized_(false), | 338 : initialized_(false), |
351 origin_path_(path), | 339 origin_path_(path), |
352 cache_task_runner_(cache_task_runner), | 340 cache_task_runner_(cache_task_runner), |
353 memory_only_(memory_only), | 341 memory_only_(memory_only), |
354 weak_factory_(this) { | 342 weak_factory_(this) { |
355 if (memory_only) | 343 if (memory_only) |
356 cache_loader_.reset(new MemoryLoader( | 344 cache_loader_.reset(new MemoryLoader( |
357 cache_task_runner_.get(), request_context, blob_context, origin)); | 345 cache_task_runner_.get(), request_context, blob_context)); |
358 else | 346 else |
359 cache_loader_.reset(new SimpleCacheLoader(origin_path_, | 347 cache_loader_.reset(new SimpleCacheLoader( |
360 cache_task_runner_.get(), | 348 origin_path_, cache_task_runner_.get(), request_context, blob_context)); |
361 request_context, | |
362 blob_context, | |
363 origin)); | |
364 } | 349 } |
365 | 350 |
366 ServiceWorkerCacheStorage::~ServiceWorkerCacheStorage() { | 351 ServiceWorkerCacheStorage::~ServiceWorkerCacheStorage() { |
367 } | 352 } |
368 | 353 |
369 void ServiceWorkerCacheStorage::CreateCache( | 354 void ServiceWorkerCacheStorage::CreateCache( |
370 const std::string& cache_name, | 355 const std::string& cache_name, |
371 const CacheAndErrorCallback& callback) { | 356 const CacheAndErrorCallback& callback) { |
372 if (!initialized_) { | 357 if (!initialized_) { |
373 LazyInit(base::Bind(&ServiceWorkerCacheStorage::CreateCache, | 358 LazyInit(base::Bind(&ServiceWorkerCacheStorage::CreateCache, |
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
505 if (!initialized_) { | 490 if (!initialized_) { |
506 LazyInit(base::Bind(&ServiceWorkerCacheStorage::EnumerateCaches, | 491 LazyInit(base::Bind(&ServiceWorkerCacheStorage::EnumerateCaches, |
507 weak_factory_.GetWeakPtr(), | 492 weak_factory_.GetWeakPtr(), |
508 callback)); | 493 callback)); |
509 return; | 494 return; |
510 } | 495 } |
511 | 496 |
512 callback.Run(ordered_cache_names_, CACHE_STORAGE_ERROR_NO_ERROR); | 497 callback.Run(ordered_cache_names_, CACHE_STORAGE_ERROR_NO_ERROR); |
513 } | 498 } |
514 | 499 |
515 void ServiceWorkerCacheStorage::CloseAllCaches() { | |
516 DCHECK_CURRENTLY_ON(BrowserThread::IO); | |
517 | |
518 if (!initialized_) | |
519 return; | |
520 | |
521 for (auto& key_value : cache_map_) { | |
522 if (key_value.second) | |
523 key_value.second->Close(); | |
524 } | |
525 } | |
526 | |
527 // Init is run lazily so that it is called on the proper MessageLoop. | 500 // Init is run lazily so that it is called on the proper MessageLoop. |
528 void ServiceWorkerCacheStorage::LazyInit(const base::Closure& callback) { | 501 void ServiceWorkerCacheStorage::LazyInit(const base::Closure& callback) { |
529 DCHECK_CURRENTLY_ON(BrowserThread::IO); | 502 DCHECK_CURRENTLY_ON(BrowserThread::IO); |
530 DCHECK(!initialized_); | 503 DCHECK(!initialized_); |
531 | 504 |
532 init_callbacks_.push_back(callback); | 505 init_callbacks_.push_back(callback); |
533 | 506 |
534 // If this isn't the first call to LazyInit then return as the initialization | 507 // If this isn't the first call to LazyInit then return as the initialization |
535 // has already started. | 508 // has already started. |
536 if (init_callbacks_.size() > 1u) | 509 if (init_callbacks_.size() > 1u) |
(...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
640 scoped_refptr<ServiceWorkerCache> new_cache = | 613 scoped_refptr<ServiceWorkerCache> new_cache = |
641 cache_loader_->CreateServiceWorkerCache(cache_name); | 614 cache_loader_->CreateServiceWorkerCache(cache_name); |
642 map_iter->second = new_cache->AsWeakPtr(); | 615 map_iter->second = new_cache->AsWeakPtr(); |
643 return new_cache; | 616 return new_cache; |
644 } | 617 } |
645 | 618 |
646 return make_scoped_refptr(cache.get()); | 619 return make_scoped_refptr(cache.get()); |
647 } | 620 } |
648 | 621 |
649 } // namespace content | 622 } // namespace content |
OLD | NEW |