| 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 | |
| 55 namespace content { | 53 namespace content { |
| 56 | 54 |
| 57 namespace { | 55 namespace { |
| 58 | 56 |
| 59 bool IsIndexFileCurrent(const base::FilePath& cache_dir) { | 57 bool IsIndexFileCurrent(const base::FilePath& cache_dir) { |
| 60 base::File::Info info; | 58 base::File::Info info; |
| 61 const base::FilePath index_path = | 59 const base::FilePath index_path = |
| 62 cache_dir.AppendASCII(CacheStorage::kIndexFileName); | 60 cache_dir.AppendASCII(CacheStorage::kIndexFileName); |
| 63 if (!GetFileInfo(index_path, &info)) | 61 if (!GetFileInfo(index_path, &info)) |
| 64 return false; | 62 return false; |
| (...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 350 base::RunLoop loop; | 348 base::RunLoop loop; |
| 351 cache_manager_->MatchAllCaches( | 349 cache_manager_->MatchAllCaches( |
| 352 origin, std::move(unique_request), match_params, | 350 origin, std::move(unique_request), match_params, |
| 353 base::BindOnce(&CacheStorageManagerTest::CacheMatchCallback, | 351 base::BindOnce(&CacheStorageManagerTest::CacheMatchCallback, |
| 354 base::Unretained(this), base::Unretained(&loop))); | 352 base::Unretained(this), base::Unretained(&loop))); |
| 355 loop.Run(); | 353 loop.Run(); |
| 356 | 354 |
| 357 return callback_error_ == CACHE_STORAGE_OK; | 355 return callback_error_ == CACHE_STORAGE_OK; |
| 358 } | 356 } |
| 359 | 357 |
| 360 bool CachePut(CacheStorageCache* cache, | 358 bool CachePut(CacheStorageCache* cache, const GURL& url) { |
| 361 const GURL& url, | |
| 362 FetchResponseType response_type = FetchResponseType::kDefault) { | |
| 363 ServiceWorkerFetchRequest request; | 359 ServiceWorkerFetchRequest request; |
| 364 request.url = url; | 360 request.url = url; |
| 365 | 361 |
| 366 return CachePutWithStatusCode(cache, request, 200, response_type); | 362 return CachePutWithStatusCode(cache, request, 200); |
| 367 } | 363 } |
| 368 | 364 |
| 369 bool CachePutWithRequestAndHeaders( | 365 bool CachePutWithRequestAndHeaders( |
| 370 CacheStorageCache* cache, | 366 CacheStorageCache* cache, |
| 371 const ServiceWorkerFetchRequest& request, | 367 const ServiceWorkerFetchRequest& request, |
| 372 const ServiceWorkerHeaderMap& response_headers, | 368 const ServiceWorkerHeaderMap& response_headers) { |
| 373 FetchResponseType response_type = FetchResponseType::kDefault) { | 369 return CachePutWithStatusCode(cache, request, 200, response_headers); |
| 374 return CachePutWithStatusCode(cache, request, 200, response_type, | |
| 375 response_headers); | |
| 376 } | 370 } |
| 377 | 371 |
| 378 bool CachePutWithStatusCode( | 372 bool CachePutWithStatusCode(CacheStorageCache* cache, |
| 379 CacheStorageCache* cache, | 373 const ServiceWorkerFetchRequest& request, |
| 380 const ServiceWorkerFetchRequest& request, | 374 int status_code, |
| 381 int status_code, | 375 const ServiceWorkerHeaderMap& response_headers = |
| 382 FetchResponseType response_type = FetchResponseType::kDefault, | 376 ServiceWorkerHeaderMap()) { |
| 383 const ServiceWorkerHeaderMap& response_headers = | |
| 384 ServiceWorkerHeaderMap()) { | |
| 385 std::unique_ptr<storage::BlobDataBuilder> blob_data( | 377 std::unique_ptr<storage::BlobDataBuilder> blob_data( |
| 386 new storage::BlobDataBuilder(base::GenerateGUID())); | 378 new storage::BlobDataBuilder(base::GenerateGUID())); |
| 387 blob_data->AppendData(request.url.spec()); | 379 blob_data->AppendData(request.url.spec()); |
| 388 | 380 |
| 389 std::unique_ptr<storage::BlobDataHandle> blob_handle = | 381 std::unique_ptr<storage::BlobDataHandle> blob_handle = |
| 390 blob_storage_context_->AddFinishedBlob(blob_data.get()); | 382 blob_storage_context_->AddFinishedBlob(blob_data.get()); |
| 391 std::unique_ptr<std::vector<GURL>> url_list = | 383 std::unique_ptr<std::vector<GURL>> url_list = |
| 392 base::MakeUnique<std::vector<GURL>>(); | 384 base::MakeUnique<std::vector<GURL>>(); |
| 393 url_list->push_back(request.url); | 385 url_list->push_back(request.url); |
| 394 ServiceWorkerResponse response( | 386 ServiceWorkerResponse response( |
| 395 std::move(url_list), status_code, "OK", response_type, | 387 std::move(url_list), status_code, "OK", |
| 388 network::mojom::FetchResponseType::kDefault, |
| 396 base::MakeUnique<ServiceWorkerHeaderMap>(response_headers), | 389 base::MakeUnique<ServiceWorkerHeaderMap>(response_headers), |
| 397 blob_handle->uuid(), request.url.spec().size(), nullptr /* blob */, | 390 blob_handle->uuid(), request.url.spec().size(), nullptr /* blob */, |
| 398 blink::kWebServiceWorkerResponseErrorUnknown, base::Time(), | 391 blink::kWebServiceWorkerResponseErrorUnknown, base::Time(), |
| 399 false /* is_in_cache_storage */, | 392 false /* is_in_cache_storage */, |
| 400 std::string() /* cache_storage_cache_name */, | 393 std::string() /* cache_storage_cache_name */, |
| 401 base::MakeUnique< | 394 base::MakeUnique< |
| 402 ServiceWorkerHeaderList>() /* cors_exposed_header_names */); | 395 ServiceWorkerHeaderList>() /* cors_exposed_header_names */); |
| 403 | 396 |
| 404 CacheStorageBatchOperation operation; | 397 CacheStorageBatchOperation operation; |
| 405 operation.operation_type = CACHE_STORAGE_CACHE_OPERATION_TYPE_PUT; | 398 operation.operation_type = CACHE_STORAGE_CACHE_OPERATION_TYPE_PUT; |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 476 | 469 |
| 477 int64_t Size(const GURL& origin) { | 470 int64_t Size(const GURL& origin) { |
| 478 base::RunLoop loop; | 471 base::RunLoop loop; |
| 479 CacheStorage* cache_storage = CacheStorageForOrigin(origin); | 472 CacheStorage* cache_storage = CacheStorageForOrigin(origin); |
| 480 cache_storage->Size(base::BindOnce(&CacheStorageManagerTest::UsageCallback, | 473 cache_storage->Size(base::BindOnce(&CacheStorageManagerTest::UsageCallback, |
| 481 base::Unretained(this), &loop)); | 474 base::Unretained(this), &loop)); |
| 482 loop.Run(); | 475 loop.Run(); |
| 483 return callback_usage_; | 476 return callback_usage_; |
| 484 } | 477 } |
| 485 | 478 |
| 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 | |
| 508 protected: | 479 protected: |
| 509 // Temporary directory must be allocated first so as to be destroyed last. | 480 // Temporary directory must be allocated first so as to be destroyed last. |
| 510 base::ScopedTempDir temp_dir_; | 481 base::ScopedTempDir temp_dir_; |
| 511 | 482 |
| 512 TestBrowserThreadBundle browser_thread_bundle_; | 483 TestBrowserThreadBundle browser_thread_bundle_; |
| 513 TestBrowserContext browser_context_; | 484 TestBrowserContext browser_context_; |
| 514 std::unique_ptr<net::URLRequestJobFactoryImpl> url_request_job_factory_; | 485 std::unique_ptr<net::URLRequestJobFactoryImpl> url_request_job_factory_; |
| 515 storage::BlobStorageContext* blob_storage_context_; | 486 storage::BlobStorageContext* blob_storage_context_; |
| 516 | 487 |
| 517 scoped_refptr<MockSpecialStoragePolicy> quota_policy_; | 488 scoped_refptr<MockSpecialStoragePolicy> quota_policy_; |
| (...skipping 429 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 947 auto size_before_close = Size(origin1_); | 918 auto size_before_close = Size(origin1_); |
| 948 EXPECT_GT(size_before_close, 0); | 919 EXPECT_GT(size_before_close, 0); |
| 949 | 920 |
| 950 DestroyStorageManager(); | 921 DestroyStorageManager(); |
| 951 CreateStorageManager(); | 922 CreateStorageManager(); |
| 952 | 923 |
| 953 EXPECT_TRUE(Open(origin1_, kCacheName)); | 924 EXPECT_TRUE(Open(origin1_, kCacheName)); |
| 954 EXPECT_EQ(size_before_close, Size(origin1_)); | 925 EXPECT_EQ(size_before_close, Size(origin1_)); |
| 955 } | 926 } |
| 956 | 927 |
| 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 | |
| 1058 // With a memory cache the cache can't be freed from memory until the client | 928 // With a memory cache the cache can't be freed from memory until the client |
| 1059 // calls delete. | 929 // calls delete. |
| 1060 TEST_F(CacheStorageManagerMemoryOnlyTest, MemoryLosesReferenceOnlyAfterDelete) { | 930 TEST_F(CacheStorageManagerMemoryOnlyTest, MemoryLosesReferenceOnlyAfterDelete) { |
| 1061 EXPECT_TRUE(Open(origin1_, "foo")); | 931 EXPECT_TRUE(Open(origin1_, "foo")); |
| 1062 base::WeakPtr<CacheStorageCache> cache = | 932 base::WeakPtr<CacheStorageCache> cache = |
| 1063 callback_cache_handle_->value()->AsWeakPtr(); | 933 callback_cache_handle_->value()->AsWeakPtr(); |
| 1064 callback_cache_handle_ = nullptr; | 934 callback_cache_handle_ = nullptr; |
| 1065 EXPECT_TRUE(cache); | 935 EXPECT_TRUE(cache); |
| 1066 EXPECT_TRUE(Delete(origin1_, "foo")); | 936 EXPECT_TRUE(Delete(origin1_, "foo")); |
| 1067 base::RunLoop().RunUntilIdle(); | 937 base::RunLoop().RunUntilIdle(); |
| (...skipping 572 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1640 | 1510 |
| 1641 INSTANTIATE_TEST_CASE_P(CacheStorageManagerTests, | 1511 INSTANTIATE_TEST_CASE_P(CacheStorageManagerTests, |
| 1642 CacheStorageManagerTestP, | 1512 CacheStorageManagerTestP, |
| 1643 ::testing::Values(false, true)); | 1513 ::testing::Values(false, true)); |
| 1644 | 1514 |
| 1645 INSTANTIATE_TEST_CASE_P(CacheStorageQuotaClientTests, | 1515 INSTANTIATE_TEST_CASE_P(CacheStorageQuotaClientTests, |
| 1646 CacheStorageQuotaClientTestP, | 1516 CacheStorageQuotaClientTestP, |
| 1647 ::testing::Values(false, true)); | 1517 ::testing::Values(false, true)); |
| 1648 | 1518 |
| 1649 } // namespace content | 1519 } // namespace content |
| OLD | NEW |