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

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

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

Powered by Google App Engine
This is Rietveld 408576698