chromium/content/browser/cache_storage/cache_storage_cache.cc

// Copyright 2014 The Chromium Authors
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifdef UNSAFE_BUFFERS_BUILD
// TODO(crbug.com/342213636): Remove this and spanify to fix the errors.
#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 =;  // 10MB query cache limit

// If the way that a cache's padding is calculated changes increment this
// version.
//
// History:
//
//   1: Uniform random 400K.
//   2: Uniform random 14,431K.
//   3: FetchAPIResponse.padding and separate side data padding.
const int32_t kCachePaddingAlgorithmVersion =;

// Maximum number of recursive QueryCacheOpenNextEntry() calls we permit
// before forcing an asynchronous task.
const int kMaxQueryCacheRecursiveDepth =;

MetadataCallback;

network::mojom::FetchResponseType ProtoResponseTypeToFetchResponseType(
    proto::CacheResponse::ResponseType response_type) {}

proto::CacheResponse::ResponseType FetchResponseTypeToProtoResponseType(
    network::mojom::FetchResponseType response_type) {}

// Assert that ConnectionInfo does not change since we cast it to
// an integer in order to serialize it to disk.
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;
// The following assert needs to be changed every time a new value is added.
// It exists to prevent us from forgetting to add new values above.
static_assert;

// Copy headers out of a cache entry and into a protobuf. The callback is
// guaranteed to be run.
void ReadMetadata(disk_cache::Entry* entry, MetadataCallback callback);
void ReadMetadataDidReadMetadata(disk_cache::Entry* entry,
                                 MetadataCallback callback,
                                 scoped_refptr<net::IOBufferWithSize> buffer,
                                 int rv);

// This method will return a normalized Cache URL. In this case, the only
// normalization being done is to remove the fragment (ref is a synonym
// for fragment).
GURL NormalizeCacheUrl(const GURL& url) {}

bool VaryMatches(const blink::FetchAPIRequestHeadersMap& request,
                 const blink::FetchAPIRequestHeadersMap& cached_request,
                 network::mojom::FetchResponseType response_type,
                 const ResponseHeaderMap& response) {}

// Checks a batch operation list for duplicate entries. Returns any duplicate
// URL strings that were found. If the return value is empty, then there were no
// duplicates.
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) {}

}  // namespace

struct CacheStorageCache::QueryCacheResult {};

struct CacheStorageCache::QueryCacheContext {};

struct CacheStorageCache::BatchInfo {};

// static
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) {}

// static
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) {}

// static
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) {}

// static
bool CacheStorageCache::QueryCacheResultCompare(const QueryCacheResult& lhs,
                                                const QueryCacheResult& rhs) {}

// static
size_t CacheStorageCache::EstimatedResponseSizeWithoutBlob(
    const blink::mojom::FetchAPIResponse& response) {}

// static
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) {}

}  // namespace content