// Copyright (c) 2012 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 "chrome/browser/io_thread.h"

#include <utility>
#include <vector>

#include "base/base64.h"
#include "base/bind.h"
#include "base/bind_helpers.h"
#include "base/command_line.h"
#include "base/compiler_specific.h"
#include "base/debug/leak_tracker.h"
#include "base/files/file_path.h"
#include "base/logging.h"
#include "base/macros.h"
#include "base/single_thread_task_runner.h"
#include "base/stl_util.h"
#include "base/strings/string_piece.h"
#include "base/strings/string_split.h"
#include "base/strings/string_util.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task/post_task.h"
#include "base/threading/thread.h"
#include "base/time/time.h"
#include "base/trace_event/trace_event.h"
#include "build/build_config.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/data_use_measurement/chrome_data_use_ascriber.h"
#include "chrome/browser/net/chrome_network_delegate.h"
#include "chrome/browser/net/dns_probe_service.h"
#include "chrome/browser/net/failing_url_request_interceptor.h"
#include "chrome/browser/net/proxy_service_factory.h"
#include "chrome/common/chrome_content_client.h"
#include "chrome/common/chrome_features.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h"
#include "components/certificate_transparency/ct_known_logs.h"
#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_prefs.h"
#include "components/data_use_measurement/core/data_use_ascriber.h"
#include "components/metrics/metrics_service.h"
#include "components/net_log/chrome_net_log.h"
#include "components/network_session_configurator/common/network_features.h"
#include "components/policy/core/common/policy_service.h"
#include "components/policy/policy_constants.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/pref_service.h"
#include "components/variations/variations_associated_data.h"
#include "components/version_info/version_info.h"
#include "content/public/browser/browser_task_traits.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/network_service_instance.h"
#include "content/public/common/content_features.h"
#include "content/public/common/content_switches.h"
#include "content/public/common/user_agent.h"
#include "extensions/buildflags/buildflags.h"
#include "net/cert/caching_cert_verifier.h"
#include "net/cert/cert_verifier.h"
#include "net/cert/cert_verify_proc.h"
#include "net/cert/ct_log_verifier.h"
#include "net/cert/multi_threaded_cert_verifier.h"
#include "net/dns/host_cache.h"
#include "net/dns/host_resolver.h"
#include "net/dns/mapped_host_resolver.h"
#include "net/http/http_network_session.h"
#include "net/http/http_server_properties_impl.h"
#include "net/http/http_transaction_factory.h"
#include "net/net_buildflags.h"
#include "net/nqe/network_quality_estimator.h"
#include "net/nqe/network_quality_estimator_params.h"
#include "net/proxy_resolution/pac_file_fetcher_impl.h"
#include "net/proxy_resolution/proxy_config_service.h"
#include "net/proxy_resolution/proxy_resolution_service.h"
#include "net/quic/quic_utils_chromium.h"
#include "net/url_request/url_fetcher.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_context_builder.h"
#include "net/url_request/url_request_context_getter.h"
#include "services/network/ignore_errors_cert_verifier.h"
#include "services/network/network_service.h"
#include "services/network/public/cpp/features.h"
#include "services/network/public/cpp/network_switches.h"
#include "services/network/url_request_context_builder_mojo.h"
#include "url/url_constants.h"

#if BUILDFLAG(ENABLE_EXTENSIONS)
#include "chrome/browser/extensions/event_router_forwarder.h"
#endif

#if defined(OS_ANDROID)
#include "net/cert/cert_verify_proc_android.h"
#endif  // defined(OS_ANDROID)

#if defined(OS_CHROMEOS)
#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
#include "chromeos/network/dhcp_pac_file_fetcher_factory_chromeos.h"
#include "services/network/cert_verify_proc_chromeos.h"
#endif

using content::BrowserThread;

class SafeBrowsingURLRequestContext;

// The IOThread object must outlive any tasks posted to the IO thread before the
// Quit task, so base::Bind() calls are not refcounted.

namespace {

net::CertVerifier* g_cert_verifier_for_io_thread_testing = nullptr;

// A CertVerifier that forwards all requests to
// |g_cert_verifier_for_io_thread_testing|. This is used to allow IOThread to
// have its own std::unique_ptr<net::CertVerifier> while forwarding calls to the
// static verifier.
class WrappedCertVerifierForIOThreadTesting : public net::CertVerifier {
 public:
  ~WrappedCertVerifierForIOThreadTesting() override = default;

  // CertVerifier implementation
  int Verify(const RequestParams& params,
             net::CertVerifyResult* verify_result,
             net::CompletionOnceCallback callback,
             std::unique_ptr<Request>* out_req,
             const net::NetLogWithSource& net_log) override {
    verify_result->Reset();
    if (!g_cert_verifier_for_io_thread_testing)
      return net::ERR_FAILED;
    return g_cert_verifier_for_io_thread_testing->Verify(
        params, verify_result, std::move(callback), out_req, net_log);
  }

  void SetConfig(const Config& config) override {
    if (!g_cert_verifier_for_io_thread_testing)
      return;
    return g_cert_verifier_for_io_thread_testing->SetConfig(config);
  }
};

#if defined(OS_MACOSX)
void ObserveKeychainEvents() {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  net::CertDatabase::GetInstance()->StartListeningForKeychainEvents();
}
#endif

std::unique_ptr<net::HostResolver> CreateGlobalHostResolver(
    net::NetLog* net_log) {
  TRACE_EVENT0("startup", "IOThread::CreateGlobalHostResolver");

  std::unique_ptr<net::HostResolver> global_host_resolver =
      net::HostResolver::CreateSystemResolver(net::HostResolver::Options(),
                                              net_log);

  // If hostname remappings were specified on the command-line, layer these
  // rules on top of the real host resolver. This allows forwarding all requests
  // through a designated test server.
  const base::CommandLine& command_line =
      *base::CommandLine::ForCurrentProcess();
  if (!command_line.HasSwitch(network::switches::kHostResolverRules))
    return global_host_resolver;

  auto remapped_resolver = std::make_unique<net::MappedHostResolver>(
      std::move(global_host_resolver));
  remapped_resolver->SetRulesFromString(
      command_line.GetSwitchValueASCII(network::switches::kHostResolverRules));
  return std::move(remapped_resolver);
}

}  // namespace

class SystemURLRequestContextGetter : public net::URLRequestContextGetter {
 public:
  explicit SystemURLRequestContextGetter(IOThread* io_thread);

  // Implementation for net::UrlRequestContextGetter.
  net::URLRequestContext* GetURLRequestContext() override;
  scoped_refptr<base::SingleThreadTaskRunner> GetNetworkTaskRunner()
      const override;

 protected:
  ~SystemURLRequestContextGetter() override;

 private:
  IOThread* const io_thread_;  // Weak pointer, owned by BrowserProcess.
  scoped_refptr<base::SingleThreadTaskRunner> network_task_runner_;

  base::debug::LeakTracker<SystemURLRequestContextGetter> leak_tracker_;
};

SystemURLRequestContextGetter::SystemURLRequestContextGetter(
    IOThread* io_thread)
    : io_thread_(io_thread),
      network_task_runner_(
          base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::IO})) {}

SystemURLRequestContextGetter::~SystemURLRequestContextGetter() {}

net::URLRequestContext* SystemURLRequestContextGetter::GetURLRequestContext() {
  DCHECK_CURRENTLY_ON(BrowserThread::IO);
  DCHECK(io_thread_->globals()->system_request_context);

  return io_thread_->globals()->system_request_context;
}

scoped_refptr<base::SingleThreadTaskRunner>
SystemURLRequestContextGetter::GetNetworkTaskRunner() const {
  return network_task_runner_;
}

IOThread::Globals::Globals() : system_request_context(nullptr) {}

IOThread::Globals::~Globals() {}

// |local_state| is passed in explicitly in order to (1) reduce implicit
// dependencies and (2) make IOThread more flexible for testing.
IOThread::IOThread(
    PrefService* local_state,
    policy::PolicyService* policy_service,
    net_log::ChromeNetLog* net_log,
    extensions::EventRouterForwarder* extension_event_router_forwarder,
    SystemNetworkContextManager* system_network_context_manager)
    : net_log_(net_log),
#if BUILDFLAG(ENABLE_EXTENSIONS)
      extension_event_router_forwarder_(extension_event_router_forwarder),
#endif
      globals_(nullptr),
      is_quic_allowed_on_init_(true),
      weak_factory_(this) {
  scoped_refptr<base::SingleThreadTaskRunner> io_thread_proxy =
      base::CreateSingleThreadTaskRunnerWithTraits({BrowserThread::IO});

  BrowserThread::SetIOThreadDelegate(this);

  system_network_context_manager->SetUp(
      &network_context_request_, &network_context_params_,
      &stub_resolver_enabled_, &dns_over_https_servers_,
      &http_auth_static_params_, &http_auth_dynamic_params_,
      &is_quic_allowed_on_init_);
}

IOThread::~IOThread() {
  // This isn't needed for production code, but in tests, IOThread may
  // be multiply constructed.
  BrowserThread::SetIOThreadDelegate(nullptr);

  DCHECK(!globals_);
}

IOThread::Globals* IOThread::globals() {
  DCHECK_CURRENTLY_ON(BrowserThread::IO);
  return globals_;
}

net_log::ChromeNetLog* IOThread::net_log() {
  return net_log_;
}

net::URLRequestContextGetter* IOThread::system_url_request_context_getter() {
  DCHECK_CURRENTLY_ON(BrowserThread::UI);
  if (!system_url_request_context_getter_.get()) {
    system_url_request_context_getter_ =
        base::MakeRefCounted<SystemURLRequestContextGetter>(this);
  }
  return system_url_request_context_getter_.get();
}

void IOThread::Init() {
  TRACE_EVENT0("startup", "IOThread::InitAsync");
  DCHECK_CURRENTLY_ON(BrowserThread::IO);

  const base::CommandLine& command_line =
      *base::CommandLine::ForCurrentProcess();

  DCHECK(!globals_);
  globals_ = new Globals;

#if BUILDFLAG(ENABLE_EXTENSIONS)
  globals_->extension_event_router_forwarder =
      extension_event_router_forwarder_;
#endif

  globals_->data_use_ascriber =
      std::make_unique<data_use_measurement::ChromeDataUseAscriber>();

  globals_->dns_probe_service =
      std::make_unique<chrome_browser_net::DnsProbeService>();

  if (command_line.HasSwitch(network::switches::kIgnoreUrlFetcherCertRequests))
    net::URLFetcher::SetIgnoreCertificateRequests(true);

#if defined(OS_MACOSX)
  // Start observing Keychain events. This needs to be done on the UI thread,
  // as Keychain services requires a CFRunLoop.
  base::PostTaskWithTraits(FROM_HERE, {BrowserThread::UI},
                           base::Bind(&ObserveKeychainEvents));
#endif

  ConstructSystemRequestContext();

  // Prevent DCHECK failures when a NetworkContext is created with an encrypted
  // cookie store.
  if (!base::FeatureList::IsEnabled(network::features::kNetworkService))
    content::GetNetworkServiceImpl()->set_os_crypt_is_configured();
}

void IOThread::CleanUp() {
  base::debug::LeakTracker<SafeBrowsingURLRequestContext>::CheckForLeaks();

  system_url_request_context_getter_ = nullptr;

  globals_->system_request_context->proxy_resolution_service()->OnShutdown();

  // Release objects that the net::URLRequestContext could have been pointing
  // to.

  delete globals_;
  globals_ = nullptr;

  base::debug::LeakTracker<SystemURLRequestContextGetter>::CheckForLeaks();

  if (net_log_)
    net_log_->ShutDownBeforeTaskScheduler();
}

// static
void IOThread::RegisterPrefs(PrefRegistrySimple* registry) {
  data_reduction_proxy::RegisterPrefs(registry);
}

// static
void IOThread::SetCertVerifierForTesting(net::CertVerifier* cert_verifier) {
  g_cert_verifier_for_io_thread_testing = cert_verifier;
}

void IOThread::DisableQuic() {
  DCHECK_CURRENTLY_ON(BrowserThread::IO);
  globals_->quic_disabled = true;
}

void IOThread::SetUpProxyService(
    network::URLRequestContextBuilderMojo* builder) const {
#if defined(OS_CHROMEOS)
  builder->SetDhcpFetcherFactory(
      std::make_unique<chromeos::DhcpPacFileFetcherFactoryChromeos>());
#endif
}

void IOThread::ConstructSystemRequestContext() {
  if (base::FeatureList::IsEnabled(network::features::kNetworkService)) {
    globals_->deprecated_network_quality_estimator =
        std::make_unique<net::NetworkQualityEstimator>(
            std::make_unique<net::NetworkQualityEstimatorParams>(
                std::map<std::string, std::string>()),
            net_log_);
    net::URLRequestContextBuilder builder;
    std::vector<std::unique_ptr<net::URLRequestInterceptor>>
        url_request_interceptors;
    url_request_interceptors.emplace_back(
        std::make_unique<FailingURLRequestInterceptor>());
    builder.SetInterceptors(std::move(url_request_interceptors));
    builder.set_network_quality_estimator(
        globals_->deprecated_network_quality_estimator.get());
    builder.SetCertVerifier(
        std::make_unique<WrappedCertVerifierForIOThreadTesting>());
    builder.set_proxy_resolution_service(
        net::ProxyResolutionService::CreateDirect());
    globals_->system_request_context_owner =
        network::URLRequestContextOwner(nullptr, builder.Build());
    globals_->system_request_context =
        globals_->system_request_context_owner.url_request_context.get();
    network_context_params_.reset();
  } else {
    std::unique_ptr<network::URLRequestContextBuilderMojo> builder =
        std::make_unique<network::URLRequestContextBuilderMojo>();

    auto chrome_network_delegate = std::make_unique<ChromeNetworkDelegate>(
        extension_event_router_forwarder());
    builder->set_network_delegate(
        globals_->data_use_ascriber->CreateNetworkDelegate(
            std::move(chrome_network_delegate)));

    std::unique_ptr<net::CertVerifier> cert_verifier;
    if (g_cert_verifier_for_io_thread_testing) {
      cert_verifier = std::make_unique<WrappedCertVerifierForIOThreadTesting>();
    } else {
#if defined(OS_CHROMEOS)
      // Creates a CertVerifyProc that doesn't allow any profile-provided certs.
      cert_verifier = std::make_unique<net::CachingCertVerifier>(
          std::make_unique<net::MultiThreadedCertVerifier>(
              base::MakeRefCounted<network::CertVerifyProcChromeOS>()));
#else
      cert_verifier = std::make_unique<net::CachingCertVerifier>(
          std::make_unique<net::MultiThreadedCertVerifier>(
              net::CertVerifyProc::CreateDefault()));
#endif
    }
    const base::CommandLine& command_line =
        *base::CommandLine::ForCurrentProcess();
    builder->SetCertVerifier(
        network::IgnoreErrorsCertVerifier::MaybeWrapCertVerifier(
            command_line, switches::kUserDataDir, std::move(cert_verifier)));

    SetUpProxyService(builder.get());

    if (!is_quic_allowed_on_init_)
      globals_->quic_disabled = true;

    network::NetworkService* network_service = content::GetNetworkServiceImpl();
    network_service->SetHostResolver(CreateGlobalHostResolver(net_log_));

    // These must be done after the SetHostResolver call.
    network_service->SetUpHttpAuth(std::move(http_auth_static_params_));
    network_service->ConfigureHttpAuthPrefs(
        std::move(http_auth_dynamic_params_));

    globals_->system_network_context =
        network_service->CreateNetworkContextWithBuilder(
            std::move(network_context_request_),
            std::move(network_context_params_), std::move(builder),
            &globals_->system_request_context);

    // This must be done after the system NetworkContext is created.
    network_service->ConfigureStubHostResolver(
        stub_resolver_enabled_, std::move(dns_over_https_servers_));
  }
}
