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

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

#include "base/feature_list.h"
#include "base/functional/bind.h"
#include "base/metrics/histogram_functions.h"
#include "content/browser/web_package/prefetched_signed_exchange_cache.h"
#include "content/browser/web_package/prefetched_signed_exchange_cache_adapter.h"
#include "content/browser/web_package/signed_exchange_prefetch_handler.h"
#include "content/browser/web_package/signed_exchange_utils.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/frame_accept_header.h"
#include "content/public/common/content_features.h"
#include "net/base/load_flags.h"
#include "net/base/network_anonymization_key.h"
#include "net/http/http_request_headers.h"
#include "services/network/public/cpp/features.h"
#include "services/network/public/cpp/record_ontransfersizeupdate_utils.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
#include "services/network/public/mojom/early_hints.mojom.h"
#include "services/network/public/mojom/fetch_api.mojom-shared.h"
#include "third_party/blink/public/common/features.h"

namespace content {

namespace {

constexpr char kSignedExchangeEnabledAcceptHeaderForCrossOriginPrefetch[] =
    "application/signed-exchange;v=b3;q=0.7,*/*;q=0.8";

}  // namespace

PrefetchURLLoader::PrefetchURLLoader(
    int32_t request_id,
    uint32_t options,
    FrameTreeNodeId frame_tree_node_id,
    const network::ResourceRequest& resource_request,
    const net::NetworkAnonymizationKey& network_anonymization_key,
    mojo::PendingRemote<network::mojom::URLLoaderClient> client,
    const net::MutableNetworkTrafficAnnotationTag& traffic_annotation,
    scoped_refptr<network::SharedURLLoaderFactory> network_loader_factory,
    URLLoaderThrottlesGetter url_loader_throttles_getter,
    BrowserContext* browser_context,
    scoped_refptr<PrefetchedSignedExchangeCache>
        prefetched_signed_exchange_cache,
    const std::string& accept_langs,
    RecursivePrefetchTokenGenerator recursive_prefetch_token_generator)
    : frame_tree_node_id_(frame_tree_node_id),
      resource_request_(resource_request),
      network_anonymization_key_(network_anonymization_key),
      network_loader_factory_(std::move(network_loader_factory)),
      forwarding_client_(std::move(client)),
      url_loader_throttles_getter_(url_loader_throttles_getter),
      accept_langs_(accept_langs),
      recursive_prefetch_token_generator_(
          std::move(recursive_prefetch_token_generator)),
      is_signed_exchange_handling_enabled_(
          signed_exchange_utils::IsSignedExchangeHandlingEnabled(
              browser_context)) {
  DCHECK(network_loader_factory_);
  CHECK(!resource_request.trusted_params ||
        resource_request.trusted_params->isolation_info.request_type() ==
            net::IsolationInfo::RequestType::kOther ||
        resource_request.trusted_params->isolation_info.request_type() ==
            net::IsolationInfo::RequestType::kMainFrame);

  if (is_signed_exchange_handling_enabled_) {
    // Set the SignedExchange accept header.
    // (https://wicg.github.io/webpackage/draft-yasskin-http-origin-signed-responses.html#internet-media-type-applicationsigned-exchange).

    // TODO(crbug.com/40250488): find a solution for CORS requests,
    // perhaps exempt the Accept header from the 128-byte rule
    // (https://fetch.spec.whatwg.org/#cors-safelisted-request-header). For now,
    // we use the frame Accept header for prefetches only in requests with a
    // no-cors/same-origin mode to avoid an unintended preflight.
    std::string accept_header =
        resource_request_.mode == network::mojom::RequestMode::kCors
            ? kSignedExchangeEnabledAcceptHeaderForCrossOriginPrefetch
            : FrameAcceptHeaderValue(/*allow_sxg_responses=*/true,
                                     browser_context);
    resource_request_.headers.SetHeader(net::HttpRequestHeaders::kAccept,
                                        std::move(accept_header));
    if (prefetched_signed_exchange_cache) {
      prefetched_signed_exchange_cache_adapter_ =
          std::make_unique<PrefetchedSignedExchangeCacheAdapter>(
              std::move(prefetched_signed_exchange_cache),
              browser_context->GetBlobStorageContext(), resource_request.url,
              this);
    }
  }

  network_loader_factory_->CreateLoaderAndStart(
      loader_.BindNewPipeAndPassReceiver(), request_id, options,
      resource_request_, client_receiver_.BindNewPipeAndPassRemote(),
      traffic_annotation);
  client_receiver_.set_disconnect_handler(base::BindOnce(
      &PrefetchURLLoader::OnNetworkConnectionError, base::Unretained(this)));
}

PrefetchURLLoader::~PrefetchURLLoader() = default;

void PrefetchURLLoader::FollowRedirect(
    const std::vector<std::string>& removed_headers,
    const net::HttpRequestHeaders& modified_headers,
    const net::HttpRequestHeaders& modified_cors_exempt_headers,
    const std::optional<GURL>& new_url) {
  DCHECK(modified_headers.IsEmpty())
      << "Redirect with modified headers was not supported yet. "
         "crbug.com/845683";
  DCHECK(!new_url) << "Redirect with modified URL was not "
                      "supported yet. crbug.com/845683";
  if (signed_exchange_prefetch_handler_) {
    // Rebind |client_receiver_| and |loader_|.
    client_receiver_.Bind(signed_exchange_prefetch_handler_->FollowRedirect(
        loader_.BindNewPipeAndPassReceiver()));
    return;
  }

  DCHECK(loader_);
  loader_->FollowRedirect(
      removed_headers, net::HttpRequestHeaders() /* modified_headers */,
      net::HttpRequestHeaders() /* modified_cors_exempt_headers */,
      std::nullopt);
}

void PrefetchURLLoader::SetPriority(net::RequestPriority priority,
                                    int intra_priority_value) {
  if (loader_) {
    loader_->SetPriority(priority, intra_priority_value);
  }
}

void PrefetchURLLoader::OnReceiveEarlyHints(
    network::mojom::EarlyHintsPtr early_hints) {
  forwarding_client_->OnReceiveEarlyHints(std::move(early_hints));
}

void PrefetchURLLoader::OnReceiveResponse(
    network::mojom::URLResponseHeadPtr response,
    mojo::ScopedDataPipeConsumerHandle body,
    std::optional<mojo_base::BigBuffer> cached_metadata) {
  if (is_signed_exchange_handling_enabled_ &&
      signed_exchange_utils::ShouldHandleAsSignedHTTPExchange(
          resource_request_.url, *response)) {
    DCHECK(!signed_exchange_prefetch_handler_);
    const bool keep_entry_for_prefetch_cache =
        !!prefetched_signed_exchange_cache_adapter_;

    // Note that after this point this doesn't directly get upcalls from the
    // network. (Until |this| calls the handler's FollowRedirect.)
    signed_exchange_prefetch_handler_ =
        std::make_unique<SignedExchangePrefetchHandler>(
            frame_tree_node_id_, resource_request_, std::move(response),
            std::move(body), loader_.Unbind(), client_receiver_.Unbind(),
            network_loader_factory_, url_loader_throttles_getter_, this,
            network_anonymization_key_, accept_langs_,
            keep_entry_for_prefetch_cache);
    return;
  }

  // If the response is marked as a restricted cross-origin prefetch, we
  // populate the response's |recursive_prefetch_token| member with a unique
  // token. The renderer will propagate this token to recursive prefetches
  // coming from this response, in the form of preload headers. This token is
  // later used by the PrefetchURLLoaderService to recover the correct
  // NetworkAnonymizationKey to use when fetching the request. In the Signed
  // Exchange case, we do this after redirects from the outer response, because
  // we redirect back here for the inner response.
  if (resource_request_.load_flags &
      net::LOAD_RESTRICTED_PREFETCH_FOR_MAIN_FRAME) {
    DCHECK(!recursive_prefetch_token_generator_.is_null());
    base::UnguessableToken recursive_prefetch_token =
        std::move(recursive_prefetch_token_generator_).Run(resource_request_);
    response->recursive_prefetch_token = recursive_prefetch_token;
  }

  // Just drop any cached metadata; we don't need to forward it to the renderer
  // for prefetch.
  cached_metadata.reset();

  if (!body) {
    forwarding_client_->OnReceiveResponse(std::move(response),
                                          mojo::ScopedDataPipeConsumerHandle(),
                                          std::nullopt);
    return;
  }

  response_ = std::move(response);
  if (prefetched_signed_exchange_cache_adapter_ &&
      signed_exchange_prefetch_handler_) {
    prefetched_signed_exchange_cache_adapter_->OnStartLoadingResponseBody(
        std::move(body));
    return;
  }

  // Just drain the original response's body here.
  DCHECK(!pipe_drainer_);
  pipe_drainer_ =
      std::make_unique<mojo::DataPipeDrainer>(this, std::move(body));

  SendEmptyBody();
}

void PrefetchURLLoader::OnReceiveRedirect(
    const net::RedirectInfo& redirect_info,
    network::mojom::URLResponseHeadPtr head) {
  if (prefetched_signed_exchange_cache_adapter_ &&
      signed_exchange_prefetch_handler_) {
    prefetched_signed_exchange_cache_adapter_->OnReceiveSignedExchange(
        signed_exchange_prefetch_handler_
            ->TakePrefetchedSignedExchangeCacheEntry());
  }

  resource_request_.url = redirect_info.new_url;
  resource_request_.site_for_cookies = redirect_info.new_site_for_cookies;
  resource_request_.referrer = GURL(redirect_info.new_referrer);
  resource_request_.referrer_policy = redirect_info.new_referrer_policy;
  forwarding_client_->OnReceiveRedirect(redirect_info, std::move(head));
}

void PrefetchURLLoader::OnUploadProgress(int64_t current_position,
                                         int64_t total_size,
                                         base::OnceCallback<void()> callback) {
  forwarding_client_->OnUploadProgress(current_position, total_size,
                                       std::move(callback));
}

void PrefetchURLLoader::OnTransferSizeUpdated(int32_t transfer_size_diff) {
  network::RecordOnTransferSizeUpdatedUMA(
      network::OnTransferSizeUpdatedFrom::kPrefetchURLLoader);
  forwarding_client_->OnTransferSizeUpdated(transfer_size_diff);
}

void PrefetchURLLoader::OnComplete(
    const network::URLLoaderCompletionStatus& status) {
  if (prefetched_signed_exchange_cache_adapter_ &&
      signed_exchange_prefetch_handler_) {
    prefetched_signed_exchange_cache_adapter_->OnComplete(status);
    return;
  }

  SendOnComplete(status);
}

bool PrefetchURLLoader::SendEmptyBody() {
  // Send an empty response's body.
  mojo::ScopedDataPipeProducerHandle producer;
  mojo::ScopedDataPipeConsumerHandle consumer;
  if (CreateDataPipe(nullptr, producer, consumer) != MOJO_RESULT_OK) {
    // No more resources available for creating a data pipe. Close the
    // connection, which will in turn make this loader destroyed.
    forwarding_client_->OnComplete(
        network::URLLoaderCompletionStatus(net::ERR_INSUFFICIENT_RESOURCES));
    forwarding_client_.reset();
    client_receiver_.reset();
    return false;
  }
  DCHECK(response_);
  forwarding_client_->OnReceiveResponse(std::move(response_),
                                        std::move(consumer), std::nullopt);
  return true;
}

void PrefetchURLLoader::SendOnComplete(
    const network::URLLoaderCompletionStatus& completion_status) {
  forwarding_client_->OnComplete(completion_status);
}

void PrefetchURLLoader::OnNetworkConnectionError() {
  // The network loader has an error; we should let the client know it's closed
  // by dropping this, which will in turn make this loader destroyed.
  forwarding_client_.reset();
}

}  // namespace content
