chromium/third_party/blink/renderer/core/fetch/fetch_manager.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/351564777): Remove this and convert code to safer constructs.
#pragma allow_unsafe_buffers
#endif

#include "third_party/blink/renderer/core/fetch/fetch_manager.h"

#include <stdint.h>

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

#include "base/check.h"
#include "base/feature_list.h"
#include "base/metrics/histogram_functions.h"
#include "base/numerics/safe_conversions.h"
#include "base/strings/strcat.h"
#include "base/task/single_thread_task_runner.h"
#include "base/time/time.h"
#include "base/unguessable_token.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "services/network/public/cpp/features.h"
#include "services/network/public/cpp/header_util.h"
#include "services/network/public/cpp/is_potentially_trustworthy.h"
#include "services/network/public/cpp/request_mode.h"
#include "services/network/public/cpp/resource_request.h"
#include "services/network/public/mojom/fetch_api.mojom-blink.h"
#include "services/network/public/mojom/trust_tokens.mojom-blink.h"
#include "services/network/public/mojom/url_loader_factory.mojom-blink.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/common/scheme_registry.h"
#include "third_party/blink/public/mojom/fetch/fetch_api_request.mojom-blink.h"
#include "third_party/blink/public/mojom/loader/code_cache.mojom-blink.h"
#include "third_party/blink/public/mojom/loader/fetch_later.mojom-blink.h"
#include "third_party/blink/public/platform/browser_interface_broker_proxy.h"
#include "third_party/blink/public/platform/task_type.h"
#include "third_party/blink/public/platform/web_url_request.h"
#include "third_party/blink/public/platform/web_url_request_util.h"
#include "third_party/blink/renderer/bindings/core/v8/script_promise_resolver.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_response_init.h"
#include "third_party/blink/renderer/bindings/core/v8/v8_throw_dom_exception.h"
#include "third_party/blink/renderer/core/dom/abort_signal.h"
#include "third_party/blink/renderer/core/dom/document.h"
#include "third_party/blink/renderer/core/dom/dom_exception.h"
#include "third_party/blink/renderer/core/execution_context/execution_context.h"
#include "third_party/blink/renderer/core/fetch/body.h"
#include "third_party/blink/renderer/core/fetch/body_stream_buffer.h"
#include "third_party/blink/renderer/core/fetch/fetch_later_result.h"
#include "third_party/blink/renderer/core/fetch/fetch_request_data.h"
#include "third_party/blink/renderer/core/fetch/form_data_bytes_consumer.h"
#include "third_party/blink/renderer/core/fetch/place_holder_bytes_consumer.h"
#include "third_party/blink/renderer/core/fetch/response.h"
#include "third_party/blink/renderer/core/fetch/trust_token_to_mojom.h"
#include "third_party/blink/renderer/core/fileapi/blob.h"
#include "third_party/blink/renderer/core/frame/csp/content_security_policy.h"
#include "third_party/blink/renderer/core/frame/frame.h"
#include "third_party/blink/renderer/core/frame/local_dom_window.h"
#include "third_party/blink/renderer/core/frame/local_frame_client.h"
#include "third_party/blink/renderer/core/inspector/console_message.h"
#include "third_party/blink/renderer/core/inspector/identifiers_factory.h"
#include "third_party/blink/renderer/core/inspector/inspector_audits_issue.h"
#include "third_party/blink/renderer/core/loader/subresource_integrity_helper.h"
#include "third_party/blink/renderer/core/loader/threadable_loader.h"
#include "third_party/blink/renderer/core/loader/threadable_loader_client.h"
#include "third_party/blink/renderer/core/page/chrome_client.h"
#include "third_party/blink/renderer/core/page/page.h"
#include "third_party/blink/renderer/core/probe/core_probes.h"
#include "third_party/blink/renderer/core/typed_arrays/dom_array_buffer.h"
#include "third_party/blink/renderer/core/workers/shared_worker_global_scope.h"
#include "third_party/blink/renderer/platform/bindings/exception_state.h"
#include "third_party/blink/renderer/platform/bindings/script_forbidden_scope.h"
#include "third_party/blink/renderer/platform/bindings/script_state.h"
#include "third_party/blink/renderer/platform/bindings/thread_debugger.h"
#include "third_party/blink/renderer/platform/bindings/v8_throw_exception.h"
#include "third_party/blink/renderer/platform/heap/garbage_collected.h"
#include "third_party/blink/renderer/platform/heap/persistent.h"
#include "third_party/blink/renderer/platform/instrumentation/use_counter.h"
#include "third_party/blink/renderer/platform/loader/cors/cors.h"
#include "third_party/blink/renderer/platform/loader/fetch/buffering_bytes_consumer.h"
#include "third_party/blink/renderer/platform/loader/fetch/bytes_consumer.h"
#include "third_party/blink/renderer/platform/loader/fetch/cached_metadata.h"
#include "third_party/blink/renderer/platform/loader/fetch/fetch_initiator_type_names.h"
#include "third_party/blink/renderer/platform/loader/fetch/fetch_parameters.h"
#include "third_party/blink/renderer/platform/loader/fetch/fetch_utils.h"
#include "third_party/blink/renderer/platform/loader/fetch/memory_cache.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_error.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_fetcher_properties.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_loader_options.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_request.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_request_utils.h"
#include "third_party/blink/renderer/platform/loader/fetch/resource_response.h"
#include "third_party/blink/renderer/platform/loader/fetch/script_cached_metadata_handler.h"
#include "third_party/blink/renderer/platform/loader/fetch/unique_identifier.h"
#include "third_party/blink/renderer/platform/loader/fetch/url_loader/request_conversion.h"
#include "third_party/blink/renderer/platform/loader/subresource_integrity.h"
#include "third_party/blink/renderer/platform/mojo/heap_mojo_associated_remote.h"
#include "third_party/blink/renderer/platform/network/http_names.h"
#include "third_party/blink/renderer/platform/network/network_utils.h"
#include "third_party/blink/renderer/platform/runtime_enabled_features.h"
#include "third_party/blink/renderer/platform/weborigin/kurl.h"
#include "third_party/blink/renderer/platform/weborigin/scheme_registry.h"
#include "third_party/blink/renderer/platform/weborigin/security_origin.h"
#include "third_party/blink/renderer/platform/weborigin/security_policy.h"
#include "third_party/blink/renderer/platform/wtf/functional.h"
#include "third_party/blink/renderer/platform/wtf/hash_set.h"
#include "third_party/blink/renderer/platform/wtf/text/wtf_string.h"
#include "third_party/blink/renderer/platform/wtf/vector.h"
#include "v8/include/v8.h"

CredentialsMode;
FetchResponseType;
RedirectMode;
RequestMode;

namespace blink {

namespace {

// 64 kilobytes.
constexpr uint64_t kMaxScheduledDeferredBytesPerOrigin =;

constexpr ResourceType kFetchLaterResourceType =;
constexpr TextResourceDecoderOptions::ContentType kFetchLaterContentType =;

constexpr net::NetworkTrafficAnnotationTag kFetchLaterTrafficAnnotationTag =;

// These values are persisted to logs. Entries should not be renumbered and
// numeric values should never be reused.
//
// Must remain in sync with FetchLaterRendererMetricType in
// tools/metrics/histograms/enums.xml.
enum class FetchLaterRendererMetricType {};

void LogFetchLaterMetric(const FetchLaterRendererMetricType& type) {}

// Tells whether the FetchLater request should use BackgroundSync permission to
// decide whether it should send out deferred requests on entering
// BackForwardCache.
bool IsFetchLaterUseBackgroundSyncPermissionEnabled() {}

// Allows manually overriding the "send-on-enter-bfcache" behavior without
// considering BackgroundSync permission.
// Defaults to true to flush on entering BackForwardCache.
// See also
// https://github.com/WICG/pending-beacon/issues/30#issuecomment-1333869614
bool IsFetchLaterSendOnEnterBackForwardCacheEnabled() {}

bool HasNonEmptyLocationHeader(const FetchHeaderList* headers) {}

const char* SerializeTrustTokenOperationType(
    network::mojom::TrustTokenOperationType operation_type) {}

// Logs a net error describing why a fetch with Trust Tokens parameters
// failed. This is a temporary measure for debugging a surprisingly high
// incidence of "TypeError: Failed to fetch" when executing Trust Tokens
// issuance operations (crbug.com/1128174).
void HistogramNetErrorForTrustTokensOperation(
    network::mojom::blink::TrustTokenOperationType operation_type,
    int net_error) {}

ResourceLoadPriority ComputeFetchLaterLoadPriority(
    const FetchParameters& params) {}

class FetchManagerResourceRequestContext final : public ResourceRequestContext {};

}  // namespace

// FetchLoaderBase provides common logic to prepare a blink::ResourceRequest
// from a FetchRequestData.
class FetchLoaderBase : public GarbageCollectedMixin {};

class FetchManager::Loader final
    : public GarbageCollected<FetchManager::Loader>,
      public FetchLoaderBase,
      public ThreadableLoaderClient {};

FetchManager::Loader::Loader(ExecutionContext* execution_context,
                             FetchManager* fetch_manager,
                             ScriptPromiseResolver<Response>* resolver,
                             FetchRequestData* fetch_request_data,
                             ScriptState* script_state,
                             AbortSignal* signal)
    :{}

FetchManager::Loader::~Loader() {}

void FetchManager::Loader::Trace(Visitor* visitor) const {}

bool FetchManager::Loader::WillFollowRedirect(
    uint64_t identifier,
    const KURL& url,
    const ResourceResponse& response) {}

void FetchManager::Loader::DidReceiveResponse(
    uint64_t,
    const ResourceResponse& response) {}

void FetchManager::Loader::DidReceiveCachedMetadata(mojo_base::BigBuffer data) {}

void FetchManager::Loader::DidStartLoadingResponseBody(BytesConsumer& body) {}

void FetchManager::Loader::DidFinishLoading(uint64_t) {}

void FetchManager::Loader::DidFail(uint64_t identifier,
                                   const ResourceError& error) {}

void FetchManager::Loader::DidFailRedirectCheck(uint64_t identifier) {}

void FetchLoaderBase::Start(ExceptionState& exception_state) {}

void FetchManager::Loader::Dispose() {}

// https://fetch.spec.whatwg.org/#abort-fetch
// To abort a fetch() call with a promise, request, responseObject, and an
// error:
void FetchManager::Loader::Abort() {}

void FetchLoaderBase::PerformSchemeFetch(ExceptionState& exception_state) {}

void FetchLoaderBase::FileIssueAndPerformNetworkError(
    RendererCorsIssueCode network_error,
    int64_t identifier) {}

void FetchLoaderBase::PerformNetworkError(
    const String& message,
    std::optional<base::UnguessableToken> issue_id) {}

void FetchLoaderBase::PerformHTTPFetch(ExceptionState& exception_state) {}

// performDataFetch() is almost the same as performHTTPFetch(), except for:
// - We set AllowCrossOriginRequests to allow requests to data: URLs in
//   'same-origin' mode.
// - We reject non-GET method.
void FetchLoaderBase::PerformDataFetch() {}

void FetchManager::Loader::CreateLoader(
    ResourceRequest request,
    const ResourceLoaderOptions& resource_loader_options) {}

bool FetchLoaderBase::AddConsoleMessage(
    const String& message,
    std::optional<base::UnguessableToken> issue_id) {}

void FetchManager::Loader::Failed(
    const String& message,
    DOMException* dom_exception,
    std::optional<String> devtools_request_id,
    std::optional<base::UnguessableToken> issue_id) {}

void FetchManager::Loader::NotifyFinished() {}

bool FetchManager::Loader::IsDeferred() const {}

void FetchManager::Loader::LogIfKeepalive(
    std::string_view request_state) const {}

// A subtype of FetchLoader to handle the deferred fetching algorithm [1].
//
// This loader and FetchManager::Loader are similar that they both runs the
// fetching algorithm provided by the base class. However, this loader does not
// go down ThreadableLoader and ResourceFetcher. Rather, it creates requests via
// a similar mojo FetchLaterLoaderFactory. Other differences include:
//   - `IsDeferred()` is true, which helps the base generate different requests.
//   - Expect no response after `Start()` is called.
//   - Support activateAfter from [2] to allow sending at specified time.
//   - Support FetchLaterResult from [2].
//
// Underlying, this loader intends to create a "deferred" fetch request,
// i.e. `ResourceRequest.is_fetch_later_api` is true, when `Start()` is called.
// The request will not be sent by network service (handled via browser)
// immediately until ExecutionContext of the FetchLaterManager is destroyed.
//
// Note that this loader does not use the "defer" mechanism as described in
// `ResourcFetcher::RequestResource()` or `ResourceFetcher::StartLoad()`, as
// the latter method can only be called when ResourcFetcher is not detached.
// Plus, the browser companion must be notified when the context is still alive.
//
// [1]:
// https://whatpr.org/fetch/1647/9ca4bda...9994c1d.html#request-a-deferred-fetch
// [2]:
// https://whatpr.org/fetch/1647/9ca4bda...9994c1d.html#dom-global-fetch-later
class FetchLaterManager::DeferredLoader final
    : public GarbageCollected<FetchLaterManager::DeferredLoader>,
      public FetchLoaderBase {};

FetchManager::FetchManager(ExecutionContext* execution_context)
    :{}

ScriptPromise<Response> FetchManager::Fetch(ScriptState* script_state,
                                            FetchRequestData* request,
                                            AbortSignal* signal,
                                            ExceptionState& exception_state) {}

FetchLaterResult* FetchLaterManager::FetchLater(
    ScriptState* script_state,
    FetchRequestData* request,
    AbortSignal* signal,
    std::optional<DOMHighResTimeStamp> activate_after_ms,
    ExceptionState& exception_state) {}

void FetchManager::ContextDestroyed() {}

void FetchManager::OnLoaderFinished(Loader* loader) {}

void FetchManager::Trace(Visitor* visitor) const {}

FetchLaterManager::FetchLaterManager(ExecutionContext* ec)
    :{}

blink::ChildURLLoaderFactoryBundle* FetchLaterManager::GetFactory() {}

void FetchLaterManager::ContextDestroyed() {}

void FetchLaterManager::ContextEnteredBackForwardCache() {}

void FetchLaterManager::OnDeferredLoaderFinished(
    DeferredLoader* deferred_loader) {}

bool FetchLaterManager::IsBackgroundSyncGranted() const {}

void FetchLaterManager::OnPermissionStatusChange(
    mojom::blink::PermissionStatus status) {}

size_t FetchLaterManager::NumLoadersForTesting() const {}

void FetchLaterManager::RecreateTimerForTesting(
    scoped_refptr<base::SingleThreadTaskRunner> task_runner,
    const base::TickClock* tick_clock) {}

// static
ResourceLoadPriority FetchLaterManager::ComputeLoadPriorityForTesting(
    const FetchParameters& params) {}

std::unique_ptr<network::ResourceRequest>
FetchLaterManager::PrepareNetworkRequest(
    ResourceRequest request,
    const ResourceLoaderOptions& options) const {}

void FetchLaterManager::Trace(Visitor* visitor) const {}

}  // namespace blink