// 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 "net/url_request/url_request_context_builder.h"

#include <memory>
#include <string>
#include <utility>
#include <vector>

#include "base/check_op.h"
#include "base/compiler_specific.h"
#include "base/notreached.h"
#include "base/strings/string_util.h"
#include "base/task/sequenced_task_runner.h"
#include "base/task/single_thread_task_runner.h"
#include "base/task/thread_pool.h"
#include "base/types/pass_key.h"
#include "build/build_config.h"
#include "net/base/cache_type.h"
#include "net/base/net_errors.h"
#include "net/base/network_delegate_impl.h"
#include "net/cert/cert_verifier.h"
#include "net/cert/ct_log_verifier.h"
#include "net/cert/ct_policy_enforcer.h"
#include "net/cert/ct_verifier.h"
#include "net/cert/multi_log_ct_verifier.h"
#include "net/cert/sct_auditing_delegate.h"
#include "net/cookies/cookie_monster.h"
#include "net/dns/context_host_resolver.h"
#include "net/dns/host_resolver.h"
#include "net/dns/host_resolver_manager.h"
#include "net/http/http_auth_handler_factory.h"
#include "net/http/http_cache.h"
#include "net/http/http_network_layer.h"
#include "net/http/http_network_session.h"
#include "net/http/http_server_properties.h"
#include "net/http/http_server_properties_manager.h"
#include "net/http/transport_security_persister.h"
#include "net/http/transport_security_state.h"
#include "net/log/net_log.h"
#include "net/net_buildflags.h"
#include "net/nqe/network_quality_estimator.h"
#include "net/proxy_resolution/configured_proxy_resolution_service.h"
#include "net/quic/quic_context.h"
#include "net/quic/quic_stream_factory.h"
#include "net/socket/network_binding_client_socket_factory.h"
#include "net/ssl/ssl_config_service_defaults.h"
#include "net/url_request/static_http_user_agent_settings.h"
#include "net/url_request/url_request_context.h"
#include "net/url_request/url_request_job_factory.h"
#include "net/url_request/url_request_throttler_manager.h"
#include "url/url_constants.h"

#if BUILDFLAG(ENABLE_REPORTING)
#include "net/network_error_logging/network_error_logging_service.h"
#include "net/network_error_logging/persistent_reporting_and_nel_store.h"
#include "net/reporting/reporting_policy.h"
#include "net/reporting/reporting_service.h"
#endif  // BUILDFLAG(ENABLE_REPORTING)

#if BUILDFLAG(IS_ANDROID)
#include "base/android/build_info.h"
#endif  // BUILDFLAG(IS_ANDROID)

namespace net {

URLRequestContextBuilder::HttpCacheParams::HttpCacheParams() = default;
URLRequestContextBuilder::HttpCacheParams::~HttpCacheParams() = default;

URLRequestContextBuilder::URLRequestContextBuilder() = default;

URLRequestContextBuilder::~URLRequestContextBuilder() = default;

void URLRequestContextBuilder::SetHttpNetworkSessionComponents(
    const URLRequestContext* request_context,
    HttpNetworkSessionContext* session_context,
    bool suppress_setting_socket_performance_watcher_factory,
    ClientSocketFactory* client_socket_factory) {
  session_context->client_socket_factory =
      client_socket_factory ? client_socket_factory
                            : ClientSocketFactory::GetDefaultFactory();
  session_context->host_resolver = request_context->host_resolver();
  session_context->cert_verifier = request_context->cert_verifier();
  session_context->transport_security_state =
      request_context->transport_security_state();
  session_context->ct_policy_enforcer = request_context->ct_policy_enforcer();
  session_context->sct_auditing_delegate =
      request_context->sct_auditing_delegate();
  session_context->proxy_resolution_service =
      request_context->proxy_resolution_service();
  session_context->proxy_delegate = request_context->proxy_delegate();
  session_context->http_user_agent_settings =
      request_context->http_user_agent_settings();
  session_context->ssl_config_service = request_context->ssl_config_service();
  session_context->http_auth_handler_factory =
      request_context->http_auth_handler_factory();
  session_context->http_server_properties =
      request_context->http_server_properties();
  session_context->quic_context = request_context->quic_context();
  session_context->net_log = request_context->net_log();
  session_context->network_quality_estimator =
      request_context->network_quality_estimator();
  if (request_context->network_quality_estimator() &&
      !suppress_setting_socket_performance_watcher_factory) {
    session_context->socket_performance_watcher_factory =
        request_context->network_quality_estimator()
            ->GetSocketPerformanceWatcherFactory();
  }
#if BUILDFLAG(ENABLE_REPORTING)
  session_context->reporting_service = request_context->reporting_service();
  session_context->network_error_logging_service =
      request_context->network_error_logging_service();
#endif
}

void URLRequestContextBuilder::set_accept_language(
    const std::string& accept_language) {
  DCHECK(!http_user_agent_settings_);
  accept_language_ = accept_language;
}
void URLRequestContextBuilder::set_user_agent(const std::string& user_agent) {
  DCHECK(!http_user_agent_settings_);
  user_agent_ = user_agent;
}

void URLRequestContextBuilder::set_http_user_agent_settings(
    std::unique_ptr<HttpUserAgentSettings> http_user_agent_settings) {
  http_user_agent_settings_ = std::move(http_user_agent_settings);
}

void URLRequestContextBuilder::EnableHttpCache(const HttpCacheParams& params) {
  http_cache_enabled_ = true;
  http_cache_params_ = params;
}

void URLRequestContextBuilder::DisableHttpCache() {
  http_cache_enabled_ = false;
  http_cache_params_ = HttpCacheParams();
}

void URLRequestContextBuilder::SetSpdyAndQuicEnabled(bool spdy_enabled,
                                                     bool quic_enabled) {
  http_network_session_params_.enable_http2 = spdy_enabled;
  http_network_session_params_.enable_quic = quic_enabled;
}

void URLRequestContextBuilder::set_ct_policy_enforcer(
    std::unique_ptr<CTPolicyEnforcer> ct_policy_enforcer) {
  ct_policy_enforcer_ = std::move(ct_policy_enforcer);
}

void URLRequestContextBuilder::set_sct_auditing_delegate(
    std::unique_ptr<SCTAuditingDelegate> sct_auditing_delegate) {
  sct_auditing_delegate_ = std::move(sct_auditing_delegate);
}

void URLRequestContextBuilder::set_quic_context(
    std::unique_ptr<QuicContext> quic_context) {
  quic_context_ = std::move(quic_context);
}

void URLRequestContextBuilder::SetCertVerifier(
    std::unique_ptr<CertVerifier> cert_verifier) {
  cert_verifier_ = std::move(cert_verifier);
}

#if BUILDFLAG(ENABLE_REPORTING)
void URLRequestContextBuilder::set_reporting_policy(
    std::unique_ptr<ReportingPolicy> reporting_policy) {
  reporting_policy_ = std::move(reporting_policy);
}

void URLRequestContextBuilder::set_reporting_service(
    std::unique_ptr<ReportingService> reporting_service) {
  reporting_service_ = std::move(reporting_service);
}

void URLRequestContextBuilder::set_persistent_reporting_and_nel_store(
    std::unique_ptr<PersistentReportingAndNelStore>
        persistent_reporting_and_nel_store) {
  persistent_reporting_and_nel_store_ =
      std::move(persistent_reporting_and_nel_store);
}
#endif  // BUILDFLAG(ENABLE_REPORTING)

void URLRequestContextBuilder::SetCookieStore(
    std::unique_ptr<CookieStore> cookie_store) {
  cookie_store_set_by_client_ = true;
  cookie_store_ = std::move(cookie_store);
}

void URLRequestContextBuilder::SetProtocolHandler(
    const std::string& scheme,
    std::unique_ptr<URLRequestJobFactory::ProtocolHandler> protocol_handler) {
  DCHECK(protocol_handler);
  // If a consumer sets a ProtocolHandler and then overwrites it with another,
  // it's probably a bug.
  DCHECK_EQ(0u, protocol_handlers_.count(scheme));
  protocol_handlers_[scheme] = std::move(protocol_handler);
}

void URLRequestContextBuilder::set_host_resolver(
    std::unique_ptr<HostResolver> host_resolver) {
  DCHECK(!host_resolver_manager_);
  DCHECK(host_mapping_rules_.empty());
  DCHECK(!host_resolver_factory_);
  host_resolver_ = std::move(host_resolver);
}

void URLRequestContextBuilder::set_host_mapping_rules(
    std::string host_mapping_rules) {
  DCHECK(!host_resolver_);
  host_mapping_rules_ = std::move(host_mapping_rules);
}

void URLRequestContextBuilder::set_host_resolver_manager(
    HostResolverManager* manager) {
  DCHECK(!host_resolver_);
  host_resolver_manager_ = manager;
}

void URLRequestContextBuilder::set_host_resolver_factory(
    HostResolver::Factory* factory) {
  DCHECK(!host_resolver_);
  host_resolver_factory_ = factory;
}

void URLRequestContextBuilder::set_proxy_delegate(
    std::unique_ptr<ProxyDelegate> proxy_delegate) {
  proxy_delegate_ = std::move(proxy_delegate);
}

void URLRequestContextBuilder::SetHttpAuthHandlerFactory(
    std::unique_ptr<HttpAuthHandlerFactory> factory) {
  http_auth_handler_factory_ = std::move(factory);
}

void URLRequestContextBuilder::SetHttpServerProperties(
    std::unique_ptr<HttpServerProperties> http_server_properties) {
  http_server_properties_ = std::move(http_server_properties);
}

void URLRequestContextBuilder::SetCreateHttpTransactionFactoryCallback(
    CreateHttpTransactionFactoryCallback
        create_http_network_transaction_factory) {
  http_transaction_factory_.reset();
  create_http_network_transaction_factory_ =
      std::move(create_http_network_transaction_factory);
}

void URLRequestContextBuilder::BindToNetwork(
    handles::NetworkHandle network,
    absl::optional<HostResolver::ManagerOptions> options) {
#if BUILDFLAG(IS_ANDROID)
  DCHECK(NetworkChangeNotifier::AreNetworkHandlesSupported());
  // DNS lookups for this context will need to target `network`. NDK to do that
  // has been introduced in Android Marshmallow
  // (https://developer.android.com/ndk/reference/group/networking#android_getaddrinfofornetwork)
  // This is also checked later on in the codepath (at lookup time), but
  // failing here should be preferred to return a more intuitive crash path.
  CHECK(base::android::BuildInfo::GetInstance()->sdk_int() >=
        base::android::SDK_VERSION_MARSHMALLOW);
  bound_network_ = network;
  manager_options_ = options.value_or(manager_options_);
#else
  NOTIMPLEMENTED();
#endif  // BUILDFLAG(IS_ANDROID)
}

std::unique_ptr<URLRequestContext> URLRequestContextBuilder::Build() {
  auto context = std::make_unique<URLRequestContext>(
      base::PassKey<URLRequestContextBuilder>());

  context->set_enable_brotli(enable_brotli_);
  context->set_check_cleartext_permitted(check_cleartext_permitted_);
  context->set_require_network_isolation_key(require_network_isolation_key_);
  context->set_network_quality_estimator(network_quality_estimator_);

  if (http_user_agent_settings_) {
    context->set_http_user_agent_settings(std::move(http_user_agent_settings_));
  } else {
    context->set_http_user_agent_settings(
        std::make_unique<StaticHttpUserAgentSettings>(accept_language_,
                                                      user_agent_));
  }

  if (!network_delegate_)
    network_delegate_ = std::make_unique<NetworkDelegateImpl>();
  context->set_network_delegate(std::move(network_delegate_));

  if (net_log_) {
    // Unlike the other builder parameters, |net_log_| is not owned by the
    // builder or resulting context.
    context->set_net_log(net_log_);
  } else {
    context->set_net_log(NetLog::Get());
  }

  if (bound_network_ != handles::kInvalidNetworkHandle) {
    DCHECK(!client_socket_factory_raw_);
    DCHECK(!host_resolver_);
    DCHECK(!host_resolver_manager_);
    DCHECK(!host_resolver_factory_);

    context->set_bound_network(bound_network_);

    // All sockets created for this context will need to be bound to
    // `bound_network_`.
    auto client_socket_factory =
        std::make_unique<NetworkBindingClientSocketFactory>(bound_network_);
    set_client_socket_factory(client_socket_factory.get());
    context->set_client_socket_factory(std::move(client_socket_factory));

    host_resolver_ = HostResolver::CreateStandaloneNetworkBoundResolver(
        context->net_log(), bound_network_, manager_options_);

    if (!quic_context_)
      set_quic_context(std::make_unique<QuicContext>());
    auto* quic_params = quic_context_->params();
    // QUIC sessions for this context should not be closed (or go away) after a
    // network change.
    quic_params->close_sessions_on_ip_change = false;
    quic_params->goaway_sessions_on_ip_change = false;

    // QUIC connection migration should not be enabled when binding a context
    // to a network.
    quic_params->migrate_sessions_on_network_change_v2 = false;

    // Objects used by network sessions for this context shouldn't listen to
    // network changes.
    http_network_session_params_.ignore_ip_address_changes = true;
  }

  if (client_socket_factory_) {
    context->set_client_socket_factory(std::move(client_socket_factory_));
  }

  if (host_resolver_) {
    DCHECK(host_mapping_rules_.empty());
    DCHECK(!host_resolver_manager_);
    DCHECK(!host_resolver_factory_);
  } else if (host_resolver_manager_) {
    if (host_resolver_factory_) {
      host_resolver_ = host_resolver_factory_->CreateResolver(
          host_resolver_manager_, host_mapping_rules_,
          true /* enable_caching */);
    } else {
      host_resolver_ = HostResolver::CreateResolver(host_resolver_manager_,
                                                    host_mapping_rules_,
                                                    true /* enable_caching */);
    }
  } else {
    if (host_resolver_factory_) {
      host_resolver_ = host_resolver_factory_->CreateStandaloneResolver(
          context->net_log(), HostResolver::ManagerOptions(),
          host_mapping_rules_, true /* enable_caching */);
    } else {
      host_resolver_ = HostResolver::CreateStandaloneResolver(
          context->net_log(), HostResolver::ManagerOptions(),
          host_mapping_rules_, true /* enable_caching */);
    }
  }
  host_resolver_->SetRequestContext(context.get());
  context->set_host_resolver(std::move(host_resolver_));

  if (ssl_config_service_) {
    context->set_ssl_config_service(std::move(ssl_config_service_));
  } else {
    context->set_ssl_config_service(
        std::make_unique<SSLConfigServiceDefaults>());
  }

  if (http_auth_handler_factory_) {
    context->set_http_auth_handler_factory(
        std::move(http_auth_handler_factory_));
  } else {
    context->set_http_auth_handler_factory(
        HttpAuthHandlerRegistryFactory::CreateDefault());
  }

  if (cookie_store_set_by_client_) {
    context->set_cookie_store(std::move(cookie_store_));
  } else {
    auto cookie_store = std::make_unique<CookieMonster>(nullptr /* store */,
                                                        context->net_log());
    context->set_cookie_store(std::move(cookie_store));
  }

  context->set_transport_security_state(
      std::make_unique<TransportSecurityState>(hsts_policy_bypass_list_));
  if (!transport_security_persister_file_path_.empty()) {
    // Use a low priority because saving this should not block anything
    // user-visible. Block shutdown to ensure it does get persisted to disk,
    // since it contains security-relevant information.
    scoped_refptr<base::SequencedTaskRunner> task_runner(
        base::ThreadPool::CreateSequencedTaskRunner(
            {base::MayBlock(), base::TaskPriority::BEST_EFFORT,
             base::TaskShutdownBehavior::BLOCK_SHUTDOWN}));

    context->set_transport_security_persister(
        std::make_unique<TransportSecurityPersister>(
            context->transport_security_state(), task_runner,
            transport_security_persister_file_path_));
  }

  if (http_server_properties_) {
    context->set_http_server_properties(std::move(http_server_properties_));
  } else {
    context->set_http_server_properties(
        std::make_unique<HttpServerProperties>());
  }

  if (cert_verifier_) {
    context->set_cert_verifier(std::move(cert_verifier_));
  } else {
    // TODO(mattm): Should URLRequestContextBuilder create a CertNetFetcher?
    context->set_cert_verifier(
        CertVerifier::CreateDefault(/*cert_net_fetcher=*/nullptr));
  }

  if (ct_policy_enforcer_) {
    context->set_ct_policy_enforcer(std::move(ct_policy_enforcer_));
  } else {
    context->set_ct_policy_enforcer(
        std::make_unique<DefaultCTPolicyEnforcer>());
  }

  if (sct_auditing_delegate_) {
    context->set_sct_auditing_delegate(std::move(sct_auditing_delegate_));
  }

  if (quic_context_) {
    context->set_quic_context(std::move(quic_context_));
  } else {
    context->set_quic_context(std::make_unique<QuicContext>());
  }

  if (throttling_enabled_) {
    context->set_throttler_manager(
        std::make_unique<URLRequestThrottlerManager>());
  }

  if (!proxy_resolution_service_) {
#if !BUILDFLAG(IS_LINUX) && !BUILDFLAG(IS_CHROMEOS) && !BUILDFLAG(IS_ANDROID)
    // TODO(willchan): Switch to using this code when
    // ProxyConfigService::CreateSystemProxyConfigService()'s
    // signature doesn't suck.
    if (!proxy_config_service_) {
      proxy_config_service_ =
          ProxyConfigService::CreateSystemProxyConfigService(
              base::SingleThreadTaskRunner::GetCurrentDefault().get());
    }
#endif  // !BUILDFLAG(IS_LINUX) && !BUILDFLAG(IS_CHROMEOS) &&
        // !BUILDFLAG(IS_ANDROID)
    proxy_resolution_service_ = CreateProxyResolutionService(
        std::move(proxy_config_service_), context.get(),
        context->host_resolver(), context->network_delegate(),
        context->net_log(), pac_quick_check_enabled_);
  }
  ProxyResolutionService* proxy_resolution_service =
      proxy_resolution_service_.get();
  context->set_proxy_resolution_service(std::move(proxy_resolution_service_));

#if BUILDFLAG(ENABLE_REPORTING)
  // Note: ReportingService::Create and NetworkErrorLoggingService::Create can
  // both return nullptr if the corresponding base::Feature is disabled.

  if (reporting_service_) {
    context->set_reporting_service(std::move(reporting_service_));
  } else if (reporting_policy_) {
    context->set_reporting_service(
        ReportingService::Create(*reporting_policy_, context.get(),
                                 persistent_reporting_and_nel_store_.get()));
  }

  if (network_error_logging_enabled_) {
    if (!network_error_logging_service_) {
      network_error_logging_service_ = NetworkErrorLoggingService::Create(
          persistent_reporting_and_nel_store_.get());
    }
    context->set_network_error_logging_service(
        std::move(network_error_logging_service_));
  }

  if (persistent_reporting_and_nel_store_) {
    context->set_persistent_reporting_and_nel_store(
        std::move(persistent_reporting_and_nel_store_));
  }

  // If both Reporting and Network Error Logging are actually enabled, then
  // connect them so Network Error Logging can use Reporting to deliver error
  // reports.
  if (context->reporting_service() &&
      context->network_error_logging_service()) {
    context->network_error_logging_service()->SetReportingService(
        context->reporting_service());
  }
#endif  // BUILDFLAG(ENABLE_REPORTING)

  if (proxy_delegate_) {
    proxy_resolution_service->SetProxyDelegate(proxy_delegate_.get());
    context->set_proxy_delegate(std::move(proxy_delegate_));
  }

  HttpNetworkSessionContext network_session_context;
  // Unlike the other fields of HttpNetworkSession::Context,
  // |client_socket_factory| is not mirrored in URLRequestContext.
  SetHttpNetworkSessionComponents(
      context.get(), &network_session_context,
      suppress_setting_socket_performance_watcher_factory_for_testing_,
      client_socket_factory_raw_);

  context->set_http_network_session(std::make_unique<HttpNetworkSession>(
      http_network_session_params_, network_session_context));

  std::unique_ptr<HttpTransactionFactory> http_transaction_factory;
  if (http_transaction_factory_) {
    http_transaction_factory = std::move(http_transaction_factory_);
  } else if (!create_http_network_transaction_factory_.is_null()) {
    http_transaction_factory =
        std::move(create_http_network_transaction_factory_)
            .Run(context->http_network_session());
  } else {
    http_transaction_factory =
        std::make_unique<HttpNetworkLayer>(context->http_network_session());
  }

  if (http_cache_enabled_) {
    std::unique_ptr<HttpCache::BackendFactory> http_cache_backend;
    if (http_cache_params_.type != HttpCacheParams::IN_MEMORY) {
      // TODO(mmenke): Maybe merge BackendType and HttpCacheParams::Type? The
      // first doesn't include in memory, so may require some work.
      BackendType backend_type = CACHE_BACKEND_DEFAULT;
      switch (http_cache_params_.type) {
        case HttpCacheParams::DISK:
          backend_type = CACHE_BACKEND_DEFAULT;
          break;
        case HttpCacheParams::DISK_BLOCKFILE:
          backend_type = CACHE_BACKEND_BLOCKFILE;
          break;
        case HttpCacheParams::DISK_SIMPLE:
          backend_type = CACHE_BACKEND_SIMPLE;
          break;
        case HttpCacheParams::IN_MEMORY:
          NOTREACHED();
          break;
      }
      http_cache_backend = std::make_unique<HttpCache::DefaultBackend>(
          DISK_CACHE, backend_type, http_cache_params_.file_operations_factory,
          http_cache_params_.path, http_cache_params_.max_size,
          http_cache_params_.reset_cache);
    } else {
      http_cache_backend =
          HttpCache::DefaultBackend::InMemory(http_cache_params_.max_size);
    }
#if BUILDFLAG(IS_ANDROID)
    http_cache_backend->SetAppStatusListener(
        http_cache_params_.app_status_listener);
#endif

    http_transaction_factory = std::make_unique<HttpCache>(
        std::move(http_transaction_factory), std::move(http_cache_backend));
  }
  context->set_http_transaction_factory(std::move(http_transaction_factory));

  std::unique_ptr<URLRequestJobFactory> job_factory =
      std::make_unique<URLRequestJobFactory>();
  for (auto& scheme_handler : protocol_handlers_) {
    job_factory->SetProtocolHandler(scheme_handler.first,
                                    std::move(scheme_handler.second));
  }
  protocol_handlers_.clear();

  context->set_job_factory(std::move(job_factory));

  return context;
}

std::unique_ptr<ProxyResolutionService>
URLRequestContextBuilder::CreateProxyResolutionService(
    std::unique_ptr<ProxyConfigService> proxy_config_service,
    URLRequestContext* url_request_context,
    HostResolver* host_resolver,
    NetworkDelegate* network_delegate,
    NetLog* net_log,
    bool pac_quick_check_enabled) {
  return ConfiguredProxyResolutionService::CreateUsingSystemProxyResolver(
      std::move(proxy_config_service), net_log, pac_quick_check_enabled);
}

}  // namespace net
