// Copyright 2018 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/worker_host/worker_script_fetch_initiator.h"

#include <string>
#include <vector>

#include "base/bind.h"
#include "base/callback.h"
#include "base/feature_list.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/metrics/field_trial_params.h"
#include "base/task/post_task.h"
#include "content/browser/appcache/appcache_navigation_handle.h"
#include "content/browser/data_url_loader_factory.h"
#include "content/browser/file_url_loader_factory.h"
#include "content/browser/fileapi/file_system_url_loader_factory.h"
#include "content/browser/loader/browser_initiated_resource_request.h"
#include "content/browser/navigation_subresource_loader_params.h"
#include "content/browser/service_worker/service_worker_context_wrapper.h"
#include "content/browser/service_worker/service_worker_navigation_handle.h"
#include "content/browser/service_worker/service_worker_navigation_handle_core.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/worker_host/worker_script_fetcher.h"
#include "content/browser/worker_host/worker_script_loader.h"
#include "content/browser/worker_host/worker_script_loader_factory.h"
#include "content/common/content_constants_internal.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/render_frame_host.h"
#include "content/public/browser/resource_context.h"
#include "content/public/browser/shared_cors_origin_access_list.h"
#include "content/public/common/content_features.h"
#include "content/public/common/referrer.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
#include "net/base/load_flags.h"
#include "net/base/network_isolation_key.h"
#include "services/network/loader_util.h"
#include "services/network/public/cpp/shared_url_loader_factory.h"
#include "services/network/public/mojom/fetch_api.mojom.h"
#include "third_party/blink/public/common/loader/url_loader_factory_bundle.h"
#include "third_party/blink/public/mojom/renderer_preferences.mojom.h"
#include "third_party/blink/public/mojom/service_worker/service_worker_provider.mojom.h"
#include "url/origin.h"

namespace content {

// static
void WorkerScriptFetchInitiator::Start(
    int worker_process_id,
    const GURL& script_url,
    RenderFrameHost* creator_render_frame_host,
    const url::Origin& request_initiator,
    const net::NetworkIsolationKey& trusted_network_isolation_key,
    network::mojom::CredentialsMode credentials_mode,
    blink::mojom::FetchClientSettingsObjectPtr
        outside_fetch_client_settings_object,
    ResourceType resource_type,
    scoped_refptr<ServiceWorkerContextWrapper> service_worker_context,
    ServiceWorkerNavigationHandle* service_worker_handle,
    base::WeakPtr<AppCacheHost> appcache_host,
    scoped_refptr<network::SharedURLLoaderFactory> blob_url_loader_factory,
    scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_override,
    StoragePartitionImpl* storage_partition,
    const std::string& storage_domain,
    CompletionCallback callback) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  DCHECK(storage_partition);
  DCHECK(resource_type == ResourceType::kWorker ||
         resource_type == ResourceType::kSharedWorker)
      << static_cast<int>(resource_type);

  BrowserContext* browser_context = storage_partition->browser_context();
  ResourceContext* resource_context =
      browser_context ? browser_context->GetResourceContext() : nullptr;
  if (!browser_context || !resource_context) {
    // The browser is shutting down. Just drop this request.
    return;
  }

  bool constructor_uses_file_url =
      request_initiator.scheme() == url::kFileScheme;

  // TODO(https://crbug.com/987517): Filesystem URL support on shared workers
  // are now broken.
  bool filesystem_url_support = resource_type == ResourceType::kWorker;

  // Set up the factory bundle for non-NetworkService URLs, e.g.,
  // chrome-extension:// URLs. One factory bundle is consumed by the browser
  // for WorkerScriptLoaderFactory, and one is sent to the renderer for
  // subresource loading.
  std::unique_ptr<blink::URLLoaderFactoryBundleInfo>
      factory_bundle_for_browser = CreateFactoryBundle(
          worker_process_id, storage_partition, storage_domain,
          constructor_uses_file_url, filesystem_url_support);
  std::unique_ptr<blink::URLLoaderFactoryBundleInfo>
      subresource_loader_factories = CreateFactoryBundle(
          worker_process_id, storage_partition, storage_domain,
          constructor_uses_file_url, filesystem_url_support);

  // Create a resource request for initiating worker script fetch from the
  // browser process.
  std::unique_ptr<network::ResourceRequest> resource_request;

  // Determine the referrer for the worker script request based on the spec.
  // https://w3c.github.io/webappsec-referrer-policy/#determine-requests-referrer
  Referrer sanitized_referrer = Referrer::SanitizeForRequest(
      script_url,
      Referrer(outside_fetch_client_settings_object->outgoing_referrer,
               outside_fetch_client_settings_object->referrer_policy));

  resource_request = std::make_unique<network::ResourceRequest>();
  resource_request->url = script_url;
  resource_request->site_for_cookies = script_url;
  resource_request->trusted_params = network::ResourceRequest::TrustedParams();
  resource_request->trusted_params->network_isolation_key =
      trusted_network_isolation_key;
  resource_request->request_initiator = request_initiator;
  resource_request->referrer = sanitized_referrer.url,
  resource_request->referrer_policy = Referrer::ReferrerPolicyForUrlRequest(
      outside_fetch_client_settings_object->referrer_policy);
  resource_request->resource_type = static_cast<int>(resource_type);
  resource_request->credentials_mode = credentials_mode;
  if (creator_render_frame_host) {
    resource_request->render_frame_id =
        creator_render_frame_host->GetRoutingID();
  }

  // For a classic worker script request:
  // https://html.spec.whatwg.org/C/#fetch-a-classic-worker-script
  // Step 1: "Let request be a new request whose ..., mode is "same-origin",
  // ..."
  //
  // For a module worker script request:
  // https://html.spec.whatwg.org/C/#fetch-a-single-module-script
  // Step 6: "If destination is "worker" or "sharedworker" and the top-level
  // module fetch flag is set, then set request's mode to "same-origin"."
  resource_request->mode = network::mojom::RequestMode::kSameOrigin;

  switch (resource_type) {
    case ResourceType::kWorker:
      resource_request->fetch_request_context_type =
          static_cast<int>(blink::mojom::RequestContextType::WORKER);
      break;
    case ResourceType::kSharedWorker:
      resource_request->fetch_request_context_type =
          static_cast<int>(blink::mojom::RequestContextType::SHARED_WORKER);
      break;
    default:
      NOTREACHED() << static_cast<int>(resource_type);
      break;
  }

  // Upgrade the request to an a priori authenticated URL, if appropriate.
  // https://w3c.github.io/webappsec-upgrade-insecure-requests/#upgrade-request
  resource_request->upgrade_if_insecure =
      outside_fetch_client_settings_object->insecure_requests_policy ==
      blink::mojom::InsecureRequestsPolicy::kUpgrade;

  AddAdditionalRequestHeaders(resource_request.get(), browser_context);

  CreateScriptLoader(
      worker_process_id, creator_render_frame_host, std::move(resource_request),
      storage_partition, std::move(factory_bundle_for_browser),
      std::move(subresource_loader_factories),
      std::move(service_worker_context), service_worker_handle,
      std::move(appcache_host), std::move(blob_url_loader_factory),
      std::move(url_loader_factory_override), std::move(callback));
}

std::unique_ptr<blink::URLLoaderFactoryBundleInfo>
WorkerScriptFetchInitiator::CreateFactoryBundle(
    int worker_process_id,
    StoragePartitionImpl* storage_partition,
    const std::string& storage_domain,
    bool file_support,
    bool filesystem_url_support) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);

  ContentBrowserClient::NonNetworkURLLoaderFactoryMap non_network_factories;
  non_network_factories[url::kDataScheme] =
      std::make_unique<DataURLLoaderFactory>();
  if (filesystem_url_support) {
    // TODO(https://crbug.com/986188): Pass ChildProcessHost::kInvalidUniqueID
    // instead of valid |worker_process_id| for |factory_bundle_for_browser|
    // once CanCommitURL-like check is implemented in PlzWorker.
    non_network_factories[url::kFileSystemScheme] =
        CreateFileSystemURLLoaderFactory(
            worker_process_id, RenderFrameHost::kNoFrameTreeNodeId,
            storage_partition->GetFileSystemContext(), storage_domain);
  }
  GetContentClient()
      ->browser()
      ->RegisterNonNetworkSubresourceURLLoaderFactories(
          worker_process_id, MSG_ROUTING_NONE, &non_network_factories);

  auto factory_bundle = std::make_unique<blink::URLLoaderFactoryBundleInfo>();
  for (auto& pair : non_network_factories) {
    const std::string& scheme = pair.first;
    std::unique_ptr<network::mojom::URLLoaderFactory> factory =
        std::move(pair.second);

    network::mojom::URLLoaderFactoryPtr factory_ptr;
    mojo::MakeStrongBinding(std::move(factory),
                            mojo::MakeRequest(&factory_ptr));
    factory_bundle->pending_scheme_specific_factories().emplace(
        scheme, factory_ptr.PassInterface());
  }

  if (file_support) {
    auto file_factory = std::make_unique<FileURLLoaderFactory>(
        storage_partition->browser_context()->GetPath(),
        storage_partition->browser_context()->GetSharedCorsOriginAccessList(),
        // USER_VISIBLE because worker script fetch may affect the UI.
        base::TaskPriority::USER_VISIBLE);
    network::mojom::URLLoaderFactoryPtr file_factory_ptr;
    mojo::MakeStrongBinding(std::move(file_factory),
                            mojo::MakeRequest(&file_factory_ptr));
    factory_bundle->pending_scheme_specific_factories().emplace(
        url::kFileScheme, file_factory_ptr.PassInterface());
  }

  return factory_bundle;
}

// TODO(nhiroki): Align this function with AddAdditionalRequestHeaders() in
// navigation_request.cc, FrameFetchContext, and WorkerFetchContext.
void WorkerScriptFetchInitiator::AddAdditionalRequestHeaders(
    network::ResourceRequest* resource_request,
    BrowserContext* browser_context) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);

  // TODO(nhiroki): Return early when the request is neither HTTP nor HTTPS
  // (i.e., Blob URL or Data URL). This should be checked by
  // SchemeIsHTTPOrHTTPS(), but currently cross-origin workers on extensions
  // are allowed and the check doesn't work well. See https://crbug.com/867302.

  // Set the "Accept" header.
  resource_request->headers.SetHeaderIfMissing(network::kAcceptHeader,
                                               network::kDefaultAcceptHeader);

  blink::mojom::RendererPreferences renderer_preferences;
  GetContentClient()->browser()->UpdateRendererPreferencesForWorker(
      browser_context, &renderer_preferences);
  UpdateAdditionalHeadersForBrowserInitiatedRequest(
      &resource_request->headers, browser_context,
      /*should_update_existing_headers=*/false, renderer_preferences);

  SetFetchMetadataHeadersForBrowserInitiatedRequest(resource_request);
}

void WorkerScriptFetchInitiator::CreateScriptLoader(
    int worker_process_id,
    RenderFrameHost* creator_render_frame_host,
    std::unique_ptr<network::ResourceRequest> resource_request,
    StoragePartitionImpl* storage_partition,
    std::unique_ptr<blink::URLLoaderFactoryBundleInfo>
        factory_bundle_for_browser_info,
    std::unique_ptr<blink::URLLoaderFactoryBundleInfo>
        subresource_loader_factories,
    scoped_refptr<ServiceWorkerContextWrapper> service_worker_context,
    ServiceWorkerNavigationHandle* service_worker_handle,
    base::WeakPtr<AppCacheHost> appcache_host,
    scoped_refptr<network::SharedURLLoaderFactory> blob_url_loader_factory,
    scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_override,
    CompletionCallback callback) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);

  // Create the URL loader factory for WorkerScriptLoaderFactory to use to load
  // the main script.
  scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory;
  if (blob_url_loader_factory) {
    // If we have a blob_url_loader_factory just use that directly rather than
    // creating a new URLLoaderFactoryBundle.
    url_loader_factory = std::move(blob_url_loader_factory);
  } else if (url_loader_factory_override) {
    // For unit tests.
    url_loader_factory = std::move(url_loader_factory_override);
  } else {
    // Add the default factory to the bundle for browser.
    DCHECK(factory_bundle_for_browser_info);

    mojo::PendingReceiver<network::mojom::URLLoaderFactory>
        default_factory_receiver =
            factory_bundle_for_browser_info->pending_default_factory()
                .InitWithNewPipeAndPassReceiver();
    mojo::PendingRemote<network::mojom::TrustedURLLoaderHeaderClient>
        default_header_client;
    bool bypass_redirect_checks = false;
    GetContentClient()->browser()->WillCreateURLLoaderFactory(
        storage_partition->browser_context(), creator_render_frame_host,
        worker_process_id,
        ContentBrowserClient::URLLoaderFactoryType::kWorkerMainResource,
        *resource_request->request_initiator, &default_factory_receiver,
        &default_header_client, &bypass_redirect_checks);
    factory_bundle_for_browser_info->set_bypass_redirect_checks(
        bypass_redirect_checks);

    // TODO(nhiroki): Call
    // devtools_instrumentation::WillCreateURLLoaderFactory() here.

    // Get the direct network factory. This doesn't support reconnection to the
    // network service after a crash, but it's OK since it's used only for a
    // single request to fetch the worker's main script during startup. If the
    // network service crashes, worker startup should simply fail.
    network::mojom::URLLoaderFactoryPtr network_factory_ptr;
    auto network_factory =
        storage_partition->GetURLLoaderFactoryForBrowserProcess();
    network_factory->Clone(std::move(default_factory_receiver));

    url_loader_factory = base::MakeRefCounted<blink::URLLoaderFactoryBundle>(
        std::move(factory_bundle_for_browser_info));
  }

  // Start loading a web worker main script.
  // TODO(nhiroki): Figure out what we should do in |wc_getter| for loading web
  // worker's main script. Returning the WebContents of the closest ancestor's
  // frame is a possible option, but it doesn't work when a shared worker
  // creates a dedicated worker after the closest ancestor's frame is gone. The
  // frame tree node ID has the same issue.
  base::RepeatingCallback<WebContents*()> wc_getter =
      base::BindRepeating([]() -> WebContents* { return nullptr; });
  std::vector<std::unique_ptr<blink::URLLoaderThrottle>> throttles =
      GetContentClient()->browser()->CreateURLLoaderThrottles(
          *resource_request, storage_partition->browser_context(), wc_getter,
          nullptr /* navigation_ui_data */,
          RenderFrameHost::kNoFrameTreeNodeId);

  // Create a BrowserContext getter using |service_worker_context|.
  // This context is aware of shutdown and safely returns a nullptr
  // instead of a destroyed BrowserContext in that case.
  auto browser_context_getter =
      base::BindRepeating(&ServiceWorkerContextWrapper::browser_context,
                          std::move(service_worker_context));

  WorkerScriptFetcher::CreateAndStart(
      std::make_unique<WorkerScriptLoaderFactory>(
          worker_process_id, service_worker_handle, std::move(appcache_host),
          browser_context_getter, std::move(url_loader_factory)),
      std::move(throttles), std::move(resource_request),
      base::BindOnce(WorkerScriptFetchInitiator::DidCreateScriptLoader,
                     std::move(callback),
                     std::move(subresource_loader_factories)));
}

void WorkerScriptFetchInitiator::DidCreateScriptLoader(
    CompletionCallback callback,
    std::unique_ptr<blink::URLLoaderFactoryBundleInfo>
        subresource_loader_factories,
    blink::mojom::WorkerMainScriptLoadParamsPtr main_script_load_params,
    base::Optional<SubresourceLoaderParams> subresource_loader_params,
    bool success) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);

  // If a URLLoaderFactory for AppCache is supplied, use that.
  if (subresource_loader_params &&
      subresource_loader_params->pending_appcache_loader_factory) {
    subresource_loader_factories->pending_appcache_factory() =
        std::move(subresource_loader_params->pending_appcache_loader_factory);
  }

  // Prepare the controller service worker info to pass to the renderer.
  blink::mojom::ControllerServiceWorkerInfoPtr controller;
  base::WeakPtr<ServiceWorkerObjectHost> controller_service_worker_object_host;
  if (subresource_loader_params &&
      subresource_loader_params->controller_service_worker_info) {
    controller =
        std::move(subresource_loader_params->controller_service_worker_info);
    controller_service_worker_object_host =
        subresource_loader_params->controller_service_worker_object_host;
  }

  std::move(callback).Run(
      std::move(subresource_loader_factories),
      std::move(main_script_load_params), std::move(controller),
      std::move(controller_service_worker_object_host), success);
}

}  // namespace content
