Chromium Code Reviews| OLD | NEW |
|---|---|
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 Loading... | |
| 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 |
| OLD | NEW |