0

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:
Clark DuVall
2018-10-18 16:17:13 +00:00
committed by Commit Bot
parent a122489ac9
commit 6bd28572e9
15 changed files with 233 additions and 50 deletions

@ -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

@ -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