blob: fc40b1c3ff1ff754d047958c0e644e150a2c4586 [file] [log] [blame]
// Copyright 2017 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 "services/network/network_context.h"
#include <memory>
#include <utility>
#include "base/command_line.h"
#include "base/logging.h"
#include "base/memory/ref_counted.h"
#include "base/message_loop/message_loop_current.h"
#include "base/optional.h"
#include "base/sequenced_task_runner.h"
#include "base/strings/string_number_conversions.h"
#include "base/task_scheduler/post_task.h"
#include "base/task_scheduler/task_traits.h"
#include "build/build_config.h"
#include "components/certificate_transparency/chrome_ct_policy_enforcer.h"
#include "components/certificate_transparency/ct_policy_manager.h"
#include "components/certificate_transparency/features.h"
#include "components/certificate_transparency/sth_distributor.h"
#include "components/certificate_transparency/sth_reporter.h"
#include "components/certificate_transparency/tree_state_tracker.h"
#include "components/cookie_config/cookie_store_util.h"
#include "components/network_session_configurator/browser/network_session_configurator.h"
#include "components/network_session_configurator/common/network_switches.h"
#include "components/prefs/json_pref_store.h"
#include "components/prefs/pref_registry_simple.h"
#include "components/prefs/pref_service.h"
#include "components/prefs/pref_service_factory.h"
#include "mojo/public/cpp/bindings/strong_binding.h"
#include "net/cert/cert_verifier.h"
#include "net/cert/ct_log_verifier.h"
#include "net/cert/multi_log_ct_verifier.h"
#include "net/cookies/cookie_monster.h"
#include "net/dns/host_resolver.h"
#include "net/dns/mapped_host_resolver.h"
#include "net/extras/sqlite/sqlite_channel_id_store.h"
#include "net/extras/sqlite/sqlite_persistent_cookie_store.h"
#include "net/http/failing_http_transaction_factory.h"
#include "net/http/http_auth_handler_factory.h"
#include "net/http/http_auth_preferences.h"
#include "net/http/http_auth_scheme.h"
#include "net/http/http_cache.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/http_transaction_factory.h"
#include "net/proxy_resolution/proxy_config.h"
#include "net/ssl/channel_id_service.h"
#include "net/ssl/default_channel_id_store.h"
#include "net/traffic_annotation/network_traffic_annotation.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_context_builder.h"
#include "services/network/http_server_properties_pref_delegate.h"
#include "services/network/ignore_errors_cert_verifier.h"
#include "services/network/mojo_net_log.h"
#include "services/network/network_service.h"
#include "services/network/proxy_config_service_mojo.h"
#include "services/network/public/cpp/features.h"
#include "services/network/public/cpp/network_switches.h"
#include "services/network/resource_scheduler_client.h"
#include "services/network/restricted_cookie_manager.h"
#include "services/network/throttling/network_conditions.h"
#include "services/network/throttling/throttling_controller.h"
#include "services/network/throttling/throttling_network_transaction_factory.h"
#include "services/network/url_loader.h"
#include "services/network/url_loader_factory.h"
#include "services/network/url_request_context_builder_mojo.h"
#if !defined(OS_IOS)
#include "services/network/websocket_factory.h"
#endif // !defined(OS_IOS)
#if BUILDFLAG(ENABLE_REPORTING)
#include "net/base/registry_controlled_domains/registry_controlled_domain.h"
#include "net/network_error_logging/network_error_logging_service.h"
#include "net/reporting/reporting_browsing_data_remover.h"
#include "net/reporting/reporting_policy.h"
#include "net/reporting/reporting_service.h"
#endif // BUILDFLAG(ENABLE_REPORTING)
namespace network {
namespace {
net::CertVerifier* g_cert_verifier_for_testing = nullptr;
const char* const kDefaultAuthSchemes[] = {net::kBasicAuthScheme,
net::kDigestAuthScheme,
#if defined(USE_KERBEROS) && !defined(OS_ANDROID)
net::kNegotiateAuthScheme,
#endif
net::kNtlmAuthScheme};
// A CertVerifier that forwards all requests to |g_cert_verifier_for_testing|.
// This is used to allow NetworkContexts to have their own
// std::unique_ptr<net::CertVerifier> while forwarding calls to the shared
// verifier.
class WrappedTestingCertVerifier : public net::CertVerifier {
public:
~WrappedTestingCertVerifier() override = default;
// CertVerifier implementation
int Verify(const RequestParams& params,
net::CRLSet* crl_set,
net::CertVerifyResult* verify_result,
const net::CompletionCallback& callback,
std::unique_ptr<Request>* out_req,
const net::NetLogWithSource& net_log) override {
verify_result->Reset();
if (!g_cert_verifier_for_testing)
return net::ERR_FAILED;
return g_cert_verifier_for_testing->Verify(params, crl_set, verify_result,
callback, out_req, net_log);
}
};
// Predicate function to determine if the given |channel_id_server_id| matches
// the |filter_type| and |filter_domains| from a |mojom::ClearDataFilter|.
bool MatchesClearChannelIdFilter(mojom::ClearDataFilter_Type filter_type,
std::set<std::string> filter_domains,
const std::string& channel_id_server_id) {
bool found_domain =
filter_domains.find(channel_id_server_id) != filter_domains.end();
return (filter_type == mojom::ClearDataFilter_Type::DELETE_MATCHES) ==
found_domain;
}
// Generic functions but currently only used for reporting.
#if BUILDFLAG(ENABLE_REPORTING)
// Predicate function to determine if the given |url| matches the |filter_type|,
// |filter_domains| and |filter_origins| from a |mojom::ClearDataFilter|.
bool MatchesUrlFilter(mojom::ClearDataFilter_Type filter_type,
std::set<std::string> filter_domains,
std::set<url::Origin> filter_origins,
const GURL& url) {
std::string url_registerable_domain =
net::registry_controlled_domains::GetDomainAndRegistry(
url, net::registry_controlled_domains::INCLUDE_PRIVATE_REGISTRIES);
bool found_domain =
(filter_domains.find(url_registerable_domain != ""
? url_registerable_domain
: url.host()) != filter_domains.end());
bool found_origin =
(filter_origins.find(url::Origin::Create(url)) != filter_origins.end());
return (filter_type == mojom::ClearDataFilter_Type::DELETE_MATCHES) ==
(found_domain || found_origin);
}
// Builds a generic GURL-matching predicate function based on |filter|. If
// |filter| is null, creates an always-true predicate.
base::RepeatingCallback<bool(const GURL&)> BuildUrlFilter(
mojom::ClearDataFilterPtr filter) {
if (!filter) {
return base::BindRepeating([](const GURL&) { return true; });
}
std::set<std::string> filter_domains;
filter_domains.insert(filter->domains.begin(), filter->domains.end());
std::set<url::Origin> filter_origins;
filter_origins.insert(filter->origins.begin(), filter->origins.end());
return base::BindRepeating(&MatchesUrlFilter, filter->type,
std::move(filter_domains),
std::move(filter_origins));
}
#endif // BUILDFLAG(ENABLE_REPORTING)
void OnClearedChannelIds(net::SSLConfigService* ssl_config_service,
base::OnceClosure callback) {
// Need to close open SSL connections which may be using the channel ids we
// deleted.
// TODO(mattm): http://crbug.com/166069 Make the server bound cert
// service/store have observers that can notify relevant things directly.
ssl_config_service->NotifySSLConfigChange();
std::move(callback).Run();
}
} // namespace
constexpr bool NetworkContext::enable_resource_scheduler_;
NetworkContext::NetworkContext(NetworkService* network_service,
mojom::NetworkContextRequest request,
mojom::NetworkContextParamsPtr params)
: network_service_(network_service),
params_(std::move(params)),
binding_(this, std::move(request)) {
url_request_context_owner_ = MakeURLRequestContext(params_.get());
url_request_context_ = url_request_context_owner_.url_request_context.get();
cookie_manager_ =
std::make_unique<CookieManager>(url_request_context_->cookie_store());
socket_factory_ = std::make_unique<SocketFactory>(network_service_->net_log(),
url_request_context_);
network_service_->RegisterNetworkContext(this);
binding_.set_connection_error_handler(base::BindOnce(
&NetworkContext::OnConnectionError, base::Unretained(this)));
resource_scheduler_ =
std::make_unique<ResourceScheduler>(enable_resource_scheduler_);
}
// TODO(mmenke): Share URLRequestContextBulder configuration between two
// constructors. Can only share them once consumer code is ready for its
// corresponding options to be overwritten.
NetworkContext::NetworkContext(
NetworkService* network_service,
mojom::NetworkContextRequest request,
mojom::NetworkContextParamsPtr params,
std::unique_ptr<URLRequestContextBuilderMojo> builder)
: network_service_(network_service),
params_(std::move(params)),
binding_(this, std::move(request)) {
url_request_context_owner_ = ApplyContextParamsToBuilder(
builder.get(), params_.get(), network_service->quic_disabled(),
network_service->net_log(), network_service->network_quality_estimator(),
network_service_->sth_reporter(), &ct_tree_tracker_,
&user_agent_settings_);
url_request_context_ = url_request_context_owner_.url_request_context.get();
if (ct_tree_tracker_ && network_service_->sth_reporter()) {
url_request_context_->cert_transparency_verifier()->SetObserver(
ct_tree_tracker_.get());
network_service_->sth_reporter()->RegisterObserver(ct_tree_tracker_.get());
}
network_service_->RegisterNetworkContext(this);
cookie_manager_ =
std::make_unique<CookieManager>(url_request_context_->cookie_store());
socket_factory_ = std::make_unique<SocketFactory>(network_service_->net_log(),
url_request_context_);
resource_scheduler_ =
std::make_unique<ResourceScheduler>(enable_resource_scheduler_);
}
NetworkContext::NetworkContext(NetworkService* network_service,
mojom::NetworkContextRequest request,
net::URLRequestContext* url_request_context)
: network_service_(network_service),
url_request_context_(url_request_context),
binding_(this, std::move(request)),
cookie_manager_(
std::make_unique<CookieManager>(url_request_context->cookie_store())),
socket_factory_(std::make_unique<SocketFactory>(
network_service_ ? network_service_->net_log() : nullptr,
url_request_context)) {
// May be nullptr in tests.
if (network_service_)
network_service_->RegisterNetworkContext(this);
resource_scheduler_ =
std::make_unique<ResourceScheduler>(enable_resource_scheduler_);
}
NetworkContext::~NetworkContext() {
// May be nullptr in tests.
if (network_service_)
network_service_->DeregisterNetworkContext(this);
if (url_request_context_ &&
url_request_context_->transport_security_state()) {
url_request_context_->transport_security_state()->SetRequireCTDelegate(
nullptr);
}
if (url_request_context_ &&
url_request_context_->cert_transparency_verifier()) {
url_request_context_->cert_transparency_verifier()->SetObserver(nullptr);
}
if (network_service_ && network_service_->sth_reporter() &&
ct_tree_tracker_) {
network_service_->sth_reporter()->UnregisterObserver(
ct_tree_tracker_.get());
}
}
std::unique_ptr<NetworkContext> NetworkContext::CreateForTesting() {
return base::WrapUnique(
new NetworkContext(mojom::NetworkContextParams::New()));
}
void NetworkContext::SetCertVerifierForTesting(
net::CertVerifier* cert_verifier) {
g_cert_verifier_for_testing = cert_verifier;
}
void NetworkContext::CreateURLLoaderFactory(
mojom::URLLoaderFactoryRequest request,
uint32_t process_id,
scoped_refptr<ResourceSchedulerClient> resource_scheduler_client) {
url_loader_factories_.emplace(std::make_unique<URLLoaderFactory>(
this, process_id, std::move(resource_scheduler_client),
std::move(request)));
}
void NetworkContext::CreateURLLoaderFactory(
mojom::URLLoaderFactoryRequest request,
uint32_t process_id) {
scoped_refptr<ResourceSchedulerClient> resource_scheduler_client;
if (process_id != 0) {
// Zero process ID means it's from the browser process and we don't want
// to throttle the requests.
resource_scheduler_client = base::MakeRefCounted<ResourceSchedulerClient>(
process_id, ++current_resource_scheduler_client_id_,
resource_scheduler_.get(),
url_request_context_->network_quality_estimator());
}
CreateURLLoaderFactory(std::move(request), process_id,
std::move(resource_scheduler_client));
}
void NetworkContext::GetCookieManager(mojom::CookieManagerRequest request) {
cookie_manager_->AddRequest(std::move(request));
}
void NetworkContext::GetRestrictedCookieManager(
mojom::RestrictedCookieManagerRequest request,
int32_t render_process_id,
int32_t render_frame_id) {
// TODO(crbug.com/729800): RestrictedCookieManager should own its bindings
// and NetworkContext should own the RestrictedCookieManager
// instances.
mojo::MakeStrongBinding(std::make_unique<RestrictedCookieManager>(
url_request_context_->cookie_store(),
render_process_id, render_frame_id),
std::move(request));
}
void NetworkContext::DisableQuic() {
url_request_context_->http_transaction_factory()->GetSession()->DisableQuic();
}
void NetworkContext::Cleanup() {
// The NetworkService is going away, so have to destroy the
// net::URLRequestContext held by this NetworkContext.
delete this;
}
NetworkContext::NetworkContext(mojom::NetworkContextParamsPtr params)
: network_service_(nullptr), params_(std::move(params)), binding_(this) {
url_request_context_owner_ = MakeURLRequestContext(params_.get());
url_request_context_ = url_request_context_owner_.url_request_context.get();
resource_scheduler_ =
std::make_unique<ResourceScheduler>(enable_resource_scheduler_);
}
void NetworkContext::OnConnectionError() {
// Don't delete |this| in response to connection errors when it was created by
// CreateForTesting.
if (network_service_)
delete this;
}
URLRequestContextOwner NetworkContext::MakeURLRequestContext(
mojom::NetworkContextParams* network_context_params) {
URLRequestContextBuilderMojo builder;
const base::CommandLine* command_line =
base::CommandLine::ForCurrentProcess();
// The cookie configuration is in this method, which is only used by the
// network process, and not ApplyContextParamsToBuilder which is used by the
// browser as well. This is because this code path doesn't handle encryption
// and other configuration done in QuotaPolicyCookieStore yet (and we still
// have to figure out which of the latter needs to move to the network
// process). TODO: http://crbug.com/789644
if (network_context_params->cookie_path) {
net::CookieCryptoDelegate* crypto_delegate = nullptr;
scoped_refptr<base::SequencedTaskRunner> client_task_runner =
base::MessageLoopCurrent::Get()->task_runner();
scoped_refptr<base::SequencedTaskRunner> background_task_runner =
base::CreateSequencedTaskRunnerWithTraits(
{base::MayBlock(), base::TaskPriority::BACKGROUND,
base::TaskShutdownBehavior::BLOCK_SHUTDOWN});
std::unique_ptr<net::ChannelIDService> channel_id_service;
if (network_context_params->channel_id_path) {
scoped_refptr<net::SQLiteChannelIDStore> channel_id_db =
new net::SQLiteChannelIDStore(
network_context_params->channel_id_path.value(),
background_task_runner);
channel_id_service = std::make_unique<net::ChannelIDService>(
new net::DefaultChannelIDStore(channel_id_db.get()));
}
scoped_refptr<net::SQLitePersistentCookieStore> sqlite_store(
new net::SQLitePersistentCookieStore(
network_context_params->cookie_path.value(), client_task_runner,
background_task_runner,
network_context_params->restore_old_session_cookies,
crypto_delegate));
std::unique_ptr<net::CookieMonster> cookie_store =
std::make_unique<net::CookieMonster>(sqlite_store.get(),
channel_id_service.get());
if (network_context_params->persist_session_cookies)
cookie_store->SetPersistSessionCookies(true);
if (channel_id_service) {
cookie_store->SetChannelIDServiceID(channel_id_service->GetUniqueID());
}
builder.SetCookieAndChannelIdStores(std::move(cookie_store),
std::move(channel_id_service));
} else {
DCHECK(!network_context_params->restore_old_session_cookies);
DCHECK(!network_context_params->persist_session_cookies);
}
std::vector<std::string> supported_schemes(std::begin(kDefaultAuthSchemes),
std::end(kDefaultAuthSchemes));
http_auth_preferences_ = std::make_unique<net::HttpAuthPreferences>(
supported_schemes
#if defined(OS_CHROMEOS)
,
network_context_params->allow_gssapi_library_load
#elif defined(OS_POSIX) && !defined(OS_ANDROID)
,
network_context_params->gssapi_library_name
#endif
);
std::unique_ptr<net::HttpAuthHandlerFactory> http_auth_handler_factory =
net::HttpAuthHandlerRegistryFactory::Create(
http_auth_preferences_.get(), network_service_->host_resolver());
builder.set_shared_host_resolver(network_service_->host_resolver());
builder.SetHttpAuthHandlerFactory(std::move(http_auth_handler_factory));
if (g_cert_verifier_for_testing) {
builder.SetCertVerifier(std::make_unique<WrappedTestingCertVerifier>());
} else {
std::unique_ptr<net::CertVerifier> cert_verifier =
net::CertVerifier::CreateDefault();
builder.SetCertVerifier(IgnoreErrorsCertVerifier::MaybeWrapCertVerifier(
*command_line, nullptr, std::move(cert_verifier)));
}
// |network_service_| may be nullptr in tests.
auto result = ApplyContextParamsToBuilder(
&builder, network_context_params,
network_service_ ? network_service_->quic_disabled() : false,
network_service_ ? network_service_->net_log() : nullptr,
network_service_ ? network_service_->network_quality_estimator()
: nullptr,
network_service_ ? network_service_->sth_reporter() : nullptr,
&ct_tree_tracker_, &user_agent_settings_);
if (ct_tree_tracker_ && network_service_ &&
network_service_->sth_reporter()) {
result.url_request_context->cert_transparency_verifier()->SetObserver(
ct_tree_tracker_.get());
network_service_->sth_reporter()->RegisterObserver(ct_tree_tracker_.get());
}
return result;
}
URLRequestContextOwner NetworkContext::ApplyContextParamsToBuilder(
URLRequestContextBuilderMojo* builder,
mojom::NetworkContextParams* network_context_params,
bool quic_disabled,
net::NetLog* net_log,
net::NetworkQualityEstimator* network_quality_estimator,
certificate_transparency::STHReporter* sth_reporter,
std::unique_ptr<certificate_transparency::TreeStateTracker>*
out_ct_tree_tracker,
net::StaticHttpUserAgentSettings** out_http_user_agent_settings) {
if (net_log)
builder->set_net_log(net_log);
if (network_quality_estimator)
builder->set_network_quality_estimator(network_quality_estimator);
std::string accept_language = network_context_params->accept_language
? *network_context_params->accept_language
: "en-us,en";
std::unique_ptr<net::StaticHttpUserAgentSettings> user_agent_settings =
std::make_unique<net::StaticHttpUserAgentSettings>(
accept_language, network_context_params->user_agent);
// Borrow an alias for future use before giving the builder ownership.
if (out_http_user_agent_settings)
*out_http_user_agent_settings = user_agent_settings.get();
builder->set_http_user_agent_settings(std::move(user_agent_settings));
builder->set_enable_brotli(network_context_params->enable_brotli);
if (network_context_params->context_name)
builder->set_name(*network_context_params->context_name);
if (network_context_params->proxy_resolver_factory) {
builder->SetMojoProxyResolverFactory(
proxy_resolver::mojom::ProxyResolverFactoryPtr(
std::move(network_context_params->proxy_resolver_factory)));
}
if (!network_context_params->http_cache_enabled) {
builder->DisableHttpCache();
} else {
net::URLRequestContextBuilder::HttpCacheParams cache_params;
cache_params.max_size = network_context_params->http_cache_max_size;
if (!network_context_params->http_cache_path) {
cache_params.type =
net::URLRequestContextBuilder::HttpCacheParams::IN_MEMORY;
} else {
cache_params.path = *network_context_params->http_cache_path;
cache_params.type = network_session_configurator::ChooseCacheType(
*base::CommandLine::ForCurrentProcess());
}
builder->EnableHttpCache(cache_params);
}
if (!network_context_params->initial_proxy_config &&
!network_context_params->proxy_config_client_request.is_pending()) {
network_context_params->initial_proxy_config =
net::ProxyConfigWithAnnotation::CreateDirect();
}
builder->set_proxy_config_service(std::make_unique<ProxyConfigServiceMojo>(
std::move(network_context_params->proxy_config_client_request),
std::move(network_context_params->initial_proxy_config),
std::move(network_context_params->proxy_config_poller_client)));
builder->set_pac_quick_check_enabled(
network_context_params->pac_quick_check_enabled);
builder->set_pac_sanitize_url_policy(
network_context_params->dangerously_allow_pac_access_to_secure_urls
? net::ProxyResolutionService::SanitizeUrlPolicy::UNSAFE
: net::ProxyResolutionService::SanitizeUrlPolicy::SAFE);
std::unique_ptr<PrefService> pref_service;
if (network_context_params->http_server_properties_path) {
scoped_refptr<JsonPrefStore> json_pref_store(new JsonPrefStore(
*network_context_params->http_server_properties_path,
base::CreateSequencedTaskRunnerWithTraits(
{base::MayBlock(), base::TaskShutdownBehavior::BLOCK_SHUTDOWN,
base::TaskPriority::BACKGROUND})));
PrefServiceFactory pref_service_factory;
pref_service_factory.set_user_prefs(json_pref_store);
pref_service_factory.set_async(true);
scoped_refptr<PrefRegistrySimple> pref_registry(new PrefRegistrySimple());
HttpServerPropertiesPrefDelegate::RegisterPrefs(pref_registry.get());
pref_service = pref_service_factory.Create(pref_registry.get());
builder->SetHttpServerProperties(
std::make_unique<net::HttpServerPropertiesManager>(
std::make_unique<HttpServerPropertiesPrefDelegate>(
pref_service.get()),
net_log));
}
if (network_context_params->transport_security_persister_path) {
builder->set_transport_security_persister_path(
*network_context_params->transport_security_persister_path);
}
builder->set_data_enabled(network_context_params->enable_data_url_support);
#if !BUILDFLAG(DISABLE_FILE_SUPPORT)
builder->set_file_enabled(network_context_params->enable_file_url_support);
#else // BUILDFLAG(DISABLE_FILE_SUPPORT)
DCHECK(!network_context_params->enable_file_url_support);
#endif
#if !BUILDFLAG(DISABLE_FTP_SUPPORT)
builder->set_ftp_enabled(network_context_params->enable_ftp_url_support);
#else // BUILDFLAG(DISABLE_FTP_SUPPORT)
DCHECK(!network_context_params->enable_ftp_url_support);
#endif
#if BUILDFLAG(ENABLE_REPORTING)
if (base::FeatureList::IsEnabled(features::kReporting))
builder->set_reporting_policy(std::make_unique<net::ReportingPolicy>());
else
builder->set_reporting_policy(nullptr);
builder->set_network_error_logging_enabled(
base::FeatureList::IsEnabled(features::kNetworkErrorLogging));
#endif // BUILDFLAG(ENABLE_REPORTING)
if (network_context_params->enforce_chrome_ct_policy) {
builder->set_ct_policy_enforcer(
std::make_unique<certificate_transparency::ChromeCTPolicyEnforcer>());
}
net::HttpNetworkSession::Params session_params;
bool is_quic_force_disabled = false;
if (quic_disabled)
is_quic_force_disabled = true;
network_session_configurator::ParseCommandLineAndFieldTrials(
*base::CommandLine::ForCurrentProcess(), is_quic_force_disabled,
network_context_params->quic_user_agent_id, &session_params);
session_params.http_09_on_non_default_ports_enabled =
network_context_params->http_09_on_non_default_ports_enabled;
builder->set_http_network_session_params(session_params);
builder->SetCreateHttpTransactionFactoryCallback(
base::BindOnce([](net::HttpNetworkSession* session)
-> std::unique_ptr<net::HttpTransactionFactory> {
return std::make_unique<ThrottlingNetworkTransactionFactory>(session);
}));
std::vector<scoped_refptr<const net::CTLogVerifier>> ct_logs;
if (!network_context_params->ct_logs.empty()) {
for (const auto& log : network_context_params->ct_logs) {
scoped_refptr<const net::CTLogVerifier> log_verifier =
net::CTLogVerifier::Create(log->public_key, log->name,
log->dns_api_endpoint);
if (!log_verifier) {
// TODO: Signal bad configuration (such as bad key).
continue;
}
ct_logs.push_back(std::move(log_verifier));
}
auto ct_verifier = std::make_unique<net::MultiLogCTVerifier>();
ct_verifier->AddLogs(ct_logs);
builder->set_ct_verifier(std::move(ct_verifier));
}
auto result =
URLRequestContextOwner(std::move(pref_service), builder->Build());
#if !defined(OS_IOS)
if (base::FeatureList::IsEnabled(certificate_transparency::kCTLogAuditing) &&
out_ct_tree_tracker && sth_reporter && !ct_logs.empty()) {
net::URLRequestContext* context = result.url_request_context.get();
*out_ct_tree_tracker =
std::make_unique<certificate_transparency::TreeStateTracker>(
ct_logs, context->host_resolver(), net_log);
}
#endif
return result;
}
void NetworkContext::DestroyURLLoaderFactory(
URLLoaderFactory* url_loader_factory) {
auto it = url_loader_factories_.find(url_loader_factory);
DCHECK(it != url_loader_factories_.end());
url_loader_factories_.erase(it);
}
void NetworkContext::ClearNetworkingHistorySince(
base::Time time,
base::OnceClosure completion_callback) {
// TODO(mmenke): Neither of these methods waits until the changes have been
// commited to disk. They probably should, as most similar methods net/
// exposes do.
// Completes synchronously.
url_request_context_->transport_security_state()->DeleteAllDynamicDataSince(
time);
url_request_context_->http_server_properties()->Clear(
std::move(completion_callback));
}
void NetworkContext::ClearHttpCache(base::Time start_time,
base::Time end_time,
mojom::ClearDataFilterPtr filter,
ClearHttpCacheCallback callback) {
// It's safe to use Unretained below as the HttpCacheDataRemover is owner by
// |this| and guarantees it won't call its callback if deleted.
http_cache_data_removers_.push_back(HttpCacheDataRemover::CreateAndStart(
url_request_context_, std::move(filter), start_time, end_time,
base::BindOnce(&NetworkContext::OnHttpCacheCleared,
base::Unretained(this), std::move(callback))));
}
void NetworkContext::OnHttpCacheCleared(ClearHttpCacheCallback callback,
HttpCacheDataRemover* remover) {
bool removed = false;
for (auto iter = http_cache_data_removers_.begin();
iter != http_cache_data_removers_.end(); ++iter) {
if (iter->get() == remover) {
removed = true;
http_cache_data_removers_.erase(iter);
break;
}
}
DCHECK(removed);
std::move(callback).Run();
}
void NetworkContext::ClearChannelIds(base::Time start_time,
base::Time end_time,
mojom::ClearDataFilterPtr filter,
ClearChannelIdsCallback callback) {
base::RepeatingCallback<bool(const std::string& channel_id_server_id)>
filter_predicate;
if (filter) {
DCHECK(filter->origins.empty())
<< "Origin filtering not allowed in a ClearChannelIds request as "
"channel IDs are only keyed by domain.";
std::set<std::string> filter_domains;
filter_domains.insert(filter->domains.begin(), filter->domains.end());
filter_predicate = base::BindRepeating(
&MatchesClearChannelIdFilter, filter->type, std::move(filter_domains));
} else {
filter_predicate =
base::BindRepeating([](const std::string&) { return true; });
}
url_request_context_->channel_id_service()
->GetChannelIDStore()
->DeleteForDomainsCreatedBetween(
std::move(filter_predicate), start_time, end_time,
base::BindOnce(
&OnClearedChannelIds,
base::RetainedRef(url_request_context_->ssl_config_service()),
std::move(callback)));
}
void NetworkContext::ClearHttpAuthCache(base::Time start_time,
ClearHttpAuthCacheCallback callback) {
net::HttpNetworkSession* http_session =
url_request_context_->http_transaction_factory()->GetSession();
DCHECK(http_session);
http_session->http_auth_cache()->ClearEntriesAddedSince(start_time);
http_session->CloseAllConnections();
std::move(callback).Run();
}
#if BUILDFLAG(ENABLE_REPORTING)
void NetworkContext::ClearReportingCacheReports(
mojom::ClearDataFilterPtr filter,
ClearReportingCacheReportsCallback callback) {
net::ReportingService* reporting_service =
url_request_context_->reporting_service();
if (reporting_service) {
if (filter) {
reporting_service->RemoveBrowsingData(
net::ReportingBrowsingDataRemover::DATA_TYPE_REPORTS,
BuildUrlFilter(std::move(filter)));
} else {
reporting_service->RemoveAllBrowsingData(
net::ReportingBrowsingDataRemover::DATA_TYPE_REPORTS);
}
}
std::move(callback).Run();
}
void NetworkContext::ClearReportingCacheClients(
mojom::ClearDataFilterPtr filter,
ClearReportingCacheClientsCallback callback) {
net::ReportingService* reporting_service =
url_request_context_->reporting_service();
if (reporting_service) {
if (filter) {
reporting_service->RemoveBrowsingData(
net::ReportingBrowsingDataRemover::DATA_TYPE_CLIENTS,
BuildUrlFilter(std::move(filter)));
} else {
reporting_service->RemoveAllBrowsingData(
net::ReportingBrowsingDataRemover::DATA_TYPE_CLIENTS);
}
}
std::move(callback).Run();
}
void NetworkContext::ClearNetworkErrorLogging(
mojom::ClearDataFilterPtr filter,
ClearNetworkErrorLoggingCallback callback) {
net::NetworkErrorLoggingService* logging_service =
url_request_context_->network_error_logging_service();
if (logging_service) {
if (filter) {
logging_service->RemoveBrowsingData(BuildUrlFilter(std::move(filter)));
} else {
logging_service->RemoveAllBrowsingData();
}
}
std::move(callback).Run();
}
#else // BUILDFLAG(ENABLE_REPORTING)
void NetworkContext::ClearReportingCacheReports(
mojom::ClearDataFilterPtr filter,
ClearReportingCacheReportsCallback callback) {
NOTREACHED();
}
void NetworkContext::ClearReportingCacheClients(
mojom::ClearDataFilterPtr filter,
ClearReportingCacheClientsCallback callback) {
NOTREACHED();
}
void NetworkContext::ClearNetworkErrorLogging(
mojom::ClearDataFilterPtr filter,
ClearNetworkErrorLoggingCallback callback) {
NOTREACHED();
}
#endif // BUILDFLAG(ENABLE_REPORTING)
void NetworkContext::SetNetworkConditions(
const std::string& profile_id,
mojom::NetworkConditionsPtr conditions) {
std::unique_ptr<NetworkConditions> network_conditions;
if (conditions) {
network_conditions.reset(new NetworkConditions(
conditions->offline, conditions->latency.InMillisecondsF(),
conditions->download_throughput, conditions->upload_throughput));
}
ThrottlingController::SetConditions(profile_id,
std::move(network_conditions));
}
void NetworkContext::SetAcceptLanguage(const std::string& new_accept_language) {
// This may only be called on NetworkContexts created with a constructor that
// calls ApplyContextParamsToBuilder.
DCHECK(user_agent_settings_);
user_agent_settings_->set_accept_language(new_accept_language);
}
void NetworkContext::SetCTPolicy(
const std::vector<std::string>& required_hosts,
const std::vector<std::string>& excluded_hosts,
const std::vector<std::string>& excluded_spkis,
const std::vector<std::string>& excluded_legacy_spkis) {
if (!ct_policy_manager_) {
ct_policy_manager_.reset(new certificate_transparency::CTPolicyManager());
url_request_context_->transport_security_state()->SetRequireCTDelegate(
ct_policy_manager_->GetDelegate());
}
ct_policy_manager_->UpdateCTPolicies(required_hosts, excluded_hosts,
excluded_spkis, excluded_legacy_spkis);
}
void NetworkContext::CreateUDPSocket(mojom::UDPSocketRequest request,
mojom::UDPSocketReceiverPtr receiver) {
socket_factory_->CreateUDPSocket(std::move(request), std::move(receiver));
}
void NetworkContext::CreateTCPServerSocket(
const net::IPEndPoint& local_addr,
uint32_t backlog,
const net::MutableNetworkTrafficAnnotationTag& traffic_annotation,
mojom::TCPServerSocketRequest request,
CreateTCPServerSocketCallback callback) {
socket_factory_->CreateTCPServerSocket(
local_addr, backlog,
static_cast<net::NetworkTrafficAnnotationTag>(traffic_annotation),
std::move(request), std::move(callback));
}
void NetworkContext::CreateTCPConnectedSocket(
const base::Optional<net::IPEndPoint>& local_addr,
const net::AddressList& remote_addr_list,
const net::MutableNetworkTrafficAnnotationTag& traffic_annotation,
mojom::TCPConnectedSocketRequest request,
mojom::SocketObserverPtr observer,
CreateTCPConnectedSocketCallback callback) {
socket_factory_->CreateTCPConnectedSocket(
local_addr, remote_addr_list,
static_cast<net::NetworkTrafficAnnotationTag>(traffic_annotation),
std::move(request), std::move(observer), std::move(callback));
}
void NetworkContext::CreateWebSocket(mojom::WebSocketRequest request,
int32_t process_id,
int32_t render_frame_id,
const url::Origin& origin) {
#if !defined(OS_IOS)
if (!websocket_factory_)
websocket_factory_ = std::make_unique<WebSocketFactory>(this);
websocket_factory_->CreateWebSocket(std::move(request), process_id,
render_frame_id, origin);
#endif // !defined(OS_IOS)
}
void NetworkContext::CreateNetLogExporter(
mojom::NetLogExporterRequest request) {
net_log_exporter_bindings_.AddBinding(std::make_unique<NetLogExporter>(this),
std::move(request));
}
void NetworkContext::AddHSTSForTesting(const std::string& host,
base::Time expiry,
bool include_subdomains,
AddHSTSForTestingCallback callback) {
net::TransportSecurityState* state =
url_request_context_->transport_security_state();
state->AddHSTS(host, expiry, include_subdomains);
std::move(callback).Run();
}
void NetworkContext::SetFailingHttpTransactionForTesting(
int32_t error_code,
SetFailingHttpTransactionForTestingCallback callback) {
net::HttpCache* cache(
url_request_context_->http_transaction_factory()->GetCache());
DCHECK(cache);
auto factory = std::make_unique<net::FailingHttpTransactionFactory>(
cache->GetSession(), static_cast<net::Error>(error_code));
// Throw away old version; since this is a a browser test, we don't
// need to restore the old state.
cache->SetHttpNetworkTransactionFactoryForTesting(std::move(factory));
std::move(callback).Run();
}
} // namespace network