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

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

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

Powered by Google App Engine
This is Rietveld 408576698