Only use core DRP proxies for media requests in network service
This implements the DRP logic for only using CORE proxies when proxying RESOURCE_TYPE_MEDIA requests. A similar approach is used to DataReductionProxyDelegate, which uses an MRUCache to associate URLs to resource type during proxy resolution, since the ProxyDelegate only has access to the URL. Bug: 721403 Cq-Include-Trybots: luci.chromium.try:linux_mojo Change-Id: Ib1c50dbc1344535e46c80b2d3a900dbb6b215141 Reviewed-on: https://chromium-review.googlesource.com/c/1274526 Commit-Queue: Clark DuVall <cduvall@chromium.org> Reviewed-by: John Abd-El-Malek <jam@chromium.org> Reviewed-by: Daniel Cheng <dcheng@chromium.org> Reviewed-by: rajendrant <rajendrant@chromium.org> Reviewed-by: Tarun Bansal <tbansal@chromium.org> Cr-Commit-Position: refs/heads/master@{#600786}
This commit is contained in:
components/data_reduction_proxy
content
common
core
services/network
network_context_unittest.ccnetwork_service_proxy_delegate.ccnetwork_service_proxy_delegate.h
public
url_loader.ccurl_loader.htesting/buildbot/filters
@ -27,6 +27,9 @@ void DataReductionProxyURLLoaderThrottle::WillStartRequest(
|
||||
request->url, static_cast<content::ResourceType>(request->resource_type),
|
||||
request->previews_state, &request->custom_proxy_pre_cache_headers);
|
||||
request->custom_proxy_post_cache_headers = post_cache_headers_;
|
||||
|
||||
if (request->resource_type == content::RESOURCE_TYPE_MEDIA)
|
||||
request->custom_proxy_use_alternate_proxy_list = true;
|
||||
}
|
||||
|
||||
} // namespace data_reduction_proxy
|
||||
|
24
components/data_reduction_proxy/content/common/data_reduction_proxy_url_loader_throttle_unittest.cc
24
components/data_reduction_proxy/content/common/data_reduction_proxy_url_loader_throttle_unittest.cc
@ -62,4 +62,28 @@ TEST(DataReductionProxyURLLoaderThrottleTest,
|
||||
EXPECT_EQ(value, "bar");
|
||||
}
|
||||
|
||||
TEST(DataReductionProxyURLLoaderThrottleTest, UseAlternateProxyList) {
|
||||
DataReductionProxyURLLoaderThrottle throttle((net::HttpRequestHeaders()));
|
||||
network::ResourceRequest request;
|
||||
request.resource_type = content::RESOURCE_TYPE_MEDIA;
|
||||
request.url = GURL("http://example.com");
|
||||
bool defer = false;
|
||||
|
||||
throttle.WillStartRequest(&request, &defer);
|
||||
|
||||
EXPECT_TRUE(request.custom_proxy_use_alternate_proxy_list);
|
||||
}
|
||||
|
||||
TEST(DataReductionProxyURLLoaderThrottleTest, DontUseAlternateProxyList) {
|
||||
DataReductionProxyURLLoaderThrottle throttle((net::HttpRequestHeaders()));
|
||||
network::ResourceRequest request;
|
||||
request.resource_type = content::RESOURCE_TYPE_MAIN_FRAME;
|
||||
request.url = GURL("http://example.com");
|
||||
bool defer = false;
|
||||
|
||||
throttle.WillStartRequest(&request, &defer);
|
||||
|
||||
EXPECT_FALSE(request.custom_proxy_use_alternate_proxy_list);
|
||||
}
|
||||
|
||||
} // namespace data_reduction_proxy
|
||||
|
@ -182,14 +182,14 @@ class DataReductionProxyConfig
|
||||
// Returns the current HTTP RTT estimate.
|
||||
base::Optional<base::TimeDelta> GetHttpRttEstimate() const;
|
||||
|
||||
protected:
|
||||
virtual base::TimeTicks GetTicksNow() const;
|
||||
|
||||
// Updates the Data Reduction Proxy configurator with the current config.
|
||||
void UpdateConfigForTesting(bool enabled,
|
||||
bool secure_proxies_allowed,
|
||||
bool insecure_proxies_allowed);
|
||||
|
||||
protected:
|
||||
virtual base::TimeTicks GetTicksNow() const;
|
||||
|
||||
// Returns true if the default bypass rules should be added. Virtualized for
|
||||
// testing.
|
||||
virtual bool ShouldAddDefaultProxyBypassRules() const;
|
||||
|
@ -122,6 +122,10 @@ class DataReductionProxyConfigServiceClient
|
||||
const net::ProxyServer& proxy_server,
|
||||
const net::LoadTimingInfo& load_timing_info);
|
||||
|
||||
void SetRemoteConfigAppliedForTesting(bool remote_config_applied) {
|
||||
remote_config_applied_ = remote_config_applied;
|
||||
}
|
||||
|
||||
protected:
|
||||
// Retrieves the backoff entry object being used to throttle request failures.
|
||||
// Virtual for testing.
|
||||
|
@ -364,8 +364,24 @@ void DataReductionProxyIOData::OnProxyConfigUpdated() {
|
||||
if (!proxy_config_client_)
|
||||
return;
|
||||
|
||||
const auto proxies_for_http = config_->GetProxiesForHttp();
|
||||
|
||||
auto config = network::mojom::CustomProxyConfig::New();
|
||||
config->rules = configurator_->GetProxyConfig().proxy_rules();
|
||||
config->rules =
|
||||
configurator_
|
||||
->CreateProxyConfig(false /* probe_url_config */,
|
||||
config_->GetNetworkPropertiesManager(),
|
||||
proxies_for_http)
|
||||
.proxy_rules();
|
||||
|
||||
// Set an alternate proxy list to be used for media requests which only
|
||||
// contains proxies supporting the media resource type.
|
||||
net::ProxyList media_proxies;
|
||||
for (const auto& proxy : proxies_for_http) {
|
||||
if (proxy.SupportsResourceType(ResourceTypeProvider::CONTENT_TYPE_MEDIA))
|
||||
media_proxies.AddProxyServer(proxy.proxy_server());
|
||||
}
|
||||
config->alternate_proxy_list = media_proxies;
|
||||
|
||||
net::EffectiveConnectionType type = GetEffectiveConnectionType();
|
||||
if (type > net::EFFECTIVE_CONNECTION_TYPE_OFFLINE) {
|
||||
|
@ -13,7 +13,10 @@
|
||||
#include "base/strings/string_number_conversions.h"
|
||||
#include "base/test/scoped_task_environment.h"
|
||||
#include "base/time/time.h"
|
||||
#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_config.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_configurator.h"
|
||||
#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_mutable_config_values.h"
|
||||
#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_prefs.h"
|
||||
#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_request_options.h"
|
||||
#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.h"
|
||||
@ -37,6 +40,7 @@
|
||||
#include "services/network/test/test_network_quality_tracker.h"
|
||||
#include "testing/gtest/include/gtest/gtest.h"
|
||||
|
||||
namespace data_reduction_proxy {
|
||||
namespace {
|
||||
// Used only to verify that a wrapped network delegate gets called.
|
||||
class CountingNetworkDelegate : public net::NetworkDelegateImpl {
|
||||
@ -62,10 +66,26 @@ class CountingNetworkDelegate : public net::NetworkDelegateImpl {
|
||||
int created_requests_;
|
||||
};
|
||||
|
||||
std::string CreateEncodedConfig(
|
||||
const std::vector<DataReductionProxyServer> proxy_servers) {
|
||||
ClientConfig config;
|
||||
config.set_session_key("session");
|
||||
for (const auto& proxy_server : proxy_servers) {
|
||||
ProxyServer* config_proxy =
|
||||
config.mutable_proxy_config()->add_http_proxy_servers();
|
||||
net::HostPortPair host_port_pair =
|
||||
proxy_server.proxy_server().host_port_pair();
|
||||
config_proxy->set_scheme(ProxyServer_ProxyScheme_HTTP);
|
||||
config_proxy->set_host(host_port_pair.host());
|
||||
config_proxy->set_port(host_port_pair.port());
|
||||
config_proxy->set_type(proxy_server.IsCoreProxy()
|
||||
? ProxyServer_ProxyType_CORE
|
||||
: ProxyServer_ProxyType_UNSPECIFIED_TYPE);
|
||||
}
|
||||
return EncodeConfig(config);
|
||||
}
|
||||
} // namespace
|
||||
|
||||
namespace data_reduction_proxy {
|
||||
|
||||
class DataReductionProxyIODataTest : public testing::Test {
|
||||
public:
|
||||
DataReductionProxyIODataTest()
|
||||
@ -247,6 +267,8 @@ TEST_F(DataReductionProxyIODataTest, TestCustomProxyConfigClient) {
|
||||
client.config->post_cache_headers.HasHeader(chrome_proxy_header()));
|
||||
EXPECT_TRUE(
|
||||
client.config->pre_cache_headers.HasHeader(chrome_proxy_ect_header()));
|
||||
// Alternate proxy list should be empty because there are no core proxies.
|
||||
EXPECT_TRUE(client.config->alternate_proxy_list.IsEmpty());
|
||||
}
|
||||
|
||||
TEST_F(DataReductionProxyIODataTest, TestCustomProxyConfigUpdatedOnECTChange) {
|
||||
@ -308,6 +330,8 @@ TEST_F(DataReductionProxyIODataTest,
|
||||
|
||||
TEST_F(DataReductionProxyIODataTest,
|
||||
TestCustomProxyConfigUpdatedOnProxyChange) {
|
||||
base::CommandLine::ForCurrentProcess()->AppendSwitch(
|
||||
switches::kDisableDataReductionProxyWarmupURLFetch);
|
||||
DataReductionProxyIOData io_data(
|
||||
Client::UNKNOWN, prefs(),
|
||||
network::TestNetworkConnectionTracker::GetInstance(),
|
||||
@ -317,21 +341,61 @@ TEST_F(DataReductionProxyIODataTest,
|
||||
NetworkPropertiesManager network_properties_manager(
|
||||
base::DefaultClock::GetInstance(), prefs(),
|
||||
scoped_task_environment_.GetMainThreadTaskRunner());
|
||||
auto proxy_server = net::ProxyServer::FromPacString("PROXY foo");
|
||||
io_data.configurator()->Enable(
|
||||
network_properties_manager,
|
||||
{DataReductionProxyServer(proxy_server, ProxyServer_ProxyType_CORE)});
|
||||
io_data.config()->SetNetworkPropertiesManagerForTesting(
|
||||
&network_properties_manager);
|
||||
io_data.config()->UpdateConfigForTesting(true, true, true);
|
||||
|
||||
auto proxy_server1 = net::ProxyServer::FromPacString("PROXY foo");
|
||||
io_data.config_client()->ApplySerializedConfig(CreateEncodedConfig(
|
||||
{DataReductionProxyServer(proxy_server1, ProxyServer_ProxyType_CORE)}));
|
||||
|
||||
network::mojom::CustomProxyConfigClientPtrInfo client_ptr_info;
|
||||
TestCustomProxyConfigClient client(mojo::MakeRequest(&client_ptr_info));
|
||||
io_data.SetCustomProxyConfigClient(std::move(client_ptr_info));
|
||||
base::RunLoop().RunUntilIdle();
|
||||
|
||||
EXPECT_EQ(client.config->rules.proxies_for_http.Get(), proxy_server);
|
||||
EXPECT_EQ(client.config->rules.proxies_for_http.Get(), proxy_server1);
|
||||
|
||||
io_data.configurator()->Disable();
|
||||
auto proxy_server2 = net::ProxyServer::FromPacString("PROXY bar");
|
||||
io_data.config_client()->SetRemoteConfigAppliedForTesting(false);
|
||||
io_data.config_client()->ApplySerializedConfig(CreateEncodedConfig(
|
||||
{DataReductionProxyServer(proxy_server2, ProxyServer_ProxyType_CORE)}));
|
||||
base::RunLoop().RunUntilIdle();
|
||||
EXPECT_TRUE(client.config->rules.proxies_for_http.IsEmpty());
|
||||
|
||||
EXPECT_EQ(client.config->rules.proxies_for_http.Get(), proxy_server2);
|
||||
}
|
||||
|
||||
TEST_F(DataReductionProxyIODataTest,
|
||||
TestCustomProxyConfigHasAlternateProxyListOfCoreProxies) {
|
||||
base::CommandLine::ForCurrentProcess()->AppendSwitch(
|
||||
switches::kDisableDataReductionProxyWarmupURLFetch);
|
||||
DataReductionProxyIOData io_data(
|
||||
Client::UNKNOWN, prefs(),
|
||||
network::TestNetworkConnectionTracker::GetInstance(),
|
||||
scoped_task_environment_.GetMainThreadTaskRunner(),
|
||||
scoped_task_environment_.GetMainThreadTaskRunner(), false /* enabled */,
|
||||
std::string() /* user_agent */, std::string() /* channel */);
|
||||
NetworkPropertiesManager network_properties_manager(
|
||||
base::DefaultClock::GetInstance(), prefs(),
|
||||
scoped_task_environment_.GetMainThreadTaskRunner());
|
||||
io_data.config()->SetNetworkPropertiesManagerForTesting(
|
||||
&network_properties_manager);
|
||||
io_data.config()->UpdateConfigForTesting(true, true, true);
|
||||
|
||||
auto core_proxy_server = net::ProxyServer::FromPacString("PROXY foo");
|
||||
io_data.config_client()->ApplySerializedConfig(CreateEncodedConfig(
|
||||
{DataReductionProxyServer(core_proxy_server, ProxyServer_ProxyType_CORE),
|
||||
DataReductionProxyServer(net::ProxyServer::FromPacString("PROXY bar"),
|
||||
ProxyServer_ProxyType_UNSPECIFIED_TYPE)}));
|
||||
|
||||
network::mojom::CustomProxyConfigClientPtrInfo client_ptr_info;
|
||||
TestCustomProxyConfigClient client(mojo::MakeRequest(&client_ptr_info));
|
||||
io_data.SetCustomProxyConfigClient(std::move(client_ptr_info));
|
||||
base::RunLoop().RunUntilIdle();
|
||||
|
||||
net::ProxyList expected_proxy_list;
|
||||
expected_proxy_list.SetSingleProxyServer(core_proxy_server);
|
||||
EXPECT_TRUE(client.config->alternate_proxy_list.Equals(expected_proxy_list));
|
||||
}
|
||||
|
||||
} // namespace data_reduction_proxy
|
||||
|
@ -3869,6 +3869,16 @@ class NetworkContextMockHostTest : public NetworkContextTest {
|
||||
EXPECT_TRUE(base_url.is_valid()) << base_url.possibly_invalid_spec();
|
||||
return base_url.Resolve(relative_url);
|
||||
}
|
||||
|
||||
net::ProxyServer ConvertToProxyServer(const net::EmbeddedTestServer& server) {
|
||||
std::string base_url = server.base_url().spec();
|
||||
// Remove slash from URL.
|
||||
base_url.pop_back();
|
||||
auto proxy_server =
|
||||
net::ProxyServer::FromURI(base_url, net::ProxyServer::SCHEME_HTTP);
|
||||
EXPECT_TRUE(proxy_server.is_valid()) << base_url;
|
||||
return proxy_server;
|
||||
}
|
||||
};
|
||||
|
||||
TEST_F(NetworkContextMockHostTest, CustomProxyAddsHeaders) {
|
||||
@ -3887,10 +3897,8 @@ TEST_F(NetworkContextMockHostTest, CustomProxyAddsHeaders) {
|
||||
CreateContextWithParams(std::move(context_params));
|
||||
|
||||
auto config = mojom::CustomProxyConfig::New();
|
||||
std::string base_url = proxy_test_server.base_url().spec();
|
||||
// Remove slash from URL.
|
||||
base_url.pop_back();
|
||||
config->rules.ParseFromString("http=" + base_url);
|
||||
net::ProxyServer proxy_server = ConvertToProxyServer(proxy_test_server);
|
||||
config->rules.ParseFromString("http=" + proxy_server.ToURI());
|
||||
config->pre_cache_headers.SetHeader("pre_foo", "pre_foo_value");
|
||||
config->post_cache_headers.SetHeader("post_foo", "post_foo_value");
|
||||
proxy_config_client->OnCustomProxyConfigUpdated(std::move(config));
|
||||
@ -3911,8 +3919,7 @@ TEST_F(NetworkContextMockHostTest, CustomProxyAddsHeaders) {
|
||||
EXPECT_EQ(response, base::JoinString({"post_bar_value", "post_foo_value",
|
||||
"pre_bar_value", "pre_foo_value"},
|
||||
"\n"));
|
||||
EXPECT_EQ(client->response_head().proxy_server,
|
||||
net::ProxyServer::FromURI(base_url, net::ProxyServer::SCHEME_HTTP));
|
||||
EXPECT_EQ(client->response_head().proxy_server, proxy_server);
|
||||
}
|
||||
|
||||
TEST_F(NetworkContextMockHostTest,
|
||||
@ -3932,10 +3939,8 @@ TEST_F(NetworkContextMockHostTest,
|
||||
CreateContextWithParams(std::move(context_params));
|
||||
|
||||
auto config = mojom::CustomProxyConfig::New();
|
||||
std::string base_url = proxy_test_server.base_url().spec();
|
||||
// Remove slash from URL.
|
||||
base_url.pop_back();
|
||||
config->rules.ParseFromString("http=" + base_url);
|
||||
net::ProxyServer proxy_server = ConvertToProxyServer(proxy_test_server);
|
||||
config->rules.ParseFromString("http=" + proxy_server.ToURI());
|
||||
config->pre_cache_headers.SetHeader("foo", "bad");
|
||||
config->post_cache_headers.SetHeader("bar", "bad");
|
||||
proxy_config_client->OnCustomProxyConfigUpdated(std::move(config));
|
||||
@ -3952,8 +3957,7 @@ TEST_F(NetworkContextMockHostTest,
|
||||
mojo::BlockingCopyToString(client->response_body_release(), &response));
|
||||
|
||||
EXPECT_EQ(response, base::JoinString({"bar_value", "foo_value"}, "\n"));
|
||||
EXPECT_EQ(client->response_head().proxy_server,
|
||||
net::ProxyServer::FromURI(base_url, net::ProxyServer::SCHEME_HTTP));
|
||||
EXPECT_EQ(client->response_head().proxy_server, proxy_server);
|
||||
}
|
||||
|
||||
TEST_F(NetworkContextMockHostTest, CustomProxyConfigHeadersAddedBeforeCache) {
|
||||
@ -3972,10 +3976,8 @@ TEST_F(NetworkContextMockHostTest, CustomProxyConfigHeadersAddedBeforeCache) {
|
||||
CreateContextWithParams(std::move(context_params));
|
||||
|
||||
auto config = mojom::CustomProxyConfig::New();
|
||||
std::string base_url = proxy_test_server.base_url().spec();
|
||||
// Remove slash from URL.
|
||||
base_url.pop_back();
|
||||
config->rules.ParseFromString("http=" + base_url);
|
||||
net::ProxyServer proxy_server = ConvertToProxyServer(proxy_test_server);
|
||||
config->rules.ParseFromString("http=" + proxy_server.ToURI());
|
||||
config->pre_cache_headers.SetHeader("foo", "foo_value");
|
||||
config->post_cache_headers.SetHeader("bar", "bar_value");
|
||||
proxy_config_client->OnCustomProxyConfigUpdated(config->Clone());
|
||||
@ -3990,8 +3992,7 @@ TEST_F(NetworkContextMockHostTest, CustomProxyConfigHeadersAddedBeforeCache) {
|
||||
mojo::BlockingCopyToString(client->response_body_release(), &response));
|
||||
|
||||
EXPECT_EQ(response, base::JoinString({"bar_value", "foo_value"}, "\n"));
|
||||
EXPECT_EQ(client->response_head().proxy_server,
|
||||
net::ProxyServer::FromURI(base_url, net::ProxyServer::SCHEME_HTTP));
|
||||
EXPECT_EQ(client->response_head().proxy_server, proxy_server);
|
||||
EXPECT_FALSE(client->response_head().was_fetched_via_cache);
|
||||
|
||||
// post_cache_headers should not break caching.
|
||||
@ -4016,8 +4017,7 @@ TEST_F(NetworkContextMockHostTest, CustomProxyConfigHeadersAddedBeforeCache) {
|
||||
mojo::BlockingCopyToString(client->response_body_release(), &response));
|
||||
|
||||
EXPECT_EQ(response, base::JoinString({"new_bar", "new_foo"}, "\n"));
|
||||
EXPECT_EQ(client->response_head().proxy_server,
|
||||
net::ProxyServer::FromURI(base_url, net::ProxyServer::SCHEME_HTTP));
|
||||
EXPECT_EQ(client->response_head().proxy_server, proxy_server);
|
||||
EXPECT_FALSE(client->response_head().was_fetched_via_cache);
|
||||
}
|
||||
|
||||
@ -4037,10 +4037,8 @@ TEST_F(NetworkContextMockHostTest, CustomProxyRequestHeadersAddedBeforeCache) {
|
||||
CreateContextWithParams(std::move(context_params));
|
||||
|
||||
auto config = mojom::CustomProxyConfig::New();
|
||||
std::string base_url = proxy_test_server.base_url().spec();
|
||||
// Remove slash from URL.
|
||||
base_url.pop_back();
|
||||
config->rules.ParseFromString("http=" + base_url);
|
||||
net::ProxyServer proxy_server = ConvertToProxyServer(proxy_test_server);
|
||||
config->rules.ParseFromString("http=" + proxy_server.ToURI());
|
||||
proxy_config_client->OnCustomProxyConfigUpdated(std::move(config));
|
||||
scoped_task_environment_.RunUntilIdle();
|
||||
|
||||
@ -4055,8 +4053,7 @@ TEST_F(NetworkContextMockHostTest, CustomProxyRequestHeadersAddedBeforeCache) {
|
||||
mojo::BlockingCopyToString(client->response_body_release(), &response));
|
||||
|
||||
EXPECT_EQ(response, base::JoinString({"bar_value", "foo_value"}, "\n"));
|
||||
EXPECT_EQ(client->response_head().proxy_server,
|
||||
net::ProxyServer::FromURI(base_url, net::ProxyServer::SCHEME_HTTP));
|
||||
EXPECT_EQ(client->response_head().proxy_server, proxy_server);
|
||||
EXPECT_FALSE(client->response_head().was_fetched_via_cache);
|
||||
|
||||
// custom_proxy_post_cache_headers should not break caching.
|
||||
@ -4077,8 +4074,7 @@ TEST_F(NetworkContextMockHostTest, CustomProxyRequestHeadersAddedBeforeCache) {
|
||||
mojo::BlockingCopyToString(client->response_body_release(), &response));
|
||||
|
||||
EXPECT_EQ(response, base::JoinString({"new_bar", "new_foo"}, "\n"));
|
||||
EXPECT_EQ(client->response_head().proxy_server,
|
||||
net::ProxyServer::FromURI(base_url, net::ProxyServer::SCHEME_HTTP));
|
||||
EXPECT_EQ(client->response_head().proxy_server, proxy_server);
|
||||
EXPECT_FALSE(client->response_head().was_fetched_via_cache);
|
||||
}
|
||||
|
||||
@ -4128,10 +4124,8 @@ TEST_F(NetworkContextMockHostTest,
|
||||
mojom::NetworkContextParamsPtr context_params = CreateContextParams();
|
||||
// Set up a proxy to be used by the proxy config service.
|
||||
net::ProxyConfig proxy_config;
|
||||
std::string base_url = proxy_test_server.base_url().spec();
|
||||
// Remove slash from URL.
|
||||
base_url.pop_back();
|
||||
proxy_config.proxy_rules().ParseFromString("http=" + base_url);
|
||||
proxy_config.proxy_rules().ParseFromString(
|
||||
"http=" + ConvertToProxyServer(proxy_test_server).ToURI());
|
||||
context_params->initial_proxy_config = net::ProxyConfigWithAnnotation(
|
||||
proxy_config, TRAFFIC_ANNOTATION_FOR_TESTS);
|
||||
|
||||
@ -4160,7 +4154,46 @@ TEST_F(NetworkContextMockHostTest,
|
||||
|
||||
EXPECT_EQ(response, base::JoinString({"None", "None", "None", "None"}, "\n"));
|
||||
EXPECT_EQ(client->response_head().proxy_server,
|
||||
net::ProxyServer::FromURI(base_url, net::ProxyServer::SCHEME_HTTP));
|
||||
ConvertToProxyServer(proxy_test_server));
|
||||
}
|
||||
|
||||
TEST_F(NetworkContextMockHostTest, CustomProxyUsesAlternateProxyList) {
|
||||
net::EmbeddedTestServer invalid_server;
|
||||
ASSERT_TRUE(invalid_server.Start());
|
||||
|
||||
net::EmbeddedTestServer proxy_test_server;
|
||||
net::test_server::RegisterDefaultHandlers(&proxy_test_server);
|
||||
ASSERT_TRUE(proxy_test_server.Start());
|
||||
|
||||
mojom::CustomProxyConfigClientPtr proxy_config_client;
|
||||
mojom::NetworkContextParamsPtr context_params = CreateContextParams();
|
||||
context_params->custom_proxy_config_client_request =
|
||||
mojo::MakeRequest(&proxy_config_client);
|
||||
std::unique_ptr<NetworkContext> network_context =
|
||||
CreateContextWithParams(std::move(context_params));
|
||||
|
||||
auto config = mojom::CustomProxyConfig::New();
|
||||
config->rules.ParseFromString("http=" +
|
||||
ConvertToProxyServer(invalid_server).ToURI());
|
||||
|
||||
config->alternate_proxy_list.AddProxyServer(
|
||||
ConvertToProxyServer(proxy_test_server));
|
||||
proxy_config_client->OnCustomProxyConfigUpdated(std::move(config));
|
||||
scoped_task_environment_.RunUntilIdle();
|
||||
|
||||
ResourceRequest request;
|
||||
request.url = GURL("http://does.not.resolve/echo");
|
||||
request.custom_proxy_use_alternate_proxy_list = true;
|
||||
std::unique_ptr<TestURLLoaderClient> client =
|
||||
FetchRequest(request, network_context.get());
|
||||
std::string response;
|
||||
EXPECT_TRUE(
|
||||
mojo::BlockingCopyToString(client->response_body_release(), &response));
|
||||
|
||||
// |invalid_server| has no handlers set up so would return an empty response.
|
||||
EXPECT_EQ(response, "Echo");
|
||||
EXPECT_EQ(client->response_head().proxy_server,
|
||||
ConvertToProxyServer(proxy_test_server));
|
||||
}
|
||||
|
||||
} // namespace
|
||||
|
@ -12,6 +12,10 @@
|
||||
namespace network {
|
||||
namespace {
|
||||
|
||||
// The maximum size of the cache that contains the GURLs that should use
|
||||
// alternate proxy list.
|
||||
constexpr size_t kMaxCacheSize = 15;
|
||||
|
||||
void GetAlternativeProxy(const GURL& url,
|
||||
const net::ProxyRetryInfoMap& proxy_retry_info,
|
||||
net::ProxyInfo* result) {
|
||||
@ -61,7 +65,8 @@ bool CheckProxyList(const net::ProxyList& proxy_list,
|
||||
|
||||
NetworkServiceProxyDelegate::NetworkServiceProxyDelegate(
|
||||
mojom::CustomProxyConfigClientRequest config_client_request)
|
||||
: binding_(this, std::move(config_client_request)) {}
|
||||
: binding_(this, std::move(config_client_request)),
|
||||
should_use_alternate_proxy_list_cache_(kMaxCacheSize) {}
|
||||
|
||||
void NetworkServiceProxyDelegate::OnBeforeStartTransaction(
|
||||
net::URLRequest* request,
|
||||
@ -73,6 +78,9 @@ void NetworkServiceProxyDelegate::OnBeforeStartTransaction(
|
||||
|
||||
auto* url_loader = URLLoader::ForRequest(*request);
|
||||
if (url_loader) {
|
||||
if (url_loader->custom_proxy_use_alternate_proxy_list()) {
|
||||
should_use_alternate_proxy_list_cache_.Put(request->url().spec(), true);
|
||||
}
|
||||
headers->MergeFrom(url_loader->custom_proxy_pre_cache_headers());
|
||||
}
|
||||
}
|
||||
@ -115,8 +123,8 @@ void NetworkServiceProxyDelegate::OnResolveProxy(
|
||||
return;
|
||||
|
||||
net::ProxyInfo proxy_info;
|
||||
if (ApplyProxyConfigToProxyInfo(proxy_config_->rules, proxy_retry_info, url,
|
||||
&proxy_info)) {
|
||||
if (ApplyProxyConfigToProxyInfo(GetProxyRulesForURL(url), proxy_retry_info,
|
||||
url, &proxy_info)) {
|
||||
DCHECK(!proxy_info.is_empty() && !proxy_info.is_direct());
|
||||
result->OverrideProxyList(proxy_info.proxy_list());
|
||||
GetAlternativeProxy(url, proxy_retry_info, result);
|
||||
@ -154,4 +162,15 @@ bool NetworkServiceProxyDelegate::EligibleForProxy(
|
||||
MayProxyURL(url) && net::HttpUtil::IsMethodIdempotent(method);
|
||||
}
|
||||
|
||||
net::ProxyConfig::ProxyRules NetworkServiceProxyDelegate::GetProxyRulesForURL(
|
||||
const GURL& url) const {
|
||||
net::ProxyConfig::ProxyRules rules = proxy_config_->rules;
|
||||
const auto iter = should_use_alternate_proxy_list_cache_.Peek(url.spec());
|
||||
if (iter == should_use_alternate_proxy_list_cache_.end())
|
||||
return rules;
|
||||
|
||||
rules.proxies_for_http = proxy_config_->alternate_proxy_list;
|
||||
return rules;
|
||||
}
|
||||
|
||||
} // namespace network
|
||||
|
@ -6,6 +6,7 @@
|
||||
#define SERVICES_NETWORK_NETWORK_SERVICE_PROXY_DELEGATE_H_
|
||||
|
||||
#include "base/component_export.h"
|
||||
#include "base/containers/mru_cache.h"
|
||||
#include "base/macros.h"
|
||||
#include "mojo/public/cpp/bindings/binding.h"
|
||||
#include "net/base/proxy_delegate.h"
|
||||
@ -55,6 +56,9 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) NetworkServiceProxyDelegate
|
||||
const GURL& url,
|
||||
const std::string& method) const;
|
||||
|
||||
// Get the proxy rules that apply to |url|.
|
||||
net::ProxyConfig::ProxyRules GetProxyRulesForURL(const GURL& url) const;
|
||||
|
||||
// mojom::CustomProxyConfigClient implementation:
|
||||
void OnCustomProxyConfigUpdated(
|
||||
mojom::CustomProxyConfigPtr proxy_config) override;
|
||||
@ -62,6 +66,8 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) NetworkServiceProxyDelegate
|
||||
mojom::CustomProxyConfigPtr proxy_config_;
|
||||
mojo::Binding<mojom::CustomProxyConfigClient> binding_;
|
||||
|
||||
base::MRUCache<std::string, bool> should_use_alternate_proxy_list_cache_;
|
||||
|
||||
DISALLOW_COPY_AND_ASSIGN(NetworkServiceProxyDelegate);
|
||||
};
|
||||
|
||||
|
@ -182,6 +182,7 @@ IPC_STRUCT_TRAITS_BEGIN(network::ResourceRequest)
|
||||
IPC_STRUCT_TRAITS_MEMBER(throttling_profile_id)
|
||||
IPC_STRUCT_TRAITS_MEMBER(custom_proxy_pre_cache_headers)
|
||||
IPC_STRUCT_TRAITS_MEMBER(custom_proxy_post_cache_headers)
|
||||
IPC_STRUCT_TRAITS_MEMBER(custom_proxy_use_alternate_proxy_list)
|
||||
IPC_STRUCT_TRAITS_END()
|
||||
|
||||
IPC_STRUCT_TRAITS_BEGIN(network::ResourceResponseInfo)
|
||||
|
@ -237,6 +237,9 @@ struct COMPONENT_EXPORT(NETWORK_CPP_BASE) ResourceRequest {
|
||||
// that match the custom proxy config, and would otherwise be made direct.
|
||||
net::HttpRequestHeaders custom_proxy_pre_cache_headers;
|
||||
net::HttpRequestHeaders custom_proxy_post_cache_headers;
|
||||
|
||||
// Whether to use the alternate proxies set in the custom proxy config.
|
||||
bool custom_proxy_use_alternate_proxy_list = false;
|
||||
};
|
||||
|
||||
} // namespace network
|
||||
|
@ -43,6 +43,10 @@ struct CustomProxyConfig {
|
||||
// http requests.
|
||||
ProxyRules rules;
|
||||
|
||||
// List of proxies that will be used if
|
||||
// ResourceRequest::custom_proxy_use_alternate_proxy_list is set.
|
||||
ProxyList alternate_proxy_list;
|
||||
|
||||
// The custom proxy can set these headers in this config which will be added
|
||||
// to all requests using the proxy. This allows setting headers that may be
|
||||
// privacy/security sensitive which we don't want to send to the renderer.
|
||||
|
@ -323,6 +323,8 @@ URLLoader::URLLoader(
|
||||
first_auth_attempt_(true),
|
||||
custom_proxy_pre_cache_headers_(request.custom_proxy_pre_cache_headers),
|
||||
custom_proxy_post_cache_headers_(request.custom_proxy_post_cache_headers),
|
||||
custom_proxy_use_alternate_proxy_list_(
|
||||
request.custom_proxy_use_alternate_proxy_list),
|
||||
weak_ptr_factory_(this) {
|
||||
DCHECK(delete_callback_);
|
||||
if (!base::FeatureList::IsEnabled(features::kNetworkService)) {
|
||||
|
@ -111,6 +111,10 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) URLLoader
|
||||
return custom_proxy_post_cache_headers_;
|
||||
}
|
||||
|
||||
bool custom_proxy_use_alternate_proxy_list() const {
|
||||
return custom_proxy_use_alternate_proxy_list_;
|
||||
}
|
||||
|
||||
// Gets the URLLoader associated with this request.
|
||||
static URLLoader* ForRequest(const net::URLRequest& request);
|
||||
|
||||
@ -265,6 +269,7 @@ class COMPONENT_EXPORT(NETWORK_SERVICE) URLLoader
|
||||
|
||||
net::HttpRequestHeaders custom_proxy_pre_cache_headers_;
|
||||
net::HttpRequestHeaders custom_proxy_post_cache_headers_;
|
||||
bool custom_proxy_use_alternate_proxy_list_ = false;
|
||||
|
||||
base::WeakPtrFactory<URLLoader> weak_ptr_factory_;
|
||||
|
||||
|
@ -108,7 +108,6 @@
|
||||
-DataReductionProxyFallbackBrowsertest.FallbackProxyUsedWhenBlockZeroHeaderSent
|
||||
-DataReductionProxyFallbackBrowsertest.FallbackProxyUsedWhenBypassHeaderSent
|
||||
-DataReductionProxyFallbackBrowsertest.NoProxyUsedWhenBlockOnceHeaderSent
|
||||
-DataReductionProxyResourceTypeBrowsertest.CoreProxyUsedForMedia
|
||||
|
||||
# NOTE: if adding an exclusion for an existing failure (e.g. additional test for
|
||||
# feature X that is already not working), please add it beside the existing
|
||||
|
Reference in New Issue
Block a user