blob: 5de3140cd43d361c0e4d739adc5f1fe082a84740 [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 "chrome/browser/net/profile_network_context_service.h"
#include <string>
#include "base/bind.h"
#include "base/feature_list.h"
#include "base/files/file_path.h"
#include "base/logging.h"
#include "build/build_config.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/net/chrome_accept_language_settings.h"
#include "chrome/browser/net/default_network_context_params.h"
#include "chrome/browser/net/system_network_context_manager.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_content_client.h"
#include "chrome/common/chrome_paths_internal.h"
#include "chrome/common/pref_names.h"
#include "components/network_session_configurator/common/network_features.h"
#include "components/pref_registry/pref_registry_syncable.h"
#include "components/prefs/pref_service.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/browser_thread.h"
#include "content/public/browser/network_service_instance.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/common/service_names.mojom.h"
#include "mojo/public/cpp/bindings/associated_interface_ptr.h"
#include "net/net_buildflags.h"
#include "services/network/public/cpp/features.h"
#if defined(OS_CHROMEOS)
#include "chrome/browser/chromeos/policy/browser_policy_connector_chromeos.h"
#endif
ProfileNetworkContextService::ProfileNetworkContextService(Profile* profile)
: profile_(profile), proxy_config_monitor_(profile) {
quic_allowed_.Init(
prefs::kQuicAllowed, profile->GetPrefs(),
base::Bind(&ProfileNetworkContextService::DisableQuicIfNotAllowed,
base::Unretained(this)));
pref_accept_language_.Init(
prefs::kAcceptLanguages, profile->GetPrefs(),
base::BindRepeating(&ProfileNetworkContextService::UpdateAcceptLanguage,
base::Unretained(this)));
// The system context must be initialized before any other network contexts.
// TODO(mmenke): Figure out a way to enforce this.
g_browser_process->system_network_context_manager()->GetContext();
DisableQuicIfNotAllowed();
}
ProfileNetworkContextService::~ProfileNetworkContextService() {}
network::mojom::NetworkContextPtr
ProfileNetworkContextService::CreateMainNetworkContext() {
if (!base::FeatureList::IsEnabled(network::features::kNetworkService)) {
// |profile_io_data_main_network_context_| may be initialized if
// SetUpProfileIOdataMainContext was called first.
if (!profile_io_data_main_network_context_) {
profile_io_data_context_request_ =
mojo::MakeRequest(&profile_io_data_main_network_context_);
}
return std::move(profile_io_data_main_network_context_);
}
network::mojom::NetworkContextPtr network_context;
content::GetNetworkService()->CreateNetworkContext(
MakeRequest(&network_context), CreateMainNetworkContextParams());
return network_context;
}
network::mojom::NetworkContextPtr
ProfileNetworkContextService::CreateNetworkContextForPartition(
bool in_memory,
const base::FilePath& relative_partition_path) {
DCHECK(base::FeatureList::IsEnabled(network::features::kNetworkService));
network::mojom::NetworkContextPtr network_context;
content::GetNetworkService()->CreateNetworkContext(
MakeRequest(&network_context),
CreateNetworkContextParams(in_memory, relative_partition_path));
return network_context;
}
void ProfileNetworkContextService::SetUpProfileIODataMainContext(
network::mojom::NetworkContextRequest* network_context_request,
network::mojom::NetworkContextParamsPtr* network_context_params) {
DCHECK(network_context_request);
DCHECK(network_context_params);
// This may be called either before or after CreateMainNetworkContext().
if (!profile_io_data_context_request_.is_pending()) {
*network_context_request =
mojo::MakeRequest(&profile_io_data_main_network_context_);
} else {
*network_context_request = std::move(profile_io_data_context_request_);
}
if (!base::FeatureList::IsEnabled(network::features::kNetworkService)) {
*network_context_params = CreateMainNetworkContextParams();
return;
}
// Just use default if network service is enabled, to avoid the legacy
// in-process URLRequestContext from fighting with the NetworkService over
// ownership of on-disk files.
*network_context_params = network::mojom::NetworkContextParams::New();
}
void ProfileNetworkContextService::RegisterProfilePrefs(
user_prefs::PrefRegistrySyncable* registry) {
registry->RegisterBooleanPref(prefs::kQuicAllowed, true);
}
void ProfileNetworkContextService::DisableQuicIfNotAllowed() {
if (!quic_allowed_.IsManaged())
return;
// If QUIC is allowed, do nothing (re-enabling QUIC is not supported).
if (quic_allowed_.GetValue())
return;
g_browser_process->system_network_context_manager()->DisableQuic();
}
void ProfileNetworkContextService::UpdateAcceptLanguage() {
content::BrowserContext::GetDefaultStoragePartition(profile_)
->GetNetworkContext()
->SetAcceptLanguage(ComputeAcceptLanguage());
}
std::string ProfileNetworkContextService::ComputeAcceptLanguage() const {
return chrome_accept_language_settings::ComputeAcceptLanguageFromPref(
pref_accept_language_.GetValue());
}
void ProfileNetworkContextService::FlushProxyConfigMonitorForTesting() {
proxy_config_monitor_.FlushForTesting();
}
network::mojom::NetworkContextParamsPtr
ProfileNetworkContextService::CreateMainNetworkContextParams() {
return CreateNetworkContextParams(profile_->IsOffTheRecord(),
base::FilePath());
}
network::mojom::NetworkContextParamsPtr
ProfileNetworkContextService::CreateNetworkContextParams(
bool in_memory,
const base::FilePath& relative_partition_path) {
// TODO(mmenke): Set up parameters here.
network::mojom::NetworkContextParamsPtr network_context_params =
CreateDefaultNetworkContextParams();
network_context_params->context_name = std::string("main");
network_context_params->accept_language = ComputeAcceptLanguage();
// Always enable the HTTP cache.
network_context_params->http_cache_enabled = true;
base::FilePath path = profile_->GetPath();
if (!relative_partition_path.empty())
path = path.Append(relative_partition_path);
// Configure on-disk storage for non-OTR profiles. OTR profiles just use
// default behavior (in memory storage, default sizes).
PrefService* prefs = profile_->GetPrefs();
if (!in_memory) {
// Configure the HTTP cache path and size.
base::FilePath base_cache_path;
chrome::GetUserCacheDirectory(path, &base_cache_path);
base::FilePath disk_cache_dir = prefs->GetFilePath(prefs::kDiskCacheDir);
if (!disk_cache_dir.empty())
base_cache_path = disk_cache_dir.Append(base_cache_path.BaseName());
network_context_params->http_cache_path =
base_cache_path.Append(chrome::kCacheDirname);
network_context_params->http_cache_max_size =
prefs->GetInteger(prefs::kDiskCacheSize);
// Currently this just contains HttpServerProperties, but that will likely
// change.
network_context_params->http_server_properties_path =
path.Append(chrome::kNetworkPersistentStateFilename);
base::FilePath cookie_path = path;
cookie_path = cookie_path.Append(chrome::kCookieFilename);
network_context_params->cookie_path = cookie_path;
// The same ChannelID store is used for both Channel ID and Token Binding,
// so if either are enabled the path must be set. If neither is enabled, the
// path must not be set.
if (base::FeatureList::IsEnabled(features::kTokenBinding) ||
base::FeatureList::IsEnabled(features::kChannelID)) {
base::FilePath channel_id_path = path;
channel_id_path = channel_id_path.Append(chrome::kChannelIDFilename);
network_context_params->channel_id_path = channel_id_path;
}
if (relative_partition_path.empty()) {
network_context_params->restore_old_session_cookies =
profile_->ShouldRestoreOldSessionCookies();
network_context_params->persist_session_cookies =
profile_->ShouldPersistSessionCookies();
} else {
// Copy behavior of ProfileImplIOData::InitializeAppRequestContext.
network_context_params->restore_old_session_cookies = false;
network_context_params->persist_session_cookies = false;
}
}
// NOTE(mmenke): Keep these protocol handlers and
// ProfileIOData::SetUpJobFactoryDefaultsForBuilder in sync with
// ProfileIOData::IsHandledProtocol().
// TODO(mmenke): Find a better way of handling tracking supported schemes.
network_context_params->enable_data_url_support = true;
network_context_params->enable_file_url_support = true;
#if !BUILDFLAG(DISABLE_FTP_SUPPORT)
network_context_params->enable_ftp_url_support = true;
#endif // !BUILDFLAG(DISABLE_FTP_SUPPORT)
proxy_config_monitor_.AddToNetworkContextParams(network_context_params.get());
#if defined(OS_POSIX) && !defined(OS_ANDROID) && !defined(OS_CHROMEOS)
if (prefs->FindPreference(prefs::kGSSAPILibraryName)) {
network_context_params->gssapi_library_name =
prefs->GetString(prefs::kGSSAPILibraryName);
}
#endif
#if defined(OS_CHROMEOS)
policy::BrowserPolicyConnectorChromeOS* connector =
g_browser_process->platform_part()->browser_policy_connector_chromeos();
network_context_params->allow_gssapi_library_load =
connector->IsActiveDirectoryManaged();
#endif
return network_context_params;
}