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

#ifndef CONTENT_BROWSER_LOADER_NAVIGATION_URL_LOADER_IMPL_H_
#define CONTENT_BROWSER_LOADER_NAVIGATION_URL_LOADER_IMPL_H_

#include <optional>

#include "base/gtest_prod_util.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/weak_ptr.h"
#include "base/time/time.h"
#include "content/browser/loader/navigation_url_loader.h"
#include "content/browser/loader/response_head_update_params.h"
#include "content/browser/navigation_subresource_loader_params.h"
#include "content/common/content_export.h"
#include "content/public/browser/frame_tree_node_id.h"
#include "content/public/browser/global_request_id.h"
#include "content/public/browser/ssl_status.h"
#include "content/public/browser/weak_document_ptr.h"
#include "content/public/common/buildflags.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "net/base/load_timing_info.h"
#include "net/cookies/cookie_setting_override.h"
#include "net/url_request/url_request.h"
#include "services/metrics/public/cpp/ukm_source_id.h"
#include "services/network/public/cpp/record_ontransfersizeupdate_utils.h"
#include "services/network/public/cpp/single_request_url_loader_factory.h"
#include "services/network/public/mojom/accept_ch_frame_observer.mojom.h"
#include "services/network/public/mojom/device_bound_sessions.mojom.h"
#include "services/network/public/mojom/network_context.mojom-forward.h"
#include "services/network/public/mojom/service_worker_router_info.mojom-forward.h"
#include "services/network/public/mojom/shared_dictionary_access_observer.mojom.h"
#include "services/network/public/mojom/url_loader.mojom.h"
#include "services/network/public/mojom/url_loader_factory.mojom.h"
#include "services/network/public/mojom/url_response_head.mojom.h"
#include "third_party/blink/public/common/navigation/navigation_policy.h"
#include "third_party/blink/public/common/tokens/tokens.h"
#include "third_party/blink/public/mojom/loader/referrer.mojom-forward.h"

namespace blink {
class URLLoaderThrottle;
}

namespace net {
struct RedirectInfo;
}

namespace network {
class URLLoaderFactoryBuilder;
}  // namespace network

namespace content {

class BrowserContext;
class FrameTreeNode;
class NavigationEarlyHintsManager;
class NavigationLoaderInterceptor;
class PrefetchedSignedExchangeCache;
class SignedExchangeRequestHandler;
class StoragePartition;
class StoragePartitionImpl;
class WebContents;
struct WebPluginInfo;

class CONTENT_EXPORT NavigationURLLoaderImpl
    : public NavigationURLLoader,
      public network::mojom::URLLoaderClient,
      public network::mojom::AcceptCHFrameObserver {
 public:
  // The caller is responsible for ensuring that `delegate` outlives the loader.
  NavigationURLLoaderImpl(
      BrowserContext* browser_context,
      StoragePartition* storage_partition,
      std::unique_ptr<NavigationRequestInfo> request_info,
      std::unique_ptr<NavigationUIData> navigation_ui_data,
      ServiceWorkerMainResourceHandle* service_worker_handle,
      scoped_refptr<PrefetchedSignedExchangeCache>
          prefetched_signed_exchange_cache,
      NavigationURLLoaderDelegate* delegate,
      mojo::PendingRemote<network::mojom::CookieAccessObserver> cookie_observer,
      mojo::PendingRemote<network::mojom::TrustTokenAccessObserver>
          trust_token_observer,
      mojo::PendingRemote<network::mojom::SharedDictionaryAccessObserver>
          shared_dictionary_observer,
      mojo::PendingRemote<network::mojom::URLLoaderNetworkServiceObserver>
          url_loader_network_observer,
      mojo::PendingRemote<network::mojom::DevToolsObserver> devtools_observer,
      mojo::PendingRemote<network::mojom::DeviceBoundSessionAccessObserver>
          device_bound_session_observer,
      std::vector<std::unique_ptr<NavigationLoaderInterceptor>>
          initial_interceptors);

  NavigationURLLoaderImpl(const NavigationURLLoaderImpl&) = delete;
  NavigationURLLoaderImpl& operator=(const NavigationURLLoaderImpl&) = delete;

  ~NavigationURLLoaderImpl() override;

  // Creates a URLLoaderFactory for a navigation. The factory uses
  // `header_client`. This should have the same settings as the factory from
  // the ReconnectableURLLoaderFactoryForIOThread. Called on the UI thread.
  static mojo::PendingRemote<network::mojom::URLLoaderFactory>
  CreateURLLoaderFactoryWithHeaderClient(
      mojo::PendingRemote<network::mojom::TrustedURLLoaderHeaderClient>
          header_client,
      network::URLLoaderFactoryBuilder factory_builder,
      StoragePartitionImpl* partition,
      std::optional<net::CookieSettingOverrides> devtools_cookie_overrides,
      std::optional<net::CookieSettingOverrides> cookie_overrides);

  // NavigationURLLoader implementation:
  // Starts the loader by finalizing loader factories initialization and
  // calling Restart().
  // This is called only once (while Restart can be called multiple times).
  // Sets `started_` true.
  void Start() override;
  void FollowRedirect(
      std::vector<std::string> removed_headers,
      net::HttpRequestHeaders modified_headers,
      net::HttpRequestHeaders modified_cors_exempt_headers) override;
  bool SetNavigationTimeout(base::TimeDelta timeout) override;
  void CancelNavigationTimeout() override;

  void TriggerTimeoutForTesting();
  const network::ResourceRequest& GetResourceRequestForTesting() const;

 private:
  FRIEND_TEST_ALL_PREFIXES(NavigationURLLoaderImplTest,
                           OnAcceptCHFrameReceivedUKM);

  // Creates a terminal URLLoaderFactory only for a known non-network scheme.
  static mojo::PendingRemote<network::mojom::URLLoaderFactory>
  CreateTerminalNonNetworkLoaderFactory(BrowserContext* browser_context,
                                        StoragePartitionImpl* storage_partition,
                                        FrameTreeNode* frame_tree_node,
                                        const GURL& url);
  // Creates a complete URLLoaderFactory for non-network-service-bound requests.
  // Unlike `CreateTerminalNonNetworkLoaderFactory()`, this supports
  // ContentBrowserClient/DevTools interception, external protocols, and unknown
  // schemes.
  // `is_cacheable` indicates whether the returned factory can be cached.
  static std::pair</*is_cacheable=*/bool,
                   scoped_refptr<network::SharedURLLoaderFactory>>
  CreateNonNetworkLoaderFactory(
      BrowserContext* browser_context,
      StoragePartitionImpl* storage_partition,
      FrameTreeNode* frame_tree_node,
      const ukm::SourceIdObj& ukm_id,
      NavigationUIData* navigation_ui_data,
      const NavigationRequestInfo& request_info,
      base::RepeatingCallback<WebContents*()> web_contents_getter,
      const network::ResourceRequest& resource_request);
  // Like `CreateNonNetworkLoaderFactory()`, but caches the factory in
  // `non_network_url_loader_factories_` if `is_cacheable` is true, and reuses
  // it when the same scheme is used more than once in a navigational redirect
  // chain. This is rare because non-network schemes basically don't redirect,
  // but can actually happen e.g. in extension scheme's dynamic URLs (see
  // `DynamicOriginBrowserTest.DynamicUrl` unit test).
  // TODO(crbug.com/40251638): Consider removing the caching, as caches are
  // often source of bug. The caching mechanism is left here to keep the
  // existing behavior.
  scoped_refptr<network::SharedURLLoaderFactory>
  GetOrCreateNonNetworkLoaderFactory();

  // Creates a SharedURLLoaderFactory for network-service-bound requests.
  static scoped_refptr<network::SharedURLLoaderFactory>
  CreateNetworkLoaderFactory(BrowserContext* browser_context,
                             StoragePartitionImpl* storage_partition,
                             FrameTreeNode* frame_tree_node,
                             const ukm::SourceIdObj& ukm_id,
                             bool* bypass_redirect_checks);

  void BindAndInterceptNonNetworkURLLoaderFactoryReceiver(
      const GURL& url,
      mojo::PendingReceiver<network::mojom::URLLoaderFactory> factory_receiver);

  void CreateInterceptors();

  // This could be called multiple times to follow a chain of redirects.
  // This internally rather recreates another loader than actually following the
  // redirects.
  void Restart();

  // `interceptor_result` is the result from the current interceptor (or nullopt
  // if not called via `LoaderCallback`).
  // `next_interceptor` indicates the index of the next interceptor to check.
  void MaybeStartLoader(
      size_t next_interceptor_index,
      std::optional<NavigationLoaderInterceptor::Result> interceptor_result);

  // Called from `MaybeStartLoader` when the request is elected to be
  // intercepted. Intercepts the request with `single_request_factory`.
  void StartInterceptedRequest(
      scoped_refptr<network::SharedURLLoaderFactory> single_request_factory);

  // Start a loader with the default behavior. This should be used when no
  // interceptors have elected to handle the request in the first place.
  void StartNonInterceptedRequest(ResponseHeadUpdateParams head_update_params);

  // This is the `fallback_callback_for_service_worker` passed to
  // NavigationLoaderInterceptor::MaybeCreateLoader. It allows an interceptor
  // to initially elect to handle a request, and later decide to fallback to
  // the default behavior. This is needed for service worker network fallback.
  //
  // This is a static method + WeakPtr `self` argument, to return `nullptr` when
  // `self` is destroyed (`base::BindOnce` + non-static member method +
  // `WeakPtr` doesn't work if the return type is not `void`).
  static network::mojom::URLLoaderFactory* FallbackToNonInterceptedRequest(
      base::WeakPtr<NavigationURLLoaderImpl> self,
      ResponseHeadUpdateParams head_update_params);

  void CreateThrottlingLoaderAndStart(
      scoped_refptr<network::SharedURLLoaderFactory> factory,
      std::vector<std::unique_ptr<blink::URLLoaderThrottle>>
          additional_throttles);

#if BUILDFLAG(ENABLE_PLUGINS)
  void CheckPluginAndContinueOnReceiveResponse(
      network::mojom::URLResponseHeadPtr head,
      network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints,
      bool is_download_if_not_handled_by_plugin,
      const std::vector<WebPluginInfo>& plugins);
#endif

  void CallOnReceivedResponse(
      network::mojom::URLResponseHeadPtr head,
      network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints,
      bool is_download);

  bool MaybeCreateLoaderForResponse(
      const network::URLLoaderCompletionStatus& status,
      network::mojom::URLResponseHeadPtr* response);

  std::vector<std::unique_ptr<blink::URLLoaderThrottle>>
  CreateURLLoaderThrottles();

  std::unique_ptr<SignedExchangeRequestHandler>
  CreateSignedExchangeRequestHandler(
      const NavigationRequestInfo& request_info,
      scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory);

  // When `clear_parsed_headers_for_testing` is true (which is only allowed in
  // tests), `head->parsed_headers` is cleared to enforce and test the async
  // `ParseHeaders()` path. https://crbug.com/434182226
  void ParseHeaders(
      const GURL& url,
      network::mojom::URLResponseHeadPtr head,
      base::OnceCallback<void(network::mojom::URLResponseHeadPtr)> continuation,
      bool clear_parsed_headers_for_testing);

  void NotifyResponseStarted(
      network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints,
      mojo::ScopedDataPipeConsumerHandle response_body,
      const GlobalRequestID& global_request_id,
      bool is_download,
      network::mojom::URLResponseHeadPtr response_head);

  void NotifyRequestRedirected(net::RedirectInfo redirect_info,
                               network::mojom::URLResponseHeadPtr response);

  void NotifyRequestFailed(const network::URLLoaderCompletionStatus& status);

  // network::mojom::URLLoaderClient implementation:
  void OnReceiveEarlyHints(network::mojom::EarlyHintsPtr early_hints) override;
  void OnReceiveResponse(
      network::mojom::URLResponseHeadPtr head,
      mojo::ScopedDataPipeConsumerHandle response_body,
      std::optional<mojo_base::BigBuffer> cached_metadata) override;
  void OnReceiveRedirect(const net::RedirectInfo& redirect_info,
                         network::mojom::URLResponseHeadPtr head) override;
  void OnUploadProgress(int64_t current_position,
                        int64_t total_size,
                        OnUploadProgressCallback callback) override;
  void OnTransferSizeUpdated(int32_t transfer_size_diff) override;
  void OnComplete(const network::URLLoaderCompletionStatus& status) override;

  // network::mojom::AcceptCHFrameObserver implementation
  void OnAcceptCHFrameReceived(
      const url::Origin& origin,
      const std::vector<network::mojom::WebClientHintsType>& accept_ch_frame,
      OnAcceptCHFrameReceivedCallback callback) override;
  void Clone(mojo::PendingReceiver<network::mojom::AcceptCHFrameObserver>
                 listener) override;

  // Records UKM for the navigation load.
  void RecordReceivedResponseUkmForOutermostMainFrame();

  // Record ServiceWorker and the static routing API evaluation related results.
  void MaybeRecordServiceWorkerMainResourceInfo(
      const network::mojom::URLResponseHeadPtr& head);

  raw_ptr<NavigationURLLoaderDelegate, DanglingUntriaged> delegate_;
  raw_ptr<BrowserContext> browser_context_;
  raw_ptr<StoragePartitionImpl> storage_partition_;
  raw_ptr<ServiceWorkerMainResourceHandle> service_worker_handle_;

  std::unique_ptr<network::ResourceRequest> resource_request_;
  std::unique_ptr<NavigationRequestInfo> request_info_;

  // Current URL that is being navigated, updated after redirection.
  GURL url_;

  const FrameTreeNodeId frame_tree_node_id_;
  const GlobalRequestID global_request_id_;
  net::RedirectInfo redirect_info_;
  int redirect_limit_ = net::URLRequest::kMaxRedirects;
  int accept_ch_restart_limit_ = net::URLRequest::kMaxRedirects;
  base::RepeatingCallback<WebContents*()> web_contents_getter_;
  std::unique_ptr<NavigationUIData> navigation_ui_data_;

  scoped_refptr<network::SharedURLLoaderFactory> network_loader_factory_;

  SubresourceLoaderParams subresource_loader_params_;

  std::vector<std::unique_ptr<NavigationLoaderInterceptor>> interceptors_;

  // Set to true if the default URLLoader (network service) was used for the
  // current navigation.
  bool default_loader_used_ = false;

  // Set to true if we receive a valid response from a URLLoader, i.e.
  // URLLoaderClient::OnReceiveResponse() is called.
  bool received_response_ = false;

  bool started_ = false;

  // The completion status if it has been received. This is needed to handle
  // the case that the response is intercepted by download, and OnComplete()
  // is already called while we are transferring the `url_loader_` and
  // response body to download code.
  std::optional<network::URLLoaderCompletionStatus> status_;

  // True when a proxy will handle the redirect checks, or when an interceptor
  // intentionally returned unsafe redirect response
  // (eg: NavigationLoaderInterceptor for loading a local Web Bundle file).
  bool bypass_redirect_checks_ = false;

  mojo::ScopedDataPipeConsumerHandle response_body_;

  // Lazily initialized and used in the case of non-network resource
  // navigations. Keyed by URL scheme.
  std::map<std::string, scoped_refptr<network::SharedURLLoaderFactory>>
      non_network_url_loader_factories_;

  // `NavigationURLLoaderImpl` performs the loading (receiving the
  // `URLLoaderClient` callbacks and related operations) in multiple ways (e.g.
  // through `url_loader_` or `response_loader_receiver_`). `LoaderHolder`
  // centralizes these, to ensure that:
  // - All related operations are cancelled when `Reset()` is called.
  // - The state transitions are consistent.
  //
  // Note: This isn't a complete encapsulation. Some states and operations
  // (especially related to https://crbug.com/434182226) are centralized and
  // checked in `LoaderHolder`, while other operations are still performed
  // directly via `url_loader()`.
  class LoaderHolder final {
   public:
    explicit LoaderHolder(network::mojom::URLLoaderClient* receiver);
    ~LoaderHolder();

    // Right now, `State` is used only for `DUMP_WILL_BE_CHECK()`ing and the
    // other underlying members (e.g. `url_loader_`) should be used to check
    // state-dependent conditions.
    // TODO(https://crbug.com/434182226): Once the `DUMP_WILL_BE_CHECK()`s stick
    // and are turned into `CHECK()`s, `State` must match with `url_loader_`
    // etc. and thus should be used also for non-CHECK purposes.
    enum class State {
      // Neither of the loader or receiver is active right now.
      // This can be a transient state when processing a redirect (after
      // resetting the previous redirect leg and just before starting the next
      // leg).
      kNone,

      // The loading is ongoing and the `NavigationURLLoaderImpl`'s
      // `URLLoaderClient` methods are called via `url_loader_` (the primary
      // cases).
      // The `URLLoaderClient` methods are called directly (synchronously) by
      // `blink::ThrottlingURLLoader`.
      kLoadingViaLoader,

      // The loading is ongoing and the `NavigationURLLoaderImpl`'s
      // `URLLoaderClient` methods are called via
      // `response_loader_receiver_` (for `MaybeCreateLoaderForResponse()`).
      // The `URLLoaderClient` methods are called via mojo.
      kLoadingViaReceiver,

      // All loading via `NavigationURLLoaderImpl` is done and further
      // operation on `LoaderHolder` or calls to `NavigationURLLoaderImpl`'s
      // `URLLoaderClient` methods shouldn't be made, except for some operations
      // directly through `url_loader()`.
      kUnbound,
    };

    State state() const { return state_; }

    blink::ThrottlingURLLoader* url_loader() const { return url_loader_.get(); }
    mojo::PendingRemote<network::mojom::URLLoader>* response_url_loader() {
      return &response_url_loader_;
    }

    // Cancel the current loading, if any.
    // Any associated pending operations should be cancelled.
    // Transitions to `State::kNone`.
    //
    // Note: The "exclusive tasks" (see `ExclusiveTaskState` below) can't be
    // gracefully cancelled here and thus `Reset()` should be called only when
    // there should always be no exclusive tasks. See also `ResetForFailure()`.
    void Reset();

    // When the caller wants to start a new loading operation while there can be
    // existing exclusive tasks, the caller should check `HasExclusiveTask()`,
    // and if there are exclusive tasks, call `ResetForFailure()` and fail the
    // entire loading instead.
    //
    // This is similar to `Reset()`, but also instructs exclusive tasks to be
    // cancelled.
    void ResetForFailure();

    // For starting loading via `url_loader` (transitioning from `kNone` to
    // `kLoadingViaLoader`). THe caller should actually start the loading by
    // calling `url_loader->Start()`.
    // Transitions to `State::kLoadingViaLoader`.
    void SetLoader(std::unique_ptr<blink::ThrottlingURLLoader> url_loader);

    // Switches to loading via `pending_receiver` (transitioning from
    // `kLoadingViaLoader` to `kLoadingViaReceiver`). The caller might already
    // call `url_loader()->Unbind()` etc.
    // Transitions to `State::kLoadingViaReceiver`.
    void BindReceiver(
        mojo::PendingReceiver<network::mojom::URLLoaderClient> pending_receiver,
        scoped_refptr<base::SequencedTaskRunner> task_runner);

    // Unbind the endpoints from ``NavigationURLLoaderImpl`` to
    // `URLLoaderClientEndpointsPtr` (transitioning to `kUnbound`).
    // Transitions to `State::kUnbound`.
    [[nodiscard]] network::mojom::URLLoaderClientEndpointsPtr Unbind();

    // Redirect handling: the expected sequence is:
    // 1. `NavigationURLLoaderImpl::OnReceiveRedirect()`
    // 2. `LoaderHolder::SetModifiedHeadersOnRedirect()`
    // 3. Either:
    //    - `LoaderHolder::FollowRedirect()`, when we want and can continue
    //      using the current `url_loader` for the next redirect leg, or
    //    - `LoaderHolder::ResetForFollowRedirect()` then
    //      `LoaderHolder::SetLoader()`, when we start the next redirect leg
    //      with a new loader.
    // Also `LoaderHolder::Reset()` can be called at any time during this to
    // cancel loading.
    // TODO(https://crbug.com/434182226): Add `CHECK()`s to confirm these
    // sequences.

    // Cache the modified request headers provided by clients during redirect.
    // They will be consumed by next `FollowRedirect()` or
    // `ResetForFollowRedirect()`.
    void SetModifiedHeadersOnRedirect(
        std::vector<std::string> removed_headers,
        net::HttpRequestHeaders modified_headers,
        net::HttpRequestHeaders modified_cors_exempt_headers);

    // Follows the redirect using the current `url_loader_`.
    void FollowRedirect();

    // Similar to `ResetLoader()`, but also calls
    // `URLLoader::ResetForFollowRedirect()` if needed.
    void ResetForFollowRedirect(network::ResourceRequest& resource_request);

    // See the `ExclusiveTaskState` comment below.
    // TODO(https://crbug.com/434182226): Add more exclusive tasks handing.
    enum ExclusiveTaskType {
      // From `OnReceiveRedirect()` until `FollowRedirect()`.
      // This contains two possible async tasks:
      // - Waiting for `network.mojom.NetworkService::ParseHeaders()` and
      // - Waiting for `NavigationURLLoaderDelegate`: from
      //   `OnRequestRedirected()` until
      //   `NavigationURLLoaderImpl::FollowRedirect()` is called.
      kRedirect,

      // Waiting for `NavigationLoaderInterceptor::MaybeCreateLoader()`.
      // From `NavigationURLLoaderImpl::Restart()`
      // Until `NavigationURLLoaderImpl::StartNonInterceptedRequest()` or
      // `NavigationURLLoaderImpl::StartInterceptedRequest()`.
      kInterceptor,
    };
    void OnExclusiveTaskStarted(ExclusiveTaskType exclusive_task_type);
    void OnExclusiveTaskCompleted(ExclusiveTaskType exclusive_task_type);
    bool HasExclusiveTask() const;
    // Should be called only during an exclusive task.
    bool ShouldCancelExclusiveTask(ExclusiveTaskType exclusive_task_type) const;

    bool receiver_is_bound_for_check() const;

   private:
    void ResetInternal();
    void CheckState() const;

    State state_ = State::kNone;

    // `NavigationURLLoaderImpl`'s `URLLoaderClient` methods are called either
    // via `url_loader_` or `response_loader_receiver_`.
    // See also the comment at `State` above for details.
    std::unique_ptr<blink::ThrottlingURLLoader> url_loader_;
    mojo::Receiver<network::mojom::URLLoaderClient> response_loader_receiver_;

    // URLLoader instance for response loaders, i.e loaders created for handling
    // responses received from the network URLLoader.
    //
    // NOTE: This looks like coupled with
    // `LoaderHolder::response_loader_receiver_` but actually isn't, because
    // `response_url_loader_` is never touched during
    // `MaybeCreateLoaderForResponse()` (at least within Chromium codesearch).
    // For now this is kept here as-is but probably can be removed.
    mojo::PendingRemote<network::mojom::URLLoader> response_url_loader_;

    struct ModifiedHeadersOnRedirect final {
      ModifiedHeadersOnRedirect(
          std::vector<std::string> removed_headers,
          net::HttpRequestHeaders modified_headers,
          net::HttpRequestHeaders modified_cors_exempt_headers);
      ModifiedHeadersOnRedirect(const ModifiedHeadersOnRedirect&) = delete;
      ModifiedHeadersOnRedirect(ModifiedHeadersOnRedirect&&) = delete;
      ~ModifiedHeadersOnRedirect();

      std::vector<std::string> removed_headers_;
      net::HttpRequestHeaders modified_headers_;
      net::HttpRequestHeaders modified_cors_exempt_headers_;
    };
    std::optional<ModifiedHeadersOnRedirect> modified_headers_on_redirect_;

    // `NavigationURLLoaderImpl` can be waiting for a certain (possibly async)
    // "exclusive task" and can't start a new request nor receive
    // URLLoaderClient method calls until the task completes. For example,
    // `NavigationURLLoaderImpl`, `NavigationLoaderInterceptor` and
    // `NavigationRequest` are going through checks before sending an initial or
    // redirected request and in the middle of updating the request and other
    // states.
    //
    // Not all arbitrary async operations are considered exclusive tasks here.
    // For example, waiting for URLLoaderClient calls from `url_loader_` or
    // `response_loader_receiver_` aren't considered exclusive tasks, because
    // e.g. we can cancel the `url_loader_`, issue a synthetic redirect response
    // as if it would be received from `url_loader_` and continue on the
    // synthetic redirect.
    //
    // Original design doc:
    // https://docs.google.com/document/d/1xCq9l9mYc3WE1adspyaX7FnPArxKDyz8BcRGTlpQIu8/edit?usp=sharing
    enum ExclusiveTaskState {
      kNoExclusiveTask,

      // There is an exclusive task, and therefore:
      // - No URLLoaderClient methods should be called (except for unexpected
      //   `OnComplete()` or error events like timeout).
      // - No actions that could initiate a new request/redirect etc. are
      //   allowed. When attempting such actions, `NavigationURLLoaderImpl`
      //   should call `ResetForFailure()` and make the navigation fail
      //   immediately.
      //
      // There should be at most one exclusive task at a time.
      kHasExclusiveTask,

      // After `ResetForFailure()` is called, navigation fails and existing
      // exclusive tasks should be cancelled.
      kCancelExclusiveTask,
    };

    ExclusiveTaskState exclusive_task_state_ =
        ExclusiveTaskState::kNoExclusiveTask;
    std::optional<ExclusiveTaskType> current_exclusive_task_type_;
  };

  LoaderHolder loader_holder_{this};

  std::unique_ptr<NavigationEarlyHintsManager> early_hints_manager_;

  // Cleared after `Start()`.
  scoped_refptr<PrefetchedSignedExchangeCache>
      prefetched_signed_exchange_cache_;

  // While it's not expected to have two active Remote ends for the same
  // NavigationURLLoaderImpl, when a TrustedParam is copied all of the pipes are
  // cloned instead of being destroyed.
  mojo::ReceiverSet<network::mojom::AcceptCHFrameObserver>
      accept_ch_frame_observers_;

  // Timer used for triggering (optional) early timeout on the navigation.
  base::OneShotTimer timeout_timer_;

  // The time this loader was created.
  base::TimeTicks loader_creation_time_;

  // Whether the navigation processed an ACCEPT_CH frame in the TLS handshake.
  bool received_accept_ch_frame_ = false;

  // UKM source id used for recording events associated with navigation loading.
  const ukm::SourceId ukm_source_id_;

  // If this navigation was intercepted by a worker but the worker didn't handle
  // it, we still expose some parameters like the worker timing as part of the
  // response.
  ResponseHeadUpdateParams head_update_params_;

  base::WeakPtrFactory<NavigationURLLoaderImpl> weak_factory_{this};
};

// Creates a `ResourceRequest` and sets fields common to navigation and
// prefetch.
// This roughly corresponds to:
// - Step 3 of
// https://html.spec.whatwg.org/multipage/browsing-the-web.html#create-navigation-params-by-fetching
// - Step 2 of
// https://wicg.github.io/nav-speculation/prefetch.html#create-a-navigation-request
// and their surrounding steps.
//
// This helper method is used to create consistent navigational
// `ResourceRequest`s (exposed to the network service and ServiceWorker fetch
// handlers) and make them look similar, regardless of whether they are created
// for prefetches or non-prefetch navigations.
std::unique_ptr<network::ResourceRequest> CreateResourceRequestForNavigation(
    const std::string& method,
    const GURL& url,
    network::mojom::RequestDestination destination,
    const blink::mojom::Referrer& referrer,
    const net::IsolationInfo& isolation_info,
    mojo::PendingRemote<network::mojom::DevToolsObserver> devtools_observer,
    net::RequestPriority priority,
    bool is_main_frame);

}  // namespace content

#endif  // CONTENT_BROWSER_LOADER_NAVIGATION_URL_LOADER_IMPL_H_
