chromium/net/http/http_cache.cc

// Copyright 2012 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/341324165): Fix and remove.
#pragma allow_unsafe_buffers
#endif

#include "net/http/http_cache.h"

#include <optional>
#include <string_view>
#include <utility>

#include "base/compiler_specific.h"
#include "base/containers/span.h"
#include "base/feature_list.h"
#include "base/files/file_util.h"
#include "base/format_macros.h"
#include "base/functional/bind.h"
#include "base/functional/callback.h"
#include "base/functional/callback_helpers.h"
#include "base/hash/sha1.h"
#include "base/location.h"
#include "base/memory/ptr_util.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/ref_counted.h"
#include "base/metrics/field_trial.h"
#include "base/metrics/histogram_macros.h"
#include "base/metrics/histogram_macros_local.h"
#include "base/not_fatal_until.h"
#include "base/numerics/safe_conversions.h"
#include "base/pickle.h"
#include "base/ranges/algorithm.h"
#include "base/strings/strcat.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/task/single_thread_task_runner.h"
#include "base/time/default_clock.h"
#include "build/build_config.h"
#include "http_request_info.h"
#include "net/base/cache_type.h"
#include "net/base/features.h"
#include "net/base/io_buffer.h"
#include "net/base/load_flags.h"
#include "net/base/net_errors.h"
#include "net/base/network_anonymization_key.h"
#include "net/base/network_isolation_key.h"
#include "net/base/upload_data_stream.h"
#include "net/disk_cache/disk_cache.h"
#include "net/http/http_cache_transaction.h"
#include "net/http/http_cache_writers.h"
#include "net/http/http_network_layer.h"
#include "net/http/http_network_session.h"
#include "net/http/http_request_info.h"
#include "net/http/http_response_headers.h"
#include "net/http/http_response_info.h"
#include "net/http/http_util.h"
#include "net/log/net_log_with_source.h"
#include "net/quic/quic_server_info.h"
#include "url/origin.h"

#if BUILDFLAG(IS_POSIX)
#include <unistd.h>
#endif

namespace net {

namespace {
// True if any HTTP cache has been initialized.
bool g_init_cache =;

// True if split cache is enabled by default. Must be set before any HTTP cache
// has been initialized.
bool g_enable_split_cache =;

}  // namespace

const char HttpCache::kDoubleKeyPrefix[] =;
const char HttpCache::kDoubleKeySeparator[] =;
const char HttpCache::kSubframeDocumentResourcePrefix[] =;

HttpCache::DefaultBackend::DefaultBackend(
    CacheType type,
    BackendType backend_type,
    scoped_refptr<disk_cache::BackendFileOperationsFactory>
        file_operations_factory,
    const base::FilePath& path,
    int max_bytes,
    bool hard_reset)
    :{}

HttpCache::DefaultBackend::~DefaultBackend() = default;

// static
std::unique_ptr<HttpCache::BackendFactory> HttpCache::DefaultBackend::InMemory(
    int max_bytes) {}

disk_cache::BackendResult HttpCache::DefaultBackend::CreateBackend(
    NetLog* net_log,
    base::OnceCallback<void(disk_cache::BackendResult)> callback) {}

#if BUILDFLAG(IS_ANDROID)
void HttpCache::DefaultBackend::SetAppStatusListenerGetter(
    disk_cache::ApplicationStatusListenerGetter app_status_listener_getter) {
  app_status_listener_getter_ = std::move(app_status_listener_getter);
}
#endif

//-----------------------------------------------------------------------------

HttpCache::ActiveEntry::ActiveEntry(base::WeakPtr<HttpCache> cache,
                                    disk_cache::Entry* entry,
                                    bool opened_in)
    :{}

HttpCache::ActiveEntry::~ActiveEntry() {}

void HttpCache::ActiveEntry::FinalizeDoomed() {}

void HttpCache::ActiveEntry::Deactivate() {}

// TODO(ricea): Add unit test for this method.
void HttpCache::ActiveEntry::SlowDeactivate() {}

bool HttpCache::ActiveEntry::TransactionInReaders(
    Transaction* transaction) const {}

void HttpCache::ActiveEntry::ReleaseWriters() {}

void HttpCache::ActiveEntry::AddTransactionToWriters(
    Transaction* transaction,
    ParallelWritingPattern parallel_writing_pattern) {}

void HttpCache::ActiveEntry::Doom() {}

void HttpCache::ActiveEntry::RestartHeadersPhaseTransactions() {}

void HttpCache::ActiveEntry::RestartHeadersTransaction() {}

void HttpCache::ActiveEntry::ProcessAddToEntryQueue() {}

bool HttpCache::ActiveEntry::RemovePendingTransaction(
    Transaction* transaction) {}

HttpCache::TransactionList HttpCache::ActiveEntry::TakeAllQueuedTransactions() {}

bool HttpCache::ActiveEntry::CanTransactionWriteResponseHeaders(
    Transaction* transaction,
    bool is_partial,
    bool is_match) const {}

//-----------------------------------------------------------------------------

// This structure keeps track of work items that are attempting to create or
// open cache entries or the backend itself.
struct HttpCache::PendingOp {};

//-----------------------------------------------------------------------------

// A work item encapsulates a single request to the backend with all the
// information needed to complete that request.
class HttpCache::WorkItem {};

//-----------------------------------------------------------------------------

HttpCache::HttpCache(std::unique_ptr<HttpTransactionFactory> network_layer,
                     std::unique_ptr<BackendFactory> backend_factory)
    :{}

HttpCache::~HttpCache() {}

HttpCache::GetBackendResult HttpCache::GetBackend(GetBackendCallback callback) {}

void HttpCache::ReportGetBackendResult(GetBackendCallback callback,
                                       int net_error) {}

disk_cache::Backend* HttpCache::GetCurrentBackend() const {}

// static
bool HttpCache::ParseResponseInfo(base::span<const uint8_t> data,
                                  HttpResponseInfo* response_info,
                                  bool* response_truncated) {}

void HttpCache::CloseAllConnections(int net_error,
                                    const char* net_log_reason_utf8) {}

void HttpCache::CloseIdleConnections(const char* net_log_reason_utf8) {}

void HttpCache::OnExternalCacheHit(
    const GURL& url,
    const std::string& http_method,
    const NetworkIsolationKey& network_isolation_key,
    bool used_credentials) {}

int HttpCache::CreateTransaction(
    RequestPriority priority,
    std::unique_ptr<HttpTransaction>* transaction) {}

HttpCache* HttpCache::GetCache() {}

HttpNetworkSession* HttpCache::GetSession() {}

std::unique_ptr<HttpTransactionFactory>
HttpCache::SetHttpNetworkTransactionFactoryForTesting(
    std::unique_ptr<HttpTransactionFactory> new_network_layer) {}

// static
std::string HttpCache::GetResourceURLFromHttpCacheKey(const std::string& key) {}

// static
bool HttpCache::CanGenerateCacheKeyForRequest(const HttpRequestInfo* request) {}

// static
// Generate a key that can be used inside the cache.
std::string HttpCache::GenerateCacheKey(
    const GURL& url,
    int load_flags,
    const NetworkIsolationKey& network_isolation_key,
    int64_t upload_data_identifier,
    bool is_subframe_document_resource,
    bool is_mainframe_navigation,
    std::optional<url::Origin> initiator) {}

// static
HttpCache::ExperimentMode HttpCache::GetExperimentMode() {}

// static
std::optional<std::string> HttpCache::GenerateCacheKeyForRequest(
    const HttpRequestInfo* request) {}

// static
void HttpCache::SplitCacheFeatureEnableByDefault() {}

// static
bool HttpCache::IsSplitCacheEnabled() {}

// static
void HttpCache::ClearGlobalsForTesting() {}

//-----------------------------------------------------------------------------

Error HttpCache::CreateAndSetWorkItem(scoped_refptr<ActiveEntry>* entry,
                                      Transaction* transaction,
                                      WorkItemOperation operation,
                                      PendingOp* pending_op) {}

int HttpCache::CreateBackend(CompletionOnceCallback callback) {}

int HttpCache::GetBackendForTransaction(Transaction* transaction) {}

void HttpCache::DoomActiveEntry(const std::string& key) {}

int HttpCache::DoomEntry(const std::string& key, Transaction* transaction) {}

int HttpCache::AsyncDoomEntry(const std::string& key,
                              Transaction* transaction) {}

void HttpCache::DoomMainEntryForUrl(
    const GURL& url,
    const NetworkIsolationKey& isolation_key,
    bool is_subframe_document_resource,
    bool is_main_frame_navigation,
    const std::optional<url::Origin>& initiator) {}

bool HttpCache::HasActiveEntry(const std::string& key) {}

scoped_refptr<HttpCache::ActiveEntry> HttpCache::GetActiveEntry(
    const std::string& key) {}

scoped_refptr<HttpCache::ActiveEntry> HttpCache::ActivateEntry(
    disk_cache::Entry* disk_entry,
    bool opened) {}

HttpCache::PendingOp* HttpCache::GetPendingOp(const std::string& key) {}

void HttpCache::DeletePendingOp(PendingOp* pending_op) {}

int HttpCache::OpenOrCreateEntry(const std::string& key,
                                 scoped_refptr<ActiveEntry>* entry,
                                 Transaction* transaction) {}

int HttpCache::OpenEntry(const std::string& key,
                         scoped_refptr<ActiveEntry>* entry,
                         Transaction* transaction) {}

int HttpCache::CreateEntry(const std::string& key,
                           scoped_refptr<ActiveEntry>* entry,
                           Transaction* transaction) {}

int HttpCache::AddTransactionToEntry(scoped_refptr<ActiveEntry>& entry,
                                     Transaction* transaction) {}

int HttpCache::DoneWithResponseHeaders(scoped_refptr<ActiveEntry>& entry,
                                       Transaction* transaction,
                                       bool is_partial) {}

void HttpCache::DoneWithEntry(scoped_refptr<ActiveEntry>& entry,
                              Transaction* transaction,
                              bool entry_is_complete,
                              bool is_partial) {}

void HttpCache::WritersDoomEntryRestartTransactions(ActiveEntry* entry) {}

void HttpCache::WritersDoneWritingToEntry(scoped_refptr<ActiveEntry> entry,
                                          bool success,
                                          bool should_keep_entry,
                                          TransactionSet make_readers) {}

void HttpCache::DoomEntryValidationNoMatch(scoped_refptr<ActiveEntry> entry) {}

void HttpCache::ProcessEntryFailure(ActiveEntry* entry) {}

void HttpCache::ProcessQueuedTransactions(scoped_refptr<ActiveEntry> entry) {}

void HttpCache::ProcessAddToEntryQueue(scoped_refptr<ActiveEntry> entry) {}

void HttpCache::ProcessAddToEntryQueueImpl(scoped_refptr<ActiveEntry> entry) {}

HttpCache::ParallelWritingPattern HttpCache::CanTransactionJoinExistingWriters(
    Transaction* transaction) {}

void HttpCache::ProcessDoneHeadersQueue(scoped_refptr<ActiveEntry> entry) {}

LoadState HttpCache::GetLoadStateForPendingTransaction(
    const Transaction* transaction) {}

void HttpCache::RemovePendingTransaction(Transaction* transaction) {}

bool HttpCache::RemovePendingTransactionFromPendingOp(
    PendingOp* pending_op,
    Transaction* transaction) {}

void HttpCache::MarkKeyNoStore(const std::string& key) {}

bool HttpCache::DidKeyLeadToNoStoreResponse(const std::string& key) {}

void HttpCache::OnProcessQueuedTransactions(scoped_refptr<ActiveEntry> entry) {}

void HttpCache::OnIOComplete(int result, PendingOp* pending_op) {}

// static
void HttpCache::OnPendingOpComplete(base::WeakPtr<HttpCache> cache,
                                    PendingOp* pending_op,
                                    int rv) {}

// static
void HttpCache::OnPendingCreationOpComplete(base::WeakPtr<HttpCache> cache,
                                            PendingOp* pending_op,
                                            disk_cache::EntryResult result) {}

// static
void HttpCache::OnPendingBackendCreationOpComplete(
    base::WeakPtr<HttpCache> cache,
    PendingOp* pending_op,
    disk_cache::BackendResult result) {}

void HttpCache::OnBackendCreated(int result, PendingOp* pending_op) {}

}  // namespace net