// Copyright 2021 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_early_hints_manager.h"

#include "base/containers/contains.h"
#include "base/feature_list.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/global_request_id.h"
#include "content/public/browser/url_loader_throttles.h"
#include "content/public/browser/web_contents.h"
#include "content/public/common/content_features.h"
#include "mojo/public/cpp/bindings/message.h"
#include "mojo/public/cpp/system/data_pipe_drainer.h"
#include "net/base/load_flags.h"
#include "net/base/schemeful_site.h"
#include "net/traffic_annotation/network_traffic_annotation.h"
#include "services/network/public/cpp/resource_request.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
#include "services/network/public/mojom/fetch_api.mojom.h"
#include "services/network/public/mojom/url_loader.mojom.h"
#include "third_party/blink/public/common/loader/throttling_url_loader.h"
#include "third_party/blink/public/common/loader/url_loader_throttle.h"
#include "third_party/blink/public/mojom/loader/resource_load_info.mojom-shared.h"
#include "url/origin.h"

namespace content {

namespace {

const net::NetworkTrafficAnnotationTag kEarlyHintsPreloadTrafficAnnotation =
    net::DefineNetworkTrafficAnnotation("early_hints_preload",
                                        R"(
    semantics {
      sender: "Early Hints"
      description:
        "This request is issued during a main frame navigation to "
        "speculatively fetch resources that will likely be used in the frame."
      trigger:
        "A 103 Early Hints HTTP informational response is received during "
        "navigation."
      data:
        "Arbitrary site-controlled data can be included in the URL."
        "Requests may include cookies and site-specific credentials."
      destination: WEBSITE
    }
    policy {
      cookies_allowed: YES
      cookies_store: "user"
      setting:
        "This feature cannot be disabled by Settings. This feature is not "
        "enabled by default yet. TODO(crbug.com/671310): Update this "
        "description once the feature is ready."
      chrome_policy {
        URLBlocklist {
          URLBlocklist: { entries: '*' }
        }
      }
      chrome_policy {
        URLAllowlist {
          URLAllowlist { }
        }
      }
    }
    comments:
      "Chrome uses this type of request during navigation and it cannot be "
      "disabled. Using either URLBlocklist or URLAllowlist (or a combination "
      "of both) limits the scope of these requests."
)");

network::mojom::RequestDestination LinkAsAttributeToRequestDestination(
    network::mojom::LinkAsAttribute attr) {
  switch (attr) {
    case network::mojom::LinkAsAttribute::kUnspecified:
      return network::mojom::RequestDestination::kEmpty;
    case network::mojom::LinkAsAttribute::kImage:
      return network::mojom::RequestDestination::kImage;
    case network::mojom::LinkAsAttribute::kFont:
      return network::mojom::RequestDestination::kFont;
    case network::mojom::LinkAsAttribute::kScript:
      return network::mojom::RequestDestination::kScript;
    case network::mojom::LinkAsAttribute::kStyleSheet:
      return network::mojom::RequestDestination::kStyle;
  }
  NOTREACHED();
  return network::mojom::RequestDestination::kEmpty;
}

// Used to determine a priority for a speculative subresource request.
// TODO(crbug.com/671310): This is almost the same as GetRequestPriority() in
// loading_predictor_tab_helper.cc and the purpose is the same. Consider merging
// them if the logic starts to be more mature.
net::RequestPriority CalculateRequestPriority(
    const network::mojom::LinkHeaderPtr& link) {
  switch (link->as) {
    case network::mojom::LinkAsAttribute::kFont:
    case network::mojom::LinkAsAttribute::kStyleSheet:
      return net::HIGHEST;
    case network::mojom::LinkAsAttribute::kScript:
      return net::MEDIUM;
    case network::mojom::LinkAsAttribute::kImage:
      return net::LOWEST;
    case network::mojom::LinkAsAttribute::kUnspecified:
      return net::IDLE;
  }
  NOTREACHED();
  return net::IDLE;
}

network::mojom::RequestMode CalculateRequestMode(
    network::mojom::CrossOriginAttribute attr) {
  switch (attr) {
    case network::mojom::CrossOriginAttribute::kUnspecified:
      return network::mojom::RequestMode::kNoCors;
    case network::mojom::CrossOriginAttribute::kAnonymous:
    case network::mojom::CrossOriginAttribute::kUseCredentials:
      return network::mojom::RequestMode::kCors;
  }
  NOTREACHED();
  return network::mojom::RequestMode::kSameOrigin;
}

network::mojom::CredentialsMode CalculateCredentialMode(
    network::mojom::CrossOriginAttribute attr) {
  switch (attr) {
    case network::mojom::CrossOriginAttribute::kUnspecified:
    case network::mojom::CrossOriginAttribute::kUseCredentials:
      return network::mojom::CredentialsMode::kInclude;
    case network::mojom::CrossOriginAttribute::kAnonymous:
      return network::mojom::CredentialsMode::kSameOrigin;
  }
  NOTREACHED();
  return network::mojom::CredentialsMode::kOmit;
}

}  // namespace

NavigationEarlyHintsManager::PreloadedResource::PreloadedResource() = default;

NavigationEarlyHintsManager::PreloadedResource::~PreloadedResource() = default;

NavigationEarlyHintsManager::PreloadedResource::PreloadedResource(
    const PreloadedResource&) = default;

NavigationEarlyHintsManager::PreloadedResource&
NavigationEarlyHintsManager::PreloadedResource::operator=(
    const PreloadedResource&) = default;

NavigationEarlyHintsManager::InflightPreload::InflightPreload(
    std::unique_ptr<blink::ThrottlingURLLoader> loader,
    std::unique_ptr<PreloadURLLoaderClient> client)
    : loader(std::move(loader)), client(std::move(client)) {}

NavigationEarlyHintsManager::InflightPreload::~InflightPreload() = default;

// A URLLoaderClient which drains the content of a request to put a
// response into the disk cache. If the response was already in the cache,
// this tries to cancel reading body to avoid further disk access.
class NavigationEarlyHintsManager::PreloadURLLoaderClient
    : public network::mojom::URLLoaderClient,
      public mojo::DataPipeDrainer::Client {
 public:
  PreloadURLLoaderClient(NavigationEarlyHintsManager& owner, const GURL& url)
      : owner_(owner), url_(url) {}

  ~PreloadURLLoaderClient() override = default;

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

 private:
  // mojom::URLLoaderClient overrides:
  void OnReceiveEarlyHints(network::mojom::EarlyHintsPtr early_hints) override {
  }
  void OnReceiveResponse(network::mojom::URLResponseHeadPtr head) override {
    if (head->network_accessed || !head->was_fetched_via_cache)
      return;
    result_.was_canceled = true;
    MaybeCompletePreload();
  }
  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 {
    NOTREACHED();
  }
  void OnReceiveCachedMetadata(mojo_base::BigBuffer data) override {}
  void OnTransferSizeUpdated(int32_t transfer_size_diff) override {}
  void OnStartLoadingResponseBody(
      mojo::ScopedDataPipeConsumerHandle body) override {
    if (response_body_drainer_) {
      mojo::ReportBadMessage("NEHM_BAD_RESPONSE_BODY");
      return;
    }
    response_body_drainer_ =
        std::make_unique<mojo::DataPipeDrainer>(this, std::move(body));
  }
  void OnComplete(const network::URLLoaderCompletionStatus& status) override {
    if (result_.was_canceled || result_.error_code.has_value()) {
      mojo::ReportBadMessage("NEHM_BAD_COMPLETE");
      return;
    }
    result_.error_code = status.error_code;
    MaybeCompletePreload();
  }

  // mojo::DataPipeDrainer::Client overrides:
  void OnDataAvailable(const void* data, size_t num_bytes) override {}
  void OnDataComplete() override {
    DCHECK(response_body_drainer_);
    response_body_drainer_.reset();
    MaybeCompletePreload();
  }

  bool CanCompletePreload() {
    if (result_.was_canceled)
      return true;
    if (result_.error_code.has_value() && !response_body_drainer_)
      return true;
    return false;
  }

  void MaybeCompletePreload() {
    if (CanCompletePreload()) {
      // Delete `this`.
      owner_.OnPreloadComplete(url_, result_);
    }
  }

  NavigationEarlyHintsManager& owner_;
  const GURL url_;

  PreloadedResource result_;
  std::unique_ptr<mojo::DataPipeDrainer> response_body_drainer_;
};

NavigationEarlyHintsManager::NavigationEarlyHintsManager(
    BrowserContext& browser_context,
    scoped_refptr<network::SharedURLLoaderFactory> loader_factory,
    int frame_tree_node_id)
    : browser_context_(browser_context),
      loader_factory_(std::move(loader_factory)),
      frame_tree_node_id_(frame_tree_node_id) {
  DCHECK(loader_factory_);
}

NavigationEarlyHintsManager::~NavigationEarlyHintsManager() = default;

void NavigationEarlyHintsManager::HandleEarlyHints(
    network::mojom::EarlyHintsPtr early_hints,
    const network::ResourceRequest& navigation_request) {
  for (const auto& link : early_hints->headers->link_headers) {
    // TODO(crbug.com/671310): Support other `rel` attributes.
    if (link->rel == network::mojom::LinkRelAttribute::kPreload)
      MaybePreloadHintedResource(link, navigation_request);
  }
}

bool NavigationEarlyHintsManager::WasPreloadLinkHeaderReceived() const {
  return was_preload_link_header_received_;
}

void NavigationEarlyHintsManager::WaitForPreloadsFinishedForTesting(
    base::OnceCallback<void(PreloadedResources)> callback) {
  DCHECK(!preloads_completion_callback_for_testing_);
  if (inflight_preloads_.empty())
    std::move(callback).Run(preloaded_resources_);
  else
    preloads_completion_callback_for_testing_ = std::move(callback);
}

void NavigationEarlyHintsManager::MaybePreloadHintedResource(
    const network::mojom::LinkHeaderPtr& link,
    const network::ResourceRequest& navigation_request) {
  // Subframes aren't supported. To support subframes, this needs to know the
  // origin of the top frame to create an appropriate IsolationInfo.
  if (!navigation_request.is_main_frame)
    return;

  was_preload_link_header_received_ = true;

  if (!base::FeatureList::IsEnabled(features::kEarlyHintsPreloadForNavigation))
    return;

  if (inflight_preloads_.contains(link->href) ||
      preloaded_resources_.contains(link->href)) {
    return;
  }

  DCHECK(navigation_request.url.SchemeIsHTTPOrHTTPS());
  auto top_frame_origin = url::Origin::Create(navigation_request.url);
  auto preload_origin = url::Origin::Create(link->href);

  net::SiteForCookies site_for_cookies =
      net::SiteForCookies(net::SchemefulSite(top_frame_origin));
  network::ResourceRequest request;
  request.method = net::HttpRequestHeaders::kGetMethod;
  request.priority = CalculateRequestPriority(link);
  request.destination = LinkAsAttributeToRequestDestination(link->as);
  request.url = link->href;
  request.site_for_cookies = site_for_cookies;
  request.request_initiator = top_frame_origin;
  request.referrer = navigation_request.url;
  request.referrer_policy = navigation_request.referrer_policy;
  request.load_flags = net::LOAD_NORMAL;
  request.resource_type =
      static_cast<int>(blink::mojom::ResourceType::kSubResource);
  request.mode = CalculateRequestMode(link->cross_origin);
  request.credentials_mode = CalculateCredentialMode(link->cross_origin);

  request.trusted_params = network::ResourceRequest::TrustedParams();
  // Ideally, IsolationInfo for preloading subresources should be created by
  // RenderFrameHostImpl::ComputeIsolationInfoForSubresourcesForPendingCommit()
  // but RenderFrameHostImpl isn't available at this point because the final
  // response is needed to determine the host. Using `top_frame_origin`
  // should create the same IsolationInfo as RenderFrameHostImpl creates for
  // top-level frames with HTTP/HTTPS URLs.
  request.trusted_params->isolation_info = net::IsolationInfo::Create(
      net::IsolationInfo::RequestType::kOther, top_frame_origin,
      /*frame_origin=*/top_frame_origin, site_for_cookies);

  std::vector<std::unique_ptr<blink::URLLoaderThrottle>> throttles =
      CreateContentBrowserURLLoaderThrottles(
          request, &browser_context_,
          base::BindRepeating(&WebContents::FromFrameTreeNodeId,
                              frame_tree_node_id_),
          /*navigation_ui_data=*/nullptr, frame_tree_node_id_);

  auto loader_client =
      std::make_unique<PreloadURLLoaderClient>(*this, request.url);
  auto loader = blink::ThrottlingURLLoader::CreateLoaderAndStart(
      loader_factory_, std::move(throttles),
      content::GlobalRequestID::MakeBrowserInitiated().request_id,
      network::mojom::kURLLoadOptionNone, &request, loader_client.get(),
      kEarlyHintsPreloadTrafficAnnotation, base::ThreadTaskRunnerHandle::Get());

  inflight_preloads_[request.url] = std::make_unique<InflightPreload>(
      std::move(loader), std::move(loader_client));
}

void NavigationEarlyHintsManager::OnPreloadComplete(
    const GURL& url,
    const PreloadedResource& result) {
  DCHECK(inflight_preloads_.contains(url));
  DCHECK(!preloaded_resources_.contains(url));
  preloaded_resources_[url] = result;
  inflight_preloads_.erase(url);

  if (inflight_preloads_.empty() && preloads_completion_callback_for_testing_) {
    std::move(preloads_completion_callback_for_testing_)
        .Run(preloaded_resources_);
  }

  // TODO(crbug.com/671310): Consider to delete `this` when there is no inflight
  // preloads.
}

}  // namespace content
