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