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

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

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

Powered by Google App Engine
This is Rietveld 408576698