| 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/cache_storage/cache_storage_cache.h" | 5 #include "content/browser/cache_storage/cache_storage_cache.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <string> | 8 #include <string> |
| 9 #include <utility> | 9 #include <utility> |
| 10 | 10 |
| 11 #include "base/barrier_closure.h" | 11 #include "base/barrier_closure.h" |
| 12 #include "base/files/file_path.h" | 12 #include "base/files/file_path.h" |
| 13 #include "base/guid.h" | 13 #include "base/guid.h" |
| 14 #include "base/macros.h" | 14 #include "base/macros.h" |
| 15 #include "base/metrics/histogram_macros.h" | 15 #include "base/metrics/histogram_macros.h" |
| 16 #include "base/strings/string_split.h" | 16 #include "base/strings/string_split.h" |
| 17 #include "base/strings/string_util.h" | 17 #include "base/strings/string_util.h" |
| 18 #include "base/threading/thread_task_runner_handle.h" | 18 #include "base/threading/thread_task_runner_handle.h" |
| 19 #include "content/browser/cache_storage/cache_storage.pb.h" | 19 #include "content/browser/cache_storage/cache_storage.pb.h" |
| 20 #include "content/browser/cache_storage/cache_storage_blob_to_disk_cache.h" | 20 #include "content/browser/cache_storage/cache_storage_blob_to_disk_cache.h" |
| 21 #include "content/browser/cache_storage/cache_storage_cache_handle.h" |
| 21 #include "content/browser/cache_storage/cache_storage_scheduler.h" | 22 #include "content/browser/cache_storage/cache_storage_scheduler.h" |
| 22 #include "content/public/browser/browser_thread.h" | 23 #include "content/public/browser/browser_thread.h" |
| 23 #include "content/public/common/referrer.h" | 24 #include "content/public/common/referrer.h" |
| 24 #include "net/base/completion_callback.h" | 25 #include "net/base/completion_callback.h" |
| 25 #include "net/base/io_buffer.h" | 26 #include "net/base/io_buffer.h" |
| 26 #include "net/base/net_errors.h" | 27 #include "net/base/net_errors.h" |
| 27 #include "net/disk_cache/disk_cache.h" | 28 #include "net/disk_cache/disk_cache.h" |
| 28 #include "net/url_request/url_request_context_getter.h" | 29 #include "net/url_request/url_request_context_getter.h" |
| 29 #include "storage/browser/blob/blob_data_builder.h" | 30 #include "storage/browser/blob/blob_data_builder.h" |
| 30 #include "storage/browser/blob/blob_data_handle.h" | 31 #include "storage/browser/blob/blob_data_handle.h" |
| 31 #include "storage/browser/blob/blob_storage_context.h" | 32 #include "storage/browser/blob/blob_storage_context.h" |
| 32 #include "storage/browser/blob/blob_url_request_job_factory.h" | 33 #include "storage/browser/blob/blob_url_request_job_factory.h" |
| 33 #include "storage/browser/quota/quota_manager_proxy.h" | 34 #include "storage/browser/quota/quota_manager_proxy.h" |
| 34 #include "third_party/WebKit/public/platform/modules/serviceworker/WebServiceWor
kerResponseType.h" | 35 #include "third_party/WebKit/public/platform/modules/serviceworker/WebServiceWor
kerResponseType.h" |
| 35 | 36 |
| 36 namespace content { | 37 namespace content { |
| 37 | 38 |
| 38 namespace { | 39 namespace { |
| 39 | 40 |
| 40 // This class ensures that the cache and the entry have a lifetime as long as | 41 // This class ensures that the cache and the entry have a lifetime as long as |
| 41 // the blob that is created to contain them. | 42 // the blob that is created to contain them. |
| 42 class CacheStorageCacheDataHandle | 43 class CacheStorageCacheDataHandle |
| 43 : public storage::BlobDataBuilder::DataHandle { | 44 : public storage::BlobDataBuilder::DataHandle { |
| 44 public: | 45 public: |
| 45 CacheStorageCacheDataHandle(scoped_refptr<CacheStorageCache> cache, | 46 CacheStorageCacheDataHandle( |
| 46 disk_cache::ScopedEntryPtr entry) | 47 std::unique_ptr<CacheStorageCacheHandle> cache_handle, |
| 47 : cache_(cache), entry_(std::move(entry)) {} | 48 disk_cache::ScopedEntryPtr entry) |
| 49 : cache_handle_(std::move(cache_handle)), entry_(std::move(entry)) {} |
| 48 | 50 |
| 49 private: | 51 private: |
| 50 ~CacheStorageCacheDataHandle() override {} | 52 ~CacheStorageCacheDataHandle() override {} |
| 51 | 53 |
| 52 scoped_refptr<CacheStorageCache> cache_; | 54 std::unique_ptr<CacheStorageCacheHandle> cache_handle_; |
| 53 disk_cache::ScopedEntryPtr entry_; | 55 disk_cache::ScopedEntryPtr entry_; |
| 54 | 56 |
| 55 DISALLOW_COPY_AND_ASSIGN(CacheStorageCacheDataHandle); | 57 DISALLOW_COPY_AND_ASSIGN(CacheStorageCacheDataHandle); |
| 56 }; | 58 }; |
| 57 | 59 |
| 58 typedef base::Callback<void(std::unique_ptr<CacheMetadata>)> MetadataCallback; | 60 typedef base::Callback<void(std::unique_ptr<CacheMetadata>)> MetadataCallback; |
| 59 | 61 |
| 60 // The maximum size of each cache. Ultimately, cache size | 62 // The maximum size of each cache. Ultimately, cache size |
| 61 // is controlled per-origin by the QuotaManager. | 63 // is controlled per-origin by the QuotaManager. |
| 62 const int kMaxCacheBytes = std::numeric_limits<int>::max(); | 64 const int kMaxCacheBytes = std::numeric_limits<int>::max(); |
| (...skipping 210 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 273 std::unique_ptr<ServiceWorkerResponse> response; | 275 std::unique_ptr<ServiceWorkerResponse> response; |
| 274 std::unique_ptr<storage::BlobDataHandle> blob_data_handle; | 276 std::unique_ptr<storage::BlobDataHandle> blob_data_handle; |
| 275 CacheStorageCache::ErrorCallback callback; | 277 CacheStorageCache::ErrorCallback callback; |
| 276 disk_cache::ScopedEntryPtr cache_entry; | 278 disk_cache::ScopedEntryPtr cache_entry; |
| 277 | 279 |
| 278 private: | 280 private: |
| 279 DISALLOW_COPY_AND_ASSIGN(PutContext); | 281 DISALLOW_COPY_AND_ASSIGN(PutContext); |
| 280 }; | 282 }; |
| 281 | 283 |
| 282 // static | 284 // static |
| 283 scoped_refptr<CacheStorageCache> CacheStorageCache::CreateMemoryCache( | 285 std::unique_ptr<CacheStorageCache> CacheStorageCache::CreateMemoryCache( |
| 284 const GURL& origin, | 286 const GURL& origin, |
| 285 const std::string& cache_name, | 287 const std::string& cache_name, |
| 288 CacheStorage* cache_storage, |
| 286 scoped_refptr<net::URLRequestContextGetter> request_context_getter, | 289 scoped_refptr<net::URLRequestContextGetter> request_context_getter, |
| 287 scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy, | 290 scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy, |
| 288 base::WeakPtr<storage::BlobStorageContext> blob_context) { | 291 base::WeakPtr<storage::BlobStorageContext> blob_context) { |
| 289 return make_scoped_refptr(new CacheStorageCache( | 292 return std::unique_ptr<CacheStorageCache>( |
| 290 origin, cache_name, base::FilePath(), std::move(request_context_getter), | 293 new CacheStorageCache(origin, cache_name, base::FilePath(), cache_storage, |
| 291 std::move(quota_manager_proxy), blob_context)); | 294 std::move(request_context_getter), |
| 295 std::move(quota_manager_proxy), blob_context)); |
| 292 } | 296 } |
| 293 | 297 |
| 294 // static | 298 // static |
| 295 scoped_refptr<CacheStorageCache> CacheStorageCache::CreatePersistentCache( | 299 std::unique_ptr<CacheStorageCache> CacheStorageCache::CreatePersistentCache( |
| 296 const GURL& origin, | 300 const GURL& origin, |
| 297 const std::string& cache_name, | 301 const std::string& cache_name, |
| 302 CacheStorage* cache_storage, |
| 298 const base::FilePath& path, | 303 const base::FilePath& path, |
| 299 scoped_refptr<net::URLRequestContextGetter> request_context_getter, | 304 scoped_refptr<net::URLRequestContextGetter> request_context_getter, |
| 300 scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy, | 305 scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy, |
| 301 base::WeakPtr<storage::BlobStorageContext> blob_context) { | 306 base::WeakPtr<storage::BlobStorageContext> blob_context) { |
| 302 return make_scoped_refptr(new CacheStorageCache( | 307 return std::unique_ptr<CacheStorageCache>( |
| 303 origin, cache_name, path, std::move(request_context_getter), | 308 new CacheStorageCache(origin, cache_name, path, cache_storage, |
| 304 std::move(quota_manager_proxy), blob_context)); | 309 std::move(request_context_getter), |
| 305 } | 310 std::move(quota_manager_proxy), blob_context)); |
| 306 | |
| 307 CacheStorageCache::~CacheStorageCache() { | |
| 308 quota_manager_proxy_->NotifyOriginNoLongerInUse(origin_); | |
| 309 } | 311 } |
| 310 | 312 |
| 311 base::WeakPtr<CacheStorageCache> CacheStorageCache::AsWeakPtr() { | 313 base::WeakPtr<CacheStorageCache> CacheStorageCache::AsWeakPtr() { |
| 312 return weak_ptr_factory_.GetWeakPtr(); | 314 return weak_ptr_factory_.GetWeakPtr(); |
| 313 } | 315 } |
| 314 | 316 |
| 315 void CacheStorageCache::Match( | 317 void CacheStorageCache::Match( |
| 316 std::unique_ptr<ServiceWorkerFetchRequest> request, | 318 std::unique_ptr<ServiceWorkerFetchRequest> request, |
| 317 const ResponseCallback& callback) { | 319 const ResponseCallback& callback) { |
| 318 if (!LazyInitialize()) { | 320 if (!LazyInitialize()) { |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 420 if (status_code != storage::kQuotaStatusOk || | 422 if (status_code != storage::kQuotaStatusOk || |
| 421 space_required > quota - usage) { | 423 space_required > quota - usage) { |
| 422 base::ThreadTaskRunnerHandle::Get()->PostTask( | 424 base::ThreadTaskRunnerHandle::Get()->PostTask( |
| 423 FROM_HERE, base::Bind(callback, CACHE_STORAGE_ERROR_QUOTA_EXCEEDED)); | 425 FROM_HERE, base::Bind(callback, CACHE_STORAGE_ERROR_QUOTA_EXCEEDED)); |
| 424 return; | 426 return; |
| 425 } | 427 } |
| 426 | 428 |
| 427 std::unique_ptr<ErrorCallback> callback_copy(new ErrorCallback(callback)); | 429 std::unique_ptr<ErrorCallback> callback_copy(new ErrorCallback(callback)); |
| 428 ErrorCallback* callback_ptr = callback_copy.get(); | 430 ErrorCallback* callback_ptr = callback_copy.get(); |
| 429 base::Closure barrier_closure = base::BarrierClosure( | 431 base::Closure barrier_closure = base::BarrierClosure( |
| 430 operations.size(), | 432 operations.size(), base::Bind(&CacheStorageCache::BatchDidAllOperations, |
| 431 base::Bind(&CacheStorageCache::BatchDidAllOperations, this, | 433 weak_ptr_factory_.GetWeakPtr(), |
| 432 base::Passed(std::move(callback_copy)))); | 434 base::Passed(std::move(callback_copy)))); |
| 433 ErrorCallback completion_callback = | 435 ErrorCallback completion_callback = |
| 434 base::Bind(&CacheStorageCache::BatchDidOneOperation, this, | 436 base::Bind(&CacheStorageCache::BatchDidOneOperation, |
| 435 barrier_closure, callback_ptr); | 437 weak_ptr_factory_.GetWeakPtr(), barrier_closure, callback_ptr); |
| 436 | 438 |
| 437 for (const auto& operation : operations) { | 439 for (const auto& operation : operations) { |
| 438 switch (operation.operation_type) { | 440 switch (operation.operation_type) { |
| 439 case CACHE_STORAGE_CACHE_OPERATION_TYPE_PUT: | 441 case CACHE_STORAGE_CACHE_OPERATION_TYPE_PUT: |
| 440 Put(operation, completion_callback); | 442 Put(operation, completion_callback); |
| 441 break; | 443 break; |
| 442 case CACHE_STORAGE_CACHE_OPERATION_TYPE_DELETE: | 444 case CACHE_STORAGE_CACHE_OPERATION_TYPE_DELETE: |
| 443 DCHECK_EQ(1u, operations.size()); | 445 DCHECK_EQ(1u, operations.size()); |
| 444 Delete(operation, completion_callback); | 446 Delete(operation, completion_callback); |
| 445 break; | 447 break; |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 528 SizeCallback pending_callback = | 530 SizeCallback pending_callback = |
| 529 base::Bind(&CacheStorageCache::PendingSizeCallback, | 531 base::Bind(&CacheStorageCache::PendingSizeCallback, |
| 530 weak_ptr_factory_.GetWeakPtr(), callback); | 532 weak_ptr_factory_.GetWeakPtr(), callback); |
| 531 | 533 |
| 532 scheduler_->ScheduleOperation( | 534 scheduler_->ScheduleOperation( |
| 533 base::Bind(&CacheStorageCache::SizeImpl, weak_ptr_factory_.GetWeakPtr(), | 535 base::Bind(&CacheStorageCache::SizeImpl, weak_ptr_factory_.GetWeakPtr(), |
| 534 base::Bind(&CacheStorageCache::GetSizeThenCloseDidGetSize, | 536 base::Bind(&CacheStorageCache::GetSizeThenCloseDidGetSize, |
| 535 weak_ptr_factory_.GetWeakPtr(), pending_callback))); | 537 weak_ptr_factory_.GetWeakPtr(), pending_callback))); |
| 536 } | 538 } |
| 537 | 539 |
| 540 CacheStorageCache::~CacheStorageCache() { |
| 541 quota_manager_proxy_->NotifyOriginNoLongerInUse(origin_); |
| 542 } |
| 543 |
| 538 CacheStorageCache::CacheStorageCache( | 544 CacheStorageCache::CacheStorageCache( |
| 539 const GURL& origin, | 545 const GURL& origin, |
| 540 const std::string& cache_name, | 546 const std::string& cache_name, |
| 541 const base::FilePath& path, | 547 const base::FilePath& path, |
| 548 CacheStorage* cache_storage, |
| 542 scoped_refptr<net::URLRequestContextGetter> request_context_getter, | 549 scoped_refptr<net::URLRequestContextGetter> request_context_getter, |
| 543 scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy, | 550 scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy, |
| 544 base::WeakPtr<storage::BlobStorageContext> blob_context) | 551 base::WeakPtr<storage::BlobStorageContext> blob_context) |
| 545 : origin_(origin), | 552 : origin_(origin), |
| 546 cache_name_(cache_name), | 553 cache_name_(cache_name), |
| 547 path_(path), | 554 path_(path), |
| 555 cache_storage_(cache_storage), |
| 548 request_context_getter_(std::move(request_context_getter)), | 556 request_context_getter_(std::move(request_context_getter)), |
| 549 quota_manager_proxy_(std::move(quota_manager_proxy)), | 557 quota_manager_proxy_(std::move(quota_manager_proxy)), |
| 550 blob_storage_context_(blob_context), | 558 blob_storage_context_(blob_context), |
| 551 scheduler_(new CacheStorageScheduler()), | 559 scheduler_(new CacheStorageScheduler()), |
| 552 memory_only_(path.empty()), | 560 memory_only_(path.empty()), |
| 553 weak_ptr_factory_(this) { | 561 weak_ptr_factory_(this) { |
| 554 DCHECK(!origin_.is_empty()); | 562 DCHECK(!origin_.is_empty()); |
| 555 DCHECK(quota_manager_proxy_.get()); | 563 DCHECK(quota_manager_proxy_.get()); |
| 556 | 564 |
| 557 quota_manager_proxy_->NotifyOriginInUse(origin_); | 565 quota_manager_proxy_->NotifyOriginInUse(origin_); |
| (...skipping 593 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1151 } | 1159 } |
| 1152 | 1160 |
| 1153 UpdateCacheSize(); | 1161 UpdateCacheSize(); |
| 1154 put_context->callback.Run(CACHE_STORAGE_OK); | 1162 put_context->callback.Run(CACHE_STORAGE_OK); |
| 1155 } | 1163 } |
| 1156 | 1164 |
| 1157 void CacheStorageCache::UpdateCacheSize() { | 1165 void CacheStorageCache::UpdateCacheSize() { |
| 1158 if (backend_state_ != BACKEND_OPEN) | 1166 if (backend_state_ != BACKEND_OPEN) |
| 1159 return; | 1167 return; |
| 1160 | 1168 |
| 1161 // Note that the callback holds a refptr to |this| since UpdateCacheSize is | 1169 // Note that the callback holds a cache handle to keep the cache alive during |
| 1162 // often called after an operation completes and the cache might be freed. | 1170 // the operation since this UpdateCacheSize is often run after an operation |
| 1163 int rv = backend_->CalculateSizeOfAllEntries( | 1171 // completes and runs its callback. |
| 1164 base::Bind(&CacheStorageCache::UpdateCacheSizeGotSize, this)); | 1172 int rv = backend_->CalculateSizeOfAllEntries(base::Bind( |
| 1173 &CacheStorageCache::UpdateCacheSizeGotSize, |
| 1174 weak_ptr_factory_.GetWeakPtr(), base::Passed(CreateCacheHandle()))); |
| 1165 | 1175 |
| 1166 if (rv != net::ERR_IO_PENDING) | 1176 if (rv != net::ERR_IO_PENDING) |
| 1167 UpdateCacheSizeGotSize(rv); | 1177 UpdateCacheSizeGotSize(CreateCacheHandle(), rv); |
| 1168 } | 1178 } |
| 1169 | 1179 |
| 1170 void CacheStorageCache::UpdateCacheSizeGotSize(int current_cache_size) { | 1180 void CacheStorageCache::UpdateCacheSizeGotSize( |
| 1181 std::unique_ptr<CacheStorageCacheHandle> cache_handle, |
| 1182 int current_cache_size) { |
| 1171 int64_t old_cache_size = cache_size_; | 1183 int64_t old_cache_size = cache_size_; |
| 1172 cache_size_ = current_cache_size; | 1184 cache_size_ = current_cache_size; |
| 1173 | 1185 |
| 1174 quota_manager_proxy_->NotifyStorageModified( | 1186 quota_manager_proxy_->NotifyStorageModified( |
| 1175 storage::QuotaClient::kServiceWorkerCache, origin_, | 1187 storage::QuotaClient::kServiceWorkerCache, origin_, |
| 1176 storage::kStorageTypeTemporary, current_cache_size - old_cache_size); | 1188 storage::kStorageTypeTemporary, current_cache_size - old_cache_size); |
| 1177 } | 1189 } |
| 1178 | 1190 |
| 1179 void CacheStorageCache::Delete(const CacheStorageBatchOperation& operation, | 1191 void CacheStorageCache::Delete(const CacheStorageBatchOperation& operation, |
| 1180 const ErrorCallback& callback) { | 1192 const ErrorCallback& callback) { |
| (...skipping 368 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1549 ServiceWorkerResponse* response) { | 1561 ServiceWorkerResponse* response) { |
| 1550 DCHECK(blob_storage_context_); | 1562 DCHECK(blob_storage_context_); |
| 1551 | 1563 |
| 1552 // Create a blob with the response body data. | 1564 // Create a blob with the response body data. |
| 1553 response->blob_size = entry->GetDataSize(INDEX_RESPONSE_BODY); | 1565 response->blob_size = entry->GetDataSize(INDEX_RESPONSE_BODY); |
| 1554 response->blob_uuid = base::GenerateGUID(); | 1566 response->blob_uuid = base::GenerateGUID(); |
| 1555 storage::BlobDataBuilder blob_data(response->blob_uuid); | 1567 storage::BlobDataBuilder blob_data(response->blob_uuid); |
| 1556 | 1568 |
| 1557 disk_cache::Entry* temp_entry = entry.get(); | 1569 disk_cache::Entry* temp_entry = entry.get(); |
| 1558 blob_data.AppendDiskCacheEntryWithSideData( | 1570 blob_data.AppendDiskCacheEntryWithSideData( |
| 1559 new CacheStorageCacheDataHandle(this, std::move(entry)), temp_entry, | 1571 new CacheStorageCacheDataHandle(CreateCacheHandle(), std::move(entry)), |
| 1560 INDEX_RESPONSE_BODY, INDEX_SIDE_DATA); | 1572 temp_entry, INDEX_RESPONSE_BODY, INDEX_SIDE_DATA); |
| 1561 return blob_storage_context_->AddFinishedBlob(&blob_data); | 1573 return blob_storage_context_->AddFinishedBlob(&blob_data); |
| 1562 } | 1574 } |
| 1563 | 1575 |
| 1576 std::unique_ptr<CacheStorageCacheHandle> |
| 1577 CacheStorageCache::CreateCacheHandle() { |
| 1578 return cache_storage_->CreateCacheHandle(this); |
| 1579 } |
| 1580 |
| 1564 } // namespace content | 1581 } // namespace content |
| OLD | NEW |