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

#include "content/browser/loader/navigation_url_loader_impl.h"

#include <map>
#include <memory>
#include <set>
#include <utility>

#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/debug/dump_without_crashing.h"
#include "base/feature_list.h"
#include "base/metrics/histogram_macros.h"
#include "base/optional.h"
#include "base/stl_util.h"
#include "base/task/thread_pool.h"
#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
#include "components/download/public/common/download_stats.h"
#include "content/browser/about_url_loader_factory.h"
#include "content/browser/appcache/appcache_navigation_handle.h"
#include "content/browser/appcache/appcache_request_handler.h"
#include "content/browser/blob_storage/chrome_blob_storage_context.h"
#include "content/browser/data_url_loader_factory.h"
#include "content/browser/devtools/devtools_instrumentation.h"
#include "content/browser/file_system/file_system_url_loader_factory.h"
#include "content/browser/frame_host/frame_tree_node.h"
#include "content/browser/frame_host/navigation_request.h"
#include "content/browser/frame_host/navigation_request_info.h"
#include "content/browser/loader/file_url_loader_factory.h"
#include "content/browser/loader/navigation_loader_interceptor.h"
#include "content/browser/loader/navigation_url_loader_delegate.h"
#include "content/browser/loader/prefetch_url_loader_service.h"
#include "content/browser/navigation_subresource_loader_params.h"
#include "content/browser/service_worker/service_worker_container_host.h"
#include "content/browser/service_worker/service_worker_main_resource_handle.h"
#include "content/browser/service_worker/service_worker_main_resource_handle_core.h"
#include "content/browser/service_worker/service_worker_main_resource_loader_interceptor.h"
#include "content/browser/storage_partition_impl.h"
#include "content/browser/url_loader_factory_getter.h"
#include "content/browser/web_contents/web_contents_impl.h"
#include "content/browser/web_package/prefetched_signed_exchange_cache.h"
#include "content/browser/web_package/signed_exchange_consts.h"
#include "content/browser/web_package/signed_exchange_request_handler.h"
#include "content/browser/web_package/signed_exchange_utils.h"
#include "content/browser/web_package/web_bundle_utils.h"
#include "content/browser/webui/url_data_manager_backend.h"
#include "content/browser/webui/web_ui_url_loader_factory_internal.h"
#include "content/common/net/record_load_histograms.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/content_browser_client.h"
#include "content/public/browser/download_utils.h"
#include "content/public/browser/navigation_ui_data.h"
#include "content/public/browser/shared_cors_origin_access_list.h"
#include "content/public/browser/ssl_status.h"
#include "content/public/browser/url_loader_request_interceptor.h"
#include "content/public/browser/url_loader_throttles.h"
#include "content/public/common/content_client.h"
#include "content/public/common/content_features.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/referrer.h"
#include "content/public/common/url_constants.h"
#include "content/public/common/url_utils.h"
#include "content/public/common/webplugininfo.h"
#include "media/media_buildflags.h"
#include "mojo/public/cpp/bindings/receiver.h"
#include "mojo/public/cpp/bindings/remote.h"
#include "net/base/load_flags.h"
#include "net/cert/sct_status_flags.h"
#include "net/cert/signed_certificate_timestamp_and_status.h"
#include "net/http/http_content_disposition.h"
#include "net/http/http_request_headers.h"
#include "net/http/http_status_code.h"
#include "net/ssl/ssl_info.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "net/url_request/redirect_util.h"
#include "net/url_request/url_request.h"
#include "net/url_request/url_request_context.h"
#include "ppapi/buildflags/buildflags.h"
#include "services/network/public/cpp/constants.h"
#include "services/network/public/cpp/features.h"
#include "services/network/public/cpp/request_destination.h"
#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
#include "services/network/public/cpp/wrapper_shared_url_loader_factory.h"
#include "services/network/public/mojom/network_context.mojom-forward.h"
#include "services/network/public/mojom/url_loader_factory.mojom.h"
#include "third_party/blink/public/common/features.h"
#include "third_party/blink/public/common/loader/mime_sniffing_throttle.h"
#include "third_party/blink/public/common/loader/throttling_url_loader.h"
#include "third_party/blink/public/common/mime_util/mime_util.h"

#if defined(OS_ANDROID)
#include "content/browser/android/content_url_loader_factory.h"
#endif

#if BUILDFLAG(ENABLE_PLUGINS)
#include "content/public/browser/plugin_service.h"
#endif

namespace content {

namespace {

class NavigationLoaderInterceptorBrowserContainer
    : public NavigationLoaderInterceptor {
 public:
  explicit NavigationLoaderInterceptorBrowserContainer(
      std::unique_ptr<URLLoaderRequestInterceptor> browser_interceptor)
      : browser_interceptor_(std::move(browser_interceptor)) {}

  ~NavigationLoaderInterceptorBrowserContainer() override = default;

  void MaybeCreateLoader(
      const network::ResourceRequest& tentative_resource_request,
      BrowserContext* browser_context,
      LoaderCallback callback,
      FallbackCallback fallback_callback) override {
    browser_interceptor_->MaybeCreateLoader(
        tentative_resource_request, browser_context,
        base::BindOnce(
            [](LoaderCallback callback,
               URLLoaderRequestInterceptor::RequestHandler handler) {
              if (handler) {
                std::move(callback).Run(
                    base::MakeRefCounted<SingleRequestURLLoaderFactory>(
                        std::move(handler)));
              } else {
                std::move(callback).Run({});
              }
            },
            std::move(callback)));
  }

 private:
  std::unique_ptr<URLLoaderRequestInterceptor> browser_interceptor_;
};

base::LazyInstance<NavigationURLLoaderImpl::URLLoaderFactoryInterceptor>::Leaky
    g_loader_factory_interceptor = LAZY_INSTANCE_INITIALIZER;

size_t GetCertificateChainsSizeInKB(const net::SSLInfo& ssl_info) {
  base::Pickle cert_pickle;
  ssl_info.cert->Persist(&cert_pickle);
  base::Pickle unverified_cert_pickle;
  ssl_info.unverified_cert->Persist(&unverified_cert_pickle);
  return (cert_pickle.size() + unverified_cert_pickle.size()) / 1000;
}

const net::NetworkTrafficAnnotationTag kNavigationUrlLoaderTrafficAnnotation =
    net::DefineNetworkTrafficAnnotation("navigation_url_loader", R"(
      semantics {
        sender: "Navigation URL Loader"
        description:
          "This request is issued by a main frame navigation to fetch the "
          "content of the page that is being navigated to."
        trigger:
          "Navigating Chrome (by clicking on a link, bookmark, history item, "
          "using session restore, etc)."
        data:
          "Arbitrary site-controlled data can be included in the URL, HTTP "
          "headers, and request body. Requests may include cookies and "
          "site-specific credentials."
        destination: WEBSITE
      }
      policy {
        cookies_allowed: YES
        cookies_store: "user"
        setting: "This feature cannot be disabled."
        chrome_policy {
          URLBlacklist {
            URLBlacklist: { entries: '*' }
          }
        }
        chrome_policy {
          URLWhitelist {
            URLWhitelist { }
          }
        }
      }
      comments:
        "Chrome would be unable to navigate to websites without this type of "
        "request. Using either URLBlacklist or URLWhitelist policies (or a "
        "combination of both) limits the scope of these requests."
      )");

// TODO(kinuko): |request_info| can likely be given as a const ref.
std::unique_ptr<network::ResourceRequest> CreateResourceRequest(
    NavigationRequestInfo* request_info,
    int frame_tree_node_id,
    mojo::PendingRemote<network::mojom::CookieAccessObserver> cookie_observer) {
  auto new_request = std::make_unique<network::ResourceRequest>();

  new_request->method = request_info->common_params->method;
  new_request->url = request_info->common_params->url;
  new_request->site_for_cookies =
      request_info->isolation_info.site_for_cookies();
  new_request->force_ignore_site_for_cookies =
      request_info->begin_params->force_ignore_site_for_cookies;
  new_request->trusted_params = network::ResourceRequest::TrustedParams();
  new_request->trusted_params->isolation_info = request_info->isolation_info;
  new_request->trusted_params->cookie_observer = std::move(cookie_observer);
  new_request->is_main_frame = request_info->is_main_frame;

  net::RequestPriority net_priority = net::HIGHEST;
  if (!request_info->is_main_frame &&
      base::FeatureList::IsEnabled(features::kLowPriorityIframes)) {
    net_priority = net::LOWEST;
  }
  new_request->priority = net_priority;

  new_request->render_frame_id = frame_tree_node_id;

  new_request->request_initiator =
      request_info->common_params->initiator_origin;
  new_request->referrer = request_info->common_params->referrer->url;
  new_request->referrer_policy = Referrer::ReferrerPolicyForUrlRequest(
      request_info->common_params->referrer->policy);
  new_request->headers.AddHeadersFromString(
      request_info->begin_params->headers);
  new_request->cors_exempt_headers = request_info->cors_exempt_headers;

  new_request->resource_type = static_cast<int>(
      request_info->is_main_frame ? blink::mojom::ResourceType::kMainFrame
                                  : blink::mojom::ResourceType::kSubFrame);
  if (request_info->is_main_frame)
    new_request->update_first_party_url_on_redirect = true;

  int load_flags = request_info->begin_params->load_flags;
  if (request_info->is_main_frame) {
    load_flags |= net::LOAD_MAIN_FRAME_DEPRECATED;
    load_flags |= net::LOAD_CAN_USE_RESTRICTED_PREFETCH;
  }

  // Sync loads should have maximum priority and should be the only
  // requests that have the ignore limits flag set.
  DCHECK(!(load_flags & net::LOAD_IGNORE_LIMITS));

  new_request->load_flags = load_flags;

  new_request->request_body = request_info->common_params->post_data.get();
  new_request->report_raw_headers = request_info->report_raw_headers;
  new_request->has_user_gesture = request_info->common_params->has_user_gesture;
  new_request->enable_load_timing = true;
  new_request->mode = network::mojom::RequestMode::kNavigate;
  new_request->destination = request_info->begin_params->request_destination;

  if (ui::PageTransitionIsWebTriggerable(
          request_info->common_params->transition)) {
    new_request->trusted_params->has_user_activation =
        request_info->common_params->has_user_gesture;
  } else {
    new_request->trusted_params->has_user_activation = true;
  }

  new_request->credentials_mode = network::mojom::CredentialsMode::kInclude;
  new_request->redirect_mode = network::mojom::RedirectMode::kManual;
  new_request->upgrade_if_insecure = request_info->upgrade_if_insecure;
  new_request->throttling_profile_id = request_info->devtools_frame_token;
  new_request->transition_type = request_info->common_params->transition;
  new_request->previews_state = request_info->common_params->previews_state;
  new_request->devtools_request_id =
      request_info->devtools_navigation_token.ToString();
  new_request->obey_origin_policy = request_info->obey_origin_policy;
  if (request_info->begin_params->trust_token_params) {
    new_request->trust_token_params =
        *request_info->begin_params->trust_token_params;
  }
  return new_request;
}

// Called for requests that we don't have a URLLoaderFactory for.
void UnknownSchemeCallback(
    bool handled_externally,
    const network::ResourceRequest& /* resource_request */,
    mojo::PendingReceiver<network::mojom::URLLoader> receiver,
    mojo::PendingRemote<network::mojom::URLLoaderClient> client) {
  mojo::Remote<network::mojom::URLLoaderClient>(std::move(client))
      ->OnComplete(network::URLLoaderCompletionStatus(
          handled_externally ? net::ERR_ABORTED : net::ERR_UNKNOWN_URL_SCHEME));
}

const char* FrameAcceptHeaderValue() {
#if BUILDFLAG(ENABLE_AV1_DECODER)
  static const char kFrameAcceptHeaderValueWithAvif[] =
      "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,"
      "image/webp,image/apng,*/*;q=0.8";
  static const char* accept_value =
      base::FeatureList::IsEnabled(blink::features::kAVIF)
          ? kFrameAcceptHeaderValueWithAvif
          : network::kFrameAcceptHeaderValue;
  return accept_value;
#else
  return network::kFrameAcceptHeaderValue;
#endif
}

}  // namespace

// TODO(kinuko): Fix the method ordering and move these methods after the ctor.
NavigationURLLoaderImpl::~NavigationURLLoaderImpl() {
  // If neither OnCompleted nor OnReceivedResponse has been invoked, the
  // request was canceled before receiving a response, so log a cancellation.
  // Results after receiving a non-error response are logged in the renderer,
  // if the request is passed to one. If it's a download, or not passed to a
  // renderer for some other reason, results will not be logged for the
  // request. The net::OK check may not be necessary - the case where OK is
  // received without receiving any headers looks broken, anyways.
  if (!received_response_ && (!status_ || status_->error_code != net::OK)) {
    RecordLoadHistograms(url::Origin::Create(url_),
                         resource_request_->destination,
                         status_ ? status_->error_code : net::ERR_ABORTED);
  }
}

uint32_t NavigationURLLoaderImpl::GetURLLoaderOptions(bool is_main_frame) {
  uint32_t options = network::mojom::kURLLoadOptionNone;

  // Ensure that Mime sniffing works.
  options |= network::mojom::kURLLoadOptionSniffMimeType;

  if (is_main_frame) {
    // SSLInfo is not needed on subframe responses because users can inspect
    // only the certificate for the main frame when using the info bubble.
    options |= network::mojom::kURLLoadOptionSendSSLInfoWithResponse;
    options |= network::mojom::kURLLoadOptionSendSSLInfoForCertificateError;
  }

  return options;
}

void NavigationURLLoaderImpl::Start(
    std::unique_ptr<network::PendingSharedURLLoaderFactory>
        pending_network_loader_factory,
    AppCacheNavigationHandle* appcache_handle,
    scoped_refptr<PrefetchedSignedExchangeCache>
        prefetched_signed_exchange_cache,
    scoped_refptr<SignedExchangePrefetchMetricRecorder>
        signed_exchange_prefetch_metric_recorder,
    mojo::PendingRemote<network::mojom::URLLoaderFactory> factory_for_webui,
    std::string accept_langs,
    bool needs_loader_factory_interceptor) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  DCHECK(!started_);
  DCHECK(!head_);
  head_ = network::mojom::URLResponseHead::New();
  started_ = true;

  GetUIThreadTaskRunner({})->PostTask(
      FROM_HERE,
      base::BindOnce(&NavigationURLLoaderImpl::NotifyRequestStarted,
                     weak_factory_.GetWeakPtr(), base::TimeTicks::Now()));

  // TODO(kinuko): This can likely be initialized in the ctor.
  network_loader_factory_ = network::SharedURLLoaderFactory::Create(
      std::move(pending_network_loader_factory));
  if (needs_loader_factory_interceptor && g_loader_factory_interceptor.Get()) {
    mojo::PendingRemote<network::mojom::URLLoaderFactory> factory;
    mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver =
        factory.InitWithNewPipeAndPassReceiver();
    g_loader_factory_interceptor.Get().Run(&receiver);
    network_loader_factory_->Clone(std::move(receiver));
    network_loader_factory_ =
        base::MakeRefCounted<network::WrapperSharedURLLoaderFactory>(
            std::move(factory));
  }

  std::string accept_header_value = FrameAcceptHeaderValue();
  if (signed_exchange_utils::IsSignedExchangeHandlingEnabled(
          browser_context_)) {
    accept_header_value.append(kAcceptHeaderSignedExchangeSuffix);
  }
  resource_request_->headers.SetHeader(net::HttpRequestHeaders::kAccept,
                                       accept_header_value);

  // Requests to WebUI scheme won't get redirected to/from other schemes
  // or be intercepted, so we just let it go here.
  if (factory_for_webui.is_valid()) {
    url_loader_ = blink::ThrottlingURLLoader::CreateLoaderAndStart(
        base::MakeRefCounted<network::WrapperSharedURLLoaderFactory>(
            std::move(factory_for_webui)),
        CreateURLLoaderThrottles(), 0 /* routing_id */,
        global_request_id_.request_id, network::mojom::kURLLoadOptionNone,
        resource_request_.get(), this, kNavigationUrlLoaderTrafficAnnotation,
        base::ThreadTaskRunnerHandle::Get());
    return;
  }

  // Requests to Blob scheme won't get redirected to/from other schemes
  // or be intercepted, so we just let it go here.
  if (request_info_->common_params->url.SchemeIsBlob() &&
      request_info_->blob_url_loader_factory) {
    url_loader_ = blink::ThrottlingURLLoader::CreateLoaderAndStart(
        network::SharedURLLoaderFactory::Create(
            std::move(request_info_->blob_url_loader_factory)),
        CreateURLLoaderThrottles(), 0 /* routing_id */,
        global_request_id_.request_id, network::mojom::kURLLoadOptionNone,
        resource_request_.get(), this, kNavigationUrlLoaderTrafficAnnotation,
        base::ThreadTaskRunnerHandle::Get());
    return;
  }

  CreateInterceptors(appcache_handle, prefetched_signed_exchange_cache,
                     signed_exchange_prefetch_metric_recorder, accept_langs);
  Restart();
}

void NavigationURLLoaderImpl::CreateInterceptors(
    AppCacheNavigationHandle* appcache_handle,
    scoped_refptr<PrefetchedSignedExchangeCache>
        prefetched_signed_exchange_cache,
    scoped_refptr<SignedExchangePrefetchMetricRecorder>
        signed_exchange_prefetch_metric_recorder,
    const std::string& accept_langs) {
  if (prefetched_signed_exchange_cache) {
    std::unique_ptr<NavigationLoaderInterceptor>
        prefetched_signed_exchange_interceptor =
            prefetched_signed_exchange_cache->MaybeCreateInterceptor(url_);
    if (prefetched_signed_exchange_interceptor) {
      interceptors_.push_back(
          std::move(prefetched_signed_exchange_interceptor));
    }
  }

  // Set up an interceptor for service workers.
  if (service_worker_handle_) {
    auto service_worker_interceptor =
        ServiceWorkerMainResourceLoaderInterceptor::CreateForNavigation(
            resource_request_->url, service_worker_handle_->AsWeakPtr(),
            *request_info_);
    // The interceptor may not be created in certain cases (e.g., the origin
    // is not secure).
    if (service_worker_interceptor)
      interceptors_.push_back(std::move(service_worker_interceptor));
  }

  // Set-up an interceptor for AppCache if non-null |appcache_handle| is
  // given.
  if (appcache_handle) {
    CHECK(appcache_handle->host());
    std::unique_ptr<NavigationLoaderInterceptor> appcache_interceptor =
        AppCacheRequestHandler::InitializeForMainResourceNetworkService(
            *resource_request_, appcache_handle->host()->GetWeakPtr());
    if (appcache_interceptor)
      interceptors_.push_back(std::move(appcache_interceptor));
  }

  // Set-up an interceptor for SignedExchange handling if it is enabled.
  if (signed_exchange_utils::IsSignedExchangeHandlingEnabled(
          browser_context_)) {
    interceptors_.push_back(CreateSignedExchangeRequestHandler(
        *request_info_, network_loader_factory_,
        std::move(signed_exchange_prefetch_metric_recorder),
        std::move(accept_langs)));
  }

  // See if embedders want to add interceptors.
  std::vector<std::unique_ptr<URLLoaderRequestInterceptor>>
      browser_interceptors =
          GetContentClient()->browser()->WillCreateURLLoaderRequestInterceptors(
              navigation_ui_data_.get(), frame_tree_node_id_,
              network_loader_factory_);
  if (!browser_interceptors.empty()) {
    for (auto& browser_interceptor : browser_interceptors) {
      interceptors_.push_back(
          std::make_unique<NavigationLoaderInterceptorBrowserContainer>(
              std::move(browser_interceptor)));
    }
  }
}

void NavigationURLLoaderImpl::Restart() {
  // Clear |url_loader_| if it's not the default one (network). This allows
  // the restarted request to use a new loader, instead of, e.g., reusing the
  // AppCache or service worker loader. For an optimization, we keep and reuse
  // the default url loader if the all |interceptors_| doesn't handle the
  // redirected request. If the network service is enabled, reset the loader
  // if the redirected URL's scheme and the previous URL scheme don't match in
  // their use or disuse of the network service loader.
  if (!default_loader_used_ ||
      (url_chain_.size() > 1 &&
       IsURLHandledByNetworkService(url_chain_[url_chain_.size() - 1]) !=
           IsURLHandledByNetworkService(url_chain_[url_chain_.size() - 2]))) {
    if (url_loader_)
      url_loader_->ResetForFollowRedirect();
    url_loader_.reset();
  }
  interceptor_index_ = 0;
  received_response_ = false;
  head_ = network::mojom::URLResponseHead::New();
  MaybeStartLoader(nullptr /* interceptor */, {} /* single_request_factory */);
}

void NavigationURLLoaderImpl::MaybeStartLoader(
    NavigationLoaderInterceptor* interceptor,
    scoped_refptr<network::SharedURLLoaderFactory> single_request_factory) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  DCHECK(started_);

  if (single_request_factory) {
    // |interceptor| wants to handle the request with
    // |single_request_handler|.
    DCHECK(interceptor);

    std::vector<std::unique_ptr<blink::URLLoaderThrottle>> throttles =
        CreateURLLoaderThrottles();
    // Intercepted requests need MimeSniffingThrottle to do mime sniffing.
    // Non-intercepted requests usually go through the regular network
    // URLLoader, which does mime sniffing.
    throttles.push_back(std::make_unique<blink::MimeSniffingThrottle>(
        base::ThreadTaskRunnerHandle::Get()));

    default_loader_used_ = false;
    // If |url_loader_| already exists, this means we are following a redirect
    // using an interceptor. In this case we should make sure to reset the
    // loader, similar to what is done in Restart().
    if (url_loader_)
      url_loader_->ResetForFollowRedirect();
    url_loader_ = blink::ThrottlingURLLoader::CreateLoaderAndStart(
        std::move(single_request_factory), std::move(throttles),
        frame_tree_node_id_, global_request_id_.request_id,
        network::mojom::kURLLoadOptionNone, resource_request_.get(), this,
        kNavigationUrlLoaderTrafficAnnotation,
        base::ThreadTaskRunnerHandle::Get());

    subresource_loader_params_ =
        interceptor->MaybeCreateSubresourceLoaderParams();
    if (interceptor->ShouldBypassRedirectChecks())
      bypass_redirect_checks_ = true;
    return;
  }

  // Before falling back to the next interceptor, see if |interceptor| still
  // wants to give additional info to the frame for subresource loading. In
  // that case we will just fall back to the default loader (i.e. won't go on
  // to the next interceptors) but send the subresource_loader_params to the
  // child process. This is necessary for correctness in the cases where, e.g.
  // there's a controlling service worker that doesn't have a fetch event
  // handler so it doesn't intercept requests. In that case we still want to
  // skip AppCache.
  if (interceptor) {
    subresource_loader_params_ =
        interceptor->MaybeCreateSubresourceLoaderParams();

    // If non-null |subresource_loader_params_| is returned, make sure
    // we skip the next interceptors.
    if (subresource_loader_params_)
      interceptor_index_ = interceptors_.size();
  }

  // See if the next interceptor wants to handle the request.
  if (interceptor_index_ < interceptors_.size()) {
    auto* next_interceptor = interceptors_[interceptor_index_++].get();
    next_interceptor->MaybeCreateLoader(
        *resource_request_, browser_context_,
        base::BindOnce(&NavigationURLLoaderImpl::MaybeStartLoader,
                       base::Unretained(this), next_interceptor),
        base::BindOnce(
            &NavigationURLLoaderImpl::FallbackToNonInterceptedRequest,
            base::Unretained(this)));
    return;
  }

  // If we already have the default |url_loader_| we must come here after a
  // redirect. No interceptors wanted to intercept the redirected request, so
  // let the loader just follow the redirect.
  if (url_loader_) {
    DCHECK(!redirect_info_.new_url.is_empty());
    url_loader_->FollowRedirect(
        std::move(url_loader_removed_headers_),
        std::move(url_loader_modified_headers_),
        std::move(url_loader_modified_cors_exempt_headers_));
    return;
  }

  // No interceptors wanted to handle this request.
  uint32_t options = network::mojom::kURLLoadOptionNone;
  scoped_refptr<network::SharedURLLoaderFactory> factory =
      PrepareForNonInterceptedRequest(&options);
  url_loader_ = blink::ThrottlingURLLoader::CreateLoaderAndStart(
      std::move(factory), CreateURLLoaderThrottles(), frame_tree_node_id_,
      global_request_id_.request_id, options, resource_request_.get(),
      this /* client */, kNavigationUrlLoaderTrafficAnnotation,
      base::ThreadTaskRunnerHandle::Get());
}

void NavigationURLLoaderImpl::FallbackToNonInterceptedRequest(
    bool reset_subresource_loader_params) {
  if (reset_subresource_loader_params)
    subresource_loader_params_.reset();

  uint32_t options = network::mojom::kURLLoadOptionNone;
  scoped_refptr<network::SharedURLLoaderFactory> factory =
      PrepareForNonInterceptedRequest(&options);
  if (url_loader_) {
    // |url_loader_| is using the factory for the interceptor that decided to
    // fallback, so restart it with the non-interceptor factory.
    url_loader_->RestartWithFactory(std::move(factory), options);
  } else {
    // In SXG cases we don't have |url_loader_| because it was reset when the
    // SXG interceptor intercepted the response in
    // MaybeCreateLoaderForResponse.
    DCHECK(response_loader_receiver_.is_bound());
    response_loader_receiver_.reset();
    url_loader_ = blink::ThrottlingURLLoader::CreateLoaderAndStart(
        std::move(factory), CreateURLLoaderThrottles(), frame_tree_node_id_,
        global_request_id_.request_id, options, resource_request_.get(),
        this /* client */, kNavigationUrlLoaderTrafficAnnotation,
        base::ThreadTaskRunnerHandle::Get());
  }
}

scoped_refptr<network::SharedURLLoaderFactory>
NavigationURLLoaderImpl::PrepareForNonInterceptedRequest(
    uint32_t* out_options) {
  // TODO(https://crbug.com/796425): We temporarily wrap raw
  // mojom::URLLoaderFactory pointers into SharedURLLoaderFactory. Need to
  // further refactor the factory getters to avoid this.
  scoped_refptr<network::SharedURLLoaderFactory> factory;

  if (!IsURLHandledByNetworkService(resource_request_->url)) {
    if (known_schemes_.find(resource_request_->url.scheme()) ==
        known_schemes_.end()) {
      mojo::PendingRemote<network::mojom::URLLoaderFactory> loader_factory;
      bool handled = GetContentClient()->browser()->HandleExternalProtocol(
          resource_request_->url, web_contents_getter_,
          ChildProcessHost::kInvalidUniqueID, navigation_ui_data_.get(),
          resource_request_->resource_type ==
              static_cast<int>(blink::mojom::ResourceType::kMainFrame),
          static_cast<ui::PageTransition>(resource_request_->transition_type),
          resource_request_->has_user_gesture,
          resource_request_->request_initiator, &loader_factory);

      if (loader_factory) {
        factory = base::MakeRefCounted<network::WrapperSharedURLLoaderFactory>(
            std::move(loader_factory));
      } else {
        factory = base::MakeRefCounted<SingleRequestURLLoaderFactory>(
            base::BindOnce(UnknownSchemeCallback, handled));
      }
    } else {
      mojo::Remote<network::mojom::URLLoaderFactory>& non_network_factory =
          non_network_url_loader_factory_remotes_[resource_request_->url
                                                      .scheme()];
      if (!non_network_factory.is_bound()) {
        BindNonNetworkURLLoaderFactoryReceiver(
            resource_request_->url,
            non_network_factory.BindNewPipeAndPassReceiver());
      }
      factory =
          base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
              non_network_factory.get());
    }

    if (g_loader_factory_interceptor.Get()) {
      mojo::PendingRemote<network::mojom::URLLoaderFactory> factory_remote;
      mojo::PendingReceiver<network::mojom::URLLoaderFactory> receiver =
          factory_remote.InitWithNewPipeAndPassReceiver();
      g_loader_factory_interceptor.Get().Run(&receiver);
      factory->Clone(std::move(receiver));
      factory = base::MakeRefCounted<network::WrapperSharedURLLoaderFactory>(
          std::move(factory_remote));
    }
  } else {
    default_loader_used_ = true;

    // NOTE: We only support embedders proxying network-service-bound requests
    // not handled by NavigationLoaderInterceptors above (e.g. Service Worker
    // or AppCache). Hence this code is only reachable when one of the above
    // interceptors isn't used and the URL is either a data URL or has a
    // scheme which is handled by the network service.
    if (proxied_factory_receiver_.is_valid()) {
      DCHECK(proxied_factory_remote_.is_valid());
      // We don't worry about reconnection since it's a single navigation.
      network_loader_factory_->Clone(std::move(proxied_factory_receiver_));
      // Replace the network factory with the proxied version since this may
      // need to be used in redirects, and we've already consumed
      // |proxied_factory_receiver_|.
      network_loader_factory_ =
          base::MakeRefCounted<network::WrapperSharedURLLoaderFactory>(
              std::move(proxied_factory_remote_));
    }
    factory = network_loader_factory_;
  }
  url_chain_.push_back(resource_request_->url);
  *out_options = GetURLLoaderOptions(
      resource_request_->resource_type ==
      static_cast<int>(blink::mojom::ResourceType::kMainFrame));
  return factory;
}

void NavigationURLLoaderImpl::FollowRedirectInternal(
    const std::vector<std::string>& removed_headers,
    const net::HttpRequestHeaders& modified_headers,
    const net::HttpRequestHeaders& modified_cors_exempt_headers,
    PreviewsState new_previews_state,
    base::Time ui_post_time) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  DCHECK(!redirect_info_.new_url.is_empty());

  // Update |resource_request_| and call Restart to give our |interceptors_| a
  // chance at handling the new location. If no interceptor wants to take
  // over, we'll use the existing url_loader to follow the redirect, see
  // MaybeStartLoader.
  // TODO(michaeln): This is still WIP and is based on URLRequest::Redirect,
  // there likely remains more to be done.
  // a. For subframe navigations, the Origin header may need to be modified
  //    differently?

  bool should_clear_upload = false;
  net::RedirectUtil::UpdateHttpRequest(
      resource_request_->url, resource_request_->method, redirect_info_,
      removed_headers, modified_headers, &resource_request_->headers,
      &should_clear_upload);
  if (should_clear_upload) {
    // The request body is no longer applicable.
    resource_request_->request_body.reset();
  }

  resource_request_->url = redirect_info_.new_url;
  resource_request_->method = redirect_info_.new_method;
  resource_request_->site_for_cookies = redirect_info_.new_site_for_cookies;

  // See if navigation network isolation key needs to be updated.
  resource_request_->trusted_params->isolation_info =
      resource_request_->trusted_params->isolation_info.CreateForRedirect(
          url::Origin::Create(resource_request_->url));

  resource_request_->referrer = GURL(redirect_info_.new_referrer);
  resource_request_->referrer_policy = redirect_info_.new_referrer_policy;
  resource_request_->previews_state = new_previews_state;
  url_chain_.push_back(redirect_info_.new_url);

  // Need to cache modified headers for |url_loader_| since it doesn't use
  // |resource_request_| during redirect.
  url_loader_removed_headers_ = removed_headers;
  url_loader_modified_headers_ = modified_headers;
  url_loader_modified_cors_exempt_headers_ = modified_cors_exempt_headers;

  // Don't send Accept: application/signed-exchange for fallback redirects.
  if (redirect_info_.is_signed_exchange_fallback_redirect) {
    url_loader_modified_headers_.SetHeader(net::HttpRequestHeaders::kAccept,
                                           FrameAcceptHeaderValue());
    resource_request_->headers.SetHeader(net::HttpRequestHeaders::kAccept,
                                         FrameAcceptHeaderValue());
  }

  Restart();
}

void NavigationURLLoaderImpl::OnReceiveResponse(
    network::mojom::URLResponseHeadPtr head) {
  head_ = std::move(head);
  on_receive_response_time_ = base::TimeTicks::Now();
}

void NavigationURLLoaderImpl::OnStartLoadingResponseBody(
    mojo::ScopedDataPipeConsumerHandle response_body) {
  if (!on_receive_response_time_.is_null()) {
    UMA_HISTOGRAM_TIMES(
        "Navigation.OnReceiveResponseToOnStartLoadingResponseBody",
        base::TimeTicks::Now() - on_receive_response_time_);
  }

  response_body_ = std::move(response_body);
  received_response_ = true;

  // If the default loader (network) was used to handle the URL load request
  // we need to see if the interceptors want to potentially create a new
  // loader for the response. e.g. AppCache.
  if (MaybeCreateLoaderForResponse(&head_))
    return;

  network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints;

  if (url_loader_) {
    url_loader_client_endpoints = url_loader_->Unbind();
  } else {
    url_loader_client_endpoints = network::mojom::URLLoaderClientEndpoints::New(
        std::move(response_url_loader_), response_loader_receiver_.Unbind());
  }

  // 304 responses should abort the navigation, rather than display the page.
  // This needs to be after the URLLoader has been moved to
  // |url_loader_client_endpoints| in order to abort the request, to avoid
  // receiving unexpected call.
  if (head_->headers &&
      head_->headers->response_code() == net::HTTP_NOT_MODIFIED) {
    // Call CancelWithError instead of OnComplete so that if there is an
    // intercepting URLLoaderFactory it gets notified.
    url_loader_->CancelWithError(
        net::ERR_ABORTED,
        base::StringPiece(base::NumberToString(net::ERR_ABORTED)));
    return;
  }

  bool must_download = download_utils::MustDownload(url_, head_->headers.get(),
                                                    head_->mime_type);
  bool known_mime_type = blink::IsSupportedMimeType(head_->mime_type);

#if BUILDFLAG(ENABLE_PLUGINS)
    if (!head_->intercepted_by_plugin && !must_download && !known_mime_type) {
      // No plugin throttles intercepted the response. Ask if the plugin
      // registered to PluginService wants to handle the request.
      CheckPluginAndContinueOnReceiveResponse(
          std::move(head_), std::move(url_loader_client_endpoints),
          true /* is_download_if_not_handled_by_plugin */,
          std::vector<WebPluginInfo>());
      return;
    }
#endif

    // When a plugin intercepted the response, we don't want to download it.
    bool is_download =
        !head_->intercepted_by_plugin && (must_download || !known_mime_type);

    CallOnReceivedResponse(std::move(head_),
                           std::move(url_loader_client_endpoints), is_download);
}

#if BUILDFLAG(ENABLE_PLUGINS)
void NavigationURLLoaderImpl::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) {
  bool stale;
  WebPluginInfo plugin;
  FrameTreeNode* frame_tree_node =
      FrameTreeNode::GloballyFindByID(frame_tree_node_id_);
  int render_process_id =
      frame_tree_node->current_frame_host()->GetProcess()->GetID();
  int routing_id = frame_tree_node->current_frame_host()->GetRoutingID();
  bool has_plugin = PluginService::GetInstance()->GetPluginInfo(
      render_process_id, routing_id, resource_request_->url, url::Origin(),
      head->mime_type, false /* allow_wildcard */, &stale, &plugin, nullptr);

  if (stale) {
    // Refresh the plugins asynchronously.
    PluginService::GetInstance()->GetPlugins(base::BindOnce(
        &NavigationURLLoaderImpl::CheckPluginAndContinueOnReceiveResponse,
        weak_factory_.GetWeakPtr(), std::move(head),
        std::move(url_loader_client_endpoints),
        is_download_if_not_handled_by_plugin));
    return;
  }

  bool is_download = !has_plugin && is_download_if_not_handled_by_plugin;
  CallOnReceivedResponse(std::move(head),
                         std::move(url_loader_client_endpoints), is_download);
}
#endif

void NavigationURLLoaderImpl::CallOnReceivedResponse(
    network::mojom::URLResponseHeadPtr head,
    network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints,
    bool is_download) {
  network::mojom::URLResponseHead* head_ptr = head.get();
  auto on_receive_response = base::BindOnce(
      &NavigationURLLoaderImpl::NotifyResponseStarted,
      weak_factory_.GetWeakPtr(), std::move(head),
      std::move(url_loader_client_endpoints), std::move(response_body_),
      global_request_id_, is_download);

  ParseHeaders(url_, head_ptr, std::move(on_receive_response));
}

void NavigationURLLoaderImpl::OnReceiveRedirect(
    const net::RedirectInfo& redirect_info,
    network::mojom::URLResponseHeadPtr head) {
  net::Error error = net::OK;
  if (!bypass_redirect_checks_ &&
      !IsSafeRedirectTarget(url_, redirect_info.new_url)) {
    error = net::ERR_UNSAFE_REDIRECT;
  } else if (--redirect_limit_ == 0) {
    error = net::ERR_TOO_MANY_REDIRECTS;
    if (redirect_info.is_signed_exchange_fallback_redirect)
      UMA_HISTOGRAM_BOOLEAN("SignedExchange.FallbackRedirectLoop", true);
  }
  if (error != net::OK) {
    if (url_loader_) {
      // Call CancelWithError instead of OnComplete so that if there is an
      // intercepting URLLoaderFactory (created through the embedder's
      // ContentBrowserClient::WillCreateURLLoaderFactory) it gets notified.
      url_loader_->CancelWithError(
          error, base::StringPiece(base::NumberToString(error)));
    } else {
      // TODO(crbug.com/1052242): Make sure ResetWithReason() is called on the
      // original url_loader_.
      OnComplete(network::URLLoaderCompletionStatus(error));
    }
    return;
  }

  // Store the redirect_info for later use in FollowRedirect where we give
  // our interceptors_ a chance to intercept the request for the new location.
  redirect_info_ = redirect_info;

  url_ = redirect_info.new_url;

  network::mojom::URLResponseHead* head_ptr = head.get();
  auto on_receive_redirect = base::BindOnce(
      &NavigationURLLoaderImpl::NotifyRequestRedirected,
      weak_factory_.GetWeakPtr(), redirect_info, std::move(head));
  ParseHeaders(url_, head_ptr, std::move(on_receive_redirect));
}

void NavigationURLLoaderImpl::OnUploadProgress(
    int64_t current_position,
    int64_t total_size,
    OnUploadProgressCallback callback) {
  NOTREACHED();
}

void NavigationURLLoaderImpl::OnReceiveCachedMetadata(
    mojo_base::BigBuffer data) {
  NOTREACHED();
}

void NavigationURLLoaderImpl::OnComplete(
    const network::URLLoaderCompletionStatus& status) {
  UMA_HISTOGRAM_BOOLEAN(
      "Navigation.URLLoaderNetworkService.OnCompleteHasSSLInfo",
      status.ssl_info.has_value());

  // Successful load must have used OnResponseStarted first. In this case, the
  // URLLoaderClient has already been transferred to the renderer process and
  // OnComplete is not expected to be called here.
  if (status.error_code == net::OK) {
    base::debug::DumpWithoutCrashing();
    return;
  }

  if (status.ssl_info.has_value()) {
    UMA_HISTOGRAM_MEMORY_KB(
        "Navigation.URLLoaderNetworkService.OnCompleteCertificateChainsSize",
        GetCertificateChainsSizeInKB(status.ssl_info.value()));
  }

  // If the default loader (network) was used to handle the URL load request
  // we need to see if the interceptors want to potentially create a new
  // loader for the response. e.g. AppCache.
  //
  // Note: Despite having received a response, the HTTP_NOT_MODIFIED(304) ones
  //       are ignored using OnComplete(net::ERR_ABORTED). No interceptor must
  //       be used in this case.
  if (!received_response_) {
    auto response = network::mojom::URLResponseHead::New();
    if (MaybeCreateLoaderForResponse(&response))
      return;
  }

  status_ = status;
  GetUIThreadTaskRunner({})->PostTask(
      FROM_HERE, base::BindOnce(&NavigationURLLoaderImpl::NotifyRequestFailed,
                                weak_factory_.GetWeakPtr(), status));
}

  // Returns true if an interceptor wants to handle the response, i.e. return a
  // different response. For e.g. AppCache may have fallback content.
bool NavigationURLLoaderImpl::MaybeCreateLoaderForResponse(
    network::mojom::URLResponseHeadPtr* response) {
  if (!default_loader_used_ &&
      !web_bundle_utils::CanLoadAsWebBundle(url_, (*response)->mime_type)) {
    return false;
  }
  for (auto& interceptor : interceptors_) {
    mojo::PendingReceiver<network::mojom::URLLoaderClient>
        response_client_receiver;
    bool skip_other_interceptors = false;
    bool will_return_unsafe_redirect = false;
    if (interceptor->MaybeCreateLoaderForResponse(
            *resource_request_, response, &response_body_,
            &response_url_loader_, &response_client_receiver, url_loader_.get(),
            &skip_other_interceptors, &will_return_unsafe_redirect)) {
      if (will_return_unsafe_redirect)
        bypass_redirect_checks_ = true;
      response_loader_receiver_.reset();
      response_loader_receiver_.Bind(std::move(response_client_receiver));
      default_loader_used_ = false;
      url_loader_.reset();     // Consumed above.
      response_body_.reset();  // Consumed above.
      if (skip_other_interceptors) {
        std::vector<std::unique_ptr<NavigationLoaderInterceptor>>
            new_interceptors;
        new_interceptors.push_back(std::move(interceptor));
        new_interceptors.swap(interceptors_);
        // Reset the state of ServiceWorkerContainerHost.
        // Currently we don't support Service Worker in Signed Exchange
        // pages. The page will not be controlled by service workers. And
        // Service Worker related APIs will fail with NoDocumentURL error.
        // TODO(crbug/898733): Support SignedExchange loading and Service
        // Worker integration.
        if (service_worker_handle_) {
          RunOrPostTaskOnThread(
              FROM_HERE, ServiceWorkerContext::GetCoreThreadId(),
              base::BindOnce(
                  [](ServiceWorkerMainResourceHandleCore* core) {
                    base::WeakPtr<ServiceWorkerContainerHost> container_host =
                        core->container_host();
                    if (container_host) {
                      container_host->SetControllerRegistration(
                          nullptr, false /* notify_controllerchange */);
                      container_host->UpdateUrls(GURL(), net::SiteForCookies(),
                                                 base::nullopt);
                    }
                  },
                  // Unretained() is safe because the handle owns the core,
                  // and core gets deleted on the core thread in a task that
                  // must occur after this task.
                  base::Unretained(service_worker_handle_->core())));
        }
      }
      return true;
    }
  }
  return false;
}

std::vector<std::unique_ptr<blink::URLLoaderThrottle>>
NavigationURLLoaderImpl::CreateURLLoaderThrottles() {
  return CreateContentBrowserURLLoaderThrottles(
      *resource_request_, browser_context_, web_contents_getter_,
      navigation_ui_data_.get(), frame_tree_node_id_);
}

std::unique_ptr<SignedExchangeRequestHandler>
NavigationURLLoaderImpl::CreateSignedExchangeRequestHandler(
    const NavigationRequestInfo& request_info,
    scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
    scoped_refptr<SignedExchangePrefetchMetricRecorder>
        signed_exchange_prefetch_metric_recorder,
    std::string accept_langs) {
  // It is safe to pass the callback of CreateURLLoaderThrottles with the
  // unretained |this|, because the passed callback will be used by a
  // SignedExchangeHandler which is indirectly owned by |this| until its
  // header is verified and parsed, that's where the getter is used.
  return std::make_unique<SignedExchangeRequestHandler>(
      GetURLLoaderOptions(request_info.is_main_frame),
      request_info.frame_tree_node_id, request_info.devtools_navigation_token,
      std::move(url_loader_factory),
      base::BindRepeating(&NavigationURLLoaderImpl::CreateURLLoaderThrottles,
                          base::Unretained(this)),
      std::move(signed_exchange_prefetch_metric_recorder),
      std::move(accept_langs));
}

void NavigationURLLoaderImpl::ParseHeaders(
    const GURL& url,
    network::mojom::URLResponseHead* head,
    base::OnceClosure continuation) {
  // The main path:
  // --------------
  // The ParsedHeaders are already provided. No more work needed.
  //
  // Currently used when the response is coming from:
  // - Network
  // - ServiceWorker
  // - WebUI
  if (head->parsed_headers) {
    std::move(continuation).Run();
    return;
  }

  // As an optimization, when we know the parsed headers will be empty, we can
  // skip the network process roundtrip.
  // TODO(arthursonzogni): If there are any performance issues, consider
  // checking the |head->headers| contains at least one header to be parsed.
  if (!head->headers) {
    head->parsed_headers = network::mojom::ParsedHeaders::New();
    std::move(continuation).Run();
    return;
  }

  auto assign = [](base::OnceClosure continuation,
                   network::mojom::URLResponseHead* head,
                   network::mojom::ParsedHeadersPtr parsed_headers) {
    head->parsed_headers = std::move(parsed_headers);
    std::move(continuation).Run();
  };

  storage_partition_->GetNetworkContext()->ParseHeaders(
      url, head->headers,
      base::BindOnce(assign, std::move(continuation), head));
}

// TODO(https://crbug.com/790734): pass |navigation_ui_data| along with the
// request so that it could be modified.
NavigationURLLoaderImpl::NavigationURLLoaderImpl(
    BrowserContext* browser_context,
    StoragePartition* storage_partition,
    std::unique_ptr<NavigationRequestInfo> request_info,
    std::unique_ptr<NavigationUIData> navigation_ui_data,
    ServiceWorkerMainResourceHandle* service_worker_handle,
    AppCacheNavigationHandle* appcache_handle,
    scoped_refptr<PrefetchedSignedExchangeCache>
        prefetched_signed_exchange_cache,
    NavigationURLLoaderDelegate* delegate,
    mojo::PendingRemote<network::mojom::CookieAccessObserver> cookie_observer,
    std::vector<std::unique_ptr<NavigationLoaderInterceptor>>
        initial_interceptors)
    : delegate_(delegate),
      browser_context_(browser_context),
      storage_partition_(static_cast<StoragePartitionImpl*>(storage_partition)),
      service_worker_handle_(service_worker_handle),
      request_info_(std::move(request_info)),
      url_(request_info_->common_params->url),
      frame_tree_node_id_(request_info_->frame_tree_node_id),
      global_request_id_(GlobalRequestID::MakeBrowserInitiated()),
      web_contents_getter_(
          base::BindRepeating(&WebContents::FromFrameTreeNodeId,
                              frame_tree_node_id_)),
      navigation_ui_data_(std::move(navigation_ui_data)),
      interceptors_(std::move(initial_interceptors)),
      download_policy_(request_info_->common_params->download_policy) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);

  TRACE_EVENT_ASYNC_BEGIN_WITH_TIMESTAMP1(
      "navigation", "Navigation timeToResponseStarted", this,
      request_info_->common_params->navigation_start, "FrameTreeNode id",
      frame_tree_node_id_);

  scoped_refptr<SignedExchangePrefetchMetricRecorder>
      signed_exchange_prefetch_metric_recorder =
          storage_partition_->GetPrefetchURLLoaderService()
              ->signed_exchange_prefetch_metric_recorder();

  resource_request_ = CreateResourceRequest(
      request_info_.get(), frame_tree_node_id_, std::move(cookie_observer));

  std::string accept_langs =
      GetContentClient()->browser()->GetAcceptLangs(browser_context_);

  // Check if a web UI scheme wants to handle this request.
  FrameTreeNode* frame_tree_node =
      FrameTreeNode::GloballyFindByID(frame_tree_node_id_);
  const auto& schemes = URLDataManagerBackend::GetWebUISchemes();
  std::string scheme = resource_request_->url.scheme();
  mojo::PendingRemote<network::mojom::URLLoaderFactory> factory_for_webui;
  if (base::Contains(schemes, scheme)) {
    DCHECK(frame_tree_node);
    DCHECK(frame_tree_node->navigation_request());
    auto factory_receiver = factory_for_webui.InitWithNewPipeAndPassReceiver();
    GetContentClient()->browser()->WillCreateURLLoaderFactory(
        browser_context_, frame_tree_node->current_frame_host(),
        frame_tree_node->current_frame_host()->GetProcess()->GetID(),
        ContentBrowserClient::URLLoaderFactoryType::kNavigation, url::Origin(),
        frame_tree_node->navigation_request()->GetNavigationId(),
        &factory_receiver, nullptr /* header_client */,
        nullptr /* bypass_redirect_checks */, nullptr /* disable_secure_dns */,
        nullptr /* factory_override */);
    CreateWebUIURLLoaderBinding(frame_tree_node->current_frame_host(), scheme,
                                std::move(factory_receiver));
  }

  mojo::PendingRemote<network::mojom::TrustedURLLoaderHeaderClient>
      header_client;
  if (frame_tree_node) {
    // Initialize proxied factory remote/receiver if necessary.
    // This also populates |bypass_redirect_checks_|.
    DCHECK(frame_tree_node->navigation_request());

    // |frame_tree_node| may be null in some unit test environments.
    GetContentClient()
        ->browser()
        ->RegisterNonNetworkNavigationURLLoaderFactories(
            frame_tree_node_id_, &non_network_url_loader_factories_);

    // The embedder may want to proxy all network-bound URLLoaderFactory
    // receivers that it can. If it elects to do so, those proxies will be
    // connected when loader is created if the request type supports proxying.
    mojo::PendingRemote<network::mojom::URLLoaderFactory> pending_factory;
    auto factory_receiver = pending_factory.InitWithNewPipeAndPassReceiver();
    // Here we give nullptr for |factory_override|, because CORS is no-op for
    // navigations.
    bool use_proxy = GetContentClient()->browser()->WillCreateURLLoaderFactory(
        browser_context_, frame_tree_node->current_frame_host(),
        frame_tree_node->current_frame_host()->GetProcess()->GetID(),
        ContentBrowserClient::URLLoaderFactoryType::kNavigation, url::Origin(),
        frame_tree_node->navigation_request()->GetNavigationId(),
        &factory_receiver, &header_client, &bypass_redirect_checks_,
        nullptr /* disable_secure_dns */, nullptr /* factory_override */);
    if (devtools_instrumentation::WillCreateURLLoaderFactory(
            frame_tree_node->current_frame_host(), true /* is_navigation */,
            false /* is_download */, &factory_receiver,
            nullptr /* factory_override */)) {
      use_proxy = true;
    }
    if (use_proxy) {
      proxied_factory_receiver_ = std::move(factory_receiver);
      proxied_factory_remote_ = std::move(pending_factory);
    }

    const std::string storage_domain;
    non_network_url_loader_factories_.emplace(
        url::kFileSystemScheme,
        CreateFileSystemURLLoaderFactory(
            ChildProcessHost::kInvalidUniqueID,
            frame_tree_node->frame_tree_node_id(),
            storage_partition_->GetFileSystemContext(), storage_domain));
  }

  non_network_url_loader_factories_.emplace(
      url::kAboutScheme, std::make_unique<AboutURLLoaderFactory>());

  non_network_url_loader_factories_.emplace(
      url::kDataScheme, std::make_unique<DataURLLoaderFactory>());

  std::unique_ptr<network::mojom::URLLoaderFactory> file_url_loader_factory =
      std::make_unique<FileURLLoaderFactory>(
          browser_context_->GetPath(),
          browser_context_->GetSharedCorsOriginAccessList(),
          // USER_VISIBLE because loaded file resources may affect the UI.
          base::TaskPriority::USER_VISIBLE);

  if (frame_tree_node) {  // May be nullptr in some unit tests.
    devtools_instrumentation::WillCreateURLLoaderFactory(
        frame_tree_node->current_frame_host(), true /* is_navigation */,
        false /* is_download */, &file_url_loader_factory);
  }

  non_network_url_loader_factories_.emplace(url::kFileScheme,
                                            std::move(file_url_loader_factory));

#if defined(OS_ANDROID)
  non_network_url_loader_factories_.emplace(
      url::kContentScheme,
      std::make_unique<ContentURLLoaderFactory>(
          base::ThreadPool::CreateSequencedTaskRunner(
              {base::MayBlock(), base::TaskPriority::BEST_EFFORT,
               base::TaskShutdownBehavior::SKIP_ON_SHUTDOWN})));
#endif

  for (auto& iter : non_network_url_loader_factories_)
    known_schemes_.insert(iter.first);

  bool needs_loader_factory_interceptor = false;
  std::unique_ptr<network::PendingSharedURLLoaderFactory>
      pending_network_factory =
          storage_partition_->GetURLLoaderFactoryForBrowserProcess()->Clone();
  if (header_client) {
    needs_loader_factory_interceptor = true;
    mojo::PendingRemote<network::mojom::URLLoaderFactory> factory_remote;
    CreateURLLoaderFactoryWithHeaderClient(
        std::move(header_client),
        factory_remote.InitWithNewPipeAndPassReceiver(), storage_partition_);
    pending_network_factory =
        std::make_unique<network::WrapperPendingSharedURLLoaderFactory>(
            std::move(factory_remote));
  }

  Start(std::move(pending_network_factory), appcache_handle,
        std::move(prefetched_signed_exchange_cache),
        std::move(signed_exchange_prefetch_metric_recorder),
        std::move(factory_for_webui), std::move(accept_langs),
        needs_loader_factory_interceptor);
}

void NavigationURLLoaderImpl::FollowRedirect(
    const std::vector<std::string>& removed_headers,
    const net::HttpRequestHeaders& modified_headers,
    const net::HttpRequestHeaders& modified_cors_exempt_headers,
    PreviewsState new_previews_state) {
  FollowRedirectInternal(removed_headers, modified_headers,
                         modified_cors_exempt_headers, new_previews_state,
                         base::Time::Now());
}

void NavigationURLLoaderImpl::NotifyRequestStarted(base::TimeTicks timestamp) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  delegate_->OnRequestStarted(timestamp);
}

void NavigationURLLoaderImpl::NotifyResponseStarted(
    network::mojom::URLResponseHeadPtr response_head,
    network::mojom::URLLoaderClientEndpointsPtr url_loader_client_endpoints,
    mojo::ScopedDataPipeConsumerHandle response_body,
    const GlobalRequestID& global_request_id,
    bool is_download) {
  // TODO(https://crbug.com/1068896): Remove
  // "Navigation.NavigationURLLoaderImplIOPostTime" histogram as well.

  TRACE_EVENT_ASYNC_END2("navigation", "Navigation timeToResponseStarted", this,
                         "&NavigationURLLoaderImpl", this, "success", true);

  if (is_download)
    download_policy_.RecordHistogram();

  // TODO(scottmg): This needs to do more of what
  // NavigationResourceHandler::OnResponseStarted() does.
  delegate_->OnResponseStarted(
      std::move(url_loader_client_endpoints), std::move(response_head),
      std::move(response_body),
      GlobalRequestID(global_request_id.child_id, global_request_id.request_id),
      is_download, download_policy_, std::move(subresource_loader_params_));
}

void NavigationURLLoaderImpl::NotifyRequestRedirected(
    net::RedirectInfo redirect_info,
    network::mojom::URLResponseHeadPtr response_head) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  delegate_->OnRequestRedirected(redirect_info, std::move(response_head));
}

void NavigationURLLoaderImpl::NotifyRequestFailed(
    const network::URLLoaderCompletionStatus& status) {
  TRACE_EVENT_ASYNC_END2("navigation", "Navigation timeToResponseStarted", this,
                         "&NavigationURLLoaderImpl", this, "success", false);
  delegate_->OnRequestFailed(status);
}

// static
void NavigationURLLoaderImpl::SetURLLoaderFactoryInterceptorForTesting(
    const URLLoaderFactoryInterceptor& interceptor) {
  DCHECK(!BrowserThread::IsThreadInitialized(BrowserThread::UI) ||
         BrowserThread::CurrentlyOn(BrowserThread::UI));
  g_loader_factory_interceptor.Get() = interceptor;
}

// static
void NavigationURLLoaderImpl::CreateURLLoaderFactoryWithHeaderClient(
    mojo::PendingRemote<network::mojom::TrustedURLLoaderHeaderClient>
        header_client,
    mojo::PendingReceiver<network::mojom::URLLoaderFactory> factory_receiver,
    StoragePartitionImpl* partition) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  network::mojom::URLLoaderFactoryParamsPtr params =
      network::mojom::URLLoaderFactoryParams::New();
  params->header_client = std::move(header_client);
  params->process_id = network::mojom::kBrowserProcessId;
  params->is_trusted = true;
  params->is_corb_enabled = false;
  params->disable_web_security =
      base::CommandLine::ForCurrentProcess()->HasSwitch(
          switches::kDisableWebSecurity);

  partition->GetNetworkContext()->CreateURLLoaderFactory(
      std::move(factory_receiver), std::move(params));
}

void NavigationURLLoaderImpl::BindNonNetworkURLLoaderFactoryReceiver(
    const GURL& url,
    mojo::PendingReceiver<network::mojom::URLLoaderFactory> factory_receiver) {
  auto it = non_network_url_loader_factories_.find(url.scheme());
  if (it == non_network_url_loader_factories_.end()) {
    DVLOG(1) << "Ignoring request with unknown scheme: " << url.spec();
    return;
  }

  FrameTreeNode* frame_tree_node =
      FrameTreeNode::GloballyFindByID(frame_tree_node_id_);
  DCHECK(frame_tree_node);
  DCHECK(frame_tree_node->navigation_request());

  auto* frame = frame_tree_node->current_frame_host();
  GetContentClient()->browser()->WillCreateURLLoaderFactory(
      frame->GetSiteInstance()->GetBrowserContext(), frame,
      frame->GetProcess()->GetID(),
      ContentBrowserClient::URLLoaderFactoryType::kNavigation, url::Origin(),
      frame_tree_node->navigation_request()->GetNavigationId(),
      &factory_receiver, nullptr /* header_client */,
      nullptr /* bypass_redirect_checks */, nullptr /* disable_secure_dns */,
      nullptr /* factory_override */);
  it->second->Clone(std::move(factory_receiver));
}

}  // namespace content
