#ifdef UNSAFE_BUFFERS_BUILD
#pragma allow_unsafe_buffers
#endif
#include "content/browser/cache_storage/cache_storage_cache.h"
#include <stddef.h>
#include <functional>
#include <limits>
#include <memory>
#include <string>
#include <utility>
#include "base/barrier_closure.h"
#include "base/containers/flat_map.h"
#include "base/files/file_path.h"
#include "base/functional/bind.h"
#include "base/functional/callback_helpers.h"
#include "base/memory/ptr_util.h"
#include "base/metrics/histogram_functions.h"
#include "base/metrics/histogram_macros.h"
#include "base/numerics/checked_math.h"
#include "base/ranges/algorithm.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/task/sequenced_task_runner.h"
#include "base/time/time.h"
#include "base/trace_event/trace_event.h"
#include "base/trace_event/traced_value.h"
#include "content/browser/cache_storage/cache_storage.h"
#include "content/browser/cache_storage/cache_storage.pb.h"
#include "content/browser/cache_storage/cache_storage_blob_to_disk_cache.h"
#include "content/browser/cache_storage/cache_storage_cache_entry_handler.h"
#include "content/browser/cache_storage/cache_storage_cache_handle.h"
#include "content/browser/cache_storage/cache_storage_cache_observer.h"
#include "content/browser/cache_storage/cache_storage_histogram_utils.h"
#include "content/browser/cache_storage/cache_storage_manager.h"
#include "content/browser/cache_storage/cache_storage_quota_client.h"
#include "content/browser/cache_storage/cache_storage_scheduler.h"
#include "content/browser/cache_storage/cache_storage_trace_utils.h"
#include "content/common/background_fetch/background_fetch_types.h"
#include "crypto/hmac.h"
#include "crypto/symmetric_key.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "net/base/completion_repeating_callback.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
#include "net/base/url_util.h"
#include "net/disk_cache/disk_cache.h"
#include "net/http/http_connection_info.h"
#include "net/http/http_request_headers.h"
#include "net/http/http_response_headers.h"
#include "net/http/http_status_code.h"
#include "services/network/public/mojom/fetch_api.mojom.h"
#include "storage/browser/quota/quota_manager_proxy.h"
#include "storage/common/quota/padding_key.h"
#include "third_party/abseil-cpp/absl/container/inlined_vector.h"
#include "third_party/blink/public/common/cache_storage/cache_storage_utils.h"
#include "third_party/blink/public/common/fetch/fetch_api_request_headers_map.h"
#include "third_party/blink/public/mojom/loader/referrer.mojom.h"
#include "third_party/blink/public/mojom/quota/quota_types.mojom.h"
CacheStorageError;
CacheStorageVerboseError;
namespace content {
namespace {
ResponseHeaderMap;
const size_t kMaxQueryCacheResultBytes = …;
const int32_t kCachePaddingAlgorithmVersion = …;
const int kMaxQueryCacheRecursiveDepth = …;
MetadataCallback;
network::mojom::FetchResponseType ProtoResponseTypeToFetchResponseType(
proto::CacheResponse::ResponseType response_type) { … }
proto::CacheResponse::ResponseType FetchResponseTypeToProtoResponseType(
network::mojom::FetchResponseType response_type) { … }
static_assert …;
static_assert …;
static_assert …;
static_assert …;
static_assert …;
static_assert …;
static_assert …;
static_assert …;
static_assert …;
static_assert …;
static_assert …;
static_assert …;
static_assert …;
static_assert …;
static_assert …;
static_assert …;
static_assert …;
static_assert …;
static_assert …;
static_assert …;
static_assert …;
static_assert …;
static_assert …;
static_assert …;
static_assert …;
static_assert …;
static_assert …;
static_assert …;
static_assert …;
static_assert …;
static_assert …;
static_assert …;
static_assert …;
static_assert …;
static_assert …;
static_assert …;
static_assert …;
static_assert …;
static_assert …;
static_assert …;
static_assert …;
static_assert …;
static_assert …;
static_assert …;
void ReadMetadata(disk_cache::Entry* entry, MetadataCallback callback);
void ReadMetadataDidReadMetadata(disk_cache::Entry* entry,
MetadataCallback callback,
scoped_refptr<net::IOBufferWithSize> buffer,
int rv);
GURL NormalizeCacheUrl(const GURL& url) { … }
bool VaryMatches(const blink::FetchAPIRequestHeadersMap& request,
const blink::FetchAPIRequestHeadersMap& cached_request,
network::mojom::FetchResponseType response_type,
const ResponseHeaderMap& response) { … }
std::vector<std::string> FindDuplicateOperations(
const std::vector<blink::mojom::BatchOperationPtr>& operations) { … }
GURL RemoveQueryParam(const GURL& url) { … }
void ReadMetadata(disk_cache::Entry* entry, MetadataCallback callback) { … }
void ReadMetadataDidReadMetadata(disk_cache::Entry* entry,
MetadataCallback callback,
scoped_refptr<net::IOBufferWithSize> buffer,
int rv) { … }
bool ShouldPadResourceSize(const content::proto::CacheResponse* response) { … }
bool ShouldPadResourceSize(const blink::mojom::FetchAPIResponse& response) { … }
blink::mojom::FetchAPIRequestPtr CreateRequest(
const proto::CacheMetadata& metadata,
const GURL& request_url) { … }
blink::mojom::FetchAPIResponsePtr CreateResponse(
const proto::CacheMetadata& metadata,
const std::string& cache_name) { … }
int64_t CalculateSideDataPadding(
const storage::BucketLocator& bucket_locator,
const ::content::proto::CacheResponse* response,
int side_data_size) { … }
net::RequestPriority GetDiskCachePriority(
CacheStorageSchedulerPriority priority) { … }
}
struct CacheStorageCache::QueryCacheResult { … };
struct CacheStorageCache::QueryCacheContext { … };
struct CacheStorageCache::BatchInfo { … };
std::unique_ptr<CacheStorageCache> CacheStorageCache::CreateMemoryCache(
const storage::BucketLocator& bucket_locator,
storage::mojom::CacheStorageOwner owner,
const std::string& cache_name,
CacheStorage* cache_storage,
scoped_refptr<base::SequencedTaskRunner> scheduler_task_runner,
scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy,
scoped_refptr<BlobStorageContextWrapper> blob_storage_context) { … }
std::unique_ptr<CacheStorageCache> CacheStorageCache::CreatePersistentCache(
const storage::BucketLocator& bucket_locator,
storage::mojom::CacheStorageOwner owner,
const std::string& cache_name,
CacheStorage* cache_storage,
const base::FilePath& path,
scoped_refptr<base::SequencedTaskRunner> scheduler_task_runner,
scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy,
scoped_refptr<BlobStorageContextWrapper> blob_storage_context,
int64_t cache_size,
int64_t cache_padding) { … }
base::WeakPtr<CacheStorageCache> CacheStorageCache::AsWeakPtr() { … }
CacheStorageCacheHandle CacheStorageCache::CreateHandle() { … }
void CacheStorageCache::AddHandleRef() { … }
void CacheStorageCache::DropHandleRef() { … }
bool CacheStorageCache::IsUnreferenced() const { … }
void CacheStorageCache::Match(blink::mojom::FetchAPIRequestPtr request,
blink::mojom::CacheQueryOptionsPtr match_options,
CacheStorageSchedulerPriority priority,
int64_t trace_id,
ResponseCallback callback) { … }
void CacheStorageCache::MatchAll(
blink::mojom::FetchAPIRequestPtr request,
blink::mojom::CacheQueryOptionsPtr match_options,
int64_t trace_id,
ResponsesCallback callback) { … }
void CacheStorageCache::WriteSideData(ErrorCallback callback,
const GURL& url,
base::Time expected_response_time,
int64_t trace_id,
scoped_refptr<net::IOBuffer> buffer,
int buf_len) { … }
void CacheStorageCache::BatchOperation(
std::vector<blink::mojom::BatchOperationPtr> operations,
int64_t trace_id,
VerboseErrorCallback callback,
BadMessageCallback bad_message_callback) { … }
void CacheStorageCache::BatchDidGetBucketSpaceRemaining(
std::vector<blink::mojom::BatchOperationPtr> operations,
int64_t trace_id,
VerboseErrorCallback callback,
BadMessageCallback bad_message_callback,
std::optional<std::string> message,
uint64_t space_required,
uint64_t side_data_size,
storage::QuotaErrorOr<int64_t> space_remaining) { … }
void CacheStorageCache::BatchDidOneOperation(BatchInfo& batch_status,
CacheStorageError error) { … }
void CacheStorageCache::Keys(blink::mojom::FetchAPIRequestPtr request,
blink::mojom::CacheQueryOptionsPtr options,
int64_t trace_id,
RequestsCallback callback) { … }
void CacheStorageCache::Close(base::OnceClosure callback) { … }
void CacheStorageCache::Size(SizeCallback callback) { … }
void CacheStorageCache::GetSizeThenClose(SizeCallback callback) { … }
void CacheStorageCache::SetObserver(CacheStorageCacheObserver* observer) { … }
size_t CacheStorageCache::EstimatedStructSize(
const blink::mojom::FetchAPIRequestPtr& request) { … }
CacheStorageCache::~CacheStorageCache() = default;
void CacheStorageCache::SetSchedulerForTesting(
std::unique_ptr<CacheStorageScheduler> scheduler) { … }
CacheStorageCache::CacheStorageCache(
const storage::BucketLocator& bucket_locator,
storage::mojom::CacheStorageOwner owner,
const std::string& cache_name,
const base::FilePath& path,
CacheStorage* cache_storage,
scoped_refptr<base::SequencedTaskRunner> scheduler_task_runner,
scoped_refptr<storage::QuotaManagerProxy> quota_manager_proxy,
scoped_refptr<BlobStorageContextWrapper> blob_storage_context,
int64_t cache_size,
int64_t cache_padding)
: … { … }
void CacheStorageCache::QueryCache(blink::mojom::FetchAPIRequestPtr request,
blink::mojom::CacheQueryOptionsPtr options,
QueryTypes query_types,
CacheStorageSchedulerPriority priority,
QueryCacheCallback callback) { … }
void CacheStorageCache::QueryCacheDidOpenFastPath(
std::unique_ptr<QueryCacheContext> query_cache_context,
disk_cache::EntryResult result) { … }
void CacheStorageCache::QueryCacheOpenNextEntry(
std::unique_ptr<QueryCacheContext> query_cache_context) { … }
void CacheStorageCache::QueryCacheFilterEntry(
std::unique_ptr<QueryCacheContext> query_cache_context,
disk_cache::EntryResult result) { … }
void CacheStorageCache::QueryCacheDidReadMetadata(
std::unique_ptr<QueryCacheContext> query_cache_context,
disk_cache::ScopedEntryPtr entry,
std::unique_ptr<proto::CacheMetadata> metadata) { … }
void CacheStorageCache::QueryCacheUpgradePadding(
std::unique_ptr<QueryCacheContext> query_cache_context,
disk_cache::ScopedEntryPtr entry,
std::unique_ptr<proto::CacheMetadata> metadata) { … }
bool CacheStorageCache::QueryCacheResultCompare(const QueryCacheResult& lhs,
const QueryCacheResult& rhs) { … }
size_t CacheStorageCache::EstimatedResponseSizeWithoutBlob(
const blink::mojom::FetchAPIResponse& response) { … }
int32_t CacheStorageCache::GetResponsePaddingVersion() { … }
void CacheStorageCache::MatchImpl(
blink::mojom::FetchAPIRequestPtr request,
blink::mojom::CacheQueryOptionsPtr match_options,
int64_t trace_id,
CacheStorageSchedulerPriority priority,
ResponseCallback callback) { … }
void CacheStorageCache::MatchDidMatchAll(
ResponseCallback callback,
CacheStorageError match_all_error,
std::vector<blink::mojom::FetchAPIResponsePtr> match_all_responses) { … }
void CacheStorageCache::MatchAllImpl(blink::mojom::FetchAPIRequestPtr request,
blink::mojom::CacheQueryOptionsPtr options,
int64_t trace_id,
CacheStorageSchedulerPriority priority,
ResponsesCallback callback) { … }
void CacheStorageCache::MatchAllDidQueryCache(
ResponsesCallback callback,
int64_t trace_id,
CacheStorageError error,
std::unique_ptr<QueryCacheResults> query_cache_results) { … }
void CacheStorageCache::WriteMetadata(disk_cache::Entry* entry,
const proto::CacheMetadata& metadata,
WriteMetadataCallback callback) { … }
void CacheStorageCache::WriteSideDataDidGetBucketSpaceRemaining(
ErrorCallback callback,
const GURL& url,
base::Time expected_response_time,
int64_t trace_id,
scoped_refptr<net::IOBuffer> buffer,
int buf_len,
storage::QuotaErrorOr<int64_t> space_remaining) { … }
void CacheStorageCache::WriteSideDataImpl(ErrorCallback callback,
const GURL& url,
base::Time expected_response_time,
int64_t trace_id,
scoped_refptr<net::IOBuffer> buffer,
int buf_len) { … }
void CacheStorageCache::WriteSideDataDidOpenEntry(
ErrorCallback callback,
base::Time expected_response_time,
int64_t trace_id,
scoped_refptr<net::IOBuffer> buffer,
int buf_len,
disk_cache::EntryResult result) { … }
void CacheStorageCache::WriteSideDataDidReadMetaData(
ErrorCallback callback,
base::Time expected_response_time,
int64_t trace_id,
scoped_refptr<net::IOBuffer> buffer,
int buf_len,
ScopedWritableEntry entry,
std::unique_ptr<proto::CacheMetadata> headers) { … }
void CacheStorageCache::WriteSideDataDidWrite(
ErrorCallback callback,
ScopedWritableEntry entry,
int expected_bytes,
std::unique_ptr<::content::proto::CacheMetadata> metadata,
int64_t trace_id,
int rv) { … }
void CacheStorageCache::WriteSideDataDidWriteMetadata(ErrorCallback callback,
ScopedWritableEntry entry,
int64_t padding,
int64_t side_data_padding,
int expected_bytes,
int rv) { … }
void CacheStorageCache::WriteSideDataComplete(
ErrorCallback callback,
ScopedWritableEntry entry,
int64_t padding,
int64_t side_data_padding,
blink::mojom::CacheStorageError error) { … }
void CacheStorageCache::Put(blink::mojom::BatchOperationPtr operation,
int64_t trace_id,
ErrorCallback callback) { … }
void CacheStorageCache::Put(blink::mojom::FetchAPIRequestPtr request,
blink::mojom::FetchAPIResponsePtr response,
int64_t trace_id,
ErrorCallback callback) { … }
void CacheStorageCache::PutImpl(std::unique_ptr<PutContext> put_context) { … }
void CacheStorageCache::PutDidDeleteEntry(
std::unique_ptr<PutContext> put_context,
CacheStorageError error) { … }
void CacheStorageCache::PutDidCreateEntry(
std::unique_ptr<PutContext> put_context,
disk_cache::EntryResult result) { … }
void CacheStorageCache::PutDidWriteHeaders(
std::unique_ptr<PutContext> put_context,
int64_t padding,
int64_t side_data_padding,
int expected_bytes,
int rv) { … }
void CacheStorageCache::PutWriteBlobToCache(
std::unique_ptr<PutContext> put_context,
int disk_cache_body_index) { … }
void CacheStorageCache::PutDidWriteBlobToCache(
std::unique_ptr<PutContext> put_context,
BlobToDiskCacheIDMap::KeyType blob_to_cache_key,
int disk_cache_body_index,
ScopedWritableEntry entry,
bool success) { … }
void CacheStorageCache::PutWriteBlobToCacheComplete(
std::unique_ptr<PutContext> put_context,
int disk_cache_body_index,
ScopedWritableEntry entry,
int rv) { … }
void CacheStorageCache::PutComplete(std::unique_ptr<PutContext> put_context,
blink::mojom::CacheStorageError error) { … }
void CacheStorageCache::CalculateCacheSizePadding(
SizePaddingCallback got_sizes_callback) { … }
void CacheStorageCache::CalculateCacheSizePaddingGotSize(
SizePaddingCallback callback,
int64_t cache_size) { … }
void CacheStorageCache::PaddingDidQueryCache(
SizePaddingCallback callback,
int64_t cache_size,
CacheStorageError error,
std::unique_ptr<QueryCacheResults> query_cache_results) { … }
void CacheStorageCache::CalculateCacheSize(
net::Int64CompletionOnceCallback callback) { … }
void CacheStorageCache::UpdateCacheSize(base::OnceClosure callback) { … }
void CacheStorageCache::UpdateCacheSizeGotSize(
CacheStorageCacheHandle cache_handle,
base::OnceClosure callback,
int64_t current_cache_size) { … }
void CacheStorageCache::UpdateCacheSizeNotifiedStorageModified(
base::OnceClosure callback) { … }
void CacheStorageCache::GetAllMatchedEntries(
blink::mojom::FetchAPIRequestPtr request,
blink::mojom::CacheQueryOptionsPtr options,
int64_t trace_id,
CacheEntriesCallback callback) { … }
void CacheStorageCache::GetAllMatchedEntriesImpl(
blink::mojom::FetchAPIRequestPtr request,
blink::mojom::CacheQueryOptionsPtr options,
int64_t trace_id,
CacheEntriesCallback callback) { … }
void CacheStorageCache::GetAllMatchedEntriesDidQueryCache(
int64_t trace_id,
CacheEntriesCallback callback,
blink::mojom::CacheStorageError error,
std::unique_ptr<QueryCacheResults> query_cache_results) { … }
CacheStorageCache::InitState CacheStorageCache::GetInitState() const { … }
void CacheStorageCache::Delete(blink::mojom::BatchOperationPtr operation,
ErrorCallback callback) { … }
void CacheStorageCache::DeleteImpl(
blink::mojom::FetchAPIRequestPtr request,
blink::mojom::CacheQueryOptionsPtr match_options,
ErrorCallback callback) { … }
void CacheStorageCache::DeleteDidQueryCache(
ErrorCallback callback,
CacheStorageError error,
std::unique_ptr<QueryCacheResults> query_cache_results) { … }
void CacheStorageCache::KeysImpl(blink::mojom::FetchAPIRequestPtr request,
blink::mojom::CacheQueryOptionsPtr options,
int64_t trace_id,
RequestsCallback callback) { … }
void CacheStorageCache::KeysDidQueryCache(
RequestsCallback callback,
int64_t trace_id,
CacheStorageError error,
std::unique_ptr<QueryCacheResults> query_cache_results) { … }
void CacheStorageCache::CloseImpl(base::OnceClosure callback) { … }
void CacheStorageCache::DeleteBackendCompletedIO() { … }
void CacheStorageCache::SizeImpl(SizeCallback callback) { … }
void CacheStorageCache::GetSizeThenCloseDidGetSize(SizeCallback callback,
int64_t cache_size) { … }
void CacheStorageCache::CreateBackend(ErrorCallback callback) { … }
void CacheStorageCache::CreateBackendDidCreate(
CacheStorageCache::ErrorCallback callback,
disk_cache::BackendResult result) { … }
void CacheStorageCache::InitBackend() { … }
void CacheStorageCache::InitDidCreateBackend(
base::OnceClosure callback,
CacheStorageError cache_create_error) { … }
void CacheStorageCache::InitGotCacheSize(base::OnceClosure callback,
CacheStorageError cache_create_error,
int64_t cache_size) { … }
void CacheStorageCache::InitGotCacheSizeAndPadding(
base::OnceClosure callback,
CacheStorageError cache_create_error,
int64_t cache_size,
int64_t cache_padding) { … }
int64_t CacheStorageCache::PaddedCacheSize() const { … }
base::CheckedNumeric<uint64_t>
CacheStorageCache::CalculateRequiredSafeSpaceForPut(
const blink::mojom::BatchOperationPtr& operation) { … }
base::CheckedNumeric<uint64_t>
CacheStorageCache::CalculateRequiredSafeSpaceForRequest(
const blink::mojom::FetchAPIRequestPtr& request) { … }
base::CheckedNumeric<uint64_t>
CacheStorageCache::CalculateRequiredSafeSpaceForResponse(
const blink::mojom::FetchAPIResponsePtr& response) { … }
}