// Copyright 2012 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/webui/url_data_manager_backend.h"

#include <set>
#include <utility>

#include "base/containers/contains.h"
#include "base/functional/bind.h"
#include "base/location.h"
#include "base/memory/ptr_util.h"
#include "base/memory/ref_counted.h"
#include "base/memory/ref_counted_memory.h"
#include "base/no_destructor.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_util.h"
#include "base/task/single_thread_task_runner.h"
#include "base/trace_event/trace_event.h"
#include "base/values.h"
#include "content/browser/blob_storage/chrome_blob_storage_context.h"
#include "content/browser/webui/shared_resources_data_source.h"
#include "content/browser/webui/url_data_source_impl.h"
#include "content/browser/webui/web_ui_data_source_impl.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_process_host.h"
#include "content/public/common/content_client.h"
#include "content/public/common/url_constants.h"
#include "net/base/io_buffer.h"
#include "net/base/net_errors.h"
#include "net/filter/source_stream.h"
#include "net/http/http_request_headers.h"
#include "net/http/http_status_code.h"
#include "net/log/net_log_util.h"
#include "services/network/public/mojom/content_security_policy.mojom.h"
#include "ui/base/template_expressions.h"
#include "ui/base/webui/i18n_source_stream.h"
#include "url/url_util.h"

namespace content {

namespace {

const char kChromeURLContentSecurityPolicyHeaderName[] =
    "Content-Security-Policy";

const char kChromeURLCrossOriginOpenerPolicyName[] =
    "Cross-Origin-Opener-Policy";
const char kChromeURLCrossOriginEmbedderPolicyName[] =
    "Cross-Origin-Embedder-Policy";
const char kChromeURLCrossOriginResourcePolicyName[] =
    "Cross-Origin-Resource-Policy";

const char kChromeURLXFrameOptionsHeaderName[] = "X-Frame-Options";
const char kChromeURLXFrameOptionsHeaderValue[] = "DENY";
const char kNetworkErrorKey[] = "netError";
const char kURLDataManagerBackendKeyName[] = "url_data_manager_backend";

bool SchemeIsInSchemes(const std::string& scheme,
                       const std::vector<std::string>& schemes) {
  return base::Contains(schemes, scheme);
}

}  // namespace

URLDataManagerBackend::URLDataManagerBackend() : next_request_id_(0) {
  {
    // Add a shared data source for chrome://resources.
    auto* source = new WebUIDataSourceImpl(kChromeUIResourcesHost);
    PopulateSharedResourcesDataSource(source);
    AddDataSource(source);  // Takes ownership.
  }

  {
    // Add a shared data source for chrome-untrusted://resources.
    auto* source = new WebUIDataSourceImpl(kChromeUIUntrustedResourcesURL);
    PopulateSharedResourcesDataSource(source);
    AddDataSource(source);  // Takes ownership.
  }
}

URLDataManagerBackend::~URLDataManagerBackend() = default;

URLDataManagerBackend* URLDataManagerBackend::GetForBrowserContext(
    BrowserContext* context) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  if (!context->GetUserData(kURLDataManagerBackendKeyName)) {
    context->SetUserData(kURLDataManagerBackendKeyName,
                         std::make_unique<URLDataManagerBackend>());
  }
  return static_cast<URLDataManagerBackend*>(
      context->GetUserData(kURLDataManagerBackendKeyName));
}

void URLDataManagerBackend::AddDataSource(URLDataSourceImpl* source) {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  if (!source->source()->ShouldReplaceExistingSource()) {
    auto i = data_sources_.find(source->source_name());
    if (i != data_sources_.end())
      return;
  }
  data_sources_[source->source_name()] = source;
  source->backend_ = weak_factory_.GetWeakPtr();
}

void URLDataManagerBackend::UpdateWebUIDataSource(
    const std::string& source_name,
    const base::Value::Dict& update) {
  auto it = data_sources_.find(source_name);
  if (it == data_sources_.end() || !it->second->IsWebUIDataSourceImpl()) {
    NOTREACHED();
    return;
  }
  static_cast<WebUIDataSourceImpl*>(it->second.get())
      ->AddLocalizedStrings(update);
}

URLDataSourceImpl* URLDataManagerBackend::GetDataSourceFromURL(
    const GURL& url) {
  // chrome-untrusted:// sources keys are of the form "chrome-untrusted://host".
  if (url.scheme() == kChromeUIUntrustedScheme) {
    auto i = data_sources_.find(url.DeprecatedGetOriginAsURL().spec());
    if (i == data_sources_.end())
      return nullptr;
    return i->second.get();
  }

  // The input usually looks like: chrome://source_name/extra_bits?foo
  // so do a lookup using the host of the URL.
  auto i = data_sources_.find(url.host());
  if (i != data_sources_.end())
    return i->second.get();

  // No match using the host of the URL, so do a lookup using the scheme for
  // URLs on the form source_name://extra_bits/foo .
  i = data_sources_.find(url.scheme() + "://");
  if (i != data_sources_.end())
    return i->second.get();

  // No matches found, so give up.
  return nullptr;
}

scoped_refptr<net::HttpResponseHeaders> URLDataManagerBackend::GetHeaders(
    URLDataSourceImpl* source_impl,
    const GURL& url,
    const std::string& origin) {
  // Set the headers so that requests serviced by ChromeURLDataManager return a
  // status code of 200. Without this they return a 0, which makes the status
  // indistiguishable from other error types. Instant relies on getting a 200.
  auto headers =
      base::MakeRefCounted<net::HttpResponseHeaders>("HTTP/1.1 200 OK");
  if (!source_impl)
    return headers;

  URLDataSource* source = source_impl->source();
  // Determine the least-privileged content security policy header, if any,
  // that is compatible with a given WebUI URL, and append it to the existing
  // response headers.
  if (source->ShouldAddContentSecurityPolicy()) {
    std::string csp_header;

    const network::mojom::CSPDirectiveName kAllDirectives[] = {
        network::mojom::CSPDirectiveName::BaseURI,
        network::mojom::CSPDirectiveName::ChildSrc,
        network::mojom::CSPDirectiveName::ConnectSrc,
        network::mojom::CSPDirectiveName::DefaultSrc,
        network::mojom::CSPDirectiveName::FencedFrameSrc,
        network::mojom::CSPDirectiveName::FormAction,
        network::mojom::CSPDirectiveName::FontSrc,
        network::mojom::CSPDirectiveName::FrameSrc,
        network::mojom::CSPDirectiveName::ImgSrc,
        network::mojom::CSPDirectiveName::MediaSrc,
        network::mojom::CSPDirectiveName::ObjectSrc,
        network::mojom::CSPDirectiveName::RequireTrustedTypesFor,
        network::mojom::CSPDirectiveName::ScriptSrc,
        network::mojom::CSPDirectiveName::StyleSrc,
        network::mojom::CSPDirectiveName::TrustedTypes,
        network::mojom::CSPDirectiveName::WorkerSrc};

    for (auto& directive : kAllDirectives) {
      csp_header.append(source->GetContentSecurityPolicy(directive));
    }

    // TODO(crbug.com/1051745): Both CSP frame ancestors and XFO headers may be
    // added to the response but frame ancestors would take precedence. In the
    // future, XFO will be removed so when that happens remove the check and
    // always add frame ancestors.
    if (source->ShouldDenyXFrameOptions()) {
      csp_header.append(source->GetContentSecurityPolicy(
          network::mojom::CSPDirectiveName::FrameAncestors));
    }

    headers->SetHeader(kChromeURLContentSecurityPolicyHeaderName, csp_header);
  }

  if (source->ShouldDenyXFrameOptions()) {
    headers->SetHeader(kChromeURLXFrameOptionsHeaderName,
                       kChromeURLXFrameOptionsHeaderValue);
  }

  if (!source->AllowCaching())
    headers->SetHeader("Cache-Control", "no-cache");

  std::string mime_type = source->GetMimeType(url);
  if (source->ShouldServeMimeTypeAsContentTypeHeader() && !mime_type.empty())
    headers->SetHeader(net::HttpRequestHeaders::kContentType, mime_type);

  const std::string coop_value = source->GetCrossOriginOpenerPolicy();
  if (!coop_value.empty()) {
    headers->SetHeader(kChromeURLCrossOriginOpenerPolicyName, coop_value);
  }
  const std::string coep_value = source->GetCrossOriginEmbedderPolicy();
  if (!coep_value.empty()) {
    headers->SetHeader(kChromeURLCrossOriginEmbedderPolicyName, coep_value);
  }
  const std::string corp_value = source->GetCrossOriginResourcePolicy();
  if (!corp_value.empty()) {
    headers->SetHeader(kChromeURLCrossOriginResourcePolicyName, corp_value);
  }

  if (!origin.empty()) {
    std::string header = source->GetAccessControlAllowOriginForOrigin(origin);
    DCHECK(header.empty() || header == origin || header == "*" ||
           header == "null");
    if (!header.empty()) {
      headers->SetHeader("Access-Control-Allow-Origin", header);
      headers->SetHeader("Vary", "Origin");
    }
  }

  return headers;
}

bool URLDataManagerBackend::CheckURLIsValid(const GURL& url) {
  std::vector<std::string> additional_schemes;
  DCHECK(url.SchemeIs(kChromeUIScheme) ||
         url.SchemeIs(kChromeUIUntrustedScheme) ||
         (GetContentClient()->browser()->GetAdditionalWebUISchemes(
              &additional_schemes),
          SchemeIsInSchemes(url.scheme(), additional_schemes)));

  if (!url.is_valid()) {
    NOTREACHED();
    return false;
  }

  return true;
}

bool URLDataManagerBackend::IsValidNetworkErrorCode(int error_code) {
  base::Value::Dict error_codes = net::GetNetConstants();
  const base::Value::Dict* net_error_codes_dict =
      error_codes.FindDict(kNetworkErrorKey);

  if (net_error_codes_dict != nullptr) {
    for (auto it = net_error_codes_dict->begin();
         it != net_error_codes_dict->end(); ++it) {
      if (error_code == it->second.GetInt())
        return true;
    }
  }
  return false;
}

std::vector<std::string> URLDataManagerBackend::GetWebUISchemes() {
  // It's OK to cache this in a static because the class implementing
  // GetAdditionalWebUISchemes() won't change while the application is
  // running, and because those methods always add the same items.
  static base::NoDestructor<std::vector<std::string>> webui_schemes([]() {
    std::vector<std::string> schemes;
    schemes.emplace_back(kChromeUIScheme);
    schemes.emplace_back(kChromeUIUntrustedScheme);
    GetContentClient()->browser()->GetAdditionalWebUISchemes(&schemes);
    return schemes;
  }());

  return *webui_schemes;
}

}  // namespace content
