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

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

Issue 2901083002: [CacheStorage] Pad and bin opaque resource sizes. (Closed)
Patch Set: Creating single padding key per session. Created 3 years, 6 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 206 matching lines...) Expand 10 before | Expand all | Expand 10 after
247 metadata.response().status_text(), 250 metadata.response().status_text(),
248 ProtoResponseTypeToWebResponseType(metadata.response().response_type()), 251 ProtoResponseTypeToWebResponseType(metadata.response().response_type()),
249 std::move(headers), "", 0, blink::kWebServiceWorkerResponseErrorUnknown, 252 std::move(headers), "", 0, blink::kWebServiceWorkerResponseErrorUnknown,
250 base::Time::FromInternalValue(metadata.response().response_time()), 253 base::Time::FromInternalValue(metadata.response().response_time()),
251 true /* is_in_cache_storage */, cache_name, 254 true /* is_in_cache_storage */, cache_name,
252 base::MakeUnique<ServiceWorkerHeaderList>( 255 base::MakeUnique<ServiceWorkerHeaderList>(
253 metadata.response().cors_exposed_header_names().begin(), 256 metadata.response().cors_exposed_header_names().begin(),
254 metadata.response().cors_exposed_header_names().end())); 257 metadata.response().cors_exposed_header_names().end()));
255 } 258 }
256 259
260 // The size of opaque (non-cors) resource responses are padded in order
261 // to obfuscate their actual size.
262 bool ShouldPadResourceSize(const ServiceWorkerResponse& response) {
263 switch (response.response_type) {
264 case blink::kWebServiceWorkerResponseTypeBasic:
265 case blink::kWebServiceWorkerResponseTypeCORS:
266 case blink::kWebServiceWorkerResponseTypeDefault:
267 case blink::kWebServiceWorkerResponseTypeError:
268 return false;
269 case blink::kWebServiceWorkerResponseTypeOpaque:
270 case blink::kWebServiceWorkerResponseTypeOpaqueRedirect:
271 return !response.url_list.empty();
272 }
273 NOTREACHED();
274 return false;
275 }
276
257 } // namespace 277 } // namespace
258 278
259 // The state needed to pass between CacheStorageCache::Put callbacks. 279 // The state needed to pass between CacheStorageCache::Put callbacks.
260 struct CacheStorageCache::PutContext { 280 struct CacheStorageCache::PutContext {
261 PutContext(std::unique_ptr<ServiceWorkerFetchRequest> request, 281 PutContext(std::unique_ptr<ServiceWorkerFetchRequest> request,
262 std::unique_ptr<ServiceWorkerResponse> response, 282 std::unique_ptr<ServiceWorkerResponse> response,
263 std::unique_ptr<storage::BlobDataHandle> blob_data_handle, 283 std::unique_ptr<storage::BlobDataHandle> blob_data_handle,
264 const CacheStorageCache::ErrorCallback& callback) 284 const CacheStorageCache::ErrorCallback& callback)
265 : request(std::move(request)), 285 : request(std::move(request)),
266 response(std::move(response)), 286 response(std::move(response)),
(...skipping 17 matching lines...) Expand all
284 std::unique_ptr<ServiceWorkerFetchRequest> request; 304 std::unique_ptr<ServiceWorkerFetchRequest> request;
285 std::unique_ptr<ServiceWorkerResponse> response; 305 std::unique_ptr<ServiceWorkerResponse> response;
286 std::unique_ptr<storage::BlobDataHandle> blob_handle; 306 std::unique_ptr<storage::BlobDataHandle> blob_handle;
287 disk_cache::ScopedEntryPtr entry; 307 disk_cache::ScopedEntryPtr entry;
288 base::Time entry_time; 308 base::Time entry_time;
289 }; 309 };
290 310
291 struct CacheStorageCache::QueryCacheContext { 311 struct CacheStorageCache::QueryCacheContext {
292 QueryCacheContext(std::unique_ptr<ServiceWorkerFetchRequest> request, 312 QueryCacheContext(std::unique_ptr<ServiceWorkerFetchRequest> request,
293 const CacheStorageCacheQueryParams& options, 313 const CacheStorageCacheQueryParams& options,
294 const QueryCacheCallback& callback) 314 const QueryCacheCallback& callback,
315 uint32_t query_types)
295 : request(std::move(request)), 316 : request(std::move(request)),
296 options(options), 317 options(options),
297 callback(callback), 318 callback(callback),
319 query_types(query_types),
298 matches(base::MakeUnique<QueryCacheResults>()) {} 320 matches(base::MakeUnique<QueryCacheResults>()) {}
299 321
300 ~QueryCacheContext() { 322 ~QueryCacheContext() {
301 // If the CacheStorageCache is deleted before a backend operation to open 323 // If the CacheStorageCache is deleted before a backend operation to open
302 // an entry completes, the callback won't be run and the resulting entry 324 // an entry completes, the callback won't be run and the resulting entry
303 // will be leaked unless we close it here. 325 // will be leaked unless we close it here.
304 if (enumerated_entry) { 326 if (enumerated_entry) {
305 enumerated_entry->Close(); 327 enumerated_entry->Close();
306 enumerated_entry = nullptr; 328 enumerated_entry = nullptr;
307 } 329 }
308 } 330 }
309 331
310 // Input to QueryCache 332 // Input to QueryCache
311 std::unique_ptr<ServiceWorkerFetchRequest> request; 333 std::unique_ptr<ServiceWorkerFetchRequest> request;
312 CacheStorageCacheQueryParams options; 334 CacheStorageCacheQueryParams options;
313 QueryCacheCallback callback; 335 QueryCacheCallback callback;
314 QueryCacheType query_type; 336 uint32_t query_types = 0x0;
315 size_t estimated_out_bytes = 0; 337 size_t estimated_out_bytes = 0;
316 338
317 // Iteration state 339 // Iteration state
318 std::unique_ptr<disk_cache::Backend::Iterator> backend_iterator; 340 std::unique_ptr<disk_cache::Backend::Iterator> backend_iterator;
319 disk_cache::Entry* enumerated_entry = nullptr; 341 disk_cache::Entry* enumerated_entry = nullptr;
320 342
321 // Output of QueryCache 343 // Output of QueryCache
322 std::unique_ptr<std::vector<QueryCacheResult>> matches; 344 std::unique_ptr<std::vector<QueryCacheResult>> matches;
323 345
324 private: 346 private:
325 DISALLOW_COPY_AND_ASSIGN(QueryCacheContext); 347 DISALLOW_COPY_AND_ASSIGN(QueryCacheContext);
326 }; 348 };
327 349
328 // static 350 // static
329 std::unique_ptr<CacheStorageCache> CacheStorageCache::CreateMemoryCache( 351 std::unique_ptr<CacheStorageCache> CacheStorageCache::CreateMemoryCache(
330 const GURL& origin, 352 const GURL& origin,
331 const std::string& cache_name, 353 const std::string& cache_name,
332 CacheStorage* cache_storage, 354 CacheStorage* cache_storage,
333 scoped_refptr<net::URLRequestContextGetter> request_context_getter, 355 scoped_refptr<net::URLRequestContextGetter> request_context_getter,
334 scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy, 356 scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy,
335 base::WeakPtr<storage::BlobStorageContext> blob_context) { 357 base::WeakPtr<storage::BlobStorageContext> blob_context,
358 std::unique_ptr<crypto::SymmetricKey> cache_padding_key) {
336 CacheStorageCache* cache = new CacheStorageCache( 359 CacheStorageCache* cache = new CacheStorageCache(
337 origin, cache_name, base::FilePath(), cache_storage, 360 origin, cache_name, base::FilePath(), cache_storage,
338 std::move(request_context_getter), std::move(quota_manager_proxy), 361 std::move(request_context_getter), std::move(quota_manager_proxy),
339 blob_context, 0 /* cache_size */); 362 blob_context, 0 /* cache_size */, 0 /* cache_padding */,
363 std::move(cache_padding_key));
340 cache->SetObserver(cache_storage); 364 cache->SetObserver(cache_storage);
341 cache->InitBackend(); 365 cache->InitBackend();
342 return base::WrapUnique(cache); 366 return base::WrapUnique(cache);
343 } 367 }
344 368
345 // static 369 // static
346 std::unique_ptr<CacheStorageCache> CacheStorageCache::CreatePersistentCache( 370 std::unique_ptr<CacheStorageCache> CacheStorageCache::CreatePersistentCache(
347 const GURL& origin, 371 const GURL& origin,
348 const std::string& cache_name, 372 const std::string& cache_name,
349 CacheStorage* cache_storage, 373 CacheStorage* cache_storage,
350 const base::FilePath& path, 374 const base::FilePath& path,
351 scoped_refptr<net::URLRequestContextGetter> request_context_getter, 375 scoped_refptr<net::URLRequestContextGetter> request_context_getter,
352 scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy, 376 scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy,
353 base::WeakPtr<storage::BlobStorageContext> blob_context, 377 base::WeakPtr<storage::BlobStorageContext> blob_context,
354 int64_t cache_size) { 378 int64_t cache_size,
379 int64_t cache_padding,
380 std::unique_ptr<crypto::SymmetricKey> cache_padding_key) {
355 CacheStorageCache* cache = new CacheStorageCache( 381 CacheStorageCache* cache = new CacheStorageCache(
356 origin, cache_name, path, cache_storage, 382 origin, cache_name, path, cache_storage,
357 std::move(request_context_getter), std::move(quota_manager_proxy), 383 std::move(request_context_getter), std::move(quota_manager_proxy),
358 blob_context, cache_size); 384 blob_context, cache_size, cache_padding, std::move(cache_padding_key));
359 cache->SetObserver(cache_storage), cache->InitBackend(); 385 cache->SetObserver(cache_storage), cache->InitBackend();
360 return base::WrapUnique(cache); 386 return base::WrapUnique(cache);
361 } 387 }
362 388
363 base::WeakPtr<CacheStorageCache> CacheStorageCache::AsWeakPtr() { 389 base::WeakPtr<CacheStorageCache> CacheStorageCache::AsWeakPtr() {
364 return weak_ptr_factory_.GetWeakPtr(); 390 return weak_ptr_factory_.GetWeakPtr();
365 } 391 }
366 392
367 void CacheStorageCache::Match( 393 void CacheStorageCache::Match(
368 std::unique_ptr<ServiceWorkerFetchRequest> request, 394 std::unique_ptr<ServiceWorkerFetchRequest> request,
(...skipping 211 matching lines...) Expand 10 before | Expand all | Expand 10 after
580 } 606 }
581 607
582 CacheStorageCache::CacheStorageCache( 608 CacheStorageCache::CacheStorageCache(
583 const GURL& origin, 609 const GURL& origin,
584 const std::string& cache_name, 610 const std::string& cache_name,
585 const base::FilePath& path, 611 const base::FilePath& path,
586 CacheStorage* cache_storage, 612 CacheStorage* cache_storage,
587 scoped_refptr<net::URLRequestContextGetter> request_context_getter, 613 scoped_refptr<net::URLRequestContextGetter> request_context_getter,
588 scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy, 614 scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy,
589 base::WeakPtr<storage::BlobStorageContext> blob_context, 615 base::WeakPtr<storage::BlobStorageContext> blob_context,
590 int64_t cache_size) 616 int64_t cache_size,
617 int64_t cache_padding,
618 std::unique_ptr<crypto::SymmetricKey> cache_padding_key)
591 : origin_(origin), 619 : origin_(origin),
592 cache_name_(cache_name), 620 cache_name_(cache_name),
593 path_(path), 621 path_(path),
594 cache_storage_(cache_storage), 622 cache_storage_(cache_storage),
595 request_context_getter_(std::move(request_context_getter)), 623 request_context_getter_(std::move(request_context_getter)),
596 quota_manager_proxy_(std::move(quota_manager_proxy)), 624 quota_manager_proxy_(std::move(quota_manager_proxy)),
597 blob_storage_context_(blob_context), 625 blob_storage_context_(blob_context),
598 scheduler_( 626 scheduler_(
599 new CacheStorageScheduler(CacheStorageSchedulerClient::CLIENT_CACHE)), 627 new CacheStorageScheduler(CacheStorageSchedulerClient::CLIENT_CACHE)),
600 cache_size_(cache_size), 628 cache_size_(cache_size),
629 cache_padding_(cache_padding),
630 cache_padding_key_(std::move(cache_padding_key)),
601 max_query_size_bytes_(kMaxQueryCacheResultBytes), 631 max_query_size_bytes_(kMaxQueryCacheResultBytes),
602 cache_observer_(nullptr), 632 cache_observer_(nullptr),
603 memory_only_(path.empty()), 633 memory_only_(path.empty()),
604 weak_ptr_factory_(this) { 634 weak_ptr_factory_(this) {
605 DCHECK(!origin_.is_empty()); 635 DCHECK(!origin_.is_empty());
606 DCHECK(quota_manager_proxy_.get()); 636 DCHECK(quota_manager_proxy_.get());
637 DCHECK(cache_padding_key_.get());
607 638
608 quota_manager_proxy_->NotifyOriginInUse(origin_); 639 quota_manager_proxy_->NotifyOriginInUse(origin_);
609 } 640 }
610 641
611 void CacheStorageCache::QueryCache( 642 void CacheStorageCache::QueryCache(
612 std::unique_ptr<ServiceWorkerFetchRequest> request, 643 std::unique_ptr<ServiceWorkerFetchRequest> request,
613 const CacheStorageCacheQueryParams& options, 644 const CacheStorageCacheQueryParams& options,
614 QueryCacheType query_type, 645 uint32_t query_types,
615 const QueryCacheCallback& callback) { 646 const QueryCacheCallback& callback) {
616 DCHECK_NE(BACKEND_UNINITIALIZED, backend_state_); 647 DCHECK_NE(
617 if (backend_state_ != BACKEND_OPEN) { 648 QUERY_CACHE_ENTRIES | QUERY_CACHE_RESPONSES_WITH_BODIES,
649 query_types & (QUERY_CACHE_ENTRIES | QUERY_CACHE_RESPONSES_WITH_BODIES));
650 if (backend_state_ == BACKEND_CLOSED) {
618 callback.Run(CACHE_STORAGE_ERROR_STORAGE, 651 callback.Run(CACHE_STORAGE_ERROR_STORAGE,
619 std::unique_ptr<QueryCacheResults>()); 652 std::unique_ptr<QueryCacheResults>());
620 return; 653 return;
621 } 654 }
622 655
623 if (!options.ignore_method && request && !request->method.empty() && 656 if (!options.ignore_method && request && !request->method.empty() &&
624 request->method != "GET") { 657 request->method != "GET") {
625 callback.Run(CACHE_STORAGE_OK, base::MakeUnique<QueryCacheResults>()); 658 callback.Run(CACHE_STORAGE_OK, base::MakeUnique<QueryCacheResults>());
626 return; 659 return;
627 } 660 }
628 661
629 ServiceWorkerFetchRequest* request_ptr = request.get(); 662 ServiceWorkerFetchRequest* request_ptr = request.get();
630 std::unique_ptr<QueryCacheContext> query_cache_context( 663 std::unique_ptr<QueryCacheContext> query_cache_context(new QueryCacheContext(
631 new QueryCacheContext(std::move(request), options, callback)); 664 std::move(request), options, callback, query_types));
632 query_cache_context->query_type = query_type;
633 665
634 if (query_cache_context->request && 666 if (query_cache_context->request &&
635 !query_cache_context->request->url.is_empty() && !options.ignore_search) { 667 !query_cache_context->request->url.is_empty() && !options.ignore_search) {
636 // There is no need to scan the entire backend, just open the exact 668 // There is no need to scan the entire backend, just open the exact
637 // URL. 669 // URL.
638 disk_cache::Entry** entry_ptr = &query_cache_context->enumerated_entry; 670 disk_cache::Entry** entry_ptr = &query_cache_context->enumerated_entry;
639 net::CompletionCallback open_entry_callback = 671 net::CompletionCallback open_entry_callback =
640 base::Bind(&CacheStorageCache::QueryCacheDidOpenFastPath, 672 base::Bind(&CacheStorageCache::QueryCacheDidOpenFastPath,
641 weak_ptr_factory_.GetWeakPtr(), 673 weak_ptr_factory_.GetWeakPtr(),
642 base::Passed(std::move(query_cache_context))); 674 base::Passed(std::move(query_cache_context)));
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
703 if (rv < 0) { 735 if (rv < 0) {
704 QueryCacheCallback callback = query_cache_context->callback; 736 QueryCacheCallback callback = query_cache_context->callback;
705 callback.Run(CACHE_STORAGE_ERROR_STORAGE, 737 callback.Run(CACHE_STORAGE_ERROR_STORAGE,
706 std::move(query_cache_context->matches)); 738 std::move(query_cache_context->matches));
707 return; 739 return;
708 } 740 }
709 741
710 disk_cache::ScopedEntryPtr entry(query_cache_context->enumerated_entry); 742 disk_cache::ScopedEntryPtr entry(query_cache_context->enumerated_entry);
711 query_cache_context->enumerated_entry = nullptr; 743 query_cache_context->enumerated_entry = nullptr;
712 744
713 if (backend_state_ != BACKEND_OPEN) { 745 if (backend_state_ == BACKEND_CLOSED) {
714 QueryCacheCallback callback = query_cache_context->callback; 746 QueryCacheCallback callback = query_cache_context->callback;
715 callback.Run(CACHE_STORAGE_ERROR_NOT_FOUND, 747 callback.Run(CACHE_STORAGE_ERROR_NOT_FOUND,
716 std::move(query_cache_context->matches)); 748 std::move(query_cache_context->matches));
717 return; 749 return;
718 } 750 }
719 751
720 if (query_cache_context->request && 752 if (query_cache_context->request &&
721 !query_cache_context->request->url.is_empty()) { 753 !query_cache_context->request->url.is_empty()) {
722 GURL requestURL = query_cache_context->request->url; 754 GURL requestURL = query_cache_context->request->url;
723 GURL cachedURL = GURL(entry->GetKey()); 755 GURL cachedURL = GURL(entry->GetKey());
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
765 797
766 if (query_cache_context->request && 798 if (query_cache_context->request &&
767 !query_cache_context->options.ignore_vary && 799 !query_cache_context->options.ignore_vary &&
768 !VaryMatches(query_cache_context->request->headers, 800 !VaryMatches(query_cache_context->request->headers,
769 match->request->headers, match->response->headers)) { 801 match->request->headers, match->response->headers)) {
770 query_cache_context->matches->pop_back(); 802 query_cache_context->matches->pop_back();
771 QueryCacheOpenNextEntry(std::move(query_cache_context)); 803 QueryCacheOpenNextEntry(std::move(query_cache_context));
772 return; 804 return;
773 } 805 }
774 806
775 if (query_cache_context->query_type == QueryCacheType::CACHE_ENTRIES) { 807 if (query_cache_context->query_types & QUERY_CACHE_ENTRIES)
808 match->entry = std::move(entry);
809
810 if (query_cache_context->query_types & QUERY_CACHE_REQUESTS) {
811 query_cache_context->estimated_out_bytes +=
812 match->request->EstimatedStructSize();
813 if (query_cache_context->estimated_out_bytes > max_query_size_bytes_) {
814 query_cache_context->callback.Run(CACHE_STORAGE_ERROR_QUERY_TOO_LARGE,
815 std::unique_ptr<QueryCacheResults>());
816 return;
817 }
818 } else {
776 match->request.reset(); 819 match->request.reset();
777 match->response.reset();
778 match->entry = std::move(entry);
779 QueryCacheOpenNextEntry(std::move(query_cache_context));
780 return;
781 } 820 }
782 821
783 query_cache_context->estimated_out_bytes += 822 if (query_cache_context->query_types & QUERY_CACHE_RESPONSES_WITH_BODIES) {
784 match->request->EstimatedStructSize(); 823 query_cache_context->estimated_out_bytes +=
785 if (query_cache_context->estimated_out_bytes > max_query_size_bytes_) { 824 match->response->EstimatedStructSize();
786 query_cache_context->callback.Run(CACHE_STORAGE_ERROR_QUERY_TOO_LARGE, 825 if (query_cache_context->estimated_out_bytes > max_query_size_bytes_) {
787 std::unique_ptr<QueryCacheResults>()); 826 query_cache_context->callback.Run(CACHE_STORAGE_ERROR_QUERY_TOO_LARGE,
788 return; 827 std::unique_ptr<QueryCacheResults>());
828 return;
829 }
830 if (entry->GetDataSize(INDEX_RESPONSE_BODY) == 0) {
831 QueryCacheOpenNextEntry(std::move(query_cache_context));
832 return;
833 }
834
835 if (!blob_storage_context_) {
836 query_cache_context->callback.Run(CACHE_STORAGE_ERROR_STORAGE,
837 std::unique_ptr<QueryCacheResults>());
838 return;
839 }
840
841 std::unique_ptr<storage::BlobDataHandle> blob_data_handle =
842 PopulateResponseBody(std::move(entry), match->response.get());
843 match->blob_handle = std::move(blob_data_handle);
844 } else if (!(query_cache_context->query_types &
845 QUERY_CACHE_RESPONSES_NO_BODIES)) {
846 match->response.reset();
789 } 847 }
790 848
791 if (query_cache_context->query_type == QueryCacheType::REQUESTS) {
792 match->response.reset();
793 QueryCacheOpenNextEntry(std::move(query_cache_context));
794 return;
795 }
796
797 DCHECK_EQ(QueryCacheType::REQUESTS_AND_RESPONSES,
798 query_cache_context->query_type);
799
800 query_cache_context->estimated_out_bytes +=
801 match->response->EstimatedStructSize();
802 if (query_cache_context->estimated_out_bytes > max_query_size_bytes_) {
803 query_cache_context->callback.Run(CACHE_STORAGE_ERROR_QUERY_TOO_LARGE,
804 std::unique_ptr<QueryCacheResults>());
805 return;
806 }
807
808 if (entry->GetDataSize(INDEX_RESPONSE_BODY) == 0) {
809 QueryCacheOpenNextEntry(std::move(query_cache_context));
810 return;
811 }
812
813 if (!blob_storage_context_) {
814 query_cache_context->callback.Run(CACHE_STORAGE_ERROR_STORAGE,
815 base::MakeUnique<QueryCacheResults>());
816 return;
817 }
818
819 std::unique_ptr<storage::BlobDataHandle> blob_data_handle =
820 PopulateResponseBody(std::move(entry), match->response.get());
821 match->blob_handle = std::move(blob_data_handle);
822
823 QueryCacheOpenNextEntry(std::move(query_cache_context)); 849 QueryCacheOpenNextEntry(std::move(query_cache_context));
824 } 850 }
825 851
826 // static 852 // static
827 bool CacheStorageCache::QueryCacheResultCompare(const QueryCacheResult& lhs, 853 bool CacheStorageCache::QueryCacheResultCompare(const QueryCacheResult& lhs,
828 const QueryCacheResult& rhs) { 854 const QueryCacheResult& rhs) {
829 return lhs.entry_time < rhs.entry_time; 855 return lhs.entry_time < rhs.entry_time;
830 } 856 }
831 857
858 // static
859 int64_t CacheStorageCache::CalculateResponsePadding(
860 const ServiceWorkerResponse& response,
861 const crypto::SymmetricKey* padding_key) {
862 const uint64_t kPaddingRange = 400 * 1024;
863
864 if (!ShouldPadResourceSize(response))
865 return 0;
866
867 const std::string& url = response.url_list.back().spec();
868 crypto::HMAC hmac(crypto::HMAC::SHA256);
869 std::vector<uint8_t> digest(hmac.DigestLength());
870 if (!hmac.Init(padding_key) || !hmac.Sign(url, &digest[0], digest.size())) {
871 LOG(FATAL) << "Failed to calculate HMAC.";
872 }
873 uint64_t val = *(reinterpret_cast<uint64_t*>(&digest[0]));
874 return val % kPaddingRange;
875 }
876
832 void CacheStorageCache::MatchImpl( 877 void CacheStorageCache::MatchImpl(
833 std::unique_ptr<ServiceWorkerFetchRequest> request, 878 std::unique_ptr<ServiceWorkerFetchRequest> request,
834 const CacheStorageCacheQueryParams& match_params, 879 const CacheStorageCacheQueryParams& match_params,
835 const ResponseCallback& callback) { 880 const ResponseCallback& callback) {
836 MatchAllImpl(std::move(request), match_params, 881 MatchAllImpl(std::move(request), match_params,
837 base::Bind(&CacheStorageCache::MatchDidMatchAll, 882 base::Bind(&CacheStorageCache::MatchDidMatchAll,
838 weak_ptr_factory_.GetWeakPtr(), callback)); 883 weak_ptr_factory_.GetWeakPtr(), callback));
839 } 884 }
840 885
841 void CacheStorageCache::MatchDidMatchAll( 886 void CacheStorageCache::MatchDidMatchAll(
(...skipping 26 matching lines...) Expand all
868 const CacheStorageCacheQueryParams& options, 913 const CacheStorageCacheQueryParams& options,
869 const ResponsesCallback& callback) { 914 const ResponsesCallback& callback) {
870 DCHECK_NE(BACKEND_UNINITIALIZED, backend_state_); 915 DCHECK_NE(BACKEND_UNINITIALIZED, backend_state_);
871 if (backend_state_ != BACKEND_OPEN) { 916 if (backend_state_ != BACKEND_OPEN) {
872 callback.Run(CACHE_STORAGE_ERROR_STORAGE, std::unique_ptr<Responses>(), 917 callback.Run(CACHE_STORAGE_ERROR_STORAGE, std::unique_ptr<Responses>(),
873 std::unique_ptr<BlobDataHandles>()); 918 std::unique_ptr<BlobDataHandles>());
874 return; 919 return;
875 } 920 }
876 921
877 QueryCache(std::move(request), options, 922 QueryCache(std::move(request), options,
878 QueryCacheType::REQUESTS_AND_RESPONSES, 923 QUERY_CACHE_REQUESTS | QUERY_CACHE_RESPONSES_WITH_BODIES,
879 base::Bind(&CacheStorageCache::MatchAllDidQueryCache, 924 base::Bind(&CacheStorageCache::MatchAllDidQueryCache,
880 weak_ptr_factory_.GetWeakPtr(), callback)); 925 weak_ptr_factory_.GetWeakPtr(), callback));
881 } 926 }
882 927
883 void CacheStorageCache::MatchAllDidQueryCache( 928 void CacheStorageCache::MatchAllDidQueryCache(
884 const ResponsesCallback& callback, 929 const ResponsesCallback& callback,
885 CacheStorageError error, 930 CacheStorageError error,
886 std::unique_ptr<QueryCacheResults> query_cache_results) { 931 std::unique_ptr<QueryCacheResults> query_cache_results) {
887 if (error != CACHE_STORAGE_OK) { 932 if (error != CACHE_STORAGE_OK) {
888 callback.Run(error, std::unique_ptr<Responses>(), 933 callback.Run(error, std::unique_ptr<Responses>(),
(...skipping 168 matching lines...) Expand 10 before | Expand all | Expand 10 after
1057 base::Passed(std::move(put_context)))); 1102 base::Passed(std::move(put_context))));
1058 } 1103 }
1059 1104
1060 void CacheStorageCache::PutImpl(std::unique_ptr<PutContext> put_context) { 1105 void CacheStorageCache::PutImpl(std::unique_ptr<PutContext> put_context) {
1061 DCHECK_NE(BACKEND_UNINITIALIZED, backend_state_); 1106 DCHECK_NE(BACKEND_UNINITIALIZED, backend_state_);
1062 if (backend_state_ != BACKEND_OPEN) { 1107 if (backend_state_ != BACKEND_OPEN) {
1063 put_context->callback.Run(CACHE_STORAGE_ERROR_STORAGE); 1108 put_context->callback.Run(CACHE_STORAGE_ERROR_STORAGE);
1064 return; 1109 return;
1065 } 1110 }
1066 1111
1067 std::string key = put_context->request->url.spec(); 1112 // Explicitly delete the incumbent resource (which may not exist). This is
1113 // only done so that it's padding will be decremented from the calculated
1114 // cache padding.
1115 auto delete_request = base::MakeUnique<ServiceWorkerFetchRequest>(
1116 put_context->request->url, "", ServiceWorkerHeaderMap(), Referrer(),
1117 false);
1068 1118
1069 net::CompletionCallback callback = base::Bind( 1119 CacheStorageCacheQueryParams query_options;
1070 &CacheStorageCache::PutDidDoomEntry, weak_ptr_factory_.GetWeakPtr(), 1120 query_options.ignore_method = true;
1071 base::Passed(std::move(put_context))); 1121 query_options.ignore_vary = true;
1072 1122 DeleteImpl(std::move(delete_request), query_options,
jkarlin 2017/06/15 16:08:35 It hurts to call DeleteImpl here, as it's going to
cmumford 2017/06/20 18:22:04 Done. Unfortunately morlovich's abandoned his inde
1073 int rv = backend_->DoomEntry(key, callback); 1123 base::Bind(&CacheStorageCache::PutDidDeleteEntry,
1074 if (rv != net::ERR_IO_PENDING) 1124 weak_ptr_factory_.GetWeakPtr(),
1075 callback.Run(rv); 1125 base::Passed(std::move(put_context))));
1076 } 1126 }
1077 1127
1078 void CacheStorageCache::PutDidDoomEntry(std::unique_ptr<PutContext> put_context, 1128 void CacheStorageCache::PutDidDeleteEntry(
1079 int rv) { 1129 std::unique_ptr<PutContext> put_context,
1130 CacheStorageError error,
1131 std::unique_ptr<QueryCacheResults> query_results) {
1080 if (backend_state_ != BACKEND_OPEN) { 1132 if (backend_state_ != BACKEND_OPEN) {
1081 put_context->callback.Run(CACHE_STORAGE_ERROR_STORAGE); 1133 put_context->callback.Run(CACHE_STORAGE_ERROR_STORAGE);
1082 return; 1134 return;
1083 } 1135 }
1084 1136
1085 // |rv| is ignored as doom entry can fail if the entry doesn't exist. 1137 if (error != CACHE_STORAGE_OK && error != CACHE_STORAGE_ERROR_NOT_FOUND) {
1138 cache_padding_ -= CalculateResponsePadding(*put_context->response,
jkarlin 2017/06/15 16:08:35 Hmm, shouldn't delete take care of removing the ca
cmumford 2017/06/20 18:22:04 This is the read of the old cache entry that must
1139 cache_padding_key_.get());
1140 put_context->callback.Run(error);
1141 return;
1142 }
1086 1143
1087 std::unique_ptr<disk_cache::Entry*> scoped_entry_ptr( 1144 std::unique_ptr<disk_cache::Entry*> scoped_entry_ptr(
1088 new disk_cache::Entry*()); 1145 new disk_cache::Entry*());
1089 disk_cache::Entry** entry_ptr = scoped_entry_ptr.get(); 1146 disk_cache::Entry** entry_ptr = scoped_entry_ptr.get();
1090 ServiceWorkerFetchRequest* request_ptr = put_context->request.get(); 1147 ServiceWorkerFetchRequest* request_ptr = put_context->request.get();
1091 disk_cache::Backend* backend_ptr = backend_.get(); 1148 disk_cache::Backend* backend_ptr = backend_.get();
1092 1149
1093 net::CompletionCallback create_entry_callback = base::Bind( 1150 net::CompletionCallback create_entry_callback = base::Bind(
1094 &CacheStorageCache::PutDidCreateEntry, weak_ptr_factory_.GetWeakPtr(), 1151 &CacheStorageCache::PutDidCreateEntry, weak_ptr_factory_.GetWeakPtr(),
1095 base::Passed(std::move(scoped_entry_ptr)), 1152 base::Passed(std::move(scoped_entry_ptr)),
1096 base::Passed(std::move(put_context))); 1153 base::Passed(std::move(put_context)));
1097 1154
1098 int create_rv = backend_ptr->CreateEntry(request_ptr->url.spec(), entry_ptr, 1155 int rv = backend_ptr->CreateEntry(request_ptr->url.spec(), entry_ptr,
1099 create_entry_callback); 1156 create_entry_callback);
1100 1157
1101 if (create_rv != net::ERR_IO_PENDING) 1158 if (rv != net::ERR_IO_PENDING)
1102 create_entry_callback.Run(create_rv); 1159 create_entry_callback.Run(rv);
1103 } 1160 }
1104 1161
1105 void CacheStorageCache::PutDidCreateEntry( 1162 void CacheStorageCache::PutDidCreateEntry(
1106 std::unique_ptr<disk_cache::Entry*> entry_ptr, 1163 std::unique_ptr<disk_cache::Entry*> entry_ptr,
1107 std::unique_ptr<PutContext> put_context, 1164 std::unique_ptr<PutContext> put_context,
1108 int rv) { 1165 int rv) {
1109 put_context->cache_entry.reset(*entry_ptr); 1166 put_context->cache_entry.reset(*entry_ptr);
1110 1167
1111 if (rv != net::OK) { 1168 if (rv != net::OK) {
1112 put_context->callback.Run(CACHE_STORAGE_ERROR_EXISTS); 1169 put_context->callback.Run(CACHE_STORAGE_ERROR_EXISTS);
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
1177 int expected_bytes, 1234 int expected_bytes,
1178 int rv) { 1235 int rv) {
1179 if (rv != expected_bytes) { 1236 if (rv != expected_bytes) {
1180 put_context->cache_entry->Doom(); 1237 put_context->cache_entry->Doom();
1181 put_context->callback.Run(CACHE_STORAGE_ERROR_STORAGE); 1238 put_context->callback.Run(CACHE_STORAGE_ERROR_STORAGE);
1182 return; 1239 return;
1183 } 1240 }
1184 1241
1185 if (rv > 0) 1242 if (rv > 0)
1186 storage::RecordBytesWritten(kRecordBytesLabel, rv); 1243 storage::RecordBytesWritten(kRecordBytesLabel, rv);
1244 cache_padding_ += CalculateResponsePadding(*put_context->response,
jkarlin 2017/06/15 16:08:35 Ah, there is another place that we need to bump th
cmumford 2017/06/20 18:22:04 A few thoughts. 1. If we did ignore the side data
jkarlin 2017/06/26 17:59:19 We'd leak the size of whatever side-data is stored
1245 cache_padding_key_.get());
1187 1246
1188 // The metadata is written, now for the response content. The data is streamed 1247 // The metadata is written, now for the response content. The data is streamed
1189 // from the blob into the cache entry. 1248 // from the blob into the cache entry.
1190 1249
1191 if (put_context->response->blob_uuid.empty()) { 1250 if (put_context->response->blob_uuid.empty()) {
1192 UpdateCacheSize(base::Bind(put_context->callback, CACHE_STORAGE_OK)); 1251 UpdateCacheSize(base::Bind(put_context->callback, CACHE_STORAGE_OK));
1193 return; 1252 return;
1194 } 1253 }
1195 1254
1196 DCHECK(put_context->blob_data_handle); 1255 DCHECK(put_context->blob_data_handle);
(...skipping 29 matching lines...) Expand all
1226 1285
1227 if (!success) { 1286 if (!success) {
1228 put_context->cache_entry->Doom(); 1287 put_context->cache_entry->Doom();
1229 put_context->callback.Run(CACHE_STORAGE_ERROR_STORAGE); 1288 put_context->callback.Run(CACHE_STORAGE_ERROR_STORAGE);
1230 return; 1289 return;
1231 } 1290 }
1232 1291
1233 UpdateCacheSize(base::Bind(put_context->callback, CACHE_STORAGE_OK)); 1292 UpdateCacheSize(base::Bind(put_context->callback, CACHE_STORAGE_OK));
1234 } 1293 }
1235 1294
1295 void CacheStorageCache::CalculateCacheSizePadding(
1296 const SizePaddingCallback& got_sizes_callback) {
1297 net::CompletionCallback got_size_callback =
1298 base::Bind(&CacheStorageCache::CalculateCacheSizePaddingGotSize,
1299 weak_ptr_factory_.GetWeakPtr(), std::move(got_sizes_callback));
1300
1301 int rv = backend_->CalculateSizeOfAllEntries(got_size_callback);
1302 if (rv != net::ERR_IO_PENDING)
1303 got_size_callback.Run(rv);
1304 }
1305
1306 void CacheStorageCache::CalculateCacheSizePaddingGotSize(
1307 const SizePaddingCallback& callback,
1308 int cache_size) {
1309 // Enumerating entries is only done during cache initialization.
1310 DCHECK_EQ(backend_state_, BACKEND_UNINITIALIZED);
1311 std::unique_ptr<ServiceWorkerFetchRequest> request;
1312 CacheStorageCacheQueryParams options;
1313 options.ignore_search = true;
1314 QueryCache(std::move(request), options,
1315 QUERY_CACHE_REQUESTS | QUERY_CACHE_RESPONSES_WITH_BODIES,
jkarlin 2017/06/15 16:08:35 You want QUERY_CACHE_RESPONSES_NO_BODIES here I th
cmumford 2017/06/20 18:22:04 Yes, that was unnecessary - thx.
1316 base::Bind(&CacheStorageCache::PaddingDidQueryCache,
1317 weak_ptr_factory_.GetWeakPtr(), std::move(callback),
1318 cache_size));
1319 }
1320
1321 void CacheStorageCache::PaddingDidQueryCache(
1322 const SizePaddingCallback& callback,
1323 int cache_size,
1324 CacheStorageError error,
1325 std::unique_ptr<QueryCacheResults> query_cache_results) {
1326 int64_t cache_padding = 0;
1327 if (error == CACHE_STORAGE_OK) {
1328 for (const auto& result : *query_cache_results)
1329 cache_padding +=
1330 CalculateResponsePadding(*result.response, cache_padding_key_.get());
1331 }
1332
1333 callback.Run(cache_size, cache_padding);
1334 }
1335
1336 void CacheStorageCache::CalculateCacheSize(
1337 const net::CompletionCallback& callback) {
1338 int rv = backend_->CalculateSizeOfAllEntries(callback);
1339 if (rv != net::ERR_IO_PENDING)
1340 callback.Run(rv);
1341 }
1342
1236 void CacheStorageCache::UpdateCacheSize(const base::Closure& callback) { 1343 void CacheStorageCache::UpdateCacheSize(const base::Closure& callback) {
1237 if (backend_state_ != BACKEND_OPEN) 1344 if (backend_state_ != BACKEND_OPEN)
1238 return; 1345 return;
1239 1346
1240 // Note that the callback holds a cache handle to keep the cache alive during 1347 // Note that the callback holds a cache handle to keep the cache alive during
1241 // the operation since this UpdateCacheSize is often run after an operation 1348 // the operation since this UpdateCacheSize is often run after an operation
1242 // completes and runs its callback. 1349 // completes and runs its callback.
1243 int rv = backend_->CalculateSizeOfAllEntries( 1350 CalculateCacheSize(base::Bind(&CacheStorageCache::UpdateCacheSizeGotSize,
1244 base::Bind(&CacheStorageCache::UpdateCacheSizeGotSize, 1351 weak_ptr_factory_.GetWeakPtr(),
1245 weak_ptr_factory_.GetWeakPtr(), 1352 base::Passed(CreateCacheHandle()), callback));
1246 base::Passed(CreateCacheHandle()), callback));
1247
1248 if (rv != net::ERR_IO_PENDING)
1249 UpdateCacheSizeGotSize(CreateCacheHandle(), callback, rv);
1250 } 1353 }
1251 1354
1252 void CacheStorageCache::UpdateCacheSizeGotSize( 1355 void CacheStorageCache::UpdateCacheSizeGotSize(
1253 std::unique_ptr<CacheStorageCacheHandle> cache_handle, 1356 std::unique_ptr<CacheStorageCacheHandle> cache_handle,
1254 const base::Closure& callback, 1357 const base::Closure& callback,
1255 int current_cache_size) { 1358 int current_cache_size) {
1256 DCHECK_NE(current_cache_size, CacheStorage::kSizeUnknown); 1359 DCHECK_NE(current_cache_size, CacheStorage::kSizeUnknown);
1257 int64_t old_cache_size = cache_size_;
1258 cache_size_ = current_cache_size; 1360 cache_size_ = current_cache_size;
1259 1361 int64_t size_delta = PaddedCacheSize() - last_reported_size_;
1260 int64_t size_delta = current_cache_size - old_cache_size; 1362 last_reported_size_ = PaddedCacheSize();
1261 1363
1262 quota_manager_proxy_->NotifyStorageModified( 1364 quota_manager_proxy_->NotifyStorageModified(
1263 storage::QuotaClient::kServiceWorkerCache, origin_, 1365 storage::QuotaClient::kServiceWorkerCache, origin_,
1264 storage::kStorageTypeTemporary, size_delta); 1366 storage::kStorageTypeTemporary, size_delta);
1265 1367
1266 if (cache_observer_) 1368 if (cache_observer_)
1267 cache_observer_->CacheSizeUpdated(this, current_cache_size); 1369 cache_observer_->CacheSizeUpdated(this, PaddedCacheSize());
1268 1370
1269 callback.Run(); 1371 callback.Run();
1270 } 1372 }
1271 1373
1272 void CacheStorageCache::Delete(const CacheStorageBatchOperation& operation, 1374 void CacheStorageCache::Delete(const CacheStorageBatchOperation& operation,
1273 const ErrorCallback& callback) { 1375 const ErrorCallback& callback) {
1274 DCHECK(BACKEND_OPEN == backend_state_ || initializing_); 1376 DCHECK(BACKEND_OPEN == backend_state_ || initializing_);
1275 DCHECK_EQ(CACHE_STORAGE_CACHE_OPERATION_TYPE_DELETE, 1377 DCHECK_EQ(CACHE_STORAGE_CACHE_OPERATION_TYPE_DELETE,
1276 operation.operation_type); 1378 operation.operation_type);
1277 1379
1278 std::unique_ptr<ServiceWorkerFetchRequest> request( 1380 std::unique_ptr<ServiceWorkerFetchRequest> request(
1279 new ServiceWorkerFetchRequest( 1381 new ServiceWorkerFetchRequest(
1280 operation.request.url, operation.request.method, 1382 operation.request.url, operation.request.method,
1281 operation.request.headers, operation.request.referrer, 1383 operation.request.headers, operation.request.referrer,
1282 operation.request.is_reload)); 1384 operation.request.is_reload));
1283 1385
1386 QueryCacheCallback delete_callback =
1387 base::Bind(&CacheStorageCache::DeleteDidDelete,
1388 weak_ptr_factory_.GetWeakPtr(), callback);
1389
1284 scheduler_->ScheduleOperation( 1390 scheduler_->ScheduleOperation(
1285 base::Bind(&CacheStorageCache::DeleteImpl, weak_ptr_factory_.GetWeakPtr(), 1391 base::Bind(&CacheStorageCache::DeleteImpl, weak_ptr_factory_.GetWeakPtr(),
1286 base::Passed(std::move(request)), operation.match_params, 1392 base::Passed(std::move(request)), operation.match_params,
1287 scheduler_->WrapCallbackToRunNext(callback))); 1393 scheduler_->WrapCallbackToRunNext(delete_callback)));
1394 }
1395
1396 void CacheStorageCache::DeleteDidDelete(
1397 const ErrorCallback& callback,
1398 CacheStorageError error,
1399 std::unique_ptr<QueryCacheResults> query_results) {
1400 callback.Run(error);
1288 } 1401 }
1289 1402
1290 void CacheStorageCache::DeleteImpl( 1403 void CacheStorageCache::DeleteImpl(
1291 std::unique_ptr<ServiceWorkerFetchRequest> request, 1404 std::unique_ptr<ServiceWorkerFetchRequest> request,
1292 const CacheStorageCacheQueryParams& match_params, 1405 const CacheStorageCacheQueryParams& match_params,
1293 const ErrorCallback& callback) { 1406 const QueryCacheCallback& callback) {
1294 DCHECK_NE(BACKEND_UNINITIALIZED, backend_state_); 1407 DCHECK_NE(BACKEND_UNINITIALIZED, backend_state_);
1295 if (backend_state_ != BACKEND_OPEN) { 1408 if (backend_state_ != BACKEND_OPEN) {
1296 callback.Run(CACHE_STORAGE_ERROR_STORAGE); 1409 callback.Run(CACHE_STORAGE_ERROR_STORAGE,
1410 base::MakeUnique<QueryCacheResults>());
1297 return; 1411 return;
1298 } 1412 }
1299 1413
1300 QueryCache(std::move(request), match_params, QueryCacheType::CACHE_ENTRIES, 1414 QueryCache(std::move(request), match_params,
1415 QUERY_CACHE_ENTRIES | QUERY_CACHE_RESPONSES_NO_BODIES,
1301 base::Bind(&CacheStorageCache::DeleteDidQueryCache, 1416 base::Bind(&CacheStorageCache::DeleteDidQueryCache,
1302 weak_ptr_factory_.GetWeakPtr(), callback)); 1417 weak_ptr_factory_.GetWeakPtr(), callback));
1303 } 1418 }
1304 1419
1305 void CacheStorageCache::DeleteDidQueryCache( 1420 void CacheStorageCache::DeleteDidQueryCache(
1306 const ErrorCallback& callback, 1421 const QueryCacheCallback& callback,
1307 CacheStorageError error, 1422 CacheStorageError error,
1308 std::unique_ptr<QueryCacheResults> query_cache_results) { 1423 std::unique_ptr<QueryCacheResults> query_cache_results) {
1309 if (error != CACHE_STORAGE_OK) { 1424 if (error != CACHE_STORAGE_OK) {
1310 callback.Run(error); 1425 callback.Run(error, std::move(query_cache_results));
1311 return; 1426 return;
1312 } 1427 }
1313 1428
1314 if (query_cache_results->empty()) { 1429 if (query_cache_results->empty()) {
1315 callback.Run(CACHE_STORAGE_ERROR_NOT_FOUND); 1430 callback.Run(CACHE_STORAGE_ERROR_NOT_FOUND, std::move(query_cache_results));
1316 return; 1431 return;
1317 } 1432 }
1318 1433
1319 for (auto& result : *query_cache_results) { 1434 for (auto& result : *query_cache_results) {
1320 disk_cache::ScopedEntryPtr entry = std::move(result.entry); 1435 disk_cache::ScopedEntryPtr entry = std::move(result.entry);
1436 cache_padding_ -=
1437 CalculateResponsePadding(*result.response, cache_padding_key_.get());
1321 entry->Doom(); 1438 entry->Doom();
1322 } 1439 }
1323 1440
1324 UpdateCacheSize(base::Bind(callback, CACHE_STORAGE_OK)); 1441 UpdateCacheSize(base::Bind(callback, CACHE_STORAGE_OK,
1442 base::Passed(std::move(query_cache_results))));
1325 } 1443 }
1326 1444
1327 void CacheStorageCache::KeysImpl( 1445 void CacheStorageCache::KeysImpl(
1328 std::unique_ptr<ServiceWorkerFetchRequest> request, 1446 std::unique_ptr<ServiceWorkerFetchRequest> request,
1329 const CacheStorageCacheQueryParams& options, 1447 const CacheStorageCacheQueryParams& options,
1330 const RequestsCallback& callback) { 1448 const RequestsCallback& callback) {
1331 DCHECK_NE(BACKEND_UNINITIALIZED, backend_state_); 1449 DCHECK_NE(BACKEND_UNINITIALIZED, backend_state_);
1332 if (backend_state_ != BACKEND_OPEN) { 1450 if (backend_state_ != BACKEND_OPEN) {
1333 callback.Run(CACHE_STORAGE_ERROR_STORAGE, std::unique_ptr<Requests>()); 1451 callback.Run(CACHE_STORAGE_ERROR_STORAGE, std::unique_ptr<Requests>());
1334 return; 1452 return;
1335 } 1453 }
1336 1454
1337 QueryCache(std::move(request), options, QueryCacheType::REQUESTS, 1455 QueryCache(std::move(request), options, QUERY_CACHE_REQUESTS,
1338 base::Bind(&CacheStorageCache::KeysDidQueryCache, 1456 base::Bind(&CacheStorageCache::KeysDidQueryCache,
1339 weak_ptr_factory_.GetWeakPtr(), callback)); 1457 weak_ptr_factory_.GetWeakPtr(), callback));
1340 } 1458 }
1341 1459
1342 void CacheStorageCache::KeysDidQueryCache( 1460 void CacheStorageCache::KeysDidQueryCache(
1343 const RequestsCallback& callback, 1461 const RequestsCallback& callback,
1344 CacheStorageError error, 1462 CacheStorageError error,
1345 std::unique_ptr<QueryCacheResults> query_cache_results) { 1463 std::unique_ptr<QueryCacheResults> query_cache_results) {
1346 if (error != CACHE_STORAGE_OK) { 1464 if (error != CACHE_STORAGE_OK) {
1347 callback.Run(error, std::unique_ptr<Requests>()); 1465 callback.Run(error, std::unique_ptr<Requests>());
(...skipping 12 matching lines...) Expand all
1360 DCHECK_NE(BACKEND_CLOSED, backend_state_); 1478 DCHECK_NE(BACKEND_CLOSED, backend_state_);
1361 1479
1362 backend_state_ = BACKEND_CLOSED; 1480 backend_state_ = BACKEND_CLOSED;
1363 backend_.reset(); 1481 backend_.reset();
1364 callback.Run(); 1482 callback.Run();
1365 } 1483 }
1366 1484
1367 void CacheStorageCache::SizeImpl(const SizeCallback& callback) { 1485 void CacheStorageCache::SizeImpl(const SizeCallback& callback) {
1368 DCHECK_NE(BACKEND_UNINITIALIZED, backend_state_); 1486 DCHECK_NE(BACKEND_UNINITIALIZED, backend_state_);
1369 1487
1370 int64_t size = backend_state_ == BACKEND_OPEN ? cache_size_ : 0; 1488 // TODO(cmumford): Can CacheStorage::kSizeUnknown be returned instead of zero?
1489 if (backend_state_ != BACKEND_OPEN) {
1490 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
1491 base::Bind(callback, 0));
1492 return;
1493 }
1494
1495 int64_t size = backend_state_ == BACKEND_OPEN ? PaddedCacheSize() : 0;
1371 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, 1496 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
1372 base::Bind(callback, size)); 1497 base::Bind(callback, size));
1373 } 1498 }
1374 1499
1375 void CacheStorageCache::GetSizeThenCloseDidGetSize(const SizeCallback& callback, 1500 void CacheStorageCache::GetSizeThenCloseDidGetSize(const SizeCallback& callback,
1376 int64_t cache_size) { 1501 int64_t cache_size) {
1377 CloseImpl(base::Bind(callback, cache_size)); 1502 CloseImpl(base::Bind(callback, cache_size));
1378 } 1503 }
1379 1504
1380 void CacheStorageCache::CreateBackend(const ErrorCallback& callback) { 1505 void CacheStorageCache::CreateBackend(const ErrorCallback& callback) {
(...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after
1453 // Now that we know the cache size either 1) the cache size should be unknown 1578 // Now that we know the cache size either 1) the cache size should be unknown
1454 // (which is why the size was calculated), or 2) it must match the current 1579 // (which is why the size was calculated), or 2) it must match the current
1455 // size. If the sizes aren't equal then there is a bug in how the cache size 1580 // size. If the sizes aren't equal then there is a bug in how the cache size
1456 // is saved in the store's index. 1581 // is saved in the store's index.
1457 if (cache_size_ != CacheStorage::kSizeUnknown) { 1582 if (cache_size_ != CacheStorage::kSizeUnknown) {
1458 LOG_IF(ERROR, cache_size_ != cache_size) 1583 LOG_IF(ERROR, cache_size_ != cache_size)
1459 << "Cache size: " << cache_size 1584 << "Cache size: " << cache_size
1460 << " does not match size from index: " << cache_size_; 1585 << " does not match size from index: " << cache_size_;
1461 UMA_HISTOGRAM_COUNTS_10M("ServiceWorkerCache.IndexSizeDifference", 1586 UMA_HISTOGRAM_COUNTS_10M("ServiceWorkerCache.IndexSizeDifference",
1462 std::abs(cache_size_ - cache_size)); 1587 std::abs(cache_size_ - cache_size));
1463 // Disabled for crbug.com/681900. 1588 if (cache_size_ != cache_size) {
1464 // DCHECK_EQ(cache_size_, cache_size); 1589 // If the actual size doesn't match the cached size, then assume the
1590 // cached padding is also incorrect and recalculate.
1591 CalculateCacheSizePaddingGotSize(
1592 base::Bind(&CacheStorageCache::InitGotCacheSizeAndPadding,
1593 weak_ptr_factory_.GetWeakPtr(), callback,
1594 cache_create_error),
1595 cache_size);
1596 return;
1597 }
1465 } 1598 }
1599
1600 if (cache_padding_ == CacheStorage::kSizeUnknown || cache_padding_ < 0) {
jkarlin 2017/06/15 16:08:35 Can you add a comment somewhere around here that w
cmumford 2017/06/20 18:22:04 The comment above on line 1589 is almost the inver
1601 CalculateCacheSizePaddingGotSize(
1602 base::Bind(&CacheStorageCache::InitGotCacheSizeAndPadding,
1603 weak_ptr_factory_.GetWeakPtr(), callback,
1604 cache_create_error),
1605 cache_size);
1606 return;
1607 }
1608
1609 // If cached size matches actual size then assume cached padding is still
1610 // correct.
1611 InitGotCacheSizeAndPadding(callback, cache_create_error, cache_size,
1612 cache_padding_);
1613 }
1614
1615 void CacheStorageCache::InitGotCacheSizeAndPadding(
1616 const base::Closure& callback,
1617 CacheStorageError cache_create_error,
1618 int64_t cache_size,
1619 int64_t cache_padding) {
1466 cache_size_ = cache_size; 1620 cache_size_ = cache_size;
1621 cache_padding_ = cache_padding;
1622
1467 initializing_ = false; 1623 initializing_ = false;
1468 backend_state_ = (cache_create_error == CACHE_STORAGE_OK && backend_ && 1624 backend_state_ = (cache_create_error == CACHE_STORAGE_OK && backend_ &&
1469 backend_state_ == BACKEND_UNINITIALIZED) 1625 backend_state_ == BACKEND_UNINITIALIZED)
1470 ? BACKEND_OPEN 1626 ? BACKEND_OPEN
1471 : BACKEND_CLOSED; 1627 : BACKEND_CLOSED;
1472 1628
1473 UMA_HISTOGRAM_ENUMERATION("ServiceWorkerCache.InitBackendResult", 1629 UMA_HISTOGRAM_ENUMERATION("ServiceWorkerCache.InitBackendResult",
1474 cache_create_error, CACHE_STORAGE_ERROR_LAST + 1); 1630 cache_create_error, CACHE_STORAGE_ERROR_LAST + 1);
1475 1631
1476 if (cache_observer_) 1632 if (cache_observer_)
1477 cache_observer_->CacheSizeUpdated(this, cache_size_); 1633 cache_observer_->CacheSizeUpdated(this, PaddedCacheSize());
1478 1634
1479 callback.Run(); 1635 callback.Run();
1480 } 1636 }
1481 1637
1482 std::unique_ptr<storage::BlobDataHandle> 1638 std::unique_ptr<storage::BlobDataHandle>
1483 CacheStorageCache::PopulateResponseBody(disk_cache::ScopedEntryPtr entry, 1639 CacheStorageCache::PopulateResponseBody(disk_cache::ScopedEntryPtr entry,
1484 ServiceWorkerResponse* response) { 1640 ServiceWorkerResponse* response) {
1485 DCHECK(blob_storage_context_); 1641 DCHECK(blob_storage_context_);
1486 1642
1487 // Create a blob with the response body data. 1643 // Create a blob with the response body data.
1488 response->blob_size = entry->GetDataSize(INDEX_RESPONSE_BODY); 1644 response->blob_size = entry->GetDataSize(INDEX_RESPONSE_BODY);
1489 response->blob_uuid = base::GenerateGUID(); 1645 response->blob_uuid = base::GenerateGUID();
1490 storage::BlobDataBuilder blob_data(response->blob_uuid); 1646 storage::BlobDataBuilder blob_data(response->blob_uuid);
1491 1647
1492 disk_cache::Entry* temp_entry = entry.get(); 1648 disk_cache::Entry* temp_entry = entry.get();
1493 blob_data.AppendDiskCacheEntryWithSideData( 1649 blob_data.AppendDiskCacheEntryWithSideData(
1494 new CacheStorageCacheDataHandle(CreateCacheHandle(), std::move(entry)), 1650 new CacheStorageCacheDataHandle(CreateCacheHandle(), std::move(entry)),
1495 temp_entry, INDEX_RESPONSE_BODY, INDEX_SIDE_DATA); 1651 temp_entry, INDEX_RESPONSE_BODY, INDEX_SIDE_DATA);
1496 return blob_storage_context_->AddFinishedBlob(&blob_data); 1652 return blob_storage_context_->AddFinishedBlob(&blob_data);
1497 } 1653 }
1498 1654
1499 std::unique_ptr<CacheStorageCacheHandle> 1655 std::unique_ptr<CacheStorageCacheHandle>
1500 CacheStorageCache::CreateCacheHandle() { 1656 CacheStorageCache::CreateCacheHandle() {
1501 return cache_storage_->CreateCacheHandle(this); 1657 return cache_storage_->CreateCacheHandle(this);
1502 } 1658 }
1503 1659
1660 int64_t CacheStorageCache::PaddedCacheSize() const {
1661 if (cache_size_ == CacheStorage::kSizeUnknown ||
1662 cache_padding_ == CacheStorage::kSizeUnknown) {
1663 return CacheStorage::kSizeUnknown;
1664 }
1665 return cache_size_ + cache_padding_;
1666 }
1667
1504 } // namespace content 1668 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698