blob: 7c29b3190a8ca3461089e9c74e1e44c567a3ba87 [file] [log] [blame]
// Copyright 2017 The Chromium Authors
// 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 <algorithm>
#include <memory>
#include <optional>
#include <string>
#include <string_view>
#include <vector>
#include "base/check_op.h"
#include "base/containers/contains.h"
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/functional/bind.h"
#include "base/memory/raw_ptr.h"
#include "base/memory/scoped_refptr.h"
#include "base/strings/string_number_conversions.h"
#include "base/strings/string_split.h"
#include "base/strings/utf_string_conversions.h"
#include "base/task/thread_pool/thread_pool_instance.h"
#include "base/test/metrics/histogram_tester.h"
#include "base/test/scoped_feature_list.h"
#include "base/threading/platform_thread.h" // For |Sleep()|.
#include "base/threading/thread_restrictions.h"
#include "build/build_config.h"
#include "build/chromeos_buildflags.h"
#include "chrome/browser/browser_process.h"
#include "chrome/browser/content_settings/host_content_settings_map_factory.h"
#include "chrome/browser/net/profile_network_context_service_factory.h"
#include "chrome/browser/net/profile_network_context_service_test_utils.h"
#include "chrome/browser/net/system_network_context_manager.h"
#include "chrome/browser/policy/policy_test_utils.h"
#include "chrome/browser/privacy_sandbox/privacy_sandbox_settings_factory.h"
#include "chrome/browser/profiles/profile.h"
#include "chrome/browser/ui/browser.h"
#include "chrome/browser/ui/browser_commands.h"
#include "chrome/common/chrome_constants.h"
#include "chrome/common/chrome_features.h"
#include "chrome/common/chrome_paths_internal.h"
#include "chrome/common/chrome_switches.h"
#include "chrome/common/pref_names.h"
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "components/content_settings/core/browser/cookie_settings.h"
#include "components/content_settings/core/browser/host_content_settings_map.h"
#include "components/content_settings/core/common/content_settings.h"
#include "components/content_settings/core/common/content_settings_types.h"
#include "components/content_settings/core/common/pref_names.h"
#include "components/metrics/content/subprocess_metrics_provider.h"
#include "components/policy/core/common/policy_map.h"
#include "components/policy/policy_constants.h"
#include "components/prefs/pref_service.h"
#include "components/privacy_sandbox/privacy_sandbox_features.h"
#include "components/privacy_sandbox/privacy_sandbox_settings.h"
#include "components/privacy_sandbox/privacy_sandbox_test_util.h"
#include "components/user_prefs/user_prefs.h"
#include "content/public/browser/network_service_instance.h"
#include "content/public/browser/storage_partition.h"
#include "content/public/common/content_features.h"
#include "content/public/test/browser_test.h"
#include "content/public/test/browser_test_utils.h"
#include "content/public/test/simple_url_loader_test_helper.h"
#include "mojo/public/cpp/bindings/pending_remote.h"
#include "mojo/public/cpp/system/data_pipe_utils.h"
#include "net/base/features.h"
#include "net/base/load_flags.h"
#include "net/disk_cache/buildflags.h"
#include "net/disk_cache/cache_util.h"
#include "net/dns/mock_host_resolver.h"
#include "net/http/http_auth_preferences.h"
#include "net/test/embedded_test_server/embedded_test_server.h"
#include "net/test/embedded_test_server/http_request.h"
#include "net/test/embedded_test_server/http_response.h"
#include "net/test/embedded_test_server/request_handler_util.h"
#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "services/cert_verifier/public/mojom/cert_verifier_service_factory.mojom.h"
#include "services/network/public/cpp/cors/cors.h"
#include "services/network/public/cpp/features.h"
#include "services/network/public/cpp/resource_request.h"
#include "services/network/public/mojom/network_context.mojom.h"
#include "services/network/public/mojom/network_service.mojom.h"
#include "services/network/public/mojom/url_loader_factory.mojom.h"
#include "services/network/test/trust_token_request_handler.h"
#include "services/network/test/trust_token_test_server_handler_registration.h"
#include "services/network/test/trust_token_test_util.h"
#include "testing/gtest/include/gtest/gtest.h"
#if BUILDFLAG(IS_CHROMEOS)
#include "chromeos/constants/chromeos_features.h"
#endif
// Most tests for this class are in NetworkContextConfigurationBrowserTest.
class ProfileNetworkContextServiceBrowsertest : public InProcessBrowserTest {
public:
ProfileNetworkContextServiceBrowsertest() = default;
~ProfileNetworkContextServiceBrowsertest() override = default;
// TODO(crbug.com/40285326): This fails with the field trial testing config.
void SetUpCommandLine(base::CommandLine* command_line) override {
InProcessBrowserTest::SetUpCommandLine(command_line);
command_line->AppendSwitch("disable-field-trial-config");
}
void SetUpOnMainThread() override {
EXPECT_TRUE(embedded_test_server()->Start());
loader_factory_ = browser()
->profile()
->GetDefaultStoragePartition()
->GetURLLoaderFactoryForBrowserProcess()
.get();
}
network::mojom::URLLoaderFactory* loader_factory() const {
return loader_factory_;
}
void CheckDiskCacheSizeHistogramRecorded() {
std::string all_metrics;
do {
content::FetchHistogramsFromChildProcesses();
metrics::SubprocessMetricsProvider::MergeHistogramDeltasForTesting();
base::PlatformThread::Sleep(base::Milliseconds(5));
all_metrics = histograms_.GetAllHistogramsRecorded();
} while (std::string::npos ==
all_metrics.find("HttpCache.MaxFileSizeOnInit"));
}
base::HistogramTester histograms_;
protected:
// The HttpCache is only created when a request is issued, thus we perform a
// navigation to ensure that the http cache is initialized.
void NavigateToCreateHttpCache() {
ASSERT_TRUE(ui_test_utils::NavigateToURL(
browser(), embedded_test_server()->GetURL("/createbackend")));
}
private:
raw_ptr<network::mojom::URLLoaderFactory> loader_factory_ = nullptr;
};
IN_PROC_BROWSER_TEST_F(ProfileNetworkContextServiceBrowsertest,
DiskCacheLocation) {
// Run a request that caches the response, to give the network service time to
// create a cache directory.
std::unique_ptr<network::ResourceRequest> request =
std::make_unique<network::ResourceRequest>();
request->url = embedded_test_server()->GetURL("/cachetime");
request->credentials_mode = network::mojom::CredentialsMode::kOmit;
content::SimpleURLLoaderTestHelper simple_loader_helper;
std::unique_ptr<network::SimpleURLLoader> simple_loader =
network::SimpleURLLoader::Create(std::move(request),
TRAFFIC_ANNOTATION_FOR_TESTS);
simple_loader->DownloadToStringOfUnboundedSizeUntilCrashAndDie(
loader_factory(), simple_loader_helper.GetCallbackDeprecated());
simple_loader_helper.WaitForCallback();
ASSERT_TRUE(simple_loader_helper.response_body());
base::FilePath expected_cache_path;
chrome::GetUserCacheDirectory(browser()->profile()->GetPath(),
&expected_cache_path);
expected_cache_path = expected_cache_path.Append(chrome::kCacheDirname);
base::ScopedAllowBlockingForTesting allow_blocking;
EXPECT_TRUE(base::PathExists(expected_cache_path));
}
IN_PROC_BROWSER_TEST_F(ProfileNetworkContextServiceBrowsertest,
DefaultCacheSize) {
// We don't have a great way of directly checking that the disk cache has the
// correct max size, but we can make sure that we set up our network context
// params correctly.
ProfileNetworkContextService* profile_network_context_service =
ProfileNetworkContextServiceFactory::GetForContext(browser()->profile());
base::FilePath empty_relative_partition_path;
network::mojom::NetworkContextParams network_context_params;
cert_verifier::mojom::CertVerifierCreationParams
cert_verifier_creation_params;
profile_network_context_service->ConfigureNetworkContextParams(
/*in_memory=*/false, empty_relative_partition_path,
&network_context_params, &cert_verifier_creation_params);
EXPECT_EQ(0, network_context_params.http_cache_max_size);
CheckDiskCacheSizeHistogramRecorded();
}
IN_PROC_BROWSER_TEST_F(ProfileNetworkContextServiceBrowsertest, CacheSize) {
// We don't have a great way of directly checking that the disk cache has the
// correct max size, but we can make sure that we set up our network context
// params correctly and that the histogram is recorded.
ProfileNetworkContextService* profile_network_context_service =
ProfileNetworkContextServiceFactory::GetForContext(browser()->profile());
base::FilePath empty_relative_partition_path;
network::mojom::NetworkContextParams network_context_params;
cert_verifier::mojom::CertVerifierCreationParams
cert_verifier_creation_params;
profile_network_context_service->ConfigureNetworkContextParams(
/*in_memory=*/false, empty_relative_partition_path,
&network_context_params, &cert_verifier_creation_params);
EXPECT_EQ(0, network_context_params.http_cache_max_size);
CheckDiskCacheSizeHistogramRecorded();
}
IN_PROC_BROWSER_TEST_F(ProfileNetworkContextServiceBrowsertest, BrotliEnabled) {
// Brotli is only used over encrypted connections.
net::EmbeddedTestServer https_server(net::EmbeddedTestServer::TYPE_HTTPS);
https_server.AddDefaultHandlers(
base::FilePath(FILE_PATH_LITERAL("content/test/data")));
ASSERT_TRUE(https_server.Start());
std::unique_ptr<network::ResourceRequest> request =
std::make_unique<network::ResourceRequest>();
request->url = https_server.GetURL("/echoheader?accept-encoding");
content::SimpleURLLoaderTestHelper simple_loader_helper;
std::unique_ptr<network::SimpleURLLoader> simple_loader =
network::SimpleURLLoader::Create(std::move(request),
TRAFFIC_ANNOTATION_FOR_TESTS);
simple_loader->DownloadToStringOfUnboundedSizeUntilCrashAndDie(
loader_factory(), simple_loader_helper.GetCallbackDeprecated());
simple_loader_helper.WaitForCallback();
ASSERT_TRUE(simple_loader_helper.response_body());
std::vector<std::string> encodings =
base::SplitString(*simple_loader_helper.response_body(), ",",
base::TRIM_WHITESPACE, base::SPLIT_WANT_NONEMPTY);
EXPECT_TRUE(base::Contains(encodings, "br"));
}
void CheckCacheResetStatus(base::HistogramTester* histograms, bool reset) {
// TODO(crbug.com/40114587): The failure case, here, is to time out. Since
// Chrome doesn't synchronize cache loading, there's no guarantee that this is
// complete and it's merely available at earliest convenience. If shutdown
// occurs prior to the cache being loaded, then nothing is reported. This
// should probably be fixed to avoid the use of the sleep function, but that
// will require synchronizing in some meaningful way to guarantee the cache
// has been loaded prior to testing the histograms.
while (!histograms->GetBucketCount("HttpCache.HardReset", reset)) {
content::FetchHistogramsFromChildProcesses();
metrics::SubprocessMetricsProvider::MergeHistogramDeltasForTesting();
base::PlatformThread::Sleep(base::Milliseconds(5));
}
if (reset) {
// Some tests load the cache multiple times, but should only be reset once.
EXPECT_EQ(histograms->GetBucketCount("HttpCache.HardReset", true), 1);
} else {
// Make sure it's never reset.
EXPECT_EQ(histograms->GetBucketCount("HttpCache.HardReset", true), 0);
}
}
class ProfileNetworkContextServiceCacheSameBrowsertest
: public ProfileNetworkContextServiceBrowsertest {
public:
ProfileNetworkContextServiceCacheSameBrowsertest() {
// Override features that are enabled via the fieldtrial testing config.
split_cache_features_disabled_feature_list_.InitWithFeatures(
{}, {
net::features::kSplitCacheByNetworkIsolationKey,
net::features::kSplitCacheByCrossSiteMainFrameNavigationBoolean,
});
}
~ProfileNetworkContextServiceCacheSameBrowsertest() override = default;
base::HistogramTester histograms_;
private:
base::test::ScopedFeatureList split_cache_features_disabled_feature_list_;
};
IN_PROC_BROWSER_TEST_F(ProfileNetworkContextServiceCacheSameBrowsertest,
PRE_TestCacheResetParameter) {
NavigateToCreateHttpCache();
CheckCacheResetStatus(&histograms_, false);
// At this point, we have already called the initialization.
// Verify that we have the correct values in the local_state.
PrefService* local_state = g_browser_process->local_state();
DCHECK_EQ(
local_state->GetString(
"profile_network_context_service.http_cache_finch_experiment_groups"),
"None None None None");
}
IN_PROC_BROWSER_TEST_F(ProfileNetworkContextServiceCacheSameBrowsertest,
TestCacheResetParameter) {
NavigateToCreateHttpCache();
CheckCacheResetStatus(&histograms_, false);
// At this point, we have already called the initialization.
// Verify that we have the correct values in the local_state.
PrefService* local_state = g_browser_process->local_state();
DCHECK_EQ(
local_state->GetString(
"profile_network_context_service.http_cache_finch_experiment_groups"),
"None None None None");
}
class ProfileNetworkContextServiceCacheChangeBrowsertest
: public ProfileNetworkContextServiceBrowsertest {
public:
ProfileNetworkContextServiceCacheChangeBrowsertest() {
split_cache_always_enabled_feature_list_.InitAndEnableFeatureWithParameters(
net::features::kSplitCacheByNetworkIsolationKey, {});
}
~ProfileNetworkContextServiceCacheChangeBrowsertest() override = default;
base::HistogramTester histograms_;
private:
base::test::ScopedFeatureList split_cache_always_enabled_feature_list_;
};
// The first time we load, even if we're in an experiment there's no reset
// from the unknown state.
IN_PROC_BROWSER_TEST_F(ProfileNetworkContextServiceCacheChangeBrowsertest,
PRE_TestCacheResetParameter) {
NavigateToCreateHttpCache();
CheckCacheResetStatus(&histograms_, false);
// At this point, we have already called the initialization.
// Verify that we have the correct values in the local_state.
PrefService* local_state = g_browser_process->local_state();
DCHECK_EQ(
local_state->GetString(
"profile_network_context_service.http_cache_finch_experiment_groups"),
"scoped_feature_list_trial_group None None None");
// Set the local state for the next test.
local_state->SetString(
"profile_network_context_service.http_cache_finch_experiment_groups",
"None None None None");
}
// The second time we load we know the state, which was "None None None None"
// for the previous test, so we should see a reset being in an experiment.
IN_PROC_BROWSER_TEST_F(ProfileNetworkContextServiceCacheChangeBrowsertest,
TestCacheResetParameter) {
NavigateToCreateHttpCache();
CheckCacheResetStatus(&histograms_, true);
// At this point, we have already called the initialization once.
// Verify that we have the correct values in the local_state.
PrefService* local_state = g_browser_process->local_state();
DCHECK_EQ(
local_state->GetString(
"profile_network_context_service.http_cache_finch_experiment_groups"),
"scoped_feature_list_trial_group None None None");
}
// This subclass adds the "SplitCacheByIncludeCredentials" feature.
class ProfileNetworkContextServiceCacheCredentialsBrowserTest
: public ProfileNetworkContextServiceBrowsertest {
public:
ProfileNetworkContextServiceCacheCredentialsBrowserTest() {
split_cache_always_enabled_feature_list_.InitAndEnableFeatureWithParameters(
net::features::kSplitCacheByIncludeCredentials, {});
}
~ProfileNetworkContextServiceCacheCredentialsBrowserTest() override = default;
base::HistogramTester histograms_;
private:
base::test::ScopedFeatureList split_cache_always_enabled_feature_list_;
};
IN_PROC_BROWSER_TEST_F(ProfileNetworkContextServiceCacheCredentialsBrowserTest,
PRE_TestCacheResetParameter) {
NavigateToCreateHttpCache();
CheckCacheResetStatus(&histograms_, false);
// At this point, we have already called the initialization.
// Verify that we have the correct values in the local_state.
PrefService* local_state = g_browser_process->local_state();
DCHECK_EQ(
local_state->GetString(
"profile_network_context_service.http_cache_finch_experiment_groups"),
"None None None scoped_feature_list_trial_group");
// Set the local state for the next test.
local_state->SetString(
"profile_network_context_service.http_cache_finch_experiment_groups",
"None None None None");
}
// The second time we load we know the state, which was "None None None None"
// for the previous test, so we should see a reset being in an experiment.
IN_PROC_BROWSER_TEST_F(ProfileNetworkContextServiceCacheCredentialsBrowserTest,
TestCacheResetParameter) {
NavigateToCreateHttpCache();
CheckCacheResetStatus(&histograms_, true);
// At this point, we have already called the initialization once.
// Verify that we have the correct values in the local_state.
PrefService* local_state = g_browser_process->local_state();
DCHECK_EQ(
local_state->GetString(
"profile_network_context_service.http_cache_finch_experiment_groups"),
"None None None scoped_feature_list_trial_group");
}
class ProfileNetworkContextServiceDiskCacheBackendExperimentBrowserTest
: public ProfileNetworkContextServiceBrowsertest,
public ::testing::WithParamInterface<net::features::DiskCacheBackend> {
public:
ProfileNetworkContextServiceDiskCacheBackendExperimentBrowserTest() {
feature_list_.InitAndEnableFeatureWithParameters(
net::features::kDiskCacheBackendExperiment,
{{"backend", GetBackendParamValue()}});
}
~ProfileNetworkContextServiceDiskCacheBackendExperimentBrowserTest()
override = default;
const char* GetBackendParamValue() {
switch (GetParam()) {
case net::features::DiskCacheBackend::kDefault:
return "default";
case net::features::DiskCacheBackend::kSimple:
return "simple";
case net::features::DiskCacheBackend::kBlockfile:
return "blockfile";
#if BUILDFLAG(ENABLE_DISK_CACHE_SQL_BACKEND)
case net::features::DiskCacheBackend::kSql:
return "sql";
#endif // ENABLE_DISK_CACHE_SQL_BACKEND
}
}
const char* GetExperimentString() {
// The date and prefix for the disk cache backend experiment.
#define DISK_CACHE_EXPERIMENT_DATE_PREFIX "20250725-DiskCache-"
switch (GetParam()) {
case net::features::DiskCacheBackend::kDefault:
return DISK_CACHE_EXPERIMENT_DATE_PREFIX "Default";
case net::features::DiskCacheBackend::kSimple:
return DISK_CACHE_EXPERIMENT_DATE_PREFIX "Simple";
case net::features::DiskCacheBackend::kBlockfile:
return DISK_CACHE_EXPERIMENT_DATE_PREFIX "Blockfile";
#if BUILDFLAG(ENABLE_DISK_CACHE_SQL_BACKEND)
case net::features::DiskCacheBackend::kSql:
return DISK_CACHE_EXPERIMENT_DATE_PREFIX "Sql";
#endif // ENABLE_DISK_CACHE_SQL_BACKEND
}
}
base::HistogramTester histograms_;
private:
base::test::ScopedFeatureList feature_list_;
};
IN_PROC_BROWSER_TEST_P(
ProfileNetworkContextServiceDiskCacheBackendExperimentBrowserTest,
PRE_TestCacheResetParameter) {
NavigateToCreateHttpCache();
CheckCacheResetStatus(&histograms_, false);
// At this point, we have already called the initialization.
// Verify that we have the correct values in the local_state.
PrefService* local_state = g_browser_process->local_state();
DCHECK_EQ(local_state->GetString("profile_network_context_service.http_"
"cache_finch_experiment_groups"),
base::StrCat({"None None None None ", GetExperimentString()}));
// Set the local state for the next test.
local_state->SetString(
"profile_network_context_service.http_cache_finch_experiment_groups",
"None None None None");
}
// The second time we load we know the state, which was "None None None None"
// for the previous test, so we should see a reset being in an experiment.
IN_PROC_BROWSER_TEST_P(
ProfileNetworkContextServiceDiskCacheBackendExperimentBrowserTest,
TestCacheResetParameter) {
NavigateToCreateHttpCache();
CheckCacheResetStatus(&histograms_, true);
// At this point, we have already called the initialization.
// Verify that we have the correct values in the local_state.
PrefService* local_state = g_browser_process->local_state();
DCHECK_EQ(local_state->GetString("profile_network_context_service.http_"
"cache_finch_experiment_groups"),
base::StrCat({"None None None None ", GetExperimentString()}));
}
INSTANTIATE_TEST_SUITE_P(
All,
ProfileNetworkContextServiceDiskCacheBackendExperimentBrowserTest,
testing::ValuesIn({net::features::DiskCacheBackend::kSimple,
net::features::DiskCacheBackend::kBlockfile
#if BUILDFLAG(ENABLE_DISK_CACHE_SQL_BACKEND)
,
net::features::DiskCacheBackend::kSql
#endif // ENABLE_DISK_CACHE_SQL_BACKEND
}));
class AmbientAuthenticationTestWithPolicy : public policy::PolicyTest {
public:
AmbientAuthenticationTestWithPolicy() {
policy::PolicyTest::SetUpInProcessBrowserTestFixture();
}
void IsAmbientAuthAllowedForProfilesTest() {
PrefService* service = g_browser_process->local_state();
int policy_value =
service->GetInteger(prefs::kAmbientAuthenticationInPrivateModesEnabled);
Profile* regular_profile = browser()->profile();
Profile* incognito_profile =
regular_profile->GetPrimaryOTRProfile(/*create_if_needed=*/true);
Profile* non_primary_otr_profile = regular_profile->GetOffTheRecordProfile(
Profile::OTRProfileID::CreateUniqueForTesting(),
/*create_if_needed=*/true);
EXPECT_TRUE(AmbientAuthenticationTestHelper::IsAmbientAuthAllowedForProfile(
regular_profile));
EXPECT_TRUE(AmbientAuthenticationTestHelper::IsAmbientAuthAllowedForProfile(
non_primary_otr_profile));
EXPECT_EQ(AmbientAuthenticationTestHelper::IsAmbientAuthAllowedForProfile(
incognito_profile),
AmbientAuthenticationTestHelper::IsIncognitoAllowedInPolicy(
policy_value));
// ChromeOS guest sessions don't have the capability to
// do ambient authentications.
#if !BUILDFLAG(IS_CHROMEOS)
EXPECT_EQ(
AmbientAuthenticationTestHelper::IsAmbientAuthAllowedForProfile(
CreateGuestBrowser()->profile()),
AmbientAuthenticationTestHelper::IsGuestAllowedInPolicy(policy_value));
#endif
}
void EnablePolicyWithValue(net::AmbientAuthAllowedProfileTypes value) {
SetPolicy(&policies_,
policy::key::kAmbientAuthenticationInPrivateModesEnabled,
base::Value(static_cast<int>(value)));
UpdateProviderPolicy(policies_);
}
private:
policy::PolicyMap policies_;
};
IN_PROC_BROWSER_TEST_F(AmbientAuthenticationTestWithPolicy, RegularOnly) {
EnablePolicyWithValue(net::AmbientAuthAllowedProfileTypes::kRegularOnly);
IsAmbientAuthAllowedForProfilesTest();
}
IN_PROC_BROWSER_TEST_F(AmbientAuthenticationTestWithPolicy,
IncognitoAndRegular) {
EnablePolicyWithValue(
net::AmbientAuthAllowedProfileTypes::kIncognitoAndRegular);
IsAmbientAuthAllowedForProfilesTest();
}
IN_PROC_BROWSER_TEST_F(AmbientAuthenticationTestWithPolicy, GuestAndRegular) {
EnablePolicyWithValue(net::AmbientAuthAllowedProfileTypes::kGuestAndRegular);
IsAmbientAuthAllowedForProfilesTest();
}
IN_PROC_BROWSER_TEST_F(AmbientAuthenticationTestWithPolicy, All) {
EnablePolicyWithValue(net::AmbientAuthAllowedProfileTypes::kAll);
IsAmbientAuthAllowedForProfilesTest();
}
// Test subclass that adds switches::kDiskCacheDir and switches::kDiskCacheSize
// to the command line, to make sure they're respected.
class ProfileNetworkContextServiceDiskCacheBrowsertest
: public ProfileNetworkContextServiceBrowsertest {
public:
const int64_t kCacheSize = 7;
ProfileNetworkContextServiceDiskCacheBrowsertest() {
EXPECT_TRUE(temp_dir_.CreateUniqueTempDir());
}
~ProfileNetworkContextServiceDiskCacheBrowsertest() override = default;
void SetUpCommandLine(base::CommandLine* command_line) override {
command_line->AppendSwitchPath(switches::kDiskCacheDir,
temp_dir_.GetPath());
command_line->AppendSwitchASCII(switches::kDiskCacheSize,
base::NumberToString(kCacheSize));
}
const base::FilePath& TempPath() { return temp_dir_.GetPath(); }
private:
base::ScopedTempDir temp_dir_;
};
// Makes sure switches::kDiskCacheDir is hooked up correctly.
IN_PROC_BROWSER_TEST_F(ProfileNetworkContextServiceDiskCacheBrowsertest,
DiskCacheLocation) {
// Make sure command line switch is hooked up to the pref.
ASSERT_EQ(TempPath(), g_browser_process->local_state()->GetFilePath(
prefs::kDiskCacheDir));
// Run a request that caches the response, to give the network service time to
// create a cache directory.
std::unique_ptr<network::ResourceRequest> request =
std::make_unique<network::ResourceRequest>();
request->url = embedded_test_server()->GetURL("/cachetime");
request->credentials_mode = network::mojom::CredentialsMode::kOmit;
content::SimpleURLLoaderTestHelper simple_loader_helper;
std::unique_ptr<network::SimpleURLLoader> simple_loader =
network::SimpleURLLoader::Create(std::move(request),
TRAFFIC_ANNOTATION_FOR_TESTS);
simple_loader->DownloadToStringOfUnboundedSizeUntilCrashAndDie(
loader_factory(), simple_loader_helper.GetCallbackDeprecated());
simple_loader_helper.WaitForCallback();
ASSERT_TRUE(simple_loader_helper.response_body());
// Cache directory should now exist.
base::FilePath expected_cache_path =
TempPath()
.Append(browser()->profile()->GetBaseName())
.Append(chrome::kCacheDirname);
base::ScopedAllowBlockingForTesting allow_blocking;
EXPECT_TRUE(base::PathExists(expected_cache_path));
}
// Makes sure switches::kDiskCacheSize is hooked up correctly.
IN_PROC_BROWSER_TEST_F(ProfileNetworkContextServiceDiskCacheBrowsertest,
DiskCacheSize) {
// Make sure command line switch is hooked up to the pref.
ASSERT_EQ(kCacheSize, g_browser_process->local_state()->GetInteger(
prefs::kDiskCacheSize));
// We don't have a great way of directly checking that the disk cache has the
// correct max size, but we can make sure that we set up our network context
// params correctly.
ProfileNetworkContextService* profile_network_context_service =
ProfileNetworkContextServiceFactory::GetForContext(browser()->profile());
base::FilePath empty_relative_partition_path;
network::mojom::NetworkContextParams network_context_params;
cert_verifier::mojom::CertVerifierCreationParams
cert_verifier_creation_params;
profile_network_context_service->ConfigureNetworkContextParams(
/*in_memory=*/false, empty_relative_partition_path,
&network_context_params, &cert_verifier_creation_params);
EXPECT_EQ(kCacheSize, network_context_params.http_cache_max_size);
}
#if BUILDFLAG(IS_CHROMEOS)
class ProfileNetworkContextServiceMemoryPressureFeatureBrowsertest
: public ProfileNetworkContextServiceBrowsertest,
public ::testing::WithParamInterface<std::optional<bool>> {
public:
ProfileNetworkContextServiceMemoryPressureFeatureBrowsertest() = default;
~ProfileNetworkContextServiceMemoryPressureFeatureBrowsertest() override =
default;
void SetUp() override {
if (GetParam().has_value()) {
if (GetParam().value()) {
scoped_feature_list_.InitWithFeatures(
{chromeos::features::kDisableIdleSocketsCloseOnMemoryPressure}, {});
} else {
scoped_feature_list_.InitWithFeatures(
{}, {chromeos::features::kDisableIdleSocketsCloseOnMemoryPressure});
}
}
ProfileNetworkContextServiceBrowsertest::SetUp();
}
private:
base::test::ScopedFeatureList scoped_feature_list_;
};
// If the feature is enabled (GetParam()==true),
// NetworkContextParams.disable_idle_sockets_close_on_memory_pressure is
// expected to be true.
// If the feature is not set or disabled (GetParam()==false or nullopt),
// NetworkContextParams.disable_idle_sockets_close_on_memory_pressure is
// expected to be false
IN_PROC_BROWSER_TEST_P(
ProfileNetworkContextServiceMemoryPressureFeatureBrowsertest,
FeaturePropagates) {
ProfileNetworkContextService* profile_network_context_service =
ProfileNetworkContextServiceFactory::GetForContext(browser()->profile());
base::FilePath empty_relative_partition_path;
network::mojom::NetworkContextParams network_context_params;
cert_verifier::mojom::CertVerifierCreationParams
cert_verifier_creation_params;
profile_network_context_service->ConfigureNetworkContextParams(
/*in_memory=*/false, empty_relative_partition_path,
&network_context_params, &cert_verifier_creation_params);
EXPECT_EQ(
GetParam().value_or(false),
network_context_params.disable_idle_sockets_close_on_memory_pressure);
}
INSTANTIATE_TEST_SUITE_P(
All,
ProfileNetworkContextServiceMemoryPressureFeatureBrowsertest,
/*disable_idle_sockets_close_on_memory_pressure=*/
::testing::Values(std::nullopt, true, false));
#endif // BUILDFLAG(IS_CHROMEOS)
class ProfileNetworkContextTrustTokensBrowsertest
: public ProfileNetworkContextServiceBrowsertest {
public:
ProfileNetworkContextTrustTokensBrowsertest() = default;
~ProfileNetworkContextTrustTokensBrowsertest() override = default;
void SetUpOnMainThread() override {
host_resolver()->AddRule("*", "127.0.0.1");
https_server_ = std::make_unique<net::EmbeddedTestServer>(
net::test_server::EmbeddedTestServer::TYPE_HTTPS);
https_server_->SetSSLConfig(net::EmbeddedTestServer::CERT_TEST_NAMES);
https_server_->AddDefaultHandlers(
base::FilePath(FILE_PATH_LITERAL("content/test/data")));
network::test::RegisterTrustTokenTestHandlers(https_server_.get(),
&request_handler_);
ASSERT_TRUE(https_server_->Start());
}
void ProvideRequestHandlerKeyCommitmentsToNetworkService(
std::string_view host) {
base::flat_map<url::Origin, std::string_view> origins_and_commitments;
std::string key_commitments = request_handler_.GetKeyCommitmentRecord();
GURL::Replacements replacements;
replacements.SetHostStr(host);
origins_and_commitments.insert_or_assign(
url::Origin::Create(
https_server_->base_url().ReplaceComponents(replacements)),
key_commitments);
base::RunLoop run_loop;
content::GetNetworkService()->SetTrustTokenKeyCommitments(
network::WrapKeyCommitmentsForIssuers(
std::move(origins_and_commitments)),
run_loop.QuitClosure());
run_loop.Run();
}
content::WebContents* GetActiveWebContents() {
return browser()->tab_strip_model()->GetActiveWebContents();
}
void Flush() {
browser()
->profile()
->GetDefaultStoragePartition()
->FlushNetworkInterfaceForTesting();
}
protected:
net::EmbeddedTestServer* https_test_server() { return https_server_.get(); }
private:
std::unique_ptr<net::EmbeddedTestServer> https_server_;
network::test::TrustTokenRequestHandler request_handler_;
};
IN_PROC_BROWSER_TEST_F(ProfileNetworkContextTrustTokensBrowsertest,
TrustTokenBlocked) {
ProvideRequestHandlerKeyCommitmentsToNetworkService("a.test");
auto* privacy_sandbox_settings =
PrivacySandboxSettingsFactory::GetForProfile(browser()->profile());
auto privacy_sandbox_delegate = std::make_unique<
privacy_sandbox_test_util::MockPrivacySandboxSettingsDelegate>();
privacy_sandbox_delegate->SetUpIsPrivacySandboxRestrictedResponse(
/*restricted=*/false);
privacy_sandbox_delegate->SetUpIsIncognitoProfileResponse(
/*incognito=*/browser()->profile()->IsIncognitoProfile());
privacy_sandbox_settings->SetDelegateForTesting(
std::move(privacy_sandbox_delegate));
privacy_sandbox_settings->SetAllPrivacySandboxAllowedForTesting();
auto* host_content_settings_map =
HostContentSettingsMapFactory::GetForProfile(browser()->profile());
Flush();
ASSERT_TRUE(ui_test_utils::NavigateToURL(
browser(), https_test_server()->GetURL("a.test", "/title1.html")));
std::string issuance_origin =
url::Origin::Create(https_test_server()->GetURL("a.test", "/"))
.Serialize();
std::string command = content::JsReplace(R"(
(async () => {
try {
await fetch("/issue", {privateToken: {version: 1,
operation: 'token-request'}});
return await document.hasPrivateToken($1);
} catch {
return false;
}
})();)",
issuance_origin);
EXPECT_EQ(true, EvalJs(GetActiveWebContents(), command));
host_content_settings_map->SetDefaultContentSetting(
ContentSettingsType::ANTI_ABUSE, CONTENT_SETTING_BLOCK);
Flush();
chrome::Reload(browser(), WindowOpenDisposition::CURRENT_TAB);
EXPECT_TRUE(content::WaitForLoadStop(GetActiveWebContents()));
EXPECT_EQ(false, EvalJs(GetActiveWebContents(), command));
host_content_settings_map->SetDefaultContentSetting(
ContentSettingsType::ANTI_ABUSE, CONTENT_SETTING_ALLOW);
Flush();
chrome::Reload(browser(), WindowOpenDisposition::CURRENT_TAB);
EXPECT_TRUE(content::WaitForLoadStop(GetActiveWebContents()));
EXPECT_EQ(true, EvalJs(GetActiveWebContents(), command));
// Trust Tokens are blocked when the top level origin cookie content setting
// is blocked
GURL top_level_origin = https_test_server()->GetURL("a.test", "/");
host_content_settings_map->SetContentSettingDefaultScope(
top_level_origin, top_level_origin, ContentSettingsType::COOKIES,
CONTENT_SETTING_BLOCK);
chrome::Reload(browser(), WindowOpenDisposition::CURRENT_TAB);
EXPECT_TRUE(content::WaitForLoadStop(GetActiveWebContents()));
EXPECT_EQ(false, EvalJs(GetActiveWebContents(), command));
}
class ReportingEndpointsPolicyTest : public policy::PolicyTest {
public:
void SetUpInProcessBrowserTestFixture() override {
scoped_feature_list_.InitAndEnableFeature(
net::features::kReportingApiEnableEnterpriseCookieIssues);
policy::PolicyTest::SetUpInProcessBrowserTestFixture();
}
void UpdateReportingEndpointsPolicy(base::Value::Dict dict) {
SetPolicy(&policies_, policy::key::kReportingEndpoints,
base::Value(std::move(dict)));
UpdateProviderPolicy(policies_);
}
private:
policy::PolicyMap policies_;
base::test::ScopedFeatureList scoped_feature_list_;
};
IN_PROC_BROWSER_TEST_F(ReportingEndpointsPolicyTest,
CheckEnterpriseEndpointsNetworkContextParamsSet) {
network::mojom::NetworkContextParams network_context_params;
EXPECT_FALSE(
network_context_params.enterprise_reporting_endpoints.has_value());
UpdateReportingEndpointsPolicy(
base::Value::Dict()
.Set("endpoint-1", "https://example.com/reports")
.Set("endpoint-2", "https://reporting.example/cookie-issues")
.Set("endpoint-3", "https://report-collector.example"));
ProfileNetworkContextService* profile_network_context_service =
ProfileNetworkContextServiceFactory::GetForContext(browser()->profile());
base::FilePath empty_relative_partition_path;
cert_verifier::mojom::CertVerifierCreationParams
cert_verifier_creation_params;
profile_network_context_service->ConfigureNetworkContextParams(
/*in_memory=*/false, empty_relative_partition_path,
&network_context_params, &cert_verifier_creation_params);
base::flat_map<std::string, GURL> expected_enterprise_endpoints{
{"endpoint-1", GURL("https://example.com/reports")},
{"endpoint-2", GURL("https://reporting.example/cookie-issues")},
{"endpoint-3", GURL("https://report-collector.example")},
};
EXPECT_EQ(expected_enterprise_endpoints,
network_context_params.enterprise_reporting_endpoints);
}