Commit 3d6bd6b5 authored by Robert Ogden's avatar Robert Ogden Committed by Commit Bot

Decouple IsolatedPrerender from Lite Mode and its config

Adds a experiment param to require the user to have Lite Mode enabled,
default true for the time being.

Also removes the integration with the Data Saver config to get the proxy
tunnel hosts and chrome-proxy header.
Now, the tunnel host will be given through experiment param or cmd line
and uses a tunnel header with the Google API key.

Also fixes some flakiness in the new probing tests.

Bug: 1135213
Change-Id: I23802a5c9787abe669759be0f782b3d586afd7dc
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2449912
Commit-Queue: Robert Ogden <robertogden@chromium.org>
Reviewed-by: default avatarTarun Bansal <tbansal@chromium.org>
Cr-Commit-Position: refs/heads/master@{#815239}
parent 9dcf1d65
......@@ -55,11 +55,9 @@
#include "chrome/test/base/in_process_browser_test.h"
#include "chrome/test/base/ui_test_utils.h"
#include "components/content_settings/core/browser/host_content_settings_map.h"
#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_config_service_client_test_utils.h"
#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.h"
#include "components/data_reduction_proxy/core/common/data_reduction_proxy_features.h"
#include "components/data_reduction_proxy/core/common/data_reduction_proxy_switches.h"
#include "components/data_reduction_proxy/proto/client_config.pb.h"
#include "components/language/core/browser/pref_names.h"
#include "components/policy/policy_constants.h"
#include "components/prefs/pref_service.h"
......@@ -128,20 +126,6 @@ constexpr gfx::Size kSize(640, 480);
const char kAllowedUAClientHint[] = "sec-ch-ua";
const char kAllowedUAMobileClientHint[] = "sec-ch-ua-mobile";
void SimulateNetworkChange(network::mojom::ConnectionType type) {
if (!content::IsInProcessNetworkService()) {
mojo::Remote<network::mojom::NetworkServiceTest> network_service_test;
content::GetNetworkService()->BindTestInterface(
network_service_test.BindNewPipeAndPassReceiver());
base::RunLoop run_loop;
network_service_test->SimulateNetworkChange(type, run_loop.QuitClosure());
run_loop.Run();
return;
}
net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(
net::NetworkChangeNotifier::ConnectionType(type));
}
class TestCustomProxyConfigClient
: public network::mojom::CustomProxyConfigClient {
public:
......@@ -382,13 +366,6 @@ class IsolatedPrerenderBrowserTest
proxy_server_->SetConnectionListener(this);
EXPECT_TRUE(proxy_server_->Start());
config_server_ = std::make_unique<net::EmbeddedTestServer>(
net::EmbeddedTestServer::TYPE_HTTPS);
config_server_->RegisterRequestHandler(
base::BindRepeating(&IsolatedPrerenderBrowserTest::GetConfigResponse,
base::Unretained(this)));
EXPECT_TRUE(config_server_->Start());
http_server_ = std::make_unique<net::EmbeddedTestServer>(
net::EmbeddedTestServer::TYPE_HTTP);
http_server_->ServeFilesFromSourceDirectory("chrome/test/data");
......@@ -411,11 +388,9 @@ class IsolatedPrerenderBrowserTest
// features since order is tricky when doing different feature lists between
// base and derived classes.
virtual void SetFeatures() {
scoped_feature_list_.InitWithFeatures(
{features::kIsolatePrerenders,
data_reduction_proxy::features::kDataReductionProxyHoldback,
data_reduction_proxy::features::kFetchClientConfig},
{});
// Important: Features with parameters can't be used here, because it will
// cause a failed DCHECK in the SSL reporting test.
scoped_feature_list_.InitAndEnableFeature(features::kIsolatePrerenders);
}
void SetUpOnMainThread() override {
......@@ -445,9 +420,8 @@ class IsolatedPrerenderBrowserTest
// For the proxy.
cmd->AppendSwitch("ignore-certificate-errors");
cmd->AppendSwitch("force-enable-metrics-reporting");
cmd->AppendSwitchASCII(
data_reduction_proxy::switches::kDataReductionProxyConfigURL,
config_server_->base_url().spec());
cmd->AppendSwitchASCII("isolated-prerender-tunnel-proxy",
GetProxyURL().spec());
}
void SetDataSaverEnabled(bool enabled) {
......@@ -492,8 +466,6 @@ class IsolatedPrerenderBrowserTest
isolated_prerender_service->proxy_configurator()
->AddCustomProxyConfigClient(std::move(client_remote));
// A network change forces the config to be fetched.
SimulateNetworkChange(network::mojom::ConnectionType::CONNECTION_3G);
run_loop.Run();
return std::move(config_client.config_);
......@@ -510,7 +482,7 @@ class IsolatedPrerenderBrowserTest
void WaitForDNSCanaryCheck() {
IsolatedPrerenderService* service =
IsolatedPrerenderServiceFactory::GetForProfile(browser()->profile());
while (!service->origin_prober()->IsDNSCanaryCheckCompleteForTesting()) {
while (service->origin_prober()->IsDNSCanaryCheckActiveForTesting()) {
base::RunLoop().RunUntilIdle();
}
}
......@@ -710,14 +682,16 @@ class IsolatedPrerenderBrowserTest
EXPECT_TRUE("a.test" == request_origin.host() ||
"b.test" == request_origin.host());
bool found_chrome_proxy_header = false;
bool found_chrome_tunnel_header = false;
for (const std::string& header : request_lines) {
if (header.find("chrome-proxy") != std::string::npos &&
header.find("s=secretsessionkey") != std::string::npos) {
found_chrome_proxy_header = true;
if (header.find("chrome-tunnel") != std::string::npos &&
header.find("key=" +
IsolatedPrerenderProxyConfigurator::GetGoogleAPIKey()) !=
std::string::npos) {
found_chrome_tunnel_header = true;
}
}
EXPECT_TRUE(found_chrome_proxy_header);
EXPECT_TRUE(found_chrome_tunnel_header);
auto new_tunnel = std::make_unique<TestProxyTunnelConnection>();
new_tunnel->SetOnDoneCallback(
......@@ -774,27 +748,6 @@ class IsolatedPrerenderBrowserTest
language::prefs::kAcceptLanguages)));
}
// Called when |config_server_| receives a request for config fetch.
std::unique_ptr<net::test_server::HttpResponse> GetConfigResponse(
const net::test_server::HttpRequest& request) {
data_reduction_proxy::ClientConfig config =
data_reduction_proxy::CreateClientConfig("secretsessionkey", 1000, 0);
data_reduction_proxy::PrefetchProxyConfig_Proxy* valid_secure_proxy =
config.mutable_prefetch_proxy_config()->add_proxy_list();
valid_secure_proxy->set_type(
data_reduction_proxy::PrefetchProxyConfig_Proxy_Type_CONNECT);
valid_secure_proxy->set_host(GetProxyURL().host());
valid_secure_proxy->set_port(GetProxyURL().EffectiveIntPort());
valid_secure_proxy->set_scheme(
data_reduction_proxy::PrefetchProxyConfig_Proxy_Scheme_HTTPS);
auto response = std::make_unique<net::test_server::BasicHttpResponse>();
response->set_content(config.SerializeAsString());
response->set_content_type("text/plain");
return response;
}
// prerender::PrerenderHandle::Observer:
void OnPrerenderStart(prerender::PrerenderHandle* handle) override {}
void OnPrerenderStopLoading(prerender::PrerenderHandle* handle) override {}
......@@ -827,7 +780,6 @@ class IsolatedPrerenderBrowserTest
std::unique_ptr<ukm::TestAutoSetUkmRecorder> ukm_recorder_;
std::unique_ptr<net::EmbeddedTestServer> proxy_server_;
std::unique_ptr<net::EmbeddedTestServer> origin_server_;
std::unique_ptr<net::EmbeddedTestServer> config_server_;
std::unique_ptr<net::EmbeddedTestServer> http_server_;
std::unique_ptr<net::EmbeddedTestServer> canary_server_;
......@@ -2133,10 +2085,17 @@ IN_PROC_BROWSER_TEST_F(
class IsolatedPrerenderBaseProbingBrowserTest
: public IsolatedPrerenderBrowserTest {
public:
const base::HistogramTester& histogram_tester() const {
return histogram_tester_;
}
void RunProbeTest(bool probe_success,
bool expect_successful_tls_probe,
int64_t expected_status,
bool expect_probe) {
WaitForTLSCanaryCheck();
WaitForDNSCanaryCheck();
// Setup a local probing server so we can watch its accepted socket count.
TestServerConnectionCounter probe_counter;
net::EmbeddedTestServer probing_server(net::EmbeddedTestServer::TYPE_HTTPS);
......@@ -2219,6 +2178,9 @@ class IsolatedPrerenderBaseProbingBrowserTest
EXPECT_EQ(base::nullopt, probe_latency_ms);
}
}
private:
base::HistogramTester histogram_tester_;
};
class ProbingEnabled_CanaryOn_BothCanaryGood_IsolatedPrerenderBrowserTest
......@@ -2335,16 +2297,14 @@ IN_PROC_BROWSER_TEST_F(
IN_PROC_BROWSER_TEST_F(
ProbingEnabled_CanaryOn_TLSCanaryGood_DNSCanaryBad_IsolatedPrerenderBrowserTest,
DISABLE_ON_WIN_MAC_CHROMEOS(DNSProbeOK)) {
base::HistogramTester histogram_tester;
RunProbeTest(/*probe_success=*/true,
/*expect_successful_tls_probe=*/false,
/*expected_status=*/1,
/*expect_probe=*/true);
histogram_tester.ExpectTotalCount(
histogram_tester().ExpectTotalCount(
"Availability.Prober.FinalState.IsolatedPrerenderDNSCanaryCheck", 1);
histogram_tester.ExpectTotalCount(
histogram_tester().ExpectTotalCount(
"Availability.Prober.FinalState.IsolatedPrerenderTLSCanaryCheck", 1);
}
......@@ -2360,17 +2320,10 @@ IN_PROC_BROWSER_TEST_F(
IN_PROC_BROWSER_TEST_F(
ProbingEnabled_CanaryOn_TLSCanaryBad_DNSCanaryBad_IsolatedPrerenderBrowserTest,
DISABLE_ON_WIN_MAC_CHROMEOS(TLSProbeOK)) {
base::HistogramTester histogram_tester;
RunProbeTest(/*probe_success=*/true,
/*expect_successful_tls_probe=*/true,
/*expected_status=*/1,
/*expect_probe=*/true);
histogram_tester.ExpectTotalCount(
"Availability.Prober.FinalState.IsolatedPrerenderDNSCanaryCheck", 1);
histogram_tester.ExpectTotalCount(
"Availability.Prober.FinalState.IsolatedPrerenderTLSCanaryCheck", 1);
}
IN_PROC_BROWSER_TEST_F(
......
......@@ -350,13 +350,11 @@ void IsolatedPrerenderOriginProber::
}
bool IsolatedPrerenderOriginProber::IsTLSCanaryCheckCompleteForTesting() const {
return tls_canary_check_ &&
tls_canary_check_->LastProbeWasSuccessful().has_value();
return tls_canary_check_->LastProbeWasSuccessful().has_value();
}
bool IsolatedPrerenderOriginProber::IsDNSCanaryCheckCompleteForTesting() const {
return dns_canary_check_ &&
dns_canary_check_->LastProbeWasSuccessful().has_value();
bool IsolatedPrerenderOriginProber::IsDNSCanaryCheckActiveForTesting() const {
return dns_canary_check_->is_active();
}
void IsolatedPrerenderOriginProber::Probe(const GURL& url,
......
......@@ -40,10 +40,8 @@ class IsolatedPrerenderOriginProber {
// failure. Used for testing.
bool IsTLSCanaryCheckCompleteForTesting() const;
// Tells whether a DNS canary check has completed, either in success or
// failure.
// Used for testing.
bool IsDNSCanaryCheckCompleteForTesting() const;
// Tells whether a DNS canary check is active. Used for testing.
bool IsDNSCanaryCheckActiveForTesting() const;
// Starts a probe to |url| and calls |callback| with a bool to indicate
// success (when true) or failure (when false).
......
......@@ -24,6 +24,41 @@ bool IsolatedPrerenderIsEnabled() {
return base::FeatureList::IsEnabled(features::kIsolatePrerenders);
}
GURL IsolatedPrerenderProxyHost() {
// Command line overrides take priority.
std::string cmd_line_value =
base::CommandLine::ForCurrentProcess()->GetSwitchValueASCII(
"isolated-prerender-tunnel-proxy");
if (!cmd_line_value.empty()) {
GURL cmd_line_url(cmd_line_value);
if (cmd_line_url.is_valid()) {
return cmd_line_url;
}
LOG(ERROR) << "--isolated-prerender-tunnel-proxy value is invalid";
}
GURL url(base::GetFieldTrialParamValueByFeature(features::kIsolatePrerenders,
"proxy_host"));
if (url.is_valid() && url.SchemeIs(url::kHttpsScheme)) {
return url;
}
return GURL("https://tunnel.googlezip.net/");
}
std::string IsolatedPrerenderProxyHeaderKey() {
std::string header = base::GetFieldTrialParamValueByFeature(
features::kIsolatePrerenders, "proxy_header_key");
if (!header.empty()) {
return header;
}
return "chrome-tunnel";
}
bool IsolatedPrerenderOnlyForLiteMode() {
return base::GetFieldTrialParamByFeatureAsBool(features::kIsolatePrerenders,
"lite_mode_only", true);
}
bool IsolatedPrerenderNoStatePrefetchSubresources() {
return base::CommandLine::ForCurrentProcess()->HasSwitch(
kIsolatedPrerenderEnableNSPCmdLineFlag) ||
......
......@@ -21,6 +21,15 @@ extern const char kIsolatedPrerenderLimitNSPSubresourcesCmdLineFlag[];
// Returns true if the Isolated Prerender feature is enabled.
bool IsolatedPrerenderIsEnabled();
// The url of the tunnel proxy.
GURL IsolatedPrerenderProxyHost();
// The header name used to connect to the tunnel proxy.
std::string IsolatedPrerenderProxyHeaderKey();
// Whether the feature is only enabled for Lite Mode users.
bool IsolatedPrerenderOnlyForLiteMode();
// Returns true when prefetched pages should run no state prefetch.
bool IsolatedPrerenderNoStatePrefetchSubresources();
......
......@@ -10,25 +10,29 @@
#include "net/proxy_resolution/proxy_config.h"
#include "url/gurl.h"
IsolatedPrerenderProxyConfigurator::IsolatedPrerenderProxyConfigurator() =
default;
IsolatedPrerenderProxyConfigurator::~IsolatedPrerenderProxyConfigurator() =
default;
#if defined(USE_GOOGLE_API_KEYS)
#include "google_apis/google_api_keys.h"
#endif
void IsolatedPrerenderProxyConfigurator::UpdateTunnelHeaders(
const net::HttpRequestHeaders& connect_tunnel_headers) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
connect_tunnel_headers_ = connect_tunnel_headers;
UpdateCustomProxyConfig();
// static
std::string IsolatedPrerenderProxyConfigurator::GetGoogleAPIKey() {
#if defined(USE_GOOGLE_API_KEYS)
std::string api_key = google_apis::GetAPIKey();
if (google_apis::HasAPIKeyConfigured() && !api_key.empty()) {
return api_key;
}
#endif
return std::string();
}
void IsolatedPrerenderProxyConfigurator::UpdateProxyHosts(
const std::vector<GURL>& proxy_hosts) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
proxy_hosts_ = proxy_hosts;
UpdateCustomProxyConfig();
IsolatedPrerenderProxyConfigurator::IsolatedPrerenderProxyConfigurator() {
connect_tunnel_headers_.SetHeader(IsolatedPrerenderProxyHeaderKey(),
"key=" + GetGoogleAPIKey());
}
IsolatedPrerenderProxyConfigurator::~IsolatedPrerenderProxyConfigurator() =
default;
void IsolatedPrerenderProxyConfigurator::AddCustomProxyConfigClient(
mojo::Remote<network::mojom::CustomProxyConfigClient> config_client) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
......@@ -38,32 +42,14 @@ void IsolatedPrerenderProxyConfigurator::AddCustomProxyConfigClient(
void IsolatedPrerenderProxyConfigurator::UpdateCustomProxyConfig() {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
// The Data Reduction Proxy (DRP) is the only other service in Chrome that
// sets a Custom Proxy in the network stack. In order for the Isolated
// Prerender feature to work, it needs to provide it's own custom proxy
// configuration. Therefore, only update the custom proxy when DRP is
// disabled.
if (!base::FeatureList::IsEnabled(
data_reduction_proxy::features::kDataReductionProxyHoldback)) {
return;
}
if (!IsolatedPrerenderIsEnabled())
return;
// If a proxy config has never been sent, and there's no hosts to send, don't
// bother.
if (proxy_hosts_.empty() && !sent_proxy_update_)
return;
network::mojom::CustomProxyConfigPtr config = CreateCustomProxyConfig();
for (auto& client : proxy_config_clients_) {
client->OnCustomProxyConfigUpdated(config->Clone());
}
if (!proxy_hosts_.empty()) {
sent_proxy_update_ = true;
}
}
network::mojom::CustomProxyConfigPtr
......@@ -77,14 +63,14 @@ IsolatedPrerenderProxyConfigurator::CreateCustomProxyConfig() const {
auto config = network::mojom::CustomProxyConfig::New();
config->rules.type =
net::ProxyConfig::ProxyRules::Type::PROXY_LIST_PER_SCHEME;
// DIRECT is intentionally not added here because we want the proxy to always
// be used in order to mask the user's IP address during the prerender.
for (const GURL& host : proxy_hosts_) {
DCHECK(host.is_valid());
config->rules.proxies_for_https.AddProxyServer(
net::ProxyServer(net::ProxyServer::GetSchemeFromURI(host.scheme()),
net::HostPortPair::FromURL(host)));
}
DCHECK(IsolatedPrerenderProxyHost().is_valid());
config->rules.proxies_for_https.AddProxyServer(net::ProxyServer(
net::ProxyServer::GetSchemeFromURI(IsolatedPrerenderProxyHost().scheme()),
net::HostPortPair::FromURL(IsolatedPrerenderProxyHost())));
// This ensures that the user's set proxy is honored, although we also disable
// the feature is such cases.
config->should_override_existing_config = false;
......
......@@ -22,20 +22,15 @@ class IsolatedPrerenderProxyConfigurator {
IsolatedPrerenderProxyConfigurator();
~IsolatedPrerenderProxyConfigurator();
// Updates the headers needed to connect to the proxy.
void UpdateTunnelHeaders(
const net::HttpRequestHeaders& connect_tunnel_headers);
// Updates the hosts used to connect to the proxy.
void UpdateProxyHosts(const std::vector<GURL>& proxy_hosts);
// Gets the Google API ket, if configured. If not, returns an empty string.
static std::string GetGoogleAPIKey();
// Adds a config client that can be used to update Data Reduction Proxy
// settings.
void AddCustomProxyConfigClient(
mojo::Remote<network::mojom::CustomProxyConfigClient> config_client);
// Should be called whenever there is a possible change to the custom proxy
// config.
// Updates the custom proxy config to all clients.
void UpdateCustomProxyConfig();
// Creates a config that can be sent to the NetworkContext.
......@@ -45,13 +40,6 @@ class IsolatedPrerenderProxyConfigurator {
// The headers used to setup the connect tunnel.
net::HttpRequestHeaders connect_tunnel_headers_;
// The configured proxy hosts.
std::vector<GURL> proxy_hosts_;
// Set to true when a custom proxy config with a non-empty set of proxies is
// sent to the Network Service.
bool sent_proxy_update_ = false;
// The set of clients that will get updates about changes to the proxy config.
mojo::RemoteSet<network::mojom::CustomProxyConfigClient>
proxy_config_clients_;
......
......@@ -10,7 +10,6 @@
#include "base/test/scoped_feature_list.h"
#include "base/test/task_environment.h"
#include "chrome/browser/prerender/isolated/isolated_prerender_features.h"
#include "components/data_reduction_proxy/core/common/data_reduction_proxy_features.h"
#include "content/public/test/browser_task_environment.h"
#include "mojo/public/cpp/bindings/pending_receiver.h"
#include "mojo/public/cpp/bindings/receiver.h"
......@@ -48,25 +47,15 @@ class TestCustomProxyConfigClient
class IsolatedPrerenderProxyConfiguratorTest : public testing::Test {
public:
IsolatedPrerenderProxyConfiguratorTest()
: configurator_(std::make_unique<IsolatedPrerenderProxyConfigurator>()) {}
IsolatedPrerenderProxyConfiguratorTest() = default;
~IsolatedPrerenderProxyConfiguratorTest() override = default;
void SetUp() override {
mojo::Remote<network::mojom::CustomProxyConfigClient> client_remote;
config_client_ = std::make_unique<TestCustomProxyConfigClient>(
client_remote.BindNewPipeAndPassReceiver());
configurator_->AddCustomProxyConfigClient(std::move(client_remote));
base::RunLoop().RunUntilIdle();
}
network::mojom::CustomProxyConfigPtr LatestProxyConfig() {
return std::move(config_client_->config_);
}
void VerifyLatestProxyConfig(const GURL& proxy_url,
const net::HttpRequestHeaders& headers,
bool want_empty = false) {
const net::HttpRequestHeaders& headers) {
auto config = LatestProxyConfig();
ASSERT_TRUE(config);
......@@ -80,15 +69,21 @@ class IsolatedPrerenderProxyConfiguratorTest : public testing::Test {
EXPECT_EQ(config->rules.proxies_for_http.size(), 0U);
EXPECT_EQ(config->rules.proxies_for_ftp.size(), 0U);
if (want_empty) {
EXPECT_EQ(config->rules.proxies_for_https.size(), 0U);
} else {
ASSERT_EQ(config->rules.proxies_for_https.size(), 1U);
EXPECT_EQ(GURL(config->rules.proxies_for_https.Get().ToURI()), proxy_url);
}
ASSERT_EQ(config->rules.proxies_for_https.size(), 1U);
EXPECT_EQ(GURL(config->rules.proxies_for_https.Get().ToURI()), proxy_url);
}
IsolatedPrerenderProxyConfigurator* configurator() {
if (!configurator_) {
// Lazy construct and init so that any changed field trials can be picked
// used.
configurator_ = std::make_unique<IsolatedPrerenderProxyConfigurator>();
mojo::Remote<network::mojom::CustomProxyConfigClient> client_remote;
config_client_ = std::make_unique<TestCustomProxyConfigClient>(
client_remote.BindNewPipeAndPassReceiver());
configurator_->AddCustomProxyConfigClient(std::move(client_remote));
base::RunLoop().RunUntilIdle();
}
return configurator_.get();
}
......@@ -98,34 +93,9 @@ class IsolatedPrerenderProxyConfiguratorTest : public testing::Test {
std::unique_ptr<TestCustomProxyConfigClient> config_client_;
};
TEST_F(IsolatedPrerenderProxyConfiguratorTest, FeaturesOff) {
base::test::ScopedFeatureList scoped_feature_list;
scoped_feature_list.InitWithFeatures(
{}, {features::kIsolatePrerenders,
data_reduction_proxy::features::kDataReductionProxyHoldback});
configurator()->UpdateCustomProxyConfig();
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(LatestProxyConfig());
}
TEST_F(IsolatedPrerenderProxyConfiguratorTest, DRPFeatureOff) {
base::test::ScopedFeatureList scoped_feature_list;
scoped_feature_list.InitWithFeatures(
{features::kIsolatePrerenders},
{data_reduction_proxy::features::kDataReductionProxyHoldback});
configurator()->UpdateCustomProxyConfig();
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(LatestProxyConfig());
}
TEST_F(IsolatedPrerenderProxyConfiguratorTest, PrefetchFeatureOff) {
TEST_F(IsolatedPrerenderProxyConfiguratorTest, FeatureOff) {
base::test::ScopedFeatureList scoped_feature_list;
scoped_feature_list.InitWithFeatures(
{data_reduction_proxy::features::kDataReductionProxyHoldback},
{features::kIsolatePrerenders});
scoped_feature_list.InitAndDisableFeature(features::kIsolatePrerenders);
configurator()->UpdateCustomProxyConfig();
base::RunLoop().RunUntilIdle();
......@@ -133,67 +103,19 @@ TEST_F(IsolatedPrerenderProxyConfiguratorTest, PrefetchFeatureOff) {
EXPECT_FALSE(LatestProxyConfig());
}
TEST_F(IsolatedPrerenderProxyConfiguratorTest, NoProxyServers) {
base::test::ScopedFeatureList scoped_feature_list;
scoped_feature_list.InitWithFeatures(
{features::kIsolatePrerenders,
data_reduction_proxy::features::kDataReductionProxyHoldback},
{});
configurator()->UpdateProxyHosts({});
base::RunLoop().RunUntilIdle();
EXPECT_FALSE(LatestProxyConfig());
}
TEST_F(IsolatedPrerenderProxyConfiguratorTest, ClearProxyServers) {
GURL proxy_url("https://proxy.com");
base::test::ScopedFeatureList scoped_feature_list;
scoped_feature_list.InitWithFeatures(
{features::kIsolatePrerenders,
data_reduction_proxy::features::kDataReductionProxyHoldback},
{});
configurator()->UpdateProxyHosts({proxy_url});
base::RunLoop().RunUntilIdle();
net::HttpRequestHeaders headers;
VerifyLatestProxyConfig(proxy_url, headers);
configurator()->UpdateProxyHosts({});
base::RunLoop().RunUntilIdle();
VerifyLatestProxyConfig(GURL(), headers, /*want_empty=*/true);
}
TEST_F(IsolatedPrerenderProxyConfiguratorTest, ValidProxyServerURL) {
TEST_F(IsolatedPrerenderProxyConfiguratorTest, ExperimentOverrides) {
GURL proxy_url("https://proxy.com");
base::test::ScopedFeatureList scoped_feature_list;
scoped_feature_list.InitWithFeatures(
{features::kIsolatePrerenders,
data_reduction_proxy::features::kDataReductionProxyHoldback},
{});
scoped_feature_list.InitAndEnableFeatureWithParameters(
features::kIsolatePrerenders,
{{"proxy_host", proxy_url.spec()}, {"proxy_header_key", "test-header"}});
configurator()->UpdateProxyHosts({proxy_url});
configurator()->UpdateCustomProxyConfig();
base::RunLoop().RunUntilIdle();
net::HttpRequestHeaders headers;
VerifyLatestProxyConfig(proxy_url, headers);
}
TEST_F(IsolatedPrerenderProxyConfiguratorTest, ValidProxyServerURLWithHeaders) {
GURL proxy_url("https://proxy.com");
base::test::ScopedFeatureList scoped_feature_list;
scoped_feature_list.InitWithFeatures(
{features::kIsolatePrerenders,
data_reduction_proxy::features::kDataReductionProxyHoldback},
{});
net::HttpRequestHeaders headers;
headers.SetHeader("X-Testing", "Hello World");
configurator()->UpdateTunnelHeaders(headers);
configurator()->UpdateProxyHosts({proxy_url});
base::RunLoop().RunUntilIdle();
headers.SetHeader(
"test-header",
"key=" + IsolatedPrerenderProxyConfigurator::GetGoogleAPIKey());
VerifyLatestProxyConfig(proxy_url, headers);
}
......@@ -22,21 +22,10 @@ IsolatedPrerenderService::IsolatedPrerenderService(Profile* profile)
proxy_configurator_(
std::make_unique<IsolatedPrerenderProxyConfigurator>()),
origin_prober_(std::make_unique<IsolatedPrerenderOriginProber>(profile)) {
DataReductionProxyChromeSettings* drp_settings =
DataReductionProxyChromeSettingsFactory::GetForBrowserContext(profile_);
if (drp_settings)
drp_settings->AddDataReductionProxySettingsObserver(this);
}
IsolatedPrerenderService::~IsolatedPrerenderService() = default;
void IsolatedPrerenderService::Shutdown() {
DataReductionProxyChromeSettings* drp_settings =
DataReductionProxyChromeSettingsFactory::GetForBrowserContext(profile_);
if (drp_settings)
drp_settings->RemoveDataReductionProxySettingsObserver(this);
}
bool IsolatedPrerenderService::MaybeProxyURLLoaderFactory(
content::RenderFrameHost* frame,
int render_process_id,
......@@ -89,16 +78,3 @@ void IsolatedPrerenderService::DestroySubresourceManagerForURL(
subresource_managers_.erase(iter);
}
}
void IsolatedPrerenderService::OnProxyRequestHeadersChanged(
const net::HttpRequestHeaders& headers) {
proxy_configurator_->UpdateTunnelHeaders(headers);
}
void IsolatedPrerenderService::OnPrefetchProxyHostsChanged(
const std::vector<GURL>& prefetch_proxies) {
proxy_configurator_->UpdateProxyHosts(prefetch_proxies);
}
void IsolatedPrerenderService::OnSettingsInitialized() {}
void IsolatedPrerenderService::OnDataSaverEnabledChanged(bool enabled) {}
......@@ -10,7 +10,6 @@
#include <vector>
#include "base/memory/weak_ptr.h"
#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.h"
#include "components/keyed_service/core/keyed_service.h"
#include "content/public/browser/content_browser_client.h"
#include "url/gurl.h"
......@@ -26,9 +25,7 @@ class RenderFrameHost;
}
// This service owns browser-level objects used in Isolated Prerenders.
class IsolatedPrerenderService
: public KeyedService,
public data_reduction_proxy::DataReductionProxySettingsObserver {
class IsolatedPrerenderService : public KeyedService {
public:
explicit IsolatedPrerenderService(Profile* profile);
~IsolatedPrerenderService() override;
......@@ -73,17 +70,6 @@ class IsolatedPrerenderService
IsolatedPrerenderService& operator=(const IsolatedPrerenderService&) = delete;
private:
// data_reduction_proxy::DataReductionProxySettingsObserver:
void OnProxyRequestHeadersChanged(
const net::HttpRequestHeaders& headers) override;
void OnSettingsInitialized() override;
void OnDataSaverEnabledChanged(bool enabled) override;
void OnPrefetchProxyHostsChanged(
const std::vector<GURL>& prefetch_proxies) override;
// KeyedService:
void Shutdown() override;
// Cleans up the NoStatePrerender response. Used in a delayed post task.
void CleanupNoStatePrefetchResponse(const GURL& url);
......
......@@ -270,6 +270,24 @@ IsolatedPrerenderTabHelper::after_srp_metrics() const {
return base::nullopt;
}
// static
bool IsolatedPrerenderTabHelper::IsProfileEligible(Profile* profile) {
if (profile->IsOffTheRecord()) {
return false;
}
if (IsolatedPrerenderOnlyForLiteMode()) {
return data_reduction_proxy::DataReductionProxySettings::
IsDataSaverEnabledByUser(profile->IsOffTheRecord(),
profile->GetPrefs());
}
return true;
}
bool IsolatedPrerenderTabHelper::IsProfileEligible() const {
return IsProfileEligible(profile_);
}
void IsolatedPrerenderTabHelper::DidStartNavigation(
content::NavigationHandle* navigation_handle) {
DCHECK_CALLED_ON_VALID_SEQUENCE(sequence_checker_);
......@@ -1013,10 +1031,7 @@ void IsolatedPrerenderTabHelper::OnPredictionUpdated(
return;
}
// DataSaver must be enabled by the user to use this feature.
if (!data_reduction_proxy::DataReductionProxySettings::
IsDataSaverEnabledByUser(profile_->IsOffTheRecord(),
profile_->GetPrefs())) {
if (!IsProfileEligible()) {
return;
}
......@@ -1092,9 +1107,7 @@ void IsolatedPrerenderTabHelper::CheckEligibilityOfURL(
Profile* profile,
const GURL& url,
OnEligibilityResultCallback result_callback) {
if (!data_reduction_proxy::DataReductionProxySettings::
IsDataSaverEnabledByUser(profile->IsOffTheRecord(),
profile->GetPrefs())) {
if (!IsProfileEligible(profile)) {
std::move(result_callback).Run(url, false, base::nullopt);
return;
}
......
......@@ -320,6 +320,11 @@ class IsolatedPrerenderTabHelper
scoped_refptr<network::SharedURLLoaderFactory> isolated_url_loader_factory_;
};
// Returns true if the current profile is not incognito and meets any
// requirements for Lite Mode being enabled.
static bool IsProfileEligible(Profile* profile);
bool IsProfileEligible() const;
// Computes the AfterSRPMetrics that would be returned for the next
// navigation, when it commits. This method exists to allow the PLM Observer
// to get the AfterSRPMetrics if the navigation fails to commit, so that
......
......@@ -409,10 +409,11 @@ TEST_F(IsolatedPrerenderTabHelperTest, FeatureDisabled) {
EXPECT_FALSE(HasAfterSRPMetrics());
}
TEST_F(IsolatedPrerenderTabHelperTest, DataSaverDisabled) {
TEST_F(IsolatedPrerenderTabHelperTest, DataSaverDisabled_Required) {
base::HistogramTester histogram_tester;
base::test::ScopedFeatureList scoped_feature_list;
scoped_feature_list.InitAndEnableFeature(features::kIsolatePrerenders);
scoped_feature_list.InitAndEnableFeatureWithParameters(
features::kIsolatePrerenders, {{"lite_mode_only", "true"}});
SetDataSaverEnabled(false);
......@@ -446,6 +447,28 @@ TEST_F(IsolatedPrerenderTabHelperTest, DataSaverDisabled) {
EXPECT_FALSE(HasAfterSRPMetrics());
}
TEST_F(IsolatedPrerenderTabHelperTest, DataSaverDisabled_NotRequired) {
base::HistogramTester histogram_tester;
base::test::ScopedFeatureList scoped_feature_list;
scoped_feature_list.InitAndEnableFeatureWithParameters(
features::kIsolatePrerenders, {{"lite_mode_only", "false"}});
SetDataSaverEnabled(false);
NavigateSomewhere();
GURL doc_url("https://www.google.com/search?q=cats");
GURL prediction_url("https://www.cat-food.com/");
MakeNavigationPrediction(web_contents(), doc_url, {prediction_url});
EXPECT_EQ(RequestCount(), 1);
EXPECT_EQ(predicted_urls_count(), 1U);
EXPECT_EQ(prefetch_eligible_count(), 1U);
EXPECT_EQ(prefetch_attempted_count(), 1U);
EXPECT_EQ(prefetch_successful_count(), 0U);
EXPECT_EQ(prefetch_total_redirect_count(), 0U);
EXPECT_TRUE(navigation_to_prefetch_start().has_value());
}
TEST_F(IsolatedPrerenderTabHelperTest, GoogleSRPOnly) {
base::HistogramTester histogram_tester;
base::test::ScopedFeatureList scoped_feature_list;
......
......@@ -21,7 +21,6 @@
#include "chrome/browser/prerender/isolated/prefetched_mainframe_response_container.h"
#include "chrome/browser/prerender/prerender_manager_factory.h"
#include "chrome/browser/profiles/profile.h"
#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.h"
#include "components/prerender/browser/prerender_manager.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/storage_partition.h"
......
......@@ -13,7 +13,6 @@
#include "chrome/browser/prerender/isolated/prefetched_mainframe_response_container.h"
#include "chrome/browser/prerender/prerender_manager_factory.h"
#include "chrome/test/base/chrome_render_view_host_test_harness.h"
#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.h"
#include "components/prerender/browser/prerender_handle.h"
#include "components/prerender/browser/prerender_manager.h"
#include "content/public/browser/web_contents.h"
......@@ -78,16 +77,6 @@ class IsolatedPrerenderURLLoaderInterceptorTest
IsolatedPrerenderURLLoaderInterceptorTest() = default;
~IsolatedPrerenderURLLoaderInterceptorTest() override = default;
void SetDataSaverEnabled(bool enabled) {
data_reduction_proxy::DataReductionProxySettings::
SetDataSaverEnabledForTesting(profile()->GetPrefs(), enabled);
}
void SetUp() override {
ChromeRenderViewHostTestHarness::SetUp();
SetDataSaverEnabled(true);
}
void TearDown() override {
prerender::PrerenderManager* prerender_manager =
prerender::PrerenderManagerFactory::GetForBrowserContext(profile());
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment