Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(826)

Side by Side Diff: content/browser/cache_storage/cache_storage_cache.cc

Issue 2901083002: [CacheStorage] Pad and bin opaque resource sizes. (Closed)
Patch Set: Patch Set 8 changes. Created 3 years, 4 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
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 <algorithm> 8 #include <algorithm>
9 #include <functional>
9 #include <limits> 10 #include <limits>
10 #include <memory> 11 #include <memory>
11 #include <string> 12 #include <string>
12 #include <utility> 13 #include <utility>
13 14
14 #include "base/barrier_closure.h" 15 #include "base/barrier_closure.h"
15 #include "base/bind_helpers.h" 16 #include "base/bind_helpers.h"
16 #include "base/files/file_path.h" 17 #include "base/files/file_path.h"
17 #include "base/guid.h" 18 #include "base/guid.h"
18 #include "base/macros.h" 19 #include "base/macros.h"
19 #include "base/memory/ptr_util.h" 20 #include "base/memory/ptr_util.h"
20 #include "base/metrics/histogram_macros.h" 21 #include "base/metrics/histogram_macros.h"
21 #include "base/strings/string_split.h" 22 #include "base/strings/string_split.h"
22 #include "base/strings/string_util.h" 23 #include "base/strings/string_util.h"
23 #include "base/threading/thread_task_runner_handle.h" 24 #include "base/threading/thread_task_runner_handle.h"
24 #include "content/browser/cache_storage/cache_storage.pb.h" 25 #include "content/browser/cache_storage/cache_storage.pb.h"
25 #include "content/browser/cache_storage/cache_storage_blob_to_disk_cache.h" 26 #include "content/browser/cache_storage/cache_storage_blob_to_disk_cache.h"
26 #include "content/browser/cache_storage/cache_storage_cache_handle.h" 27 #include "content/browser/cache_storage/cache_storage_cache_handle.h"
27 #include "content/browser/cache_storage/cache_storage_cache_observer.h" 28 #include "content/browser/cache_storage/cache_storage_cache_observer.h"
28 #include "content/browser/cache_storage/cache_storage_scheduler.h" 29 #include "content/browser/cache_storage/cache_storage_scheduler.h"
29 #include "content/public/browser/browser_thread.h" 30 #include "content/public/browser/browser_thread.h"
30 #include "content/public/common/referrer.h" 31 #include "content/public/common/referrer.h"
32 #include "crypto/hmac.h"
33 #include "crypto/symmetric_key.h"
31 #include "net/base/completion_callback.h" 34 #include "net/base/completion_callback.h"
32 #include "net/base/io_buffer.h" 35 #include "net/base/io_buffer.h"
33 #include "net/base/net_errors.h" 36 #include "net/base/net_errors.h"
34 #include "net/disk_cache/disk_cache.h" 37 #include "net/disk_cache/disk_cache.h"
35 #include "net/url_request/url_request_context_getter.h" 38 #include "net/url_request/url_request_context_getter.h"
36 #include "storage/browser/blob/blob_data_builder.h" 39 #include "storage/browser/blob/blob_data_builder.h"
37 #include "storage/browser/blob/blob_data_handle.h" 40 #include "storage/browser/blob/blob_data_handle.h"
38 #include "storage/browser/blob/blob_storage_context.h" 41 #include "storage/browser/blob/blob_storage_context.h"
39 #include "storage/browser/blob/blob_url_request_job_factory.h" 42 #include "storage/browser/blob/blob_url_request_job_factory.h"
40 #include "storage/browser/quota/quota_manager_proxy.h" 43 #include "storage/browser/quota/quota_manager_proxy.h"
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
248 metadata.response().status_text(), 251 metadata.response().status_text(),
249 ProtoResponseTypeToFetchResponseType(metadata.response().response_type()), 252 ProtoResponseTypeToFetchResponseType(metadata.response().response_type()),
250 std::move(headers), "", 0, blink::kWebServiceWorkerResponseErrorUnknown, 253 std::move(headers), "", 0, blink::kWebServiceWorkerResponseErrorUnknown,
251 base::Time::FromInternalValue(metadata.response().response_time()), 254 base::Time::FromInternalValue(metadata.response().response_time()),
252 true /* is_in_cache_storage */, cache_name, 255 true /* is_in_cache_storage */, cache_name,
253 base::MakeUnique<ServiceWorkerHeaderList>( 256 base::MakeUnique<ServiceWorkerHeaderList>(
254 metadata.response().cors_exposed_header_names().begin(), 257 metadata.response().cors_exposed_header_names().begin(),
255 metadata.response().cors_exposed_header_names().end())); 258 metadata.response().cors_exposed_header_names().end()));
256 } 259 }
257 260
261 // The size of opaque (non-cors) resource responses are padded in order
262 // to obfuscate their actual size.
263 bool ShouldPadResponseType(blink::mojom::FetchResponseType response_type,
264 bool has_urls) {
265 switch (response_type) {
266 case blink::mojom::FetchResponseType::kBasic:
267 case blink::mojom::FetchResponseType::kCORS:
268 case blink::mojom::FetchResponseType::kDefault:
269 case blink::mojom::FetchResponseType::kError:
270 return false;
271 case blink::mojom::FetchResponseType::kOpaque:
272 case blink::mojom::FetchResponseType::kOpaqueRedirect:
273 return has_urls;
274 }
275 NOTREACHED();
276 return false;
277 }
278
279 bool ShouldPadResourceSize(const content::proto::CacheResponse* response) {
280 return ShouldPadResponseType(
281 ProtoResponseTypeToFetchResponseType(response->response_type()),
282 response->url_list_size());
283 }
284
285 bool ShouldPadResourceSize(const ServiceWorkerResponse* response) {
286 return ShouldPadResponseType(response->response_type,
287 !response->url_list.empty());
288 }
289
290 // If the way that a cache's padding is calculated changes increment this
291 // version.
292 //
293 // History:
294 //
295 // 1: Uniform random 400K.
296 const int32_t kCachePaddingAlgorithmVersion = 1;
297
298 int64_t CalculateResponsePaddingInternal(
299 const std::string& response_url,
300 const crypto::SymmetricKey* padding_key,
301 int side_data_size) {
302 const uint64_t kPaddingRange = 400 * 1024; // Increment version if changed.
303
304 DCHECK(!response_url.empty());
305
306 crypto::HMAC hmac(crypto::HMAC::SHA256);
307 if (!hmac.Init(padding_key))
308 LOG(FATAL) << "Failed to init HMAC.";
309
310 std::vector<uint8_t> digest(hmac.DigestLength());
311 bool success;
312 if (side_data_size)
313 success = hmac.Sign(response_url + "METADATA", &digest[0], digest.size());
314 else
315 success = hmac.Sign(response_url, &digest[0], digest.size());
316 if (!success)
317 LOG(FATAL) << "Failed to sign URL.";
318
319 DCHECK_GE(digest.size(), sizeof(uint64_t));
320 uint64_t val = *(reinterpret_cast<uint64_t*>(&digest[0]));
321 return val % kPaddingRange;
322 }
323
324 int64_t CalculateResponsePaddingInternal(
325 const ::content::proto::CacheResponse* response,
326 const crypto::SymmetricKey* padding_key,
327 int side_data_size) {
328 DCHECK(ShouldPadResourceSize(response));
329 const std::string& url = response->url_list(response->url_list_size() - 1);
330 return CalculateResponsePaddingInternal(url, padding_key, side_data_size);
331 }
332
258 } // namespace 333 } // namespace
259 334
260 // The state needed to pass between CacheStorageCache::Put callbacks. 335 // The state needed to pass between CacheStorageCache::Put callbacks.
261 struct CacheStorageCache::PutContext { 336 struct CacheStorageCache::PutContext {
262 PutContext(std::unique_ptr<ServiceWorkerFetchRequest> request, 337 PutContext(std::unique_ptr<ServiceWorkerFetchRequest> request,
263 std::unique_ptr<ServiceWorkerResponse> response, 338 std::unique_ptr<ServiceWorkerResponse> response,
264 std::unique_ptr<storage::BlobDataHandle> blob_data_handle, 339 std::unique_ptr<storage::BlobDataHandle> blob_data_handle,
265 CacheStorageCache::ErrorCallback callback) 340 CacheStorageCache::ErrorCallback callback)
266 : request(std::move(request)), 341 : request(std::move(request)),
267 response(std::move(response)), 342 response(std::move(response)),
(...skipping 17 matching lines...) Expand all
285 std::unique_ptr<ServiceWorkerFetchRequest> request; 360 std::unique_ptr<ServiceWorkerFetchRequest> request;
286 std::unique_ptr<ServiceWorkerResponse> response; 361 std::unique_ptr<ServiceWorkerResponse> response;
287 std::unique_ptr<storage::BlobDataHandle> blob_handle; 362 std::unique_ptr<storage::BlobDataHandle> blob_handle;
288 disk_cache::ScopedEntryPtr entry; 363 disk_cache::ScopedEntryPtr entry;
289 base::Time entry_time; 364 base::Time entry_time;
290 }; 365 };
291 366
292 struct CacheStorageCache::QueryCacheContext { 367 struct CacheStorageCache::QueryCacheContext {
293 QueryCacheContext(std::unique_ptr<ServiceWorkerFetchRequest> request, 368 QueryCacheContext(std::unique_ptr<ServiceWorkerFetchRequest> request,
294 const CacheStorageCacheQueryParams& options, 369 const CacheStorageCacheQueryParams& options,
295 QueryCacheCallback callback) 370 QueryCacheCallback callback,
371 QueryTypes query_types)
296 : request(std::move(request)), 372 : request(std::move(request)),
297 options(options), 373 options(options),
298 callback(std::move(callback)), 374 callback(std::move(callback)),
375 query_types(query_types),
299 matches(base::MakeUnique<QueryCacheResults>()) {} 376 matches(base::MakeUnique<QueryCacheResults>()) {}
300 377
301 ~QueryCacheContext() { 378 ~QueryCacheContext() {
302 // If the CacheStorageCache is deleted before a backend operation to open 379 // If the CacheStorageCache is deleted before a backend operation to open
303 // an entry completes, the callback won't be run and the resulting entry 380 // an entry completes, the callback won't be run and the resulting entry
304 // will be leaked unless we close it here. 381 // will be leaked unless we close it here.
305 if (enumerated_entry) { 382 if (enumerated_entry) {
306 enumerated_entry->Close(); 383 enumerated_entry->Close();
307 enumerated_entry = nullptr; 384 enumerated_entry = nullptr;
308 } 385 }
309 } 386 }
310 387
311 // Input to QueryCache 388 // Input to QueryCache
312 std::unique_ptr<ServiceWorkerFetchRequest> request; 389 std::unique_ptr<ServiceWorkerFetchRequest> request;
313 CacheStorageCacheQueryParams options; 390 CacheStorageCacheQueryParams options;
314 QueryCacheCallback callback; 391 QueryCacheCallback callback;
315 QueryCacheType query_type; 392 QueryTypes query_types = 0;
316 size_t estimated_out_bytes = 0; 393 size_t estimated_out_bytes = 0;
317 394
318 // Iteration state 395 // Iteration state
319 std::unique_ptr<disk_cache::Backend::Iterator> backend_iterator; 396 std::unique_ptr<disk_cache::Backend::Iterator> backend_iterator;
320 disk_cache::Entry* enumerated_entry = nullptr; 397 disk_cache::Entry* enumerated_entry = nullptr;
321 398
322 // Output of QueryCache 399 // Output of QueryCache
323 std::unique_ptr<std::vector<QueryCacheResult>> matches; 400 std::unique_ptr<std::vector<QueryCacheResult>> matches;
324 401
325 private: 402 private:
326 DISALLOW_COPY_AND_ASSIGN(QueryCacheContext); 403 DISALLOW_COPY_AND_ASSIGN(QueryCacheContext);
327 }; 404 };
328 405
329 // static 406 // static
330 std::unique_ptr<CacheStorageCache> CacheStorageCache::CreateMemoryCache( 407 std::unique_ptr<CacheStorageCache> CacheStorageCache::CreateMemoryCache(
331 const GURL& origin, 408 const GURL& origin,
332 const std::string& cache_name, 409 const std::string& cache_name,
333 CacheStorage* cache_storage, 410 CacheStorage* cache_storage,
334 scoped_refptr<net::URLRequestContextGetter> request_context_getter, 411 scoped_refptr<net::URLRequestContextGetter> request_context_getter,
335 scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy, 412 scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy,
336 base::WeakPtr<storage::BlobStorageContext> blob_context) { 413 base::WeakPtr<storage::BlobStorageContext> blob_context,
414 std::unique_ptr<crypto::SymmetricKey> cache_padding_key) {
337 CacheStorageCache* cache = new CacheStorageCache( 415 CacheStorageCache* cache = new CacheStorageCache(
338 origin, cache_name, base::FilePath(), cache_storage, 416 origin, cache_name, base::FilePath(), cache_storage,
339 std::move(request_context_getter), std::move(quota_manager_proxy), 417 std::move(request_context_getter), std::move(quota_manager_proxy),
340 blob_context, 0 /* cache_size */); 418 blob_context, 0 /* cache_size */, 0 /* cache_padding */,
419 std::move(cache_padding_key));
341 cache->SetObserver(cache_storage); 420 cache->SetObserver(cache_storage);
342 cache->InitBackend(); 421 cache->InitBackend();
343 return base::WrapUnique(cache); 422 return base::WrapUnique(cache);
344 } 423 }
345 424
346 // static 425 // static
347 std::unique_ptr<CacheStorageCache> CacheStorageCache::CreatePersistentCache( 426 std::unique_ptr<CacheStorageCache> CacheStorageCache::CreatePersistentCache(
348 const GURL& origin, 427 const GURL& origin,
349 const std::string& cache_name, 428 const std::string& cache_name,
350 CacheStorage* cache_storage, 429 CacheStorage* cache_storage,
351 const base::FilePath& path, 430 const base::FilePath& path,
352 scoped_refptr<net::URLRequestContextGetter> request_context_getter, 431 scoped_refptr<net::URLRequestContextGetter> request_context_getter,
353 scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy, 432 scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy,
354 base::WeakPtr<storage::BlobStorageContext> blob_context, 433 base::WeakPtr<storage::BlobStorageContext> blob_context,
355 int64_t cache_size) { 434 int64_t cache_size,
435 int64_t cache_padding,
436 std::unique_ptr<crypto::SymmetricKey> cache_padding_key) {
356 CacheStorageCache* cache = new CacheStorageCache( 437 CacheStorageCache* cache = new CacheStorageCache(
357 origin, cache_name, path, cache_storage, 438 origin, cache_name, path, cache_storage,
358 std::move(request_context_getter), std::move(quota_manager_proxy), 439 std::move(request_context_getter), std::move(quota_manager_proxy),
359 blob_context, cache_size); 440 blob_context, cache_size, cache_padding, std::move(cache_padding_key));
360 cache->SetObserver(cache_storage), cache->InitBackend(); 441 cache->SetObserver(cache_storage), cache->InitBackend();
361 return base::WrapUnique(cache); 442 return base::WrapUnique(cache);
362 } 443 }
363 444
364 base::WeakPtr<CacheStorageCache> CacheStorageCache::AsWeakPtr() { 445 base::WeakPtr<CacheStorageCache> CacheStorageCache::AsWeakPtr() {
365 return weak_ptr_factory_.GetWeakPtr(); 446 return weak_ptr_factory_.GetWeakPtr();
366 } 447 }
367 448
368 void CacheStorageCache::Match( 449 void CacheStorageCache::Match(
369 std::unique_ptr<ServiceWorkerFetchRequest> request, 450 std::unique_ptr<ServiceWorkerFetchRequest> request,
(...skipping 225 matching lines...) Expand 10 before | Expand all | Expand 10 after
595 } 676 }
596 677
597 CacheStorageCache::CacheStorageCache( 678 CacheStorageCache::CacheStorageCache(
598 const GURL& origin, 679 const GURL& origin,
599 const std::string& cache_name, 680 const std::string& cache_name,
600 const base::FilePath& path, 681 const base::FilePath& path,
601 CacheStorage* cache_storage, 682 CacheStorage* cache_storage,
602 scoped_refptr<net::URLRequestContextGetter> request_context_getter, 683 scoped_refptr<net::URLRequestContextGetter> request_context_getter,
603 scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy, 684 scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy,
604 base::WeakPtr<storage::BlobStorageContext> blob_context, 685 base::WeakPtr<storage::BlobStorageContext> blob_context,
605 int64_t cache_size) 686 int64_t cache_size,
687 int64_t cache_padding,
688 std::unique_ptr<crypto::SymmetricKey> cache_padding_key)
606 : origin_(origin), 689 : origin_(origin),
607 cache_name_(cache_name), 690 cache_name_(cache_name),
608 path_(path), 691 path_(path),
609 cache_storage_(cache_storage), 692 cache_storage_(cache_storage),
610 request_context_getter_(std::move(request_context_getter)), 693 request_context_getter_(std::move(request_context_getter)),
611 quota_manager_proxy_(std::move(quota_manager_proxy)), 694 quota_manager_proxy_(std::move(quota_manager_proxy)),
612 blob_storage_context_(blob_context), 695 blob_storage_context_(blob_context),
613 scheduler_( 696 scheduler_(
614 new CacheStorageScheduler(CacheStorageSchedulerClient::CLIENT_CACHE)), 697 new CacheStorageScheduler(CacheStorageSchedulerClient::CLIENT_CACHE)),
615 cache_size_(cache_size), 698 cache_size_(cache_size),
699 cache_padding_(cache_padding),
700 cache_padding_key_(std::move(cache_padding_key)),
616 max_query_size_bytes_(kMaxQueryCacheResultBytes), 701 max_query_size_bytes_(kMaxQueryCacheResultBytes),
617 cache_observer_(nullptr), 702 cache_observer_(nullptr),
618 memory_only_(path.empty()), 703 memory_only_(path.empty()),
619 weak_ptr_factory_(this) { 704 weak_ptr_factory_(this) {
620 DCHECK(!origin_.is_empty()); 705 DCHECK(!origin_.is_empty());
621 DCHECK(quota_manager_proxy_.get()); 706 DCHECK(quota_manager_proxy_.get());
707 DCHECK(cache_padding_key_.get());
622 708
623 quota_manager_proxy_->NotifyOriginInUse(origin_); 709 quota_manager_proxy_->NotifyOriginInUse(origin_);
624 } 710 }
625 711
626 void CacheStorageCache::QueryCache( 712 void CacheStorageCache::QueryCache(
627 std::unique_ptr<ServiceWorkerFetchRequest> request, 713 std::unique_ptr<ServiceWorkerFetchRequest> request,
628 const CacheStorageCacheQueryParams& options, 714 const CacheStorageCacheQueryParams& options,
629 QueryCacheType query_type, 715 QueryTypes query_types,
630 QueryCacheCallback callback) { 716 QueryCacheCallback callback) {
631 DCHECK_NE(BACKEND_UNINITIALIZED, backend_state_); 717 DCHECK_NE(
632 if (backend_state_ != BACKEND_OPEN) { 718 QUERY_CACHE_ENTRIES | QUERY_CACHE_RESPONSES_WITH_BODIES,
719 query_types & (QUERY_CACHE_ENTRIES | QUERY_CACHE_RESPONSES_WITH_BODIES));
720 if (backend_state_ == BACKEND_CLOSED) {
633 std::move(callback).Run(CACHE_STORAGE_ERROR_STORAGE, 721 std::move(callback).Run(CACHE_STORAGE_ERROR_STORAGE,
634 std::unique_ptr<QueryCacheResults>()); 722 std::unique_ptr<QueryCacheResults>());
635 return; 723 return;
636 } 724 }
637 725
638 if (!options.ignore_method && request && !request->method.empty() && 726 if (!options.ignore_method && request && !request->method.empty() &&
639 request->method != "GET") { 727 request->method != "GET") {
640 std::move(callback).Run(CACHE_STORAGE_OK, 728 std::move(callback).Run(CACHE_STORAGE_OK,
641 base::MakeUnique<QueryCacheResults>()); 729 base::MakeUnique<QueryCacheResults>());
642 return; 730 return;
643 } 731 }
644 732
645 ServiceWorkerFetchRequest* request_ptr = request.get(); 733 ServiceWorkerFetchRequest* request_ptr = request.get();
646 std::unique_ptr<QueryCacheContext> query_cache_context( 734 std::unique_ptr<QueryCacheContext> query_cache_context(new QueryCacheContext(
647 new QueryCacheContext(std::move(request), options, std::move(callback))); 735 std::move(request), options, std::move(callback), query_types));
648 query_cache_context->query_type = query_type;
649 736
650 if (query_cache_context->request && 737 if (query_cache_context->request &&
651 !query_cache_context->request->url.is_empty() && !options.ignore_search) { 738 !query_cache_context->request->url.is_empty() && !options.ignore_search) {
652 // There is no need to scan the entire backend, just open the exact 739 // There is no need to scan the entire backend, just open the exact
653 // URL. 740 // URL.
654 disk_cache::Entry** entry_ptr = &query_cache_context->enumerated_entry; 741 disk_cache::Entry** entry_ptr = &query_cache_context->enumerated_entry;
655 net::CompletionCallback open_entry_callback = 742 net::CompletionCallback open_entry_callback =
656 base::AdaptCallbackForRepeating( 743 base::AdaptCallbackForRepeating(
657 base::BindOnce(&CacheStorageCache::QueryCacheDidOpenFastPath, 744 base::BindOnce(&CacheStorageCache::QueryCacheDidOpenFastPath,
658 weak_ptr_factory_.GetWeakPtr(), 745 weak_ptr_factory_.GetWeakPtr(),
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
721 if (rv < 0) { 808 if (rv < 0) {
722 std::move(query_cache_context->callback) 809 std::move(query_cache_context->callback)
723 .Run(CACHE_STORAGE_ERROR_STORAGE, 810 .Run(CACHE_STORAGE_ERROR_STORAGE,
724 std::move(query_cache_context->matches)); 811 std::move(query_cache_context->matches));
725 return; 812 return;
726 } 813 }
727 814
728 disk_cache::ScopedEntryPtr entry(query_cache_context->enumerated_entry); 815 disk_cache::ScopedEntryPtr entry(query_cache_context->enumerated_entry);
729 query_cache_context->enumerated_entry = nullptr; 816 query_cache_context->enumerated_entry = nullptr;
730 817
731 if (backend_state_ != BACKEND_OPEN) { 818 if (backend_state_ == BACKEND_CLOSED) {
732 std::move(query_cache_context->callback) 819 std::move(query_cache_context->callback)
733 .Run(CACHE_STORAGE_ERROR_NOT_FOUND, 820 .Run(CACHE_STORAGE_ERROR_NOT_FOUND,
734 std::move(query_cache_context->matches)); 821 std::move(query_cache_context->matches));
735 return; 822 return;
736 } 823 }
737 824
738 if (query_cache_context->request && 825 if (query_cache_context->request &&
739 !query_cache_context->request->url.is_empty()) { 826 !query_cache_context->request->url.is_empty()) {
740 GURL requestURL = query_cache_context->request->url; 827 GURL requestURL = query_cache_context->request->url;
741 GURL cachedURL = GURL(entry->GetKey()); 828 GURL cachedURL = GURL(entry->GetKey());
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
783 870
784 if (query_cache_context->request && 871 if (query_cache_context->request &&
785 !query_cache_context->options.ignore_vary && 872 !query_cache_context->options.ignore_vary &&
786 !VaryMatches(query_cache_context->request->headers, 873 !VaryMatches(query_cache_context->request->headers,
787 match->request->headers, match->response->headers)) { 874 match->request->headers, match->response->headers)) {
788 query_cache_context->matches->pop_back(); 875 query_cache_context->matches->pop_back();
789 QueryCacheOpenNextEntry(std::move(query_cache_context)); 876 QueryCacheOpenNextEntry(std::move(query_cache_context));
790 return; 877 return;
791 } 878 }
792 879
793 if (query_cache_context->query_type == QueryCacheType::CACHE_ENTRIES) { 880 if (query_cache_context->query_types & QUERY_CACHE_ENTRIES)
881 match->entry = std::move(entry);
882
883 if (query_cache_context->query_types & QUERY_CACHE_REQUESTS) {
884 query_cache_context->estimated_out_bytes +=
885 match->request->EstimatedStructSize();
886 if (query_cache_context->estimated_out_bytes > max_query_size_bytes_) {
887 std::move(query_cache_context->callback)
888 .Run(CACHE_STORAGE_ERROR_QUERY_TOO_LARGE,
889 std::unique_ptr<QueryCacheResults>());
890 return;
891 }
892 } else {
794 match->request.reset(); 893 match->request.reset();
795 match->response.reset();
796 match->entry = std::move(entry);
797 QueryCacheOpenNextEntry(std::move(query_cache_context));
798 return;
799 } 894 }
800 895
801 query_cache_context->estimated_out_bytes += 896 if (query_cache_context->query_types & QUERY_CACHE_RESPONSES_WITH_BODIES) {
802 match->request->EstimatedStructSize(); 897 query_cache_context->estimated_out_bytes +=
803 if (query_cache_context->estimated_out_bytes > max_query_size_bytes_) { 898 match->response->EstimatedStructSize();
804 std::move(query_cache_context->callback) 899 if (query_cache_context->estimated_out_bytes > max_query_size_bytes_) {
805 .Run(CACHE_STORAGE_ERROR_QUERY_TOO_LARGE, 900 std::move(query_cache_context->callback)
806 std::unique_ptr<QueryCacheResults>()); 901 .Run(CACHE_STORAGE_ERROR_QUERY_TOO_LARGE,
807 return; 902 std::unique_ptr<QueryCacheResults>());
903 return;
904 }
905 if (entry->GetDataSize(INDEX_RESPONSE_BODY) == 0) {
906 QueryCacheOpenNextEntry(std::move(query_cache_context));
907 return;
908 }
909
910 if (!blob_storage_context_) {
911 std::move(query_cache_context->callback)
912 .Run(CACHE_STORAGE_ERROR_STORAGE,
913 std::unique_ptr<QueryCacheResults>());
914 return;
915 }
916
917 match->blob_handle =
918 PopulateResponseBody(std::move(entry), match->response.get());
919 } else if (!(query_cache_context->query_types &
920 QUERY_CACHE_RESPONSES_NO_BODIES)) {
921 match->response.reset();
808 } 922 }
809 923
810 if (query_cache_context->query_type == QueryCacheType::REQUESTS) {
811 match->response.reset();
812 QueryCacheOpenNextEntry(std::move(query_cache_context));
813 return;
814 }
815
816 DCHECK_EQ(QueryCacheType::REQUESTS_AND_RESPONSES,
817 query_cache_context->query_type);
818
819 query_cache_context->estimated_out_bytes +=
820 match->response->EstimatedStructSize();
821 if (query_cache_context->estimated_out_bytes > max_query_size_bytes_) {
822 std::move(query_cache_context->callback)
823 .Run(CACHE_STORAGE_ERROR_QUERY_TOO_LARGE,
824 std::unique_ptr<QueryCacheResults>());
825 return;
826 }
827
828 if (entry->GetDataSize(INDEX_RESPONSE_BODY) == 0) {
829 QueryCacheOpenNextEntry(std::move(query_cache_context));
830 return;
831 }
832
833 if (!blob_storage_context_) {
834 std::move(query_cache_context->callback)
835 .Run(CACHE_STORAGE_ERROR_STORAGE,
836 base::MakeUnique<QueryCacheResults>());
837 return;
838 }
839
840 std::unique_ptr<storage::BlobDataHandle> blob_data_handle =
841 PopulateResponseBody(std::move(entry), match->response.get());
842 match->blob_handle = std::move(blob_data_handle);
843
844 QueryCacheOpenNextEntry(std::move(query_cache_context)); 924 QueryCacheOpenNextEntry(std::move(query_cache_context));
845 } 925 }
846 926
847 // static 927 // static
848 bool CacheStorageCache::QueryCacheResultCompare(const QueryCacheResult& lhs, 928 bool CacheStorageCache::QueryCacheResultCompare(const QueryCacheResult& lhs,
849 const QueryCacheResult& rhs) { 929 const QueryCacheResult& rhs) {
850 return lhs.entry_time < rhs.entry_time; 930 return lhs.entry_time < rhs.entry_time;
851 } 931 }
852 932
933 // static
934 int64_t CacheStorageCache::CalculateResponsePadding(
935 const ServiceWorkerResponse& response,
936 const crypto::SymmetricKey* padding_key,
937 int side_data_size) {
938 if (!ShouldPadResourceSize(&response))
939 return 0;
940 return CalculateResponsePaddingInternal(response.url_list.back().spec(),
941 padding_key, side_data_size);
942 }
943
944 // static
945 int32_t CacheStorageCache::GetResponsePaddingVersion() {
946 return kCachePaddingAlgorithmVersion;
947 }
948
853 void CacheStorageCache::MatchImpl( 949 void CacheStorageCache::MatchImpl(
854 std::unique_ptr<ServiceWorkerFetchRequest> request, 950 std::unique_ptr<ServiceWorkerFetchRequest> request,
855 const CacheStorageCacheQueryParams& match_params, 951 const CacheStorageCacheQueryParams& match_params,
856 ResponseCallback callback) { 952 ResponseCallback callback) {
857 MatchAllImpl( 953 MatchAllImpl(
858 std::move(request), match_params, 954 std::move(request), match_params,
859 base::BindOnce(&CacheStorageCache::MatchDidMatchAll, 955 base::BindOnce(&CacheStorageCache::MatchDidMatchAll,
860 weak_ptr_factory_.GetWeakPtr(), std::move(callback))); 956 weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
861 } 957 }
862 958
(...skipping 29 matching lines...) Expand all
892 ResponsesCallback callback) { 988 ResponsesCallback callback) {
893 DCHECK_NE(BACKEND_UNINITIALIZED, backend_state_); 989 DCHECK_NE(BACKEND_UNINITIALIZED, backend_state_);
894 if (backend_state_ != BACKEND_OPEN) { 990 if (backend_state_ != BACKEND_OPEN) {
895 std::move(callback).Run(CACHE_STORAGE_ERROR_STORAGE, 991 std::move(callback).Run(CACHE_STORAGE_ERROR_STORAGE,
896 std::unique_ptr<Responses>(), 992 std::unique_ptr<Responses>(),
897 std::unique_ptr<BlobDataHandles>()); 993 std::unique_ptr<BlobDataHandles>());
898 return; 994 return;
899 } 995 }
900 996
901 QueryCache( 997 QueryCache(
902 std::move(request), options, QueryCacheType::REQUESTS_AND_RESPONSES, 998 std::move(request), options,
999 QUERY_CACHE_REQUESTS | QUERY_CACHE_RESPONSES_WITH_BODIES,
903 base::BindOnce(&CacheStorageCache::MatchAllDidQueryCache, 1000 base::BindOnce(&CacheStorageCache::MatchAllDidQueryCache,
904 weak_ptr_factory_.GetWeakPtr(), std::move(callback))); 1001 weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
905 } 1002 }
906 1003
907 void CacheStorageCache::MatchAllDidQueryCache( 1004 void CacheStorageCache::MatchAllDidQueryCache(
908 ResponsesCallback callback, 1005 ResponsesCallback callback,
909 CacheStorageError error, 1006 CacheStorageError error,
910 std::unique_ptr<QueryCacheResults> query_cache_results) { 1007 std::unique_ptr<QueryCacheResults> query_cache_results) {
911 if (error != CACHE_STORAGE_OK) { 1008 if (error != CACHE_STORAGE_OK) {
912 std::move(callback).Run(error, std::unique_ptr<Responses>(), 1009 std::move(callback).Run(error, std::unique_ptr<Responses>(),
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after
1005 std::unique_ptr<proto::CacheMetadata> headers) { 1102 std::unique_ptr<proto::CacheMetadata> headers) {
1006 if (!headers || 1103 if (!headers ||
1007 headers->response().response_time() != 1104 headers->response().response_time() !=
1008 expected_response_time.ToInternalValue()) { 1105 expected_response_time.ToInternalValue()) {
1009 std::move(callback).Run(CACHE_STORAGE_ERROR_NOT_FOUND); 1106 std::move(callback).Run(CACHE_STORAGE_ERROR_NOT_FOUND);
1010 return; 1107 return;
1011 } 1108 }
1012 // Get a temporary copy of the entry pointer before passing it in base::Bind. 1109 // Get a temporary copy of the entry pointer before passing it in base::Bind.
1013 disk_cache::Entry* temp_entry_ptr = entry.get(); 1110 disk_cache::Entry* temp_entry_ptr = entry.get();
1014 1111
1112 std::unique_ptr<content::proto::CacheResponse> response(
1113 headers->release_response());
1114
1115 int side_data_size_before_write = 0;
1116 if (ShouldPadResourceSize(response.get()))
1117 side_data_size_before_write = entry->GetDataSize(INDEX_SIDE_DATA);
1118
1015 net::CompletionCallback write_side_data_callback = 1119 net::CompletionCallback write_side_data_callback =
1016 base::AdaptCallbackForRepeating( 1120 base::AdaptCallbackForRepeating(
1017 base::BindOnce(&CacheStorageCache::WriteSideDataDidWrite, 1121 base::BindOnce(&CacheStorageCache::WriteSideDataDidWrite,
1018 weak_ptr_factory_.GetWeakPtr(), std::move(callback), 1122 weak_ptr_factory_.GetWeakPtr(), std::move(callback),
1019 base::Passed(std::move(entry)), buf_len)); 1123 base::Passed(std::move(entry)), buf_len,
1124 std::move(response), side_data_size_before_write));
1020 1125
1021 int rv = temp_entry_ptr->WriteData( 1126 int rv = temp_entry_ptr->WriteData(
1022 INDEX_SIDE_DATA, 0 /* offset */, buffer.get(), buf_len, 1127 INDEX_SIDE_DATA, 0 /* offset */, buffer.get(), buf_len,
1023 write_side_data_callback, true /* truncate */); 1128 write_side_data_callback, true /* truncate */);
1024 1129
1025 if (rv != net::ERR_IO_PENDING) 1130 if (rv != net::ERR_IO_PENDING)
1026 write_side_data_callback.Run(rv); 1131 write_side_data_callback.Run(rv);
1027 } 1132 }
1028 1133
1029 void CacheStorageCache::WriteSideDataDidWrite(ErrorCallback callback, 1134 void CacheStorageCache::WriteSideDataDidWrite(
1030 disk_cache::ScopedEntryPtr entry, 1135 ErrorCallback callback,
1031 int expected_bytes, 1136 disk_cache::ScopedEntryPtr entry,
1032 int rv) { 1137 int expected_bytes,
1138 std::unique_ptr<::content::proto::CacheResponse> response,
1139 int side_data_size_before_write,
1140 int rv) {
1033 if (rv != expected_bytes) { 1141 if (rv != expected_bytes) {
1034 entry->Doom(); 1142 entry->Doom();
1035 UpdateCacheSize( 1143 UpdateCacheSize(
1036 base::BindOnce(std::move(callback), CACHE_STORAGE_ERROR_NOT_FOUND)); 1144 base::BindOnce(std::move(callback), CACHE_STORAGE_ERROR_NOT_FOUND));
1037 return; 1145 return;
1038 } 1146 }
1039 1147
1040 if (rv > 0) 1148 if (rv > 0)
1041 storage::RecordBytesWritten(kRecordBytesLabel, rv); 1149 storage::RecordBytesWritten(kRecordBytesLabel, rv);
1042 1150
1151 if (ShouldPadResourceSize(response.get())) {
1152 cache_padding_ -= CalculateResponsePaddingInternal(
1153 response.get(), cache_padding_key_.get(), side_data_size_before_write);
1154
1155 cache_padding_ += CalculateResponsePaddingInternal(
1156 response.get(), cache_padding_key_.get(), rv);
1157 }
1158
1043 UpdateCacheSize(base::BindOnce(std::move(callback), CACHE_STORAGE_OK)); 1159 UpdateCacheSize(base::BindOnce(std::move(callback), CACHE_STORAGE_OK));
1044 } 1160 }
1045 1161
1046 void CacheStorageCache::Put(const CacheStorageBatchOperation& operation, 1162 void CacheStorageCache::Put(const CacheStorageBatchOperation& operation,
1047 ErrorCallback callback) { 1163 ErrorCallback callback) {
1048 DCHECK(BACKEND_OPEN == backend_state_ || initializing_); 1164 DCHECK(BACKEND_OPEN == backend_state_ || initializing_);
1049 DCHECK_EQ(CACHE_STORAGE_CACHE_OPERATION_TYPE_PUT, operation.operation_type); 1165 DCHECK_EQ(CACHE_STORAGE_CACHE_OPERATION_TYPE_PUT, operation.operation_type);
1050 1166
1051 std::unique_ptr<ServiceWorkerFetchRequest> request( 1167 std::unique_ptr<ServiceWorkerFetchRequest> request(
1052 new ServiceWorkerFetchRequest( 1168 new ServiceWorkerFetchRequest(
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
1085 base::Passed(std::move(put_context)))); 1201 base::Passed(std::move(put_context))));
1086 } 1202 }
1087 1203
1088 void CacheStorageCache::PutImpl(std::unique_ptr<PutContext> put_context) { 1204 void CacheStorageCache::PutImpl(std::unique_ptr<PutContext> put_context) {
1089 DCHECK_NE(BACKEND_UNINITIALIZED, backend_state_); 1205 DCHECK_NE(BACKEND_UNINITIALIZED, backend_state_);
1090 if (backend_state_ != BACKEND_OPEN) { 1206 if (backend_state_ != BACKEND_OPEN) {
1091 std::move(put_context->callback).Run(CACHE_STORAGE_ERROR_STORAGE); 1207 std::move(put_context->callback).Run(CACHE_STORAGE_ERROR_STORAGE);
1092 return; 1208 return;
1093 } 1209 }
1094 1210
1095 std::string key = put_context->request->url.spec(); 1211 // Explicitly delete the incumbent resource (which may not exist). This is
1212 // only done so that it's padding will be decremented from the calculated
1213 // cache padding.
1214 // TODO(cmumford): Research alternatives to this explicit delete as it
1215 // seriously impacts put performance.
1216 auto delete_request = base::MakeUnique<ServiceWorkerFetchRequest>(
1217 put_context->request->url, "", ServiceWorkerHeaderMap(), Referrer(),
1218 false);
1096 1219
1097 net::CompletionCallback callback = 1220 CacheStorageCacheQueryParams query_options;
1098 base::AdaptCallbackForRepeating(base::BindOnce( 1221 query_options.ignore_method = true;
1099 &CacheStorageCache::PutDidDoomEntry, weak_ptr_factory_.GetWeakPtr(), 1222 query_options.ignore_vary = true;
1100 base::Passed(std::move(put_context)))); 1223 DeleteImpl(std::move(delete_request), query_options,
1101 1224 base::BindOnce(&CacheStorageCache::PutDidDeleteEntry,
1102 int rv = backend_->DoomEntry(key, callback); 1225 weak_ptr_factory_.GetWeakPtr(),
1103 if (rv != net::ERR_IO_PENDING) 1226 base::Passed(std::move(put_context))));
1104 callback.Run(rv);
1105 } 1227 }
1106 1228
1107 void CacheStorageCache::PutDidDoomEntry(std::unique_ptr<PutContext> put_context, 1229 void CacheStorageCache::PutDidDeleteEntry(
1108 int rv) { 1230 std::unique_ptr<PutContext> put_context,
1231 CacheStorageError error,
1232 std::unique_ptr<QueryCacheResults> query_results) {
1109 if (backend_state_ != BACKEND_OPEN) { 1233 if (backend_state_ != BACKEND_OPEN) {
1110 std::move(put_context->callback).Run(CACHE_STORAGE_ERROR_STORAGE); 1234 std::move(put_context->callback).Run(CACHE_STORAGE_ERROR_STORAGE);
1111 return; 1235 return;
1112 } 1236 }
1113 1237
1114 // |rv| is ignored as doom entry can fail if the entry doesn't exist. 1238 if (error != CACHE_STORAGE_OK && error != CACHE_STORAGE_ERROR_NOT_FOUND) {
1239 std::move(put_context->callback).Run(error);
1240 return;
1241 }
1115 1242
1116 std::unique_ptr<disk_cache::Entry*> scoped_entry_ptr( 1243 std::unique_ptr<disk_cache::Entry*> scoped_entry_ptr(
1117 new disk_cache::Entry*()); 1244 new disk_cache::Entry*());
1118 disk_cache::Entry** entry_ptr = scoped_entry_ptr.get(); 1245 disk_cache::Entry** entry_ptr = scoped_entry_ptr.get();
1119 ServiceWorkerFetchRequest* request_ptr = put_context->request.get(); 1246 ServiceWorkerFetchRequest* request_ptr = put_context->request.get();
1120 disk_cache::Backend* backend_ptr = backend_.get(); 1247 disk_cache::Backend* backend_ptr = backend_.get();
1121 1248
1122 net::CompletionCallback create_entry_callback = 1249 net::CompletionCallback create_entry_callback =
1123 base::AdaptCallbackForRepeating(base::BindOnce( 1250 base::AdaptCallbackForRepeating(base::BindOnce(
1124 &CacheStorageCache::PutDidCreateEntry, weak_ptr_factory_.GetWeakPtr(), 1251 &CacheStorageCache::PutDidCreateEntry, weak_ptr_factory_.GetWeakPtr(),
1125 base::Passed(std::move(scoped_entry_ptr)), 1252 base::Passed(std::move(scoped_entry_ptr)),
1126 base::Passed(std::move(put_context)))); 1253 base::Passed(std::move(put_context))));
1127 1254
1128 int create_rv = backend_ptr->CreateEntry(request_ptr->url.spec(), entry_ptr, 1255 int rv = backend_ptr->CreateEntry(request_ptr->url.spec(), entry_ptr,
1129 create_entry_callback); 1256 create_entry_callback);
1130 1257
1131 if (create_rv != net::ERR_IO_PENDING) 1258 if (rv != net::ERR_IO_PENDING)
1132 create_entry_callback.Run(create_rv); 1259 create_entry_callback.Run(rv);
1133 } 1260 }
1134 1261
1135 void CacheStorageCache::PutDidCreateEntry( 1262 void CacheStorageCache::PutDidCreateEntry(
1136 std::unique_ptr<disk_cache::Entry*> entry_ptr, 1263 std::unique_ptr<disk_cache::Entry*> entry_ptr,
1137 std::unique_ptr<PutContext> put_context, 1264 std::unique_ptr<PutContext> put_context,
1138 int rv) { 1265 int rv) {
1139 put_context->cache_entry.reset(*entry_ptr); 1266 put_context->cache_entry.reset(*entry_ptr);
1140 1267
1141 if (rv != net::OK) { 1268 if (rv != net::OK) {
1142 std::move(put_context->callback).Run(CACHE_STORAGE_ERROR_EXISTS); 1269 std::move(put_context->callback).Run(CACHE_STORAGE_ERROR_EXISTS);
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
1209 int expected_bytes, 1336 int expected_bytes,
1210 int rv) { 1337 int rv) {
1211 if (rv != expected_bytes) { 1338 if (rv != expected_bytes) {
1212 put_context->cache_entry->Doom(); 1339 put_context->cache_entry->Doom();
1213 std::move(put_context->callback).Run(CACHE_STORAGE_ERROR_STORAGE); 1340 std::move(put_context->callback).Run(CACHE_STORAGE_ERROR_STORAGE);
1214 return; 1341 return;
1215 } 1342 }
1216 1343
1217 if (rv > 0) 1344 if (rv > 0)
1218 storage::RecordBytesWritten(kRecordBytesLabel, rv); 1345 storage::RecordBytesWritten(kRecordBytesLabel, rv);
1346 if (ShouldPadResourceSize(put_context->response.get())) {
1347 cache_padding_ += CalculateResponsePadding(*put_context->response,
1348 cache_padding_key_.get(),
1349 0 /* side_data_size */);
1350 }
1219 1351
1220 // The metadata is written, now for the response content. The data is streamed 1352 // The metadata is written, now for the response content. The data is streamed
1221 // from the blob into the cache entry. 1353 // from the blob into the cache entry.
1222 1354
1223 if (put_context->response->blob_uuid.empty()) { 1355 if (put_context->response->blob_uuid.empty()) {
1224 UpdateCacheSize( 1356 UpdateCacheSize(
1225 base::BindOnce(std::move(put_context->callback), CACHE_STORAGE_OK)); 1357 base::BindOnce(std::move(put_context->callback), CACHE_STORAGE_OK));
1226 return; 1358 return;
1227 } 1359 }
1228 1360
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after
1260 if (!success) { 1392 if (!success) {
1261 put_context->cache_entry->Doom(); 1393 put_context->cache_entry->Doom();
1262 std::move(put_context->callback).Run(CACHE_STORAGE_ERROR_STORAGE); 1394 std::move(put_context->callback).Run(CACHE_STORAGE_ERROR_STORAGE);
1263 return; 1395 return;
1264 } 1396 }
1265 1397
1266 UpdateCacheSize( 1398 UpdateCacheSize(
1267 base::BindOnce(std::move(put_context->callback), CACHE_STORAGE_OK)); 1399 base::BindOnce(std::move(put_context->callback), CACHE_STORAGE_OK));
1268 } 1400 }
1269 1401
1402 void CacheStorageCache::CalculateCacheSizePadding(
1403 SizePaddingCallback got_sizes_callback) {
1404 net::CompletionCallback got_size_callback =
1405 base::AdaptCallbackForRepeating(base::BindOnce(
1406 &CacheStorageCache::CalculateCacheSizePaddingGotSize,
1407 weak_ptr_factory_.GetWeakPtr(), std::move(got_sizes_callback)));
1408
1409 int rv = backend_->CalculateSizeOfAllEntries(got_size_callback);
1410 if (rv != net::ERR_IO_PENDING)
1411 got_size_callback.Run(rv);
1412 }
1413
1414 void CacheStorageCache::CalculateCacheSizePaddingGotSize(
1415 SizePaddingCallback callback,
1416 int cache_size) {
1417 // Enumerating entries is only done during cache initialization and only if
1418 // necessary.
1419 DCHECK_EQ(backend_state_, BACKEND_UNINITIALIZED);
1420 std::unique_ptr<ServiceWorkerFetchRequest> request;
1421 CacheStorageCacheQueryParams options;
1422 options.ignore_search = true;
1423 QueryCache(std::move(request), options, QUERY_CACHE_RESPONSES_NO_BODIES,
1424 base::BindOnce(&CacheStorageCache::PaddingDidQueryCache,
1425 weak_ptr_factory_.GetWeakPtr(), std::move(callback),
1426 cache_size));
1427 }
1428
1429 void CacheStorageCache::PaddingDidQueryCache(
1430 SizePaddingCallback callback,
1431 int cache_size,
1432 CacheStorageError error,
1433 std::unique_ptr<QueryCacheResults> query_cache_results) {
1434 int64_t cache_padding = 0;
1435 if (error == CACHE_STORAGE_OK) {
1436 for (const auto& result : *query_cache_results) {
1437 if (ShouldPadResourceSize(result.response.get())) {
1438 int32_t side_data_size =
1439 result.entry ? result.entry->GetDataSize(INDEX_SIDE_DATA) : 0;
1440 cache_padding += CalculateResponsePadding(
1441 *result.response, cache_padding_key_.get(), side_data_size);
1442 }
1443 }
1444 }
1445
1446 std::move(callback).Run(cache_size, cache_padding);
1447 }
1448
1449 void CacheStorageCache::CalculateCacheSize(
1450 const net::CompletionCallback& callback) {
1451 int rv = backend_->CalculateSizeOfAllEntries(callback);
1452 if (rv != net::ERR_IO_PENDING)
1453 callback.Run(rv);
1454 }
1455
1270 void CacheStorageCache::UpdateCacheSize(base::OnceClosure callback) { 1456 void CacheStorageCache::UpdateCacheSize(base::OnceClosure callback) {
1271 if (backend_state_ != BACKEND_OPEN) 1457 if (backend_state_ != BACKEND_OPEN)
1272 return; 1458 return;
1273 1459
1274 // Note that the callback holds a cache handle to keep the cache alive during 1460 // Note that the callback holds a cache handle to keep the cache alive during
1275 // the operation since this UpdateCacheSize is often run after an operation 1461 // the operation since this UpdateCacheSize is often run after an operation
1276 // completes and runs its callback. 1462 // completes and runs its callback.
1277 net::CompletionCallback size_callback = base::AdaptCallbackForRepeating( 1463 CalculateCacheSize(base::AdaptCallbackForRepeating(
1278 base::BindOnce(&CacheStorageCache::UpdateCacheSizeGotSize, 1464 base::BindOnce(&CacheStorageCache::UpdateCacheSizeGotSize,
1279 weak_ptr_factory_.GetWeakPtr(), 1465 weak_ptr_factory_.GetWeakPtr(),
1280 base::Passed(CreateCacheHandle()), std::move(callback))); 1466 base::Passed(CreateCacheHandle()), std::move(callback))));
1281
1282 int rv = backend_->CalculateSizeOfAllEntries(size_callback);
1283 if (rv != net::ERR_IO_PENDING)
1284 std::move(size_callback).Run(rv);
1285 } 1467 }
1286 1468
1287 void CacheStorageCache::UpdateCacheSizeGotSize( 1469 void CacheStorageCache::UpdateCacheSizeGotSize(
1288 std::unique_ptr<CacheStorageCacheHandle> cache_handle, 1470 std::unique_ptr<CacheStorageCacheHandle> cache_handle,
1289 base::OnceClosure callback, 1471 base::OnceClosure callback,
1290 int current_cache_size) { 1472 int current_cache_size) {
1291 DCHECK_NE(current_cache_size, CacheStorage::kSizeUnknown); 1473 DCHECK_NE(current_cache_size, CacheStorage::kSizeUnknown);
1292 int64_t old_cache_size = cache_size_;
1293 cache_size_ = current_cache_size; 1474 cache_size_ = current_cache_size;
1294 1475 int64_t size_delta = PaddedCacheSize() - last_reported_size_;
1295 int64_t size_delta = current_cache_size - old_cache_size; 1476 last_reported_size_ = PaddedCacheSize();
1296 1477
1297 quota_manager_proxy_->NotifyStorageModified( 1478 quota_manager_proxy_->NotifyStorageModified(
1298 storage::QuotaClient::kServiceWorkerCache, origin_, 1479 storage::QuotaClient::kServiceWorkerCache, origin_,
1299 storage::kStorageTypeTemporary, size_delta); 1480 storage::kStorageTypeTemporary, size_delta);
1300 1481
1301 if (cache_observer_) 1482 if (cache_observer_)
1302 cache_observer_->CacheSizeUpdated(this, current_cache_size); 1483 cache_observer_->CacheSizeUpdated(this, PaddedCacheSize());
1303 1484
1304 std::move(callback).Run(); 1485 std::move(callback).Run();
1305 } 1486 }
1306 1487
1307 void CacheStorageCache::Delete(const CacheStorageBatchOperation& operation, 1488 void CacheStorageCache::Delete(const CacheStorageBatchOperation& operation,
1308 ErrorCallback callback) { 1489 ErrorCallback callback) {
1309 DCHECK(BACKEND_OPEN == backend_state_ || initializing_); 1490 DCHECK(BACKEND_OPEN == backend_state_ || initializing_);
1310 DCHECK_EQ(CACHE_STORAGE_CACHE_OPERATION_TYPE_DELETE, 1491 DCHECK_EQ(CACHE_STORAGE_CACHE_OPERATION_TYPE_DELETE,
1311 operation.operation_type); 1492 operation.operation_type);
1312 1493
1313 std::unique_ptr<ServiceWorkerFetchRequest> request( 1494 std::unique_ptr<ServiceWorkerFetchRequest> request(
1314 new ServiceWorkerFetchRequest( 1495 new ServiceWorkerFetchRequest(
1315 operation.request.url, operation.request.method, 1496 operation.request.url, operation.request.method,
1316 operation.request.headers, operation.request.referrer, 1497 operation.request.headers, operation.request.referrer,
1317 operation.request.is_reload)); 1498 operation.request.is_reload));
1318 1499
1500 QueryCacheCallback delete_callback =
1501 base::BindOnce(&CacheStorageCache::DeleteDidDelete,
1502 weak_ptr_factory_.GetWeakPtr(), std::move(callback));
1503
1319 scheduler_->ScheduleOperation(base::BindOnce( 1504 scheduler_->ScheduleOperation(base::BindOnce(
1320 &CacheStorageCache::DeleteImpl, weak_ptr_factory_.GetWeakPtr(), 1505 &CacheStorageCache::DeleteImpl, weak_ptr_factory_.GetWeakPtr(),
1321 base::Passed(std::move(request)), operation.match_params, 1506 base::Passed(std::move(request)), operation.match_params,
1322 scheduler_->WrapCallbackToRunNext(std::move(callback)))); 1507 scheduler_->WrapCallbackToRunNext(std::move(delete_callback))));
1323 } 1508 }
1324 1509
1325 void CacheStorageCache::DeleteImpl( 1510 void CacheStorageCache::DeleteImpl(
1326 std::unique_ptr<ServiceWorkerFetchRequest> request, 1511 std::unique_ptr<ServiceWorkerFetchRequest> request,
1327 const CacheStorageCacheQueryParams& match_params, 1512 const CacheStorageCacheQueryParams& match_params,
1328 ErrorCallback callback) { 1513 QueryCacheCallback callback) {
1329 DCHECK_NE(BACKEND_UNINITIALIZED, backend_state_); 1514 DCHECK_NE(BACKEND_UNINITIALIZED, backend_state_);
1330 if (backend_state_ != BACKEND_OPEN) { 1515 if (backend_state_ != BACKEND_OPEN) {
1331 std::move(callback).Run(CACHE_STORAGE_ERROR_STORAGE); 1516 std::move(callback).Run(CACHE_STORAGE_ERROR_STORAGE,
1517 base::MakeUnique<QueryCacheResults>());
1332 return; 1518 return;
1333 } 1519 }
1334 1520
1335 QueryCache( 1521 QueryCache(
1336 std::move(request), match_params, QueryCacheType::CACHE_ENTRIES, 1522 std::move(request), match_params,
1523 QUERY_CACHE_ENTRIES | QUERY_CACHE_RESPONSES_NO_BODIES,
1337 base::BindOnce(&CacheStorageCache::DeleteDidQueryCache, 1524 base::BindOnce(&CacheStorageCache::DeleteDidQueryCache,
1338 weak_ptr_factory_.GetWeakPtr(), std::move(callback))); 1525 weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
1339 } 1526 }
1340 1527
1341 void CacheStorageCache::DeleteDidQueryCache( 1528 void CacheStorageCache::DeleteDidQueryCache(
1342 ErrorCallback callback, 1529 QueryCacheCallback callback,
1343 CacheStorageError error, 1530 CacheStorageError error,
1344 std::unique_ptr<QueryCacheResults> query_cache_results) { 1531 std::unique_ptr<QueryCacheResults> query_cache_results) {
1345 if (error != CACHE_STORAGE_OK) { 1532 if (error != CACHE_STORAGE_OK) {
1346 std::move(callback).Run(error); 1533 std::move(callback).Run(error, std::move(query_cache_results));
1347 return; 1534 return;
1348 } 1535 }
1349 1536
1350 if (query_cache_results->empty()) { 1537 if (query_cache_results->empty()) {
1351 std::move(callback).Run(CACHE_STORAGE_ERROR_NOT_FOUND); 1538 std::move(callback).Run(CACHE_STORAGE_ERROR_NOT_FOUND,
1539 std::move(query_cache_results));
1352 return; 1540 return;
1353 } 1541 }
1354 1542
1355 for (auto& result : *query_cache_results) { 1543 for (auto& result : *query_cache_results) {
1356 disk_cache::ScopedEntryPtr entry = std::move(result.entry); 1544 disk_cache::ScopedEntryPtr entry = std::move(result.entry);
1545 if (ShouldPadResourceSize(result.response.get())) {
1546 cache_padding_ -=
1547 CalculateResponsePadding(*result.response, cache_padding_key_.get(),
1548 entry->GetDataSize(INDEX_SIDE_DATA));
1549 }
1357 entry->Doom(); 1550 entry->Doom();
1358 } 1551 }
1359 1552
1360 UpdateCacheSize(base::BindOnce(std::move(callback), CACHE_STORAGE_OK)); 1553 UpdateCacheSize(base::BindOnce(std::move(callback), CACHE_STORAGE_OK,
1554 base::Passed(std::move(query_cache_results))));
1555 }
1556
1557 // Used in one call to DeleteImpl where |query_results| are not used and to be
1558 // ignored.
1559 void CacheStorageCache::DeleteDidDelete(
jkarlin 2017/07/31 14:03:24 This method shouldn't be needed any longer once we
cmumford 2017/08/10 16:37:11 Thx for noticing. Much simpler w/o it.
1560 ErrorCallback callback,
1561 CacheStorageError error,
1562 std::unique_ptr<QueryCacheResults> query_results) {
1563 std::move(callback).Run(error);
1361 } 1564 }
1362 1565
1363 void CacheStorageCache::KeysImpl( 1566 void CacheStorageCache::KeysImpl(
1364 std::unique_ptr<ServiceWorkerFetchRequest> request, 1567 std::unique_ptr<ServiceWorkerFetchRequest> request,
1365 const CacheStorageCacheQueryParams& options, 1568 const CacheStorageCacheQueryParams& options,
1366 RequestsCallback callback) { 1569 RequestsCallback callback) {
1367 DCHECK_NE(BACKEND_UNINITIALIZED, backend_state_); 1570 DCHECK_NE(BACKEND_UNINITIALIZED, backend_state_);
1368 if (backend_state_ != BACKEND_OPEN) { 1571 if (backend_state_ != BACKEND_OPEN) {
1369 std::move(callback).Run(CACHE_STORAGE_ERROR_STORAGE, 1572 std::move(callback).Run(CACHE_STORAGE_ERROR_STORAGE,
1370 std::unique_ptr<Requests>()); 1573 std::unique_ptr<Requests>());
1371 return; 1574 return;
1372 } 1575 }
1373 1576
1374 QueryCache( 1577 QueryCache(
1375 std::move(request), options, QueryCacheType::REQUESTS, 1578 std::move(request), options, QUERY_CACHE_REQUESTS,
1376 base::BindOnce(&CacheStorageCache::KeysDidQueryCache, 1579 base::BindOnce(&CacheStorageCache::KeysDidQueryCache,
1377 weak_ptr_factory_.GetWeakPtr(), std::move(callback))); 1580 weak_ptr_factory_.GetWeakPtr(), std::move(callback)));
1378 } 1581 }
1379 1582
1380 void CacheStorageCache::KeysDidQueryCache( 1583 void CacheStorageCache::KeysDidQueryCache(
1381 RequestsCallback callback, 1584 RequestsCallback callback,
1382 CacheStorageError error, 1585 CacheStorageError error,
1383 std::unique_ptr<QueryCacheResults> query_cache_results) { 1586 std::unique_ptr<QueryCacheResults> query_cache_results) {
1384 if (error != CACHE_STORAGE_OK) { 1587 if (error != CACHE_STORAGE_OK) {
1385 std::move(callback).Run(error, std::unique_ptr<Requests>()); 1588 std::move(callback).Run(error, std::unique_ptr<Requests>());
(...skipping 12 matching lines...) Expand all
1398 DCHECK_NE(BACKEND_CLOSED, backend_state_); 1601 DCHECK_NE(BACKEND_CLOSED, backend_state_);
1399 1602
1400 backend_state_ = BACKEND_CLOSED; 1603 backend_state_ = BACKEND_CLOSED;
1401 backend_.reset(); 1604 backend_.reset();
1402 std::move(callback).Run(); 1605 std::move(callback).Run();
1403 } 1606 }
1404 1607
1405 void CacheStorageCache::SizeImpl(SizeCallback callback) { 1608 void CacheStorageCache::SizeImpl(SizeCallback callback) {
1406 DCHECK_NE(BACKEND_UNINITIALIZED, backend_state_); 1609 DCHECK_NE(BACKEND_UNINITIALIZED, backend_state_);
1407 1610
1408 int64_t size = backend_state_ == BACKEND_OPEN ? cache_size_ : 0; 1611 // TODO(cmumford): Can CacheStorage::kSizeUnknown be returned instead of zero?
1612 if (backend_state_ != BACKEND_OPEN) {
1613 base::ThreadTaskRunnerHandle::Get()->PostTask(
1614 FROM_HERE, base::BindOnce(std::move(callback), 0));
1615 return;
1616 }
1617
1618 int64_t size = backend_state_ == BACKEND_OPEN ? PaddedCacheSize() : 0;
1409 base::ThreadTaskRunnerHandle::Get()->PostTask( 1619 base::ThreadTaskRunnerHandle::Get()->PostTask(
1410 FROM_HERE, base::BindOnce(std::move(callback), size)); 1620 FROM_HERE, base::BindOnce(std::move(callback), size));
1411 } 1621 }
1412 1622
1413 void CacheStorageCache::GetSizeThenCloseDidGetSize(SizeCallback callback, 1623 void CacheStorageCache::GetSizeThenCloseDidGetSize(SizeCallback callback,
1414 int64_t cache_size) { 1624 int64_t cache_size) {
1415 CloseImpl(base::BindOnce(std::move(callback), cache_size)); 1625 CloseImpl(base::BindOnce(std::move(callback), cache_size));
1416 } 1626 }
1417 1627
1418 void CacheStorageCache::CreateBackend(ErrorCallback callback) { 1628 void CacheStorageCache::CreateBackend(ErrorCallback callback) {
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
1471 } 1681 }
1472 1682
1473 void CacheStorageCache::InitDidCreateBackend( 1683 void CacheStorageCache::InitDidCreateBackend(
1474 base::OnceClosure callback, 1684 base::OnceClosure callback,
1475 CacheStorageError cache_create_error) { 1685 CacheStorageError cache_create_error) {
1476 if (cache_create_error != CACHE_STORAGE_OK) { 1686 if (cache_create_error != CACHE_STORAGE_OK) {
1477 InitGotCacheSize(std::move(callback), cache_create_error, 0); 1687 InitGotCacheSize(std::move(callback), cache_create_error, 0);
1478 return; 1688 return;
1479 } 1689 }
1480 1690
1481 net::CompletionCallback size_callback = 1691 auto calculate_size_callback =
1482 base::AdaptCallbackForRepeating(base::BindOnce( 1692 base::AdaptCallbackForRepeating(std::move(callback));
1483 &CacheStorageCache::InitGotCacheSize, weak_ptr_factory_.GetWeakPtr(), 1693 int rv = backend_->CalculateSizeOfAllEntries(base::Bind(
1484 std::move(callback), cache_create_error)); 1694 &CacheStorageCache::InitGotCacheSize, weak_ptr_factory_.GetWeakPtr(),
1695 calculate_size_callback, cache_create_error));
1485 1696
1486 int rv = backend_->CalculateSizeOfAllEntries(size_callback);
1487 if (rv != net::ERR_IO_PENDING) 1697 if (rv != net::ERR_IO_PENDING)
1488 std::move(size_callback).Run(rv); 1698 InitGotCacheSize(calculate_size_callback, cache_create_error, rv);
1489 } 1699 }
1490 1700
1491 void CacheStorageCache::InitGotCacheSize(base::OnceClosure callback, 1701 void CacheStorageCache::InitGotCacheSize(base::OnceClosure callback,
1492 CacheStorageError cache_create_error, 1702 CacheStorageError cache_create_error,
1493 int cache_size) { 1703 int cache_size) {
1494 // Now that we know the cache size either 1) the cache size should be unknown 1704 // Now that we know the cache size either 1) the cache size should be unknown
1495 // (which is why the size was calculated), or 2) it must match the current 1705 // (which is why the size was calculated), or 2) it must match the current
1496 // size. If the sizes aren't equal then there is a bug in how the cache size 1706 // size. If the sizes aren't equal then there is a bug in how the cache size
1497 // is saved in the store's index. 1707 // is saved in the store's index.
1498 if (cache_size_ != CacheStorage::kSizeUnknown) { 1708 if (cache_size_ != CacheStorage::kSizeUnknown) {
1499 DLOG_IF(ERROR, cache_size_ != cache_size) 1709 DLOG_IF(ERROR, cache_size_ != cache_size)
1500 << "Cache size: " << cache_size 1710 << "Cache size: " << cache_size
1501 << " does not match size from index: " << cache_size_; 1711 << " does not match size from index: " << cache_size_;
1502 UMA_HISTOGRAM_COUNTS_10M("ServiceWorkerCache.IndexSizeDifference", 1712 UMA_HISTOGRAM_COUNTS_10M("ServiceWorkerCache.IndexSizeDifference",
1503 std::abs(cache_size_ - cache_size)); 1713 std::abs(cache_size_ - cache_size));
1504 // Disabled for crbug.com/681900. 1714 if (cache_size_ != cache_size) {
1505 // DCHECK_EQ(cache_size_, cache_size); 1715 // We assume that if the sizes match then then cached padding is still
1716 // correct. If not then we recalculate the padding.
1717 CalculateCacheSizePaddingGotSize(
1718 base::BindOnce(&CacheStorageCache::InitGotCacheSizeAndPadding,
1719 weak_ptr_factory_.GetWeakPtr(), std::move(callback),
1720 cache_create_error),
1721 cache_size);
1722 return;
1723 }
1506 } 1724 }
1725
1726 if (cache_padding_ == CacheStorage::kSizeUnknown || cache_padding_ < 0) {
1727 CalculateCacheSizePaddingGotSize(
1728 base::BindOnce(&CacheStorageCache::InitGotCacheSizeAndPadding,
1729 weak_ptr_factory_.GetWeakPtr(), std::move(callback),
1730 cache_create_error),
1731 cache_size);
1732 return;
1733 }
1734
1735 // If cached size matches actual size then assume cached padding is still
1736 // correct.
1737 InitGotCacheSizeAndPadding(std::move(callback), cache_create_error,
1738 cache_size, cache_padding_);
1739 }
1740
1741 void CacheStorageCache::InitGotCacheSizeAndPadding(
1742 base::OnceClosure callback,
1743 CacheStorageError cache_create_error,
1744 int64_t cache_size,
1745 int64_t cache_padding) {
1507 cache_size_ = cache_size; 1746 cache_size_ = cache_size;
1747 cache_padding_ = cache_padding;
1748
1508 initializing_ = false; 1749 initializing_ = false;
1509 backend_state_ = (cache_create_error == CACHE_STORAGE_OK && backend_ && 1750 backend_state_ = (cache_create_error == CACHE_STORAGE_OK && backend_ &&
1510 backend_state_ == BACKEND_UNINITIALIZED) 1751 backend_state_ == BACKEND_UNINITIALIZED)
1511 ? BACKEND_OPEN 1752 ? BACKEND_OPEN
1512 : BACKEND_CLOSED; 1753 : BACKEND_CLOSED;
1513 1754
1514 UMA_HISTOGRAM_ENUMERATION("ServiceWorkerCache.InitBackendResult", 1755 UMA_HISTOGRAM_ENUMERATION("ServiceWorkerCache.InitBackendResult",
1515 cache_create_error, CACHE_STORAGE_ERROR_LAST + 1); 1756 cache_create_error, CACHE_STORAGE_ERROR_LAST + 1);
1516 1757
1517 if (cache_observer_) 1758 if (cache_observer_)
1518 cache_observer_->CacheSizeUpdated(this, cache_size_); 1759 cache_observer_->CacheSizeUpdated(this, PaddedCacheSize());
1519 1760
1520 std::move(callback).Run(); 1761 std::move(callback).Run();
1521 } 1762 }
1522 1763
1523 std::unique_ptr<storage::BlobDataHandle> 1764 std::unique_ptr<storage::BlobDataHandle>
1524 CacheStorageCache::PopulateResponseBody(disk_cache::ScopedEntryPtr entry, 1765 CacheStorageCache::PopulateResponseBody(disk_cache::ScopedEntryPtr entry,
1525 ServiceWorkerResponse* response) { 1766 ServiceWorkerResponse* response) {
1526 DCHECK(blob_storage_context_); 1767 DCHECK(blob_storage_context_);
1527 1768
1528 // Create a blob with the response body data. 1769 // Create a blob with the response body data.
1529 response->blob_size = entry->GetDataSize(INDEX_RESPONSE_BODY); 1770 response->blob_size = entry->GetDataSize(INDEX_RESPONSE_BODY);
1530 response->blob_uuid = base::GenerateGUID(); 1771 response->blob_uuid = base::GenerateGUID();
1531 storage::BlobDataBuilder blob_data(response->blob_uuid); 1772 storage::BlobDataBuilder blob_data(response->blob_uuid);
1532 1773
1533 disk_cache::Entry* temp_entry = entry.get(); 1774 disk_cache::Entry* temp_entry = entry.get();
1534 blob_data.AppendDiskCacheEntryWithSideData( 1775 blob_data.AppendDiskCacheEntryWithSideData(
1535 new CacheStorageCacheDataHandle(CreateCacheHandle(), std::move(entry)), 1776 new CacheStorageCacheDataHandle(CreateCacheHandle(), std::move(entry)),
1536 temp_entry, INDEX_RESPONSE_BODY, INDEX_SIDE_DATA); 1777 temp_entry, INDEX_RESPONSE_BODY, INDEX_SIDE_DATA);
1537 return blob_storage_context_->AddFinishedBlob(&blob_data); 1778 return blob_storage_context_->AddFinishedBlob(&blob_data);
1538 } 1779 }
1539 1780
1540 std::unique_ptr<CacheStorageCacheHandle> 1781 std::unique_ptr<CacheStorageCacheHandle>
1541 CacheStorageCache::CreateCacheHandle() { 1782 CacheStorageCache::CreateCacheHandle() {
1542 return cache_storage_->CreateCacheHandle(this); 1783 return cache_storage_->CreateCacheHandle(this);
1543 } 1784 }
1544 1785
1786 int64_t CacheStorageCache::PaddedCacheSize() const {
1787 DCHECK_NE(BACKEND_UNINITIALIZED, backend_state_);
1788 if (cache_size_ == CacheStorage::kSizeUnknown ||
1789 cache_padding_ == CacheStorage::kSizeUnknown) {
1790 return CacheStorage::kSizeUnknown;
1791 }
1792 return cache_size_ + cache_padding_;
1793 }
1794
1545 } // namespace content 1795 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698