| 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_manager.h" | 5 #include "content/browser/cache_storage/cache_storage_manager.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include <list> | 10 #include <list> |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 43 #include "storage/browser/blob/blob_data_builder.h" | 43 #include "storage/browser/blob/blob_data_builder.h" |
| 44 #include "storage/browser/blob/blob_data_handle.h" | 44 #include "storage/browser/blob/blob_data_handle.h" |
| 45 #include "storage/browser/blob/blob_storage_context.h" | 45 #include "storage/browser/blob/blob_storage_context.h" |
| 46 #include "storage/browser/blob/blob_url_request_job_factory.h" | 46 #include "storage/browser/blob/blob_url_request_job_factory.h" |
| 47 #include "storage/browser/quota/quota_manager_proxy.h" | 47 #include "storage/browser/quota/quota_manager_proxy.h" |
| 48 #include "storage/browser/test/mock_quota_manager_proxy.h" | 48 #include "storage/browser/test/mock_quota_manager_proxy.h" |
| 49 #include "storage/browser/test/mock_special_storage_policy.h" | 49 #include "storage/browser/test/mock_special_storage_policy.h" |
| 50 #include "storage/common/blob_storage/blob_handle.h" | 50 #include "storage/common/blob_storage/blob_handle.h" |
| 51 #include "testing/gtest/include/gtest/gtest.h" | 51 #include "testing/gtest/include/gtest/gtest.h" |
| 52 | 52 |
| 53 using network::mojom::FetchResponseType; |
| 54 |
| 53 namespace content { | 55 namespace content { |
| 54 | 56 |
| 55 namespace { | 57 namespace { |
| 56 | 58 |
| 57 bool IsIndexFileCurrent(const base::FilePath& cache_dir) { | 59 bool IsIndexFileCurrent(const base::FilePath& cache_dir) { |
| 58 base::File::Info info; | 60 base::File::Info info; |
| 59 const base::FilePath index_path = | 61 const base::FilePath index_path = |
| 60 cache_dir.AppendASCII(CacheStorage::kIndexFileName); | 62 cache_dir.AppendASCII(CacheStorage::kIndexFileName); |
| 61 if (!GetFileInfo(index_path, &info)) | 63 if (!GetFileInfo(index_path, &info)) |
| 62 return false; | 64 return false; |
| (...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 348 base::RunLoop loop; | 350 base::RunLoop loop; |
| 349 cache_manager_->MatchAllCaches( | 351 cache_manager_->MatchAllCaches( |
| 350 origin, std::move(unique_request), match_params, | 352 origin, std::move(unique_request), match_params, |
| 351 base::BindOnce(&CacheStorageManagerTest::CacheMatchCallback, | 353 base::BindOnce(&CacheStorageManagerTest::CacheMatchCallback, |
| 352 base::Unretained(this), base::Unretained(&loop))); | 354 base::Unretained(this), base::Unretained(&loop))); |
| 353 loop.Run(); | 355 loop.Run(); |
| 354 | 356 |
| 355 return callback_error_ == CACHE_STORAGE_OK; | 357 return callback_error_ == CACHE_STORAGE_OK; |
| 356 } | 358 } |
| 357 | 359 |
| 358 bool CachePut(CacheStorageCache* cache, const GURL& url) { | 360 bool CachePut(CacheStorageCache* cache, |
| 361 const GURL& url, |
| 362 FetchResponseType response_type = FetchResponseType::kDefault) { |
| 359 ServiceWorkerFetchRequest request; | 363 ServiceWorkerFetchRequest request; |
| 360 request.url = url; | 364 request.url = url; |
| 361 | 365 |
| 362 return CachePutWithStatusCode(cache, request, 200); | 366 return CachePutWithStatusCode(cache, request, 200, response_type); |
| 363 } | 367 } |
| 364 | 368 |
| 365 bool CachePutWithRequestAndHeaders( | 369 bool CachePutWithRequestAndHeaders( |
| 366 CacheStorageCache* cache, | 370 CacheStorageCache* cache, |
| 367 const ServiceWorkerFetchRequest& request, | 371 const ServiceWorkerFetchRequest& request, |
| 368 const ServiceWorkerHeaderMap& response_headers) { | 372 const ServiceWorkerHeaderMap& response_headers, |
| 369 return CachePutWithStatusCode(cache, request, 200, response_headers); | 373 FetchResponseType response_type = FetchResponseType::kDefault) { |
| 374 return CachePutWithStatusCode(cache, request, 200, response_type, |
| 375 response_headers); |
| 370 } | 376 } |
| 371 | 377 |
| 372 bool CachePutWithStatusCode(CacheStorageCache* cache, | 378 bool CachePutWithStatusCode( |
| 373 const ServiceWorkerFetchRequest& request, | 379 CacheStorageCache* cache, |
| 374 int status_code, | 380 const ServiceWorkerFetchRequest& request, |
| 375 const ServiceWorkerHeaderMap& response_headers = | 381 int status_code, |
| 376 ServiceWorkerHeaderMap()) { | 382 FetchResponseType response_type = FetchResponseType::kDefault, |
| 383 const ServiceWorkerHeaderMap& response_headers = |
| 384 ServiceWorkerHeaderMap()) { |
| 377 std::unique_ptr<storage::BlobDataBuilder> blob_data( | 385 std::unique_ptr<storage::BlobDataBuilder> blob_data( |
| 378 new storage::BlobDataBuilder(base::GenerateGUID())); | 386 new storage::BlobDataBuilder(base::GenerateGUID())); |
| 379 blob_data->AppendData(request.url.spec()); | 387 blob_data->AppendData(request.url.spec()); |
| 380 | 388 |
| 381 std::unique_ptr<storage::BlobDataHandle> blob_handle = | 389 std::unique_ptr<storage::BlobDataHandle> blob_handle = |
| 382 blob_storage_context_->AddFinishedBlob(blob_data.get()); | 390 blob_storage_context_->AddFinishedBlob(blob_data.get()); |
| 383 std::unique_ptr<std::vector<GURL>> url_list = | 391 std::unique_ptr<std::vector<GURL>> url_list = |
| 384 base::MakeUnique<std::vector<GURL>>(); | 392 base::MakeUnique<std::vector<GURL>>(); |
| 385 url_list->push_back(request.url); | 393 url_list->push_back(request.url); |
| 386 ServiceWorkerResponse response( | 394 ServiceWorkerResponse response( |
| 387 std::move(url_list), status_code, "OK", | 395 std::move(url_list), status_code, "OK", response_type, |
| 388 network::mojom::FetchResponseType::kDefault, | |
| 389 base::MakeUnique<ServiceWorkerHeaderMap>(response_headers), | 396 base::MakeUnique<ServiceWorkerHeaderMap>(response_headers), |
| 390 blob_handle->uuid(), request.url.spec().size(), nullptr /* blob */, | 397 blob_handle->uuid(), request.url.spec().size(), nullptr /* blob */, |
| 391 blink::kWebServiceWorkerResponseErrorUnknown, base::Time(), | 398 blink::kWebServiceWorkerResponseErrorUnknown, base::Time(), |
| 392 false /* is_in_cache_storage */, | 399 false /* is_in_cache_storage */, |
| 393 std::string() /* cache_storage_cache_name */, | 400 std::string() /* cache_storage_cache_name */, |
| 394 base::MakeUnique< | 401 base::MakeUnique< |
| 395 ServiceWorkerHeaderList>() /* cors_exposed_header_names */); | 402 ServiceWorkerHeaderList>() /* cors_exposed_header_names */); |
| 396 | 403 |
| 397 CacheStorageBatchOperation operation; | 404 CacheStorageBatchOperation operation; |
| 398 operation.operation_type = CACHE_STORAGE_CACHE_OPERATION_TYPE_PUT; | 405 operation.operation_type = CACHE_STORAGE_CACHE_OPERATION_TYPE_PUT; |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 469 | 476 |
| 470 int64_t Size(const GURL& origin) { | 477 int64_t Size(const GURL& origin) { |
| 471 base::RunLoop loop; | 478 base::RunLoop loop; |
| 472 CacheStorage* cache_storage = CacheStorageForOrigin(origin); | 479 CacheStorage* cache_storage = CacheStorageForOrigin(origin); |
| 473 cache_storage->Size(base::BindOnce(&CacheStorageManagerTest::UsageCallback, | 480 cache_storage->Size(base::BindOnce(&CacheStorageManagerTest::UsageCallback, |
| 474 base::Unretained(this), &loop)); | 481 base::Unretained(this), &loop)); |
| 475 loop.Run(); | 482 loop.Run(); |
| 476 return callback_usage_; | 483 return callback_usage_; |
| 477 } | 484 } |
| 478 | 485 |
| 486 int64_t GetQuotaOriginUsage(const GURL& origin) { |
| 487 int64_t usage(CacheStorage::kSizeUnknown); |
| 488 base::RunLoop loop; |
| 489 quota_manager_proxy_->GetUsageAndQuota( |
| 490 base::ThreadTaskRunnerHandle::Get().get(), origin, |
| 491 StorageType::kStorageTypeTemporary, |
| 492 base::Bind(&CacheStorageManagerTest::DidGetQuotaOriginUsage, |
| 493 base::Unretained(this), base::Unretained(&usage), &loop)); |
| 494 loop.Run(); |
| 495 return usage; |
| 496 } |
| 497 |
| 498 void DidGetQuotaOriginUsage(int64_t* out_usage, |
| 499 base::RunLoop* run_loop, |
| 500 QuotaStatusCode status_code, |
| 501 int64_t usage, |
| 502 int64_t quota) { |
| 503 if (status_code == storage::kQuotaStatusOk) |
| 504 *out_usage = usage; |
| 505 run_loop->Quit(); |
| 506 } |
| 507 |
| 479 protected: | 508 protected: |
| 480 // Temporary directory must be allocated first so as to be destroyed last. | 509 // Temporary directory must be allocated first so as to be destroyed last. |
| 481 base::ScopedTempDir temp_dir_; | 510 base::ScopedTempDir temp_dir_; |
| 482 | 511 |
| 483 TestBrowserThreadBundle browser_thread_bundle_; | 512 TestBrowserThreadBundle browser_thread_bundle_; |
| 484 TestBrowserContext browser_context_; | 513 TestBrowserContext browser_context_; |
| 485 std::unique_ptr<net::URLRequestJobFactoryImpl> url_request_job_factory_; | 514 std::unique_ptr<net::URLRequestJobFactoryImpl> url_request_job_factory_; |
| 486 storage::BlobStorageContext* blob_storage_context_; | 515 storage::BlobStorageContext* blob_storage_context_; |
| 487 | 516 |
| 488 scoped_refptr<MockSpecialStoragePolicy> quota_policy_; | 517 scoped_refptr<MockSpecialStoragePolicy> quota_policy_; |
| (...skipping 429 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 918 auto size_before_close = Size(origin1_); | 947 auto size_before_close = Size(origin1_); |
| 919 EXPECT_GT(size_before_close, 0); | 948 EXPECT_GT(size_before_close, 0); |
| 920 | 949 |
| 921 DestroyStorageManager(); | 950 DestroyStorageManager(); |
| 922 CreateStorageManager(); | 951 CreateStorageManager(); |
| 923 | 952 |
| 924 EXPECT_TRUE(Open(origin1_, kCacheName)); | 953 EXPECT_TRUE(Open(origin1_, kCacheName)); |
| 925 EXPECT_EQ(size_before_close, Size(origin1_)); | 954 EXPECT_EQ(size_before_close, Size(origin1_)); |
| 926 } | 955 } |
| 927 | 956 |
| 957 TEST_F(CacheStorageManagerTest, CacheSizePaddedAfterReopen) { |
| 958 const GURL kFooURL = origin1_.Resolve("foo"); |
| 959 const std::string kCacheName = "foo"; |
| 960 |
| 961 int64_t put_delta = quota_manager_proxy_->last_notified_delta(); |
| 962 EXPECT_EQ(0, put_delta); |
| 963 EXPECT_EQ(0, quota_manager_proxy_->notify_storage_modified_count()); |
| 964 |
| 965 EXPECT_TRUE(Open(origin1_, kCacheName)); |
| 966 std::unique_ptr<CacheStorageCacheHandle> original_handle = |
| 967 std::move(callback_cache_handle_); |
| 968 |
| 969 base::RunLoop().RunUntilIdle(); |
| 970 put_delta += quota_manager_proxy_->last_notified_delta(); |
| 971 EXPECT_EQ(0, put_delta); |
| 972 EXPECT_EQ(0, quota_manager_proxy_->notify_storage_modified_count()); |
| 973 |
| 974 EXPECT_TRUE( |
| 975 CachePut(original_handle->value(), kFooURL, FetchResponseType::kOpaque)); |
| 976 int64_t cache_size_before_close = Size(origin1_); |
| 977 base::FilePath storage_dir = original_handle->value()->path().DirName(); |
| 978 original_handle = nullptr; |
| 979 EXPECT_GT(cache_size_before_close, 0); |
| 980 |
| 981 base::RunLoop().RunUntilIdle(); |
| 982 EXPECT_EQ(cache_size_before_close, GetQuotaOriginUsage(origin1_)); |
| 983 |
| 984 base::RunLoop().RunUntilIdle(); |
| 985 put_delta = quota_manager_proxy_->last_notified_delta(); |
| 986 EXPECT_GT(put_delta, 0); |
| 987 EXPECT_EQ(1, quota_manager_proxy_->notify_storage_modified_count()); |
| 988 |
| 989 EXPECT_EQ(GetQuotaOriginUsage(origin1_), put_delta); |
| 990 |
| 991 // Close the caches and cache manager. |
| 992 EXPECT_TRUE(FlushCacheStorageIndex(origin1_)); |
| 993 DestroyStorageManager(); |
| 994 |
| 995 // Create a new CacheStorageManager that hasn't yet loaded the origin. |
| 996 CreateStorageManager(); |
| 997 quota_manager_proxy_->SimulateQuotaManagerDestroyed(); |
| 998 cache_manager_ = CacheStorageManager::Create(cache_manager_.get()); |
| 999 EXPECT_TRUE(Open(origin1_, kCacheName)); |
| 1000 |
| 1001 base::RunLoop().RunUntilIdle(); |
| 1002 put_delta = quota_manager_proxy_->last_notified_delta(); |
| 1003 EXPECT_EQ(0, put_delta); |
| 1004 EXPECT_EQ(0, quota_manager_proxy_->notify_storage_modified_count()); |
| 1005 |
| 1006 EXPECT_EQ(cache_size_before_close, Size(origin1_)); |
| 1007 } |
| 1008 |
| 1009 TEST_F(CacheStorageManagerTest, PersistedCacheKeyUsed) { |
| 1010 const GURL kFooURL = origin1_.Resolve("foo"); |
| 1011 const std::string kCacheName = "foo"; |
| 1012 |
| 1013 EXPECT_TRUE(Open(origin1_, kCacheName)); |
| 1014 std::unique_ptr<CacheStorageCacheHandle> original_handle = |
| 1015 std::move(callback_cache_handle_); |
| 1016 |
| 1017 EXPECT_TRUE( |
| 1018 CachePut(original_handle->value(), kFooURL, FetchResponseType::kOpaque)); |
| 1019 |
| 1020 int64_t cache_size_after_put = Size(origin1_); |
| 1021 EXPECT_LT(0, cache_size_after_put); |
| 1022 |
| 1023 // Close the caches and cache manager. |
| 1024 EXPECT_TRUE(FlushCacheStorageIndex(origin1_)); |
| 1025 DestroyStorageManager(); |
| 1026 |
| 1027 // GenerateNewKeyForTest isn't thread safe so |
| 1028 base::RunLoop().RunUntilIdle(); |
| 1029 CacheStorage::GenerateNewKeyForTesting(); |
| 1030 |
| 1031 // Create a new CacheStorageManager that hasn't yet loaded the origin. |
| 1032 CreateStorageManager(); |
| 1033 quota_manager_proxy_->SimulateQuotaManagerDestroyed(); |
| 1034 cache_manager_ = CacheStorageManager::Create(cache_manager_.get()); |
| 1035 |
| 1036 // Reopening the origin/cache creates a new CacheStorage instance with a new |
| 1037 // random key. |
| 1038 EXPECT_TRUE(Open(origin1_, kCacheName)); |
| 1039 |
| 1040 // Size (before any change) should be the same as before it was closed. |
| 1041 EXPECT_EQ(cache_size_after_put, Size(origin1_)); |
| 1042 |
| 1043 // Delete the value. If the new padding key was used to deduct the padded size |
| 1044 // then after deletion we would expect to see a non-zero cache size. |
| 1045 EXPECT_TRUE(Delete(origin1_, "foo")); |
| 1046 EXPECT_EQ(0, Size(origin1_)); |
| 1047 |
| 1048 // Now put the exact same resource back into the cache. This time we expect to |
| 1049 // see a different size as the padding is calculated with a different key. |
| 1050 std::unique_ptr<CacheStorageCacheHandle> new_handle = |
| 1051 std::move(callback_cache_handle_); |
| 1052 EXPECT_TRUE( |
| 1053 CachePut(new_handle->value(), kFooURL, FetchResponseType::kOpaque)); |
| 1054 |
| 1055 EXPECT_NE(cache_size_after_put, Size(origin1_)); |
| 1056 } |
| 1057 |
| 928 // With a memory cache the cache can't be freed from memory until the client | 1058 // With a memory cache the cache can't be freed from memory until the client |
| 929 // calls delete. | 1059 // calls delete. |
| 930 TEST_F(CacheStorageManagerMemoryOnlyTest, MemoryLosesReferenceOnlyAfterDelete) { | 1060 TEST_F(CacheStorageManagerMemoryOnlyTest, MemoryLosesReferenceOnlyAfterDelete) { |
| 931 EXPECT_TRUE(Open(origin1_, "foo")); | 1061 EXPECT_TRUE(Open(origin1_, "foo")); |
| 932 base::WeakPtr<CacheStorageCache> cache = | 1062 base::WeakPtr<CacheStorageCache> cache = |
| 933 callback_cache_handle_->value()->AsWeakPtr(); | 1063 callback_cache_handle_->value()->AsWeakPtr(); |
| 934 callback_cache_handle_ = nullptr; | 1064 callback_cache_handle_ = nullptr; |
| 935 EXPECT_TRUE(cache); | 1065 EXPECT_TRUE(cache); |
| 936 EXPECT_TRUE(Delete(origin1_, "foo")); | 1066 EXPECT_TRUE(Delete(origin1_, "foo")); |
| 937 base::RunLoop().RunUntilIdle(); | 1067 base::RunLoop().RunUntilIdle(); |
| (...skipping 572 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1510 | 1640 |
| 1511 INSTANTIATE_TEST_CASE_P(CacheStorageManagerTests, | 1641 INSTANTIATE_TEST_CASE_P(CacheStorageManagerTests, |
| 1512 CacheStorageManagerTestP, | 1642 CacheStorageManagerTestP, |
| 1513 ::testing::Values(false, true)); | 1643 ::testing::Values(false, true)); |
| 1514 | 1644 |
| 1515 INSTANTIATE_TEST_CASE_P(CacheStorageQuotaClientTests, | 1645 INSTANTIATE_TEST_CASE_P(CacheStorageQuotaClientTests, |
| 1516 CacheStorageQuotaClientTestP, | 1646 CacheStorageQuotaClientTestP, |
| 1517 ::testing::Values(false, true)); | 1647 ::testing::Values(false, true)); |
| 1518 | 1648 |
| 1519 } // namespace content | 1649 } // namespace content |
| OLD | NEW |