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

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

Issue 2901083002: [CacheStorage] Pad and bin opaque resource sizes. (Closed)
Patch Set: Storing padding key in cache. 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"
19 #include "base/lazy_instance.h"
18 #include "base/macros.h" 20 #include "base/macros.h"
19 #include "base/memory/ptr_util.h" 21 #include "base/memory/ptr_util.h"
20 #include "base/metrics/histogram_macros.h" 22 #include "base/metrics/histogram_macros.h"
21 #include "base/strings/string_split.h" 23 #include "base/strings/string_split.h"
22 #include "base/strings/string_util.h" 24 #include "base/strings/string_util.h"
23 #include "base/threading/thread_task_runner_handle.h" 25 #include "base/threading/thread_task_runner_handle.h"
24 #include "content/browser/cache_storage/cache_storage.pb.h" 26 #include "content/browser/cache_storage/cache_storage.pb.h"
25 #include "content/browser/cache_storage/cache_storage_blob_to_disk_cache.h" 27 #include "content/browser/cache_storage/cache_storage_blob_to_disk_cache.h"
26 #include "content/browser/cache_storage/cache_storage_cache_handle.h" 28 #include "content/browser/cache_storage/cache_storage_cache_handle.h"
27 #include "content/browser/cache_storage/cache_storage_cache_observer.h" 29 #include "content/browser/cache_storage/cache_storage_cache_observer.h"
28 #include "content/browser/cache_storage/cache_storage_scheduler.h" 30 #include "content/browser/cache_storage/cache_storage_scheduler.h"
29 #include "content/public/browser/browser_thread.h" 31 #include "content/public/browser/browser_thread.h"
30 #include "content/public/common/referrer.h" 32 #include "content/public/common/referrer.h"
33 #include "crypto/hmac.h"
34 #include "crypto/random.h"
31 #include "net/base/completion_callback.h" 35 #include "net/base/completion_callback.h"
32 #include "net/base/io_buffer.h" 36 #include "net/base/io_buffer.h"
33 #include "net/base/net_errors.h" 37 #include "net/base/net_errors.h"
34 #include "net/disk_cache/disk_cache.h" 38 #include "net/disk_cache/disk_cache.h"
35 #include "net/url_request/url_request_context_getter.h" 39 #include "net/url_request/url_request_context_getter.h"
36 #include "storage/browser/blob/blob_data_builder.h" 40 #include "storage/browser/blob/blob_data_builder.h"
37 #include "storage/browser/blob/blob_data_handle.h" 41 #include "storage/browser/blob/blob_data_handle.h"
38 #include "storage/browser/blob/blob_storage_context.h" 42 #include "storage/browser/blob/blob_storage_context.h"
39 #include "storage/browser/blob/blob_url_request_job_factory.h" 43 #include "storage/browser/blob/blob_url_request_job_factory.h"
40 #include "storage/browser/quota/quota_manager_proxy.h" 44 #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(), 251 metadata.response().status_text(),
248 ProtoResponseTypeToWebResponseType(metadata.response().response_type()), 252 ProtoResponseTypeToWebResponseType(metadata.response().response_type()),
249 std::move(headers), "", 0, blink::kWebServiceWorkerResponseErrorUnknown, 253 std::move(headers), "", 0, blink::kWebServiceWorkerResponseErrorUnknown,
250 base::Time::FromInternalValue(metadata.response().response_time()), 254 base::Time::FromInternalValue(metadata.response().response_time()),
251 true /* is_in_cache_storage */, cache_name, 255 true /* is_in_cache_storage */, cache_name,
252 base::MakeUnique<ServiceWorkerHeaderList>( 256 base::MakeUnique<ServiceWorkerHeaderList>(
253 metadata.response().cors_exposed_header_names().begin(), 257 metadata.response().cors_exposed_header_names().begin(),
254 metadata.response().cors_exposed_header_names().end())); 258 metadata.response().cors_exposed_header_names().end()));
255 } 259 }
256 260
261 // The size of opaque (non-cors) resource responses are padded in order
262 // to obfuscate their actual size.
263 bool ShouldPadResourceSize(const ServiceWorkerResponse& response) {
264 return (response.response_type ==
265 blink::kWebServiceWorkerResponseTypeOpaque ||
266 response.response_type ==
267 blink::kWebServiceWorkerResponseTypeOpaqueRedirect) &&
268 !response.url_list.empty();
269 }
270
271 // Return a hash of the |response| values to be used for the resource padding
272 // calculation.
273 std::string CalculateResponsePaddingHash(
274 const ServiceWorkerResponse& response) {
275 DCHECK(!response.url_list.empty());
276
277 size_t h = std::hash<std::string>{}(response.url_list.back().spec());
278 return std::string(reinterpret_cast<const char*>(&h), sizeof(h));
279 }
280
281 class PaddingHMACKey : public std::string {
282 public:
283 PaddingHMACKey() {
284 const size_t kKeyLen = 20;
285 reserve(kKeyLen);
286 crypto::RandBytes(&(*this)[0], capacity());
287 }
288 };
289
290 std::string CalculatePaddingHMAC(const std::string& value,
291 const std::string& hmac_key) {
292 crypto::HMAC hmac(crypto::HMAC::SHA256);
293 std::string result(hmac.DigestLength(), '\0');
294 if (!hmac.Init(hmac_key) ||
295 !hmac.Sign(value, reinterpret_cast<uint8_t*>(&result[0]),
296 result.length())) {
297 LOG(FATAL) << "Failed to calculate HMAC.";
298 }
299 return result;
300 }
301
302 // Converts the |response_hmac| bytes into a value from the random distribution
303 // determined by threat analysis.
304 int64_t ResponsePaddingDistribution(const std::string& response_hmac) {
305 size_t response_hash = std::hash<std::string>{}(response_hmac);
306 const size_t kPaddingRange = 400 * 1024;
307 const size_t kMinPadding = 20 * 1024;
jkarlin 2017/06/08 18:58:48 I don't believe having a min padding > 0 has any s
cmumford 2017/06/12 18:09:31 Done.
308 return kMinPadding + (response_hash % kPaddingRange);
309 }
310
257 } // namespace 311 } // namespace
258 312
259 // The state needed to pass between CacheStorageCache::Put callbacks. 313 // The state needed to pass between CacheStorageCache::Put callbacks.
260 struct CacheStorageCache::PutContext { 314 struct CacheStorageCache::PutContext {
261 PutContext(std::unique_ptr<ServiceWorkerFetchRequest> request, 315 PutContext(std::unique_ptr<ServiceWorkerFetchRequest> request,
262 std::unique_ptr<ServiceWorkerResponse> response, 316 std::unique_ptr<ServiceWorkerResponse> response,
263 std::unique_ptr<storage::BlobDataHandle> blob_data_handle, 317 std::unique_ptr<storage::BlobDataHandle> blob_data_handle,
264 const CacheStorageCache::ErrorCallback& callback) 318 const CacheStorageCache::ErrorCallback& callback)
265 : request(std::move(request)), 319 : request(std::move(request)),
266 response(std::move(response)), 320 response(std::move(response)),
(...skipping 17 matching lines...) Expand all
284 std::unique_ptr<ServiceWorkerFetchRequest> request; 338 std::unique_ptr<ServiceWorkerFetchRequest> request;
285 std::unique_ptr<ServiceWorkerResponse> response; 339 std::unique_ptr<ServiceWorkerResponse> response;
286 std::unique_ptr<storage::BlobDataHandle> blob_handle; 340 std::unique_ptr<storage::BlobDataHandle> blob_handle;
287 disk_cache::ScopedEntryPtr entry; 341 disk_cache::ScopedEntryPtr entry;
288 base::Time entry_time; 342 base::Time entry_time;
289 }; 343 };
290 344
291 struct CacheStorageCache::QueryCacheContext { 345 struct CacheStorageCache::QueryCacheContext {
292 QueryCacheContext(std::unique_ptr<ServiceWorkerFetchRequest> request, 346 QueryCacheContext(std::unique_ptr<ServiceWorkerFetchRequest> request,
293 const CacheStorageCacheQueryParams& options, 347 const CacheStorageCacheQueryParams& options,
294 const QueryCacheCallback& callback) 348 const QueryCacheCallback& callback,
349 uint32_t query_types)
295 : request(std::move(request)), 350 : request(std::move(request)),
296 options(options), 351 options(options),
297 callback(callback), 352 callback(callback),
353 query_types(query_types),
298 matches(base::MakeUnique<QueryCacheResults>()) {} 354 matches(base::MakeUnique<QueryCacheResults>()) {}
299 355
300 ~QueryCacheContext() { 356 ~QueryCacheContext() {
301 // If the CacheStorageCache is deleted before a backend operation to open 357 // 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 358 // an entry completes, the callback won't be run and the resulting entry
303 // will be leaked unless we close it here. 359 // will be leaked unless we close it here.
304 if (enumerated_entry) { 360 if (enumerated_entry) {
305 enumerated_entry->Close(); 361 enumerated_entry->Close();
306 enumerated_entry = nullptr; 362 enumerated_entry = nullptr;
307 } 363 }
308 } 364 }
309 365
310 // Input to QueryCache 366 // Input to QueryCache
311 std::unique_ptr<ServiceWorkerFetchRequest> request; 367 std::unique_ptr<ServiceWorkerFetchRequest> request;
312 CacheStorageCacheQueryParams options; 368 CacheStorageCacheQueryParams options;
313 QueryCacheCallback callback; 369 QueryCacheCallback callback;
314 QueryCacheType query_type; 370 uint32_t query_types = 0x0;
315 size_t estimated_out_bytes = 0; 371 size_t estimated_out_bytes = 0;
316 372
317 // Iteration state 373 // Iteration state
318 std::unique_ptr<disk_cache::Backend::Iterator> backend_iterator; 374 std::unique_ptr<disk_cache::Backend::Iterator> backend_iterator;
319 disk_cache::Entry* enumerated_entry = nullptr; 375 disk_cache::Entry* enumerated_entry = nullptr;
320 376
321 // Output of QueryCache 377 // Output of QueryCache
322 std::unique_ptr<std::vector<QueryCacheResult>> matches; 378 std::unique_ptr<std::vector<QueryCacheResult>> matches;
323 379
324 private: 380 private:
325 DISALLOW_COPY_AND_ASSIGN(QueryCacheContext); 381 DISALLOW_COPY_AND_ASSIGN(QueryCacheContext);
326 }; 382 };
327 383
328 // static 384 // static
329 std::unique_ptr<CacheStorageCache> CacheStorageCache::CreateMemoryCache( 385 std::unique_ptr<CacheStorageCache> CacheStorageCache::CreateMemoryCache(
330 const GURL& origin, 386 const GURL& origin,
331 const std::string& cache_name, 387 const std::string& cache_name,
332 CacheStorage* cache_storage, 388 CacheStorage* cache_storage,
333 scoped_refptr<net::URLRequestContextGetter> request_context_getter, 389 scoped_refptr<net::URLRequestContextGetter> request_context_getter,
334 scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy, 390 scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy,
335 base::WeakPtr<storage::BlobStorageContext> blob_context) { 391 base::WeakPtr<storage::BlobStorageContext> blob_context) {
336 CacheStorageCache* cache = new CacheStorageCache( 392 CacheStorageCache* cache = new CacheStorageCache(
337 origin, cache_name, base::FilePath(), cache_storage, 393 origin, cache_name, base::FilePath(), cache_storage,
338 std::move(request_context_getter), std::move(quota_manager_proxy), 394 std::move(request_context_getter), std::move(quota_manager_proxy),
339 blob_context, 0 /* cache_size */); 395 blob_context, 0 /* cache_size */, 0 /* cache_padding */,
396 SessionPaddingHMACKey());
340 cache->SetObserver(cache_storage); 397 cache->SetObserver(cache_storage);
341 cache->InitBackend(); 398 cache->InitBackend();
342 return base::WrapUnique(cache); 399 return base::WrapUnique(cache);
343 } 400 }
344 401
345 // static 402 // static
346 std::unique_ptr<CacheStorageCache> CacheStorageCache::CreatePersistentCache( 403 std::unique_ptr<CacheStorageCache> CacheStorageCache::CreatePersistentCache(
347 const GURL& origin, 404 const GURL& origin,
348 const std::string& cache_name, 405 const std::string& cache_name,
349 CacheStorage* cache_storage, 406 CacheStorage* cache_storage,
350 const base::FilePath& path, 407 const base::FilePath& path,
351 scoped_refptr<net::URLRequestContextGetter> request_context_getter, 408 scoped_refptr<net::URLRequestContextGetter> request_context_getter,
352 scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy, 409 scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy,
353 base::WeakPtr<storage::BlobStorageContext> blob_context, 410 base::WeakPtr<storage::BlobStorageContext> blob_context,
354 int64_t cache_size) { 411 int64_t cache_size,
412 int64_t cache_padding,
413 const std::string& cache_padding_key) {
355 CacheStorageCache* cache = new CacheStorageCache( 414 CacheStorageCache* cache = new CacheStorageCache(
356 origin, cache_name, path, cache_storage, 415 origin, cache_name, path, cache_storage,
357 std::move(request_context_getter), std::move(quota_manager_proxy), 416 std::move(request_context_getter), std::move(quota_manager_proxy),
358 blob_context, cache_size); 417 blob_context, cache_size, cache_padding, cache_padding_key);
359 cache->SetObserver(cache_storage), cache->InitBackend(); 418 cache->SetObserver(cache_storage), cache->InitBackend();
360 return base::WrapUnique(cache); 419 return base::WrapUnique(cache);
361 } 420 }
362 421
422 // static
423 const std::string& CacheStorageCache::SessionPaddingHMACKey() {
424 static base::LazyInstance<PaddingHMACKey>::Leaky s_key =
425 LAZY_INSTANCE_INITIALIZER;
426 return s_key.Get();
427 }
428
363 base::WeakPtr<CacheStorageCache> CacheStorageCache::AsWeakPtr() { 429 base::WeakPtr<CacheStorageCache> CacheStorageCache::AsWeakPtr() {
364 return weak_ptr_factory_.GetWeakPtr(); 430 return weak_ptr_factory_.GetWeakPtr();
365 } 431 }
366 432
367 void CacheStorageCache::Match( 433 void CacheStorageCache::Match(
368 std::unique_ptr<ServiceWorkerFetchRequest> request, 434 std::unique_ptr<ServiceWorkerFetchRequest> request,
369 const CacheStorageCacheQueryParams& match_params, 435 const CacheStorageCacheQueryParams& match_params,
370 const ResponseCallback& callback) { 436 const ResponseCallback& callback) {
371 if (backend_state_ == BACKEND_CLOSED) { 437 if (backend_state_ == BACKEND_CLOSED) {
372 callback.Run(CACHE_STORAGE_ERROR_STORAGE, 438 callback.Run(CACHE_STORAGE_ERROR_STORAGE,
(...skipping 207 matching lines...) Expand 10 before | Expand all | Expand 10 after
580 } 646 }
581 647
582 CacheStorageCache::CacheStorageCache( 648 CacheStorageCache::CacheStorageCache(
583 const GURL& origin, 649 const GURL& origin,
584 const std::string& cache_name, 650 const std::string& cache_name,
585 const base::FilePath& path, 651 const base::FilePath& path,
586 CacheStorage* cache_storage, 652 CacheStorage* cache_storage,
587 scoped_refptr<net::URLRequestContextGetter> request_context_getter, 653 scoped_refptr<net::URLRequestContextGetter> request_context_getter,
588 scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy, 654 scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy,
589 base::WeakPtr<storage::BlobStorageContext> blob_context, 655 base::WeakPtr<storage::BlobStorageContext> blob_context,
590 int64_t cache_size) 656 int64_t cache_size,
657 int64_t cache_padding,
658 const std::string& cache_padding_key)
591 : origin_(origin), 659 : origin_(origin),
592 cache_name_(cache_name), 660 cache_name_(cache_name),
593 path_(path), 661 path_(path),
594 cache_storage_(cache_storage), 662 cache_storage_(cache_storage),
595 request_context_getter_(std::move(request_context_getter)), 663 request_context_getter_(std::move(request_context_getter)),
596 quota_manager_proxy_(std::move(quota_manager_proxy)), 664 quota_manager_proxy_(std::move(quota_manager_proxy)),
597 blob_storage_context_(blob_context), 665 blob_storage_context_(blob_context),
598 scheduler_( 666 scheduler_(
599 new CacheStorageScheduler(CacheStorageSchedulerClient::CLIENT_CACHE)), 667 new CacheStorageScheduler(CacheStorageSchedulerClient::CLIENT_CACHE)),
600 cache_size_(cache_size), 668 cache_size_(cache_size),
669 cache_padding_(cache_padding),
670 cache_padding_key_(cache_padding_key),
601 max_query_size_bytes_(kMaxQueryCacheResultBytes), 671 max_query_size_bytes_(kMaxQueryCacheResultBytes),
602 cache_observer_(nullptr), 672 cache_observer_(nullptr),
603 memory_only_(path.empty()), 673 memory_only_(path.empty()),
604 weak_ptr_factory_(this) { 674 weak_ptr_factory_(this) {
605 DCHECK(!origin_.is_empty()); 675 DCHECK(!origin_.is_empty());
606 DCHECK(quota_manager_proxy_.get()); 676 DCHECK(quota_manager_proxy_.get());
607 677
608 quota_manager_proxy_->NotifyOriginInUse(origin_); 678 quota_manager_proxy_->NotifyOriginInUse(origin_);
609 } 679 }
610 680
611 void CacheStorageCache::QueryCache( 681 void CacheStorageCache::QueryCache(
612 std::unique_ptr<ServiceWorkerFetchRequest> request, 682 std::unique_ptr<ServiceWorkerFetchRequest> request,
613 const CacheStorageCacheQueryParams& options, 683 const CacheStorageCacheQueryParams& options,
614 QueryCacheType query_type, 684 uint32_t query_types,
615 const QueryCacheCallback& callback) { 685 const QueryCacheCallback& callback) {
616 DCHECK_NE(BACKEND_UNINITIALIZED, backend_state_); 686 DCHECK_NE(
617 if (backend_state_ != BACKEND_OPEN) { 687 QUERY_CACHE_ENTRIES | QUERY_CACHE_RESPONSES_WITH_BODIES,
688 query_types & (QUERY_CACHE_ENTRIES | QUERY_CACHE_RESPONSES_WITH_BODIES));
689 if (backend_state_ == BACKEND_CLOSED) {
618 callback.Run(CACHE_STORAGE_ERROR_STORAGE, 690 callback.Run(CACHE_STORAGE_ERROR_STORAGE,
619 std::unique_ptr<QueryCacheResults>()); 691 std::unique_ptr<QueryCacheResults>());
620 return; 692 return;
621 } 693 }
622 694
623 if (!options.ignore_method && request && !request->method.empty() && 695 if (!options.ignore_method && request && !request->method.empty() &&
624 request->method != "GET") { 696 request->method != "GET") {
625 callback.Run(CACHE_STORAGE_OK, base::MakeUnique<QueryCacheResults>()); 697 callback.Run(CACHE_STORAGE_OK, base::MakeUnique<QueryCacheResults>());
626 return; 698 return;
627 } 699 }
628 700
629 ServiceWorkerFetchRequest* request_ptr = request.get(); 701 ServiceWorkerFetchRequest* request_ptr = request.get();
630 std::unique_ptr<QueryCacheContext> query_cache_context( 702 std::unique_ptr<QueryCacheContext> query_cache_context(new QueryCacheContext(
631 new QueryCacheContext(std::move(request), options, callback)); 703 std::move(request), options, callback, query_types));
632 query_cache_context->query_type = query_type;
633 704
634 if (query_cache_context->request && 705 if (query_cache_context->request &&
635 !query_cache_context->request->url.is_empty() && !options.ignore_search) { 706 !query_cache_context->request->url.is_empty() && !options.ignore_search) {
636 // There is no need to scan the entire backend, just open the exact 707 // There is no need to scan the entire backend, just open the exact
637 // URL. 708 // URL.
638 disk_cache::Entry** entry_ptr = &query_cache_context->enumerated_entry; 709 disk_cache::Entry** entry_ptr = &query_cache_context->enumerated_entry;
639 net::CompletionCallback open_entry_callback = 710 net::CompletionCallback open_entry_callback =
640 base::Bind(&CacheStorageCache::QueryCacheDidOpenFastPath, 711 base::Bind(&CacheStorageCache::QueryCacheDidOpenFastPath,
641 weak_ptr_factory_.GetWeakPtr(), 712 weak_ptr_factory_.GetWeakPtr(),
642 base::Passed(std::move(query_cache_context))); 713 base::Passed(std::move(query_cache_context)));
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after
703 if (rv < 0) { 774 if (rv < 0) {
704 QueryCacheCallback callback = query_cache_context->callback; 775 QueryCacheCallback callback = query_cache_context->callback;
705 callback.Run(CACHE_STORAGE_ERROR_STORAGE, 776 callback.Run(CACHE_STORAGE_ERROR_STORAGE,
706 std::move(query_cache_context->matches)); 777 std::move(query_cache_context->matches));
707 return; 778 return;
708 } 779 }
709 780
710 disk_cache::ScopedEntryPtr entry(query_cache_context->enumerated_entry); 781 disk_cache::ScopedEntryPtr entry(query_cache_context->enumerated_entry);
711 query_cache_context->enumerated_entry = nullptr; 782 query_cache_context->enumerated_entry = nullptr;
712 783
713 if (backend_state_ != BACKEND_OPEN) { 784 if (backend_state_ == BACKEND_CLOSED) {
714 QueryCacheCallback callback = query_cache_context->callback; 785 QueryCacheCallback callback = query_cache_context->callback;
715 callback.Run(CACHE_STORAGE_ERROR_NOT_FOUND, 786 callback.Run(CACHE_STORAGE_ERROR_NOT_FOUND,
716 std::move(query_cache_context->matches)); 787 std::move(query_cache_context->matches));
717 return; 788 return;
718 } 789 }
719 790
720 if (query_cache_context->request && 791 if (query_cache_context->request &&
721 !query_cache_context->request->url.is_empty()) { 792 !query_cache_context->request->url.is_empty()) {
722 GURL requestURL = query_cache_context->request->url; 793 GURL requestURL = query_cache_context->request->url;
723 GURL cachedURL = GURL(entry->GetKey()); 794 GURL cachedURL = GURL(entry->GetKey());
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
765 836
766 if (query_cache_context->request && 837 if (query_cache_context->request &&
767 !query_cache_context->options.ignore_vary && 838 !query_cache_context->options.ignore_vary &&
768 !VaryMatches(query_cache_context->request->headers, 839 !VaryMatches(query_cache_context->request->headers,
769 match->request->headers, match->response->headers)) { 840 match->request->headers, match->response->headers)) {
770 query_cache_context->matches->pop_back(); 841 query_cache_context->matches->pop_back();
771 QueryCacheOpenNextEntry(std::move(query_cache_context)); 842 QueryCacheOpenNextEntry(std::move(query_cache_context));
772 return; 843 return;
773 } 844 }
774 845
775 if (query_cache_context->query_type == QueryCacheType::CACHE_ENTRIES) { 846 if (query_cache_context->query_types & QUERY_CACHE_ENTRIES)
847 match->entry = std::move(entry);
848
849 if (query_cache_context->query_types & QUERY_CACHE_REQUESTS) {
850 query_cache_context->estimated_out_bytes +=
851 match->request->EstimatedStructSize();
852 if (query_cache_context->estimated_out_bytes > max_query_size_bytes_) {
853 query_cache_context->callback.Run(CACHE_STORAGE_ERROR_QUERY_TOO_LARGE,
854 std::unique_ptr<QueryCacheResults>());
855 return;
856 }
857 } else {
776 match->request.reset(); 858 match->request.reset();
777 match->response.reset();
778 match->entry = std::move(entry);
779 QueryCacheOpenNextEntry(std::move(query_cache_context));
780 return;
781 } 859 }
782 860
783 query_cache_context->estimated_out_bytes += 861 if (query_cache_context->query_types & QUERY_CACHE_RESPONSES_WITH_BODIES) {
784 match->request->EstimatedStructSize(); 862 query_cache_context->estimated_out_bytes +=
785 if (query_cache_context->estimated_out_bytes > max_query_size_bytes_) { 863 match->response->EstimatedStructSize();
786 query_cache_context->callback.Run(CACHE_STORAGE_ERROR_QUERY_TOO_LARGE, 864 if (query_cache_context->estimated_out_bytes > max_query_size_bytes_) {
787 std::unique_ptr<QueryCacheResults>()); 865 query_cache_context->callback.Run(CACHE_STORAGE_ERROR_QUERY_TOO_LARGE,
788 return; 866 std::unique_ptr<QueryCacheResults>());
867 return;
868 }
869 if (entry->GetDataSize(INDEX_RESPONSE_BODY) == 0) {
870 QueryCacheOpenNextEntry(std::move(query_cache_context));
871 return;
872 }
873
874 if (!blob_storage_context_) {
875 query_cache_context->callback.Run(CACHE_STORAGE_ERROR_STORAGE,
876 std::unique_ptr<QueryCacheResults>());
877 return;
878 }
879
880 std::unique_ptr<storage::BlobDataHandle> blob_data_handle =
881 PopulateResponseBody(std::move(entry), match->response.get());
882 match->blob_handle = std::move(blob_data_handle);
883 } else if (!(query_cache_context->query_types &
884 QUERY_CACHE_RESPONSES_NO_BODIES)) {
885 match->response.reset();
789 } 886 }
790 887
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)); 888 QueryCacheOpenNextEntry(std::move(query_cache_context));
824 } 889 }
825 890
826 // static 891 // static
827 bool CacheStorageCache::QueryCacheResultCompare(const QueryCacheResult& lhs, 892 bool CacheStorageCache::QueryCacheResultCompare(const QueryCacheResult& lhs,
828 const QueryCacheResult& rhs) { 893 const QueryCacheResult& rhs) {
829 return lhs.entry_time < rhs.entry_time; 894 return lhs.entry_time < rhs.entry_time;
830 } 895 }
831 896
897 // static
898 int64_t CacheStorageCache::CalculateResponsePadding(
899 const ServiceWorkerResponse& response,
900 const std::string& padding_key) {
901 if (!ShouldPadResourceSize(response))
902 return 0;
903 return ResponsePaddingDistribution(CalculatePaddingHMAC(
904 CalculateResponsePaddingHash(response), padding_key));
905 }
906
832 void CacheStorageCache::MatchImpl( 907 void CacheStorageCache::MatchImpl(
833 std::unique_ptr<ServiceWorkerFetchRequest> request, 908 std::unique_ptr<ServiceWorkerFetchRequest> request,
834 const CacheStorageCacheQueryParams& match_params, 909 const CacheStorageCacheQueryParams& match_params,
835 const ResponseCallback& callback) { 910 const ResponseCallback& callback) {
836 MatchAllImpl(std::move(request), match_params, 911 MatchAllImpl(std::move(request), match_params,
837 base::Bind(&CacheStorageCache::MatchDidMatchAll, 912 base::Bind(&CacheStorageCache::MatchDidMatchAll,
838 weak_ptr_factory_.GetWeakPtr(), callback)); 913 weak_ptr_factory_.GetWeakPtr(), callback));
839 } 914 }
840 915
841 void CacheStorageCache::MatchDidMatchAll( 916 void CacheStorageCache::MatchDidMatchAll(
(...skipping 26 matching lines...) Expand all
868 const CacheStorageCacheQueryParams& options, 943 const CacheStorageCacheQueryParams& options,
869 const ResponsesCallback& callback) { 944 const ResponsesCallback& callback) {
870 DCHECK_NE(BACKEND_UNINITIALIZED, backend_state_); 945 DCHECK_NE(BACKEND_UNINITIALIZED, backend_state_);
871 if (backend_state_ != BACKEND_OPEN) { 946 if (backend_state_ != BACKEND_OPEN) {
872 callback.Run(CACHE_STORAGE_ERROR_STORAGE, std::unique_ptr<Responses>(), 947 callback.Run(CACHE_STORAGE_ERROR_STORAGE, std::unique_ptr<Responses>(),
873 std::unique_ptr<BlobDataHandles>()); 948 std::unique_ptr<BlobDataHandles>());
874 return; 949 return;
875 } 950 }
876 951
877 QueryCache(std::move(request), options, 952 QueryCache(std::move(request), options,
878 QueryCacheType::REQUESTS_AND_RESPONSES, 953 QUERY_CACHE_REQUESTS | QUERY_CACHE_RESPONSES_WITH_BODIES,
879 base::Bind(&CacheStorageCache::MatchAllDidQueryCache, 954 base::Bind(&CacheStorageCache::MatchAllDidQueryCache,
880 weak_ptr_factory_.GetWeakPtr(), callback)); 955 weak_ptr_factory_.GetWeakPtr(), callback));
881 } 956 }
882 957
883 void CacheStorageCache::MatchAllDidQueryCache( 958 void CacheStorageCache::MatchAllDidQueryCache(
884 const ResponsesCallback& callback, 959 const ResponsesCallback& callback,
885 CacheStorageError error, 960 CacheStorageError error,
886 std::unique_ptr<QueryCacheResults> query_cache_results) { 961 std::unique_ptr<QueryCacheResults> query_cache_results) {
887 if (error != CACHE_STORAGE_OK) { 962 if (error != CACHE_STORAGE_OK) {
888 callback.Run(error, std::unique_ptr<Responses>(), 963 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)))); 1132 base::Passed(std::move(put_context))));
1058 } 1133 }
1059 1134
1060 void CacheStorageCache::PutImpl(std::unique_ptr<PutContext> put_context) { 1135 void CacheStorageCache::PutImpl(std::unique_ptr<PutContext> put_context) {
1061 DCHECK_NE(BACKEND_UNINITIALIZED, backend_state_); 1136 DCHECK_NE(BACKEND_UNINITIALIZED, backend_state_);
1062 if (backend_state_ != BACKEND_OPEN) { 1137 if (backend_state_ != BACKEND_OPEN) {
1063 put_context->callback.Run(CACHE_STORAGE_ERROR_STORAGE); 1138 put_context->callback.Run(CACHE_STORAGE_ERROR_STORAGE);
1064 return; 1139 return;
1065 } 1140 }
1066 1141
1067 std::string key = put_context->request->url.spec(); 1142 // Explicitly delete the incumbent resource (which may not exist). This is
1143 // only done so that it's padding will be decremented from the calculated
1144 // cache padding.
1145 auto delete_request = base::MakeUnique<ServiceWorkerFetchRequest>(
1146 put_context->request->url, "", ServiceWorkerHeaderMap(), Referrer(),
1147 false);
1068 1148
1069 net::CompletionCallback callback = base::Bind( 1149 CacheStorageCacheQueryParams query_options;
1070 &CacheStorageCache::PutDidDoomEntry, weak_ptr_factory_.GetWeakPtr(), 1150 query_options.ignore_method = true;
1071 base::Passed(std::move(put_context))); 1151 query_options.ignore_vary = true;
1072 1152 DeleteImpl(std::move(delete_request), query_options,
1073 int rv = backend_->DoomEntry(key, callback); 1153 base::Bind(&CacheStorageCache::PutDidDeleteEntry,
1074 if (rv != net::ERR_IO_PENDING) 1154 weak_ptr_factory_.GetWeakPtr(),
1075 callback.Run(rv); 1155 base::Passed(std::move(put_context))));
1076 } 1156 }
1077 1157
1078 void CacheStorageCache::PutDidDoomEntry(std::unique_ptr<PutContext> put_context, 1158 void CacheStorageCache::PutDidDeleteEntry(
1079 int rv) { 1159 std::unique_ptr<PutContext> put_context,
1160 CacheStorageError error,
1161 std::unique_ptr<QueryCacheResults> query_results) {
1080 if (backend_state_ != BACKEND_OPEN) { 1162 if (backend_state_ != BACKEND_OPEN) {
1081 put_context->callback.Run(CACHE_STORAGE_ERROR_STORAGE); 1163 put_context->callback.Run(CACHE_STORAGE_ERROR_STORAGE);
1082 return; 1164 return;
1083 } 1165 }
1084 1166
1085 // |rv| is ignored as doom entry can fail if the entry doesn't exist. 1167 if (error != CACHE_STORAGE_OK && error != CACHE_STORAGE_ERROR_NOT_FOUND) {
1168 cache_padding_ -=
1169 CalculateResponsePadding(*put_context->response, cache_padding_key_);
1170 put_context->callback.Run(error);
1171 return;
1172 }
1086 1173
1087 std::unique_ptr<disk_cache::Entry*> scoped_entry_ptr( 1174 std::unique_ptr<disk_cache::Entry*> scoped_entry_ptr(
1088 new disk_cache::Entry*()); 1175 new disk_cache::Entry*());
1089 disk_cache::Entry** entry_ptr = scoped_entry_ptr.get(); 1176 disk_cache::Entry** entry_ptr = scoped_entry_ptr.get();
1090 ServiceWorkerFetchRequest* request_ptr = put_context->request.get(); 1177 ServiceWorkerFetchRequest* request_ptr = put_context->request.get();
1091 disk_cache::Backend* backend_ptr = backend_.get(); 1178 disk_cache::Backend* backend_ptr = backend_.get();
1092 1179
1093 net::CompletionCallback create_entry_callback = base::Bind( 1180 net::CompletionCallback create_entry_callback = base::Bind(
1094 &CacheStorageCache::PutDidCreateEntry, weak_ptr_factory_.GetWeakPtr(), 1181 &CacheStorageCache::PutDidCreateEntry, weak_ptr_factory_.GetWeakPtr(),
1095 base::Passed(std::move(scoped_entry_ptr)), 1182 base::Passed(std::move(scoped_entry_ptr)),
1096 base::Passed(std::move(put_context))); 1183 base::Passed(std::move(put_context)));
1097 1184
1098 int create_rv = backend_ptr->CreateEntry(request_ptr->url.spec(), entry_ptr, 1185 int rv = backend_ptr->CreateEntry(request_ptr->url.spec(), entry_ptr,
1099 create_entry_callback); 1186 create_entry_callback);
1100 1187
1101 if (create_rv != net::ERR_IO_PENDING) 1188 if (rv != net::ERR_IO_PENDING)
1102 create_entry_callback.Run(create_rv); 1189 create_entry_callback.Run(rv);
1103 } 1190 }
1104 1191
1105 void CacheStorageCache::PutDidCreateEntry( 1192 void CacheStorageCache::PutDidCreateEntry(
1106 std::unique_ptr<disk_cache::Entry*> entry_ptr, 1193 std::unique_ptr<disk_cache::Entry*> entry_ptr,
1107 std::unique_ptr<PutContext> put_context, 1194 std::unique_ptr<PutContext> put_context,
1108 int rv) { 1195 int rv) {
1109 put_context->cache_entry.reset(*entry_ptr); 1196 put_context->cache_entry.reset(*entry_ptr);
1110 1197
1111 if (rv != net::OK) { 1198 if (rv != net::OK) {
1112 put_context->callback.Run(CACHE_STORAGE_ERROR_EXISTS); 1199 put_context->callback.Run(CACHE_STORAGE_ERROR_EXISTS);
(...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after
1177 int expected_bytes, 1264 int expected_bytes,
1178 int rv) { 1265 int rv) {
1179 if (rv != expected_bytes) { 1266 if (rv != expected_bytes) {
1180 put_context->cache_entry->Doom(); 1267 put_context->cache_entry->Doom();
1181 put_context->callback.Run(CACHE_STORAGE_ERROR_STORAGE); 1268 put_context->callback.Run(CACHE_STORAGE_ERROR_STORAGE);
1182 return; 1269 return;
1183 } 1270 }
1184 1271
1185 if (rv > 0) 1272 if (rv > 0)
1186 storage::RecordBytesWritten(kRecordBytesLabel, rv); 1273 storage::RecordBytesWritten(kRecordBytesLabel, rv);
1274 cache_padding_ +=
1275 CalculateResponsePadding(*put_context->response, cache_padding_key_);
1187 1276
1188 // The metadata is written, now for the response content. The data is streamed 1277 // The metadata is written, now for the response content. The data is streamed
1189 // from the blob into the cache entry. 1278 // from the blob into the cache entry.
1190 1279
1191 if (put_context->response->blob_uuid.empty()) { 1280 if (put_context->response->blob_uuid.empty()) {
1192 UpdateCacheSize(base::Bind(put_context->callback, CACHE_STORAGE_OK)); 1281 UpdateCacheSize(base::Bind(put_context->callback, CACHE_STORAGE_OK));
1193 return; 1282 return;
1194 } 1283 }
1195 1284
1196 DCHECK(put_context->blob_data_handle); 1285 DCHECK(put_context->blob_data_handle);
(...skipping 29 matching lines...) Expand all
1226 1315
1227 if (!success) { 1316 if (!success) {
1228 put_context->cache_entry->Doom(); 1317 put_context->cache_entry->Doom();
1229 put_context->callback.Run(CACHE_STORAGE_ERROR_STORAGE); 1318 put_context->callback.Run(CACHE_STORAGE_ERROR_STORAGE);
1230 return; 1319 return;
1231 } 1320 }
1232 1321
1233 UpdateCacheSize(base::Bind(put_context->callback, CACHE_STORAGE_OK)); 1322 UpdateCacheSize(base::Bind(put_context->callback, CACHE_STORAGE_OK));
1234 } 1323 }
1235 1324
1325 void CacheStorageCache::CalculateCacheSizePadding(
1326 const SizePaddingCallback& got_sizes_callback) {
1327 net::CompletionCallback got_size_callback =
1328 base::Bind(&CacheStorageCache::CalculateCacheSizePaddingGotSize,
1329 weak_ptr_factory_.GetWeakPtr(), std::move(got_sizes_callback));
1330
1331 int rv = backend_->CalculateSizeOfAllEntries(got_size_callback);
1332 if (rv != net::ERR_IO_PENDING)
1333 got_size_callback.Run(rv);
1334 }
1335
1336 void CacheStorageCache::CalculateCacheSizePaddingGotSize(
1337 const SizePaddingCallback& callback,
1338 int cache_size) {
1339 // Enumerating entries is only done during cache initialization.
1340 DCHECK_EQ(backend_state_, BACKEND_UNINITIALIZED);
1341 std::unique_ptr<ServiceWorkerFetchRequest> request;
1342 CacheStorageCacheQueryParams options;
1343 options.ignore_search = true;
1344 QueryCache(std::move(request), options,
1345 QUERY_CACHE_REQUESTS | QUERY_CACHE_RESPONSES_WITH_BODIES,
1346 base::Bind(&CacheStorageCache::PaddingDidQueryCache,
1347 weak_ptr_factory_.GetWeakPtr(), std::move(callback),
1348 cache_size));
1349 }
1350
1351 void CacheStorageCache::PaddingDidQueryCache(
1352 const SizePaddingCallback& callback,
1353 int cache_size,
1354 CacheStorageError error,
1355 std::unique_ptr<QueryCacheResults> query_cache_results) {
1356 int64_t cache_padding = 0;
1357 if (error == CACHE_STORAGE_OK) {
1358 for (const auto& result : *query_cache_results)
1359 cache_padding +=
1360 CalculateResponsePadding(*result.response, cache_padding_key_);
1361 }
1362
1363 callback.Run(cache_size, cache_padding);
1364 }
1365
1366 void CacheStorageCache::CalculateCacheSize(
1367 const net::CompletionCallback& callback) {
1368 int rv = backend_->CalculateSizeOfAllEntries(callback);
1369 if (rv != net::ERR_IO_PENDING)
1370 callback.Run(rv);
1371 }
1372
1236 void CacheStorageCache::UpdateCacheSize(const base::Closure& callback) { 1373 void CacheStorageCache::UpdateCacheSize(const base::Closure& callback) {
1237 if (backend_state_ != BACKEND_OPEN) 1374 if (backend_state_ != BACKEND_OPEN)
1238 return; 1375 return;
1239 1376
1240 // Note that the callback holds a cache handle to keep the cache alive during 1377 // 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 1378 // the operation since this UpdateCacheSize is often run after an operation
1242 // completes and runs its callback. 1379 // completes and runs its callback.
1243 int rv = backend_->CalculateSizeOfAllEntries( 1380 CalculateCacheSize(base::Bind(&CacheStorageCache::UpdateCacheSizeGotSize,
1244 base::Bind(&CacheStorageCache::UpdateCacheSizeGotSize, 1381 weak_ptr_factory_.GetWeakPtr(),
1245 weak_ptr_factory_.GetWeakPtr(), 1382 base::Passed(CreateCacheHandle()), callback));
1246 base::Passed(CreateCacheHandle()), callback));
1247
1248 if (rv != net::ERR_IO_PENDING)
1249 UpdateCacheSizeGotSize(CreateCacheHandle(), callback, rv);
1250 } 1383 }
1251 1384
1252 void CacheStorageCache::UpdateCacheSizeGotSize( 1385 void CacheStorageCache::UpdateCacheSizeGotSize(
1253 std::unique_ptr<CacheStorageCacheHandle> cache_handle, 1386 std::unique_ptr<CacheStorageCacheHandle> cache_handle,
1254 const base::Closure& callback, 1387 const base::Closure& callback,
1255 int current_cache_size) { 1388 int current_cache_size) {
1256 DCHECK_NE(current_cache_size, CacheStorage::kSizeUnknown); 1389 DCHECK_NE(current_cache_size, CacheStorage::kSizeUnknown);
1257 int64_t old_cache_size = cache_size_;
1258 cache_size_ = current_cache_size; 1390 cache_size_ = current_cache_size;
1259 1391 int64_t size_delta = PaddedCacheSize() - last_reported_size_;
1260 int64_t size_delta = current_cache_size - old_cache_size; 1392 last_reported_size_ = PaddedCacheSize();
1261 1393
1262 quota_manager_proxy_->NotifyStorageModified( 1394 quota_manager_proxy_->NotifyStorageModified(
1263 storage::QuotaClient::kServiceWorkerCache, origin_, 1395 storage::QuotaClient::kServiceWorkerCache, origin_,
1264 storage::kStorageTypeTemporary, size_delta); 1396 storage::kStorageTypeTemporary, size_delta);
1265 1397
1266 if (cache_observer_) 1398 if (cache_observer_)
1267 cache_observer_->CacheSizeUpdated(this, current_cache_size); 1399 cache_observer_->CacheSizeUpdated(this, PaddedCacheSize());
1268 1400
1269 callback.Run(); 1401 callback.Run();
1270 } 1402 }
1271 1403
1272 void CacheStorageCache::Delete(const CacheStorageBatchOperation& operation, 1404 void CacheStorageCache::Delete(const CacheStorageBatchOperation& operation,
1273 const ErrorCallback& callback) { 1405 const ErrorCallback& callback) {
1274 DCHECK(BACKEND_OPEN == backend_state_ || initializing_); 1406 DCHECK(BACKEND_OPEN == backend_state_ || initializing_);
1275 DCHECK_EQ(CACHE_STORAGE_CACHE_OPERATION_TYPE_DELETE, 1407 DCHECK_EQ(CACHE_STORAGE_CACHE_OPERATION_TYPE_DELETE,
1276 operation.operation_type); 1408 operation.operation_type);
1277 1409
1278 std::unique_ptr<ServiceWorkerFetchRequest> request( 1410 std::unique_ptr<ServiceWorkerFetchRequest> request(
1279 new ServiceWorkerFetchRequest( 1411 new ServiceWorkerFetchRequest(
1280 operation.request.url, operation.request.method, 1412 operation.request.url, operation.request.method,
1281 operation.request.headers, operation.request.referrer, 1413 operation.request.headers, operation.request.referrer,
1282 operation.request.is_reload)); 1414 operation.request.is_reload));
1283 1415
1416 QueryCacheCallback delete_callback =
1417 base::Bind(&CacheStorageCache::DeleteDidDelete,
1418 weak_ptr_factory_.GetWeakPtr(), callback);
1419
1284 scheduler_->ScheduleOperation( 1420 scheduler_->ScheduleOperation(
1285 base::Bind(&CacheStorageCache::DeleteImpl, weak_ptr_factory_.GetWeakPtr(), 1421 base::Bind(&CacheStorageCache::DeleteImpl, weak_ptr_factory_.GetWeakPtr(),
1286 base::Passed(std::move(request)), operation.match_params, 1422 base::Passed(std::move(request)), operation.match_params,
1287 scheduler_->WrapCallbackToRunNext(callback))); 1423 scheduler_->WrapCallbackToRunNext(delete_callback)));
1424 }
1425
1426 void CacheStorageCache::DeleteDidDelete(
1427 const ErrorCallback& callback,
1428 CacheStorageError error,
1429 std::unique_ptr<QueryCacheResults> query_results) {
1430 callback.Run(error);
1288 } 1431 }
1289 1432
1290 void CacheStorageCache::DeleteImpl( 1433 void CacheStorageCache::DeleteImpl(
1291 std::unique_ptr<ServiceWorkerFetchRequest> request, 1434 std::unique_ptr<ServiceWorkerFetchRequest> request,
1292 const CacheStorageCacheQueryParams& match_params, 1435 const CacheStorageCacheQueryParams& match_params,
1293 const ErrorCallback& callback) { 1436 const QueryCacheCallback& callback) {
1294 DCHECK_NE(BACKEND_UNINITIALIZED, backend_state_); 1437 DCHECK_NE(BACKEND_UNINITIALIZED, backend_state_);
1295 if (backend_state_ != BACKEND_OPEN) { 1438 if (backend_state_ != BACKEND_OPEN) {
1296 callback.Run(CACHE_STORAGE_ERROR_STORAGE); 1439 callback.Run(CACHE_STORAGE_ERROR_STORAGE,
1440 base::MakeUnique<QueryCacheResults>());
1297 return; 1441 return;
1298 } 1442 }
1299 1443
1300 QueryCache(std::move(request), match_params, QueryCacheType::CACHE_ENTRIES, 1444 QueryCache(std::move(request), match_params,
1445 QUERY_CACHE_ENTRIES | QUERY_CACHE_RESPONSES_NO_BODIES,
1301 base::Bind(&CacheStorageCache::DeleteDidQueryCache, 1446 base::Bind(&CacheStorageCache::DeleteDidQueryCache,
1302 weak_ptr_factory_.GetWeakPtr(), callback)); 1447 weak_ptr_factory_.GetWeakPtr(), callback));
1303 } 1448 }
1304 1449
1305 void CacheStorageCache::DeleteDidQueryCache( 1450 void CacheStorageCache::DeleteDidQueryCache(
1306 const ErrorCallback& callback, 1451 const QueryCacheCallback& callback,
1307 CacheStorageError error, 1452 CacheStorageError error,
1308 std::unique_ptr<QueryCacheResults> query_cache_results) { 1453 std::unique_ptr<QueryCacheResults> query_cache_results) {
1309 if (error != CACHE_STORAGE_OK) { 1454 if (error != CACHE_STORAGE_OK) {
1310 callback.Run(error); 1455 callback.Run(error, std::move(query_cache_results));
1311 return; 1456 return;
1312 } 1457 }
1313 1458
1314 if (query_cache_results->empty()) { 1459 if (query_cache_results->empty()) {
1315 callback.Run(CACHE_STORAGE_ERROR_NOT_FOUND); 1460 callback.Run(CACHE_STORAGE_ERROR_NOT_FOUND, std::move(query_cache_results));
1316 return; 1461 return;
1317 } 1462 }
1318 1463
1319 for (auto& result : *query_cache_results) { 1464 for (auto& result : *query_cache_results) {
1320 disk_cache::ScopedEntryPtr entry = std::move(result.entry); 1465 disk_cache::ScopedEntryPtr entry = std::move(result.entry);
1466 cache_padding_ -=
1467 CalculateResponsePadding(*result.response, cache_padding_key_);
1321 entry->Doom(); 1468 entry->Doom();
1322 } 1469 }
1323 1470
1324 UpdateCacheSize(base::Bind(callback, CACHE_STORAGE_OK)); 1471 UpdateCacheSize(base::Bind(callback, CACHE_STORAGE_OK,
1472 base::Passed(std::move(query_cache_results))));
1325 } 1473 }
1326 1474
1327 void CacheStorageCache::KeysImpl( 1475 void CacheStorageCache::KeysImpl(
1328 std::unique_ptr<ServiceWorkerFetchRequest> request, 1476 std::unique_ptr<ServiceWorkerFetchRequest> request,
1329 const CacheStorageCacheQueryParams& options, 1477 const CacheStorageCacheQueryParams& options,
1330 const RequestsCallback& callback) { 1478 const RequestsCallback& callback) {
1331 DCHECK_NE(BACKEND_UNINITIALIZED, backend_state_); 1479 DCHECK_NE(BACKEND_UNINITIALIZED, backend_state_);
1332 if (backend_state_ != BACKEND_OPEN) { 1480 if (backend_state_ != BACKEND_OPEN) {
1333 callback.Run(CACHE_STORAGE_ERROR_STORAGE, std::unique_ptr<Requests>()); 1481 callback.Run(CACHE_STORAGE_ERROR_STORAGE, std::unique_ptr<Requests>());
1334 return; 1482 return;
1335 } 1483 }
1336 1484
1337 QueryCache(std::move(request), options, QueryCacheType::REQUESTS, 1485 QueryCache(std::move(request), options, QUERY_CACHE_REQUESTS,
1338 base::Bind(&CacheStorageCache::KeysDidQueryCache, 1486 base::Bind(&CacheStorageCache::KeysDidQueryCache,
1339 weak_ptr_factory_.GetWeakPtr(), callback)); 1487 weak_ptr_factory_.GetWeakPtr(), callback));
1340 } 1488 }
1341 1489
1342 void CacheStorageCache::KeysDidQueryCache( 1490 void CacheStorageCache::KeysDidQueryCache(
1343 const RequestsCallback& callback, 1491 const RequestsCallback& callback,
1344 CacheStorageError error, 1492 CacheStorageError error,
1345 std::unique_ptr<QueryCacheResults> query_cache_results) { 1493 std::unique_ptr<QueryCacheResults> query_cache_results) {
1346 if (error != CACHE_STORAGE_OK) { 1494 if (error != CACHE_STORAGE_OK) {
1347 callback.Run(error, std::unique_ptr<Requests>()); 1495 callback.Run(error, std::unique_ptr<Requests>());
(...skipping 12 matching lines...) Expand all
1360 DCHECK_NE(BACKEND_CLOSED, backend_state_); 1508 DCHECK_NE(BACKEND_CLOSED, backend_state_);
1361 1509
1362 backend_state_ = BACKEND_CLOSED; 1510 backend_state_ = BACKEND_CLOSED;
1363 backend_.reset(); 1511 backend_.reset();
1364 callback.Run(); 1512 callback.Run();
1365 } 1513 }
1366 1514
1367 void CacheStorageCache::SizeImpl(const SizeCallback& callback) { 1515 void CacheStorageCache::SizeImpl(const SizeCallback& callback) {
1368 DCHECK_NE(BACKEND_UNINITIALIZED, backend_state_); 1516 DCHECK_NE(BACKEND_UNINITIALIZED, backend_state_);
1369 1517
1370 int64_t size = backend_state_ == BACKEND_OPEN ? cache_size_ : 0; 1518 // TODO(cmumford): Can CacheStorage::kSizeUnknown be returned instead of zero?
1519 if (backend_state_ != BACKEND_OPEN) {
1520 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
1521 base::Bind(callback, 0));
1522 return;
1523 }
1524
1525 int64_t size = backend_state_ == BACKEND_OPEN ? PaddedCacheSize() : 0;
1371 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE, 1526 base::ThreadTaskRunnerHandle::Get()->PostTask(FROM_HERE,
1372 base::Bind(callback, size)); 1527 base::Bind(callback, size));
1373 } 1528 }
1374 1529
1375 void CacheStorageCache::GetSizeThenCloseDidGetSize(const SizeCallback& callback, 1530 void CacheStorageCache::GetSizeThenCloseDidGetSize(const SizeCallback& callback,
1376 int64_t cache_size) { 1531 int64_t cache_size) {
1377 CloseImpl(base::Bind(callback, cache_size)); 1532 CloseImpl(base::Bind(callback, cache_size));
1378 } 1533 }
1379 1534
1380 void CacheStorageCache::CreateBackend(const ErrorCallback& callback) { 1535 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 1608 // 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 1609 // (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 1610 // 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. 1611 // is saved in the store's index.
1457 if (cache_size_ != CacheStorage::kSizeUnknown) { 1612 if (cache_size_ != CacheStorage::kSizeUnknown) {
1458 LOG_IF(ERROR, cache_size_ != cache_size) 1613 LOG_IF(ERROR, cache_size_ != cache_size)
1459 << "Cache size: " << cache_size 1614 << "Cache size: " << cache_size
1460 << " does not match size from index: " << cache_size_; 1615 << " does not match size from index: " << cache_size_;
1461 UMA_HISTOGRAM_COUNTS_10M("ServiceWorkerCache.IndexSizeDifference", 1616 UMA_HISTOGRAM_COUNTS_10M("ServiceWorkerCache.IndexSizeDifference",
1462 std::abs(cache_size_ - cache_size)); 1617 std::abs(cache_size_ - cache_size));
1463 // Disabled for crbug.com/681900. 1618 if (cache_size_ != cache_size) {
1464 // DCHECK_EQ(cache_size_, cache_size); 1619 // If the actual size doesn't match the cached size, then assume the
1620 // cached padding is also incorrect and recalculate.
1621 CalculateCacheSizePaddingGotSize(
1622 base::Bind(&CacheStorageCache::InitGotCacheSizeAndPadding,
1623 weak_ptr_factory_.GetWeakPtr(), callback,
1624 cache_create_error),
1625 cache_size);
1626 return;
1627 }
1465 } 1628 }
1629
1630 if (cache_padding_ == CacheStorage::kSizeUnknown || cache_padding_ < 0) {
1631 CalculateCacheSizePaddingGotSize(
1632 base::Bind(&CacheStorageCache::InitGotCacheSizeAndPadding,
1633 weak_ptr_factory_.GetWeakPtr(), callback,
1634 cache_create_error),
1635 cache_size);
1636 return;
1637 }
1638
1639 // If cached size matches actual size then assume cached padding is still
1640 // correct.
1641 InitGotCacheSizeAndPadding(callback, cache_create_error, cache_size,
1642 cache_padding_);
1643 }
1644
1645 void CacheStorageCache::InitGotCacheSizeAndPadding(
1646 const base::Closure& callback,
1647 CacheStorageError cache_create_error,
1648 int64_t cache_size,
1649 int64_t cache_padding) {
1466 cache_size_ = cache_size; 1650 cache_size_ = cache_size;
1651 cache_padding_ = cache_padding;
1652
1467 initializing_ = false; 1653 initializing_ = false;
1468 backend_state_ = (cache_create_error == CACHE_STORAGE_OK && backend_ && 1654 backend_state_ = (cache_create_error == CACHE_STORAGE_OK && backend_ &&
1469 backend_state_ == BACKEND_UNINITIALIZED) 1655 backend_state_ == BACKEND_UNINITIALIZED)
1470 ? BACKEND_OPEN 1656 ? BACKEND_OPEN
1471 : BACKEND_CLOSED; 1657 : BACKEND_CLOSED;
1472 1658
1473 UMA_HISTOGRAM_ENUMERATION("ServiceWorkerCache.InitBackendResult", 1659 UMA_HISTOGRAM_ENUMERATION("ServiceWorkerCache.InitBackendResult",
1474 cache_create_error, CACHE_STORAGE_ERROR_LAST + 1); 1660 cache_create_error, CACHE_STORAGE_ERROR_LAST + 1);
1475 1661
1476 if (cache_observer_) 1662 if (cache_observer_)
1477 cache_observer_->CacheSizeUpdated(this, cache_size_); 1663 cache_observer_->CacheSizeUpdated(this, PaddedCacheSize());
1478 1664
1479 callback.Run(); 1665 callback.Run();
1480 } 1666 }
1481 1667
1482 std::unique_ptr<storage::BlobDataHandle> 1668 std::unique_ptr<storage::BlobDataHandle>
1483 CacheStorageCache::PopulateResponseBody(disk_cache::ScopedEntryPtr entry, 1669 CacheStorageCache::PopulateResponseBody(disk_cache::ScopedEntryPtr entry,
1484 ServiceWorkerResponse* response) { 1670 ServiceWorkerResponse* response) {
1485 DCHECK(blob_storage_context_); 1671 DCHECK(blob_storage_context_);
1486 1672
1487 // Create a blob with the response body data. 1673 // Create a blob with the response body data.
1488 response->blob_size = entry->GetDataSize(INDEX_RESPONSE_BODY); 1674 response->blob_size = entry->GetDataSize(INDEX_RESPONSE_BODY);
1489 response->blob_uuid = base::GenerateGUID(); 1675 response->blob_uuid = base::GenerateGUID();
1490 storage::BlobDataBuilder blob_data(response->blob_uuid); 1676 storage::BlobDataBuilder blob_data(response->blob_uuid);
1491 1677
1492 disk_cache::Entry* temp_entry = entry.get(); 1678 disk_cache::Entry* temp_entry = entry.get();
1493 blob_data.AppendDiskCacheEntryWithSideData( 1679 blob_data.AppendDiskCacheEntryWithSideData(
1494 new CacheStorageCacheDataHandle(CreateCacheHandle(), std::move(entry)), 1680 new CacheStorageCacheDataHandle(CreateCacheHandle(), std::move(entry)),
1495 temp_entry, INDEX_RESPONSE_BODY, INDEX_SIDE_DATA); 1681 temp_entry, INDEX_RESPONSE_BODY, INDEX_SIDE_DATA);
1496 return blob_storage_context_->AddFinishedBlob(&blob_data); 1682 return blob_storage_context_->AddFinishedBlob(&blob_data);
1497 } 1683 }
1498 1684
1499 std::unique_ptr<CacheStorageCacheHandle> 1685 std::unique_ptr<CacheStorageCacheHandle>
1500 CacheStorageCache::CreateCacheHandle() { 1686 CacheStorageCache::CreateCacheHandle() {
1501 return cache_storage_->CreateCacheHandle(this); 1687 return cache_storage_->CreateCacheHandle(this);
1502 } 1688 }
1503 1689
1690 int64_t CacheStorageCache::PaddedCacheSize() const {
1691 if (cache_size_ == CacheStorage::kSizeUnknown ||
1692 cache_padding_ == CacheStorage::kSizeUnknown) {
1693 return CacheStorage::kSizeUnknown;
1694 }
1695 return cache_size_ + cache_padding_;
1696 }
1697
1504 } // namespace content 1698 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698