Commit 9e621293 authored by sclittle's avatar sclittle Committed by Commit bot

Make Data Saver proxy bypass logic apply to redirects.

This change makes the DataReductionProxyInterceptor intercept redirects
as well as responses. This will cause clients on captive portal networks
that cause redirect loops when trying to use Data Saver bypass
immediately instead of waiting for 21 redirects.

BUG=460346

Review URL: https://codereview.chromium.org/958163004

Cr-Commit-Position: refs/heads/master@{#319120}
parent a03124d1
...@@ -181,6 +181,8 @@ ...@@ -181,6 +181,8 @@
'data_reduction_proxy/core/common/data_reduction_proxy_params_test_utils.cc', 'data_reduction_proxy/core/common/data_reduction_proxy_params_test_utils.cc',
'data_reduction_proxy/core/common/data_reduction_proxy_params_test_utils.h', 'data_reduction_proxy/core/common/data_reduction_proxy_params_test_utils.h',
], ],
# TODO(jschuh): crbug.com/167187 fix size_t to int truncations.
'msvs_disabled_warnings': [4267, ],
}, },
{ {
'target_name': 'data_reduction_proxy_version_header', 'target_name': 'data_reduction_proxy_version_header',
......
...@@ -64,6 +64,8 @@ source_set("test_support") { ...@@ -64,6 +64,8 @@ source_set("test_support") {
"data_reduction_proxy_test_utils.h", "data_reduction_proxy_test_utils.h",
] ]
configs += [ "//build/config/compiler:no_size_t_to_int_warning" ]
public_deps = [ public_deps = [
":browser", ":browser",
] ]
......
...@@ -34,9 +34,23 @@ net::URLRequestJob* DataReductionProxyInterceptor::MaybeInterceptRequest( ...@@ -34,9 +34,23 @@ net::URLRequestJob* DataReductionProxyInterceptor::MaybeInterceptRequest(
return nullptr; return nullptr;
} }
net::URLRequestJob* DataReductionProxyInterceptor::MaybeInterceptRedirect(
net::URLRequest* request,
net::NetworkDelegate* network_delegate,
const GURL& location) const {
return MaybeInterceptResponseOrRedirect(request, network_delegate);
}
net::URLRequestJob* DataReductionProxyInterceptor::MaybeInterceptResponse( net::URLRequestJob* DataReductionProxyInterceptor::MaybeInterceptResponse(
net::URLRequest* request, net::URLRequest* request,
net::NetworkDelegate* network_delegate) const { net::NetworkDelegate* network_delegate) const {
return MaybeInterceptResponseOrRedirect(request, network_delegate);
}
net::URLRequestJob*
DataReductionProxyInterceptor::MaybeInterceptResponseOrRedirect(
net::URLRequest* request,
net::NetworkDelegate* network_delegate) const {
if (request->response_info().was_cached) if (request->response_info().was_cached)
return nullptr; return nullptr;
DataReductionProxyBypassType bypass_type = BYPASS_EVENT_TYPE_MAX; DataReductionProxyBypassType bypass_type = BYPASS_EVENT_TYPE_MAX;
......
...@@ -15,7 +15,7 @@ class DataReductionProxyEventStore; ...@@ -15,7 +15,7 @@ class DataReductionProxyEventStore;
class DataReductionProxyUsageStats; class DataReductionProxyUsageStats;
// Used to intercept responses that contain explicit and implicit signals // Used to intercept responses that contain explicit and implicit signals
// to bypass the data reduction proxy. If the proxy should be bypassed, // to bypass the Data Reduction Proxy. If the proxy should be bypassed,
// the interceptor returns a new URLRequestHTTPJob that fetches the resource // the interceptor returns a new URLRequestHTTPJob that fetches the resource
// without use of the proxy. // without use of the proxy.
class DataReductionProxyInterceptor : public net::URLRequestInterceptor { class DataReductionProxyInterceptor : public net::URLRequestInterceptor {
...@@ -34,15 +34,28 @@ class DataReductionProxyInterceptor : public net::URLRequestInterceptor { ...@@ -34,15 +34,28 @@ class DataReductionProxyInterceptor : public net::URLRequestInterceptor {
net::URLRequest* request, net::URLRequest* request,
net::NetworkDelegate* network_delegate) const override; net::NetworkDelegate* network_delegate) const override;
// Returns a new URLRequestHTTPJob if the response indicates that the data // Returns a new URLRequestHTTPJob if the redirect indicates that the Data
// reduction proxy should be bypassed according to the rules in |protocol_|. // Reduction Proxy should be bypassed. See |MaybeInterceptResponseOrRedirect|
// Returns NULL otherwise. If a job is returned, the interceptor's // for more details.
// URLRequestInterceptingJobFactory will restart the request. net::URLRequestJob* MaybeInterceptRedirect(
net::URLRequest* request, net::NetworkDelegate* network_delegate,
const GURL& location) const override;
// Returns a new URLRequestHTTPJob if the response indicates that the Data
// Reduction Proxy should be bypassed. See |MaybeInterceptResponseOrRedirect|
// for more details.
net::URLRequestJob* MaybeInterceptResponse( net::URLRequestJob* MaybeInterceptResponse(
net::URLRequest* request, net::URLRequest* request,
net::NetworkDelegate* network_delegate) const override; net::NetworkDelegate* network_delegate) const override;
private: private:
// Returns a new URLRequestHTTPJob if the response or redirect indicates that
// the data reduction proxy should be bypassed according to the rules in
// |bypass_protocol_|. Returns NULL otherwise. If a job is returned, the
// interceptor's URLRequestInterceptingJobFactory will restart the request.
net::URLRequestJob* MaybeInterceptResponseOrRedirect(
net::URLRequest* request, net::NetworkDelegate* network_delegate) const;
// Must outlive |this| if non-NULL. // Must outlive |this| if non-NULL.
DataReductionProxyUsageStats* usage_stats_; DataReductionProxyUsageStats* usage_stats_;
......
...@@ -5,23 +5,31 @@ ...@@ -5,23 +5,31 @@
#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_interceptor.h" #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_interceptor.h"
#include <string> #include <string>
#include <vector>
#include "base/files/file_path.h" #include "base/files/file_path.h"
#include "base/memory/ref_counted.h" #include "base/memory/ref_counted.h"
#include "base/memory/scoped_ptr.h" #include "base/memory/scoped_ptr.h"
#include "base/memory/scoped_vector.h"
#include "base/message_loop/message_loop.h" #include "base/message_loop/message_loop.h"
#include "base/prefs/pref_service.h"
#include "base/run_loop.h" #include "base/run_loop.h"
#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_config_test_utils.h" #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_config_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_io_data.h" #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.h"
#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.h" #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.h"
#include "components/data_reduction_proxy/core/common/data_reduction_proxy_params.h" #include "components/data_reduction_proxy/core/common/data_reduction_proxy_params.h"
#include "components/data_reduction_proxy/core/common/data_reduction_proxy_params_test_utils.h" #include "components/data_reduction_proxy/core/common/data_reduction_proxy_params_test_utils.h"
#include "components/data_reduction_proxy/core/common/data_reduction_proxy_pref_names.h"
#include "net/base/capturing_net_log.h" #include "net/base/capturing_net_log.h"
#include "net/base/net_errors.h"
#include "net/base/request_priority.h" #include "net/base/request_priority.h"
#include "net/http/http_response_headers.h" #include "net/http/http_response_headers.h"
#include "net/proxy/proxy_server.h" #include "net/proxy/proxy_server.h"
#include "net/socket/socket_test_util.h"
#include "net/test/embedded_test_server/embedded_test_server.h" #include "net/test/embedded_test_server/embedded_test_server.h"
#include "net/url_request/url_request.h" #include "net/url_request/url_request.h"
#include "net/url_request/url_request_context_storage.h"
#include "net/url_request/url_request_intercepting_job_factory.h" #include "net/url_request/url_request_intercepting_job_factory.h"
#include "net/url_request/url_request_interceptor.h" #include "net/url_request/url_request_interceptor.h"
#include "net/url_request/url_request_job.h" #include "net/url_request/url_request_job.h"
...@@ -30,8 +38,12 @@ ...@@ -30,8 +38,12 @@
#include "net/url_request/url_request_test_util.h" #include "net/url_request/url_request_test_util.h"
#include "testing/gtest/include/gtest/gtest.h" #include "testing/gtest/include/gtest/gtest.h"
using net::MockRead;
namespace data_reduction_proxy { namespace data_reduction_proxy {
namespace {
class CountingURLRequestInterceptor : public net::URLRequestInterceptor { class CountingURLRequestInterceptor : public net::URLRequestInterceptor {
public: public:
CountingURLRequestInterceptor() CountingURLRequestInterceptor()
...@@ -264,4 +276,206 @@ TEST_F(DataReductionProxyInterceptorWithServerTest, TestNoBypass) { ...@@ -264,4 +276,206 @@ TEST_F(DataReductionProxyInterceptorWithServerTest, TestNoBypass) {
EXPECT_EQ("hello", delegate.data_received()); EXPECT_EQ("hello", delegate.data_received());
} }
class DataReductionProxyInterceptorEndToEndTest : public testing::Test {
public:
DataReductionProxyInterceptorEndToEndTest()
: context_(true), context_storage_(&context_) {}
~DataReductionProxyInterceptorEndToEndTest() override {}
void SetUp() override {
drp_test_context_ =
DataReductionProxyTestContext::Builder()
.WithParamsFlags(DataReductionProxyParams::kAllowed |
DataReductionProxyParams::kFallbackAllowed)
.WithParamsDefinitions(
TestDataReductionProxyParams::HAS_EVERYTHING &
~TestDataReductionProxyParams::HAS_DEV_ORIGIN &
~TestDataReductionProxyParams::HAS_DEV_FALLBACK_ORIGIN)
.WithURLRequestContext(&context_)
.WithMockClientSocketFactory(&mock_socket_factory_)
.Build();
drp_test_context_->AttachToURLRequestContext(&context_storage_);
context_.set_client_socket_factory(&mock_socket_factory_);
context_.Init();
drp_test_context_->EnableDataReductionProxyWithSecureProxyCheckSuccess();
// Three proxies should be available for use: primary, fallback, and direct.
const net::ProxyConfig& proxy_config =
drp_test_context_->configurator()->GetProxyConfigOnIOThread();
EXPECT_EQ(3U, proxy_config.proxy_rules().proxies_for_http.size());
}
// Creates a URLRequest using the test's TestURLRequestContext and executes
// it. Returns the created URLRequest.
scoped_ptr<net::URLRequest> CreateAndExecuteRequest(const GURL& url) {
scoped_ptr<net::URLRequest> request(
context_.CreateRequest(url, net::IDLE, &delegate_, NULL));
request->Start();
drp_test_context_->RunUntilIdle();
return request.Pass();
}
const net::TestDelegate& delegate() const {
return delegate_;
}
net::MockClientSocketFactory* mock_socket_factory() {
return &mock_socket_factory_;
}
DataReductionProxyConfig* config() const {
return drp_test_context_->config();
}
private:
net::TestDelegate delegate_;
net::MockClientSocketFactory mock_socket_factory_;
net::TestURLRequestContext context_;
net::URLRequestContextStorage context_storage_;
scoped_ptr<DataReductionProxyTestContext> drp_test_context_;
};
const std::string kBody = "response body";
TEST_F(DataReductionProxyInterceptorEndToEndTest, ResponseWithoutRetry) {
// The response comes through the proxy and should not be retried.
MockRead mock_reads[] = {
MockRead("HTTP/1.1 200 OK\r\nVia: 1.1 Chrome-Compression-Proxy\r\n\r\n"),
MockRead(kBody.c_str()),
MockRead(net::SYNCHRONOUS, net::OK),
};
net::StaticSocketDataProvider socket_data_provider(
mock_reads, arraysize(mock_reads), nullptr, 0);
mock_socket_factory()->AddSocketDataProvider(&socket_data_provider);
scoped_ptr<net::URLRequest> request =
CreateAndExecuteRequest(GURL("http://foo.com"));
EXPECT_EQ(net::URLRequestStatus::SUCCESS, request->status().status());
EXPECT_EQ(200, request->GetResponseCode());
EXPECT_EQ(kBody, delegate().data_received());
EXPECT_EQ(config()->Origin().host_port_pair().ToString(),
request->proxy_server().ToString());
}
TEST_F(DataReductionProxyInterceptorEndToEndTest, RedirectWithoutRetry) {
// The redirect comes through the proxy and should not be retried.
MockRead redirect_mock_reads[] = {
MockRead("HTTP/1.1 302 Found\r\n"
"Via: 1.1 Chrome-Compression-Proxy\r\n"
"Location: http://bar.com/\r\n\r\n"),
MockRead(""),
MockRead(net::SYNCHRONOUS, net::OK),
};
net::StaticSocketDataProvider redirect_socket_data_provider(
redirect_mock_reads, arraysize(redirect_mock_reads), nullptr, 0);
mock_socket_factory()->AddSocketDataProvider(&redirect_socket_data_provider);
// The response after the redirect comes through proxy and should not be
// retried.
MockRead response_mock_reads[] = {
MockRead("HTTP/1.1 200 OK\r\nVia: 1.1 Chrome-Compression-Proxy\r\n\r\n"),
MockRead(kBody.c_str()),
MockRead(net::SYNCHRONOUS, net::OK),
};
net::StaticSocketDataProvider response_socket_data_provider(
response_mock_reads, arraysize(response_mock_reads), nullptr, 0);
mock_socket_factory()->AddSocketDataProvider(&response_socket_data_provider);
scoped_ptr<net::URLRequest> request =
CreateAndExecuteRequest(GURL("http://foo.com"));
EXPECT_EQ(net::URLRequestStatus::SUCCESS, request->status().status());
EXPECT_EQ(200, request->GetResponseCode());
EXPECT_EQ(kBody, delegate().data_received());
EXPECT_EQ(config()->Origin().host_port_pair().ToString(),
request->proxy_server().ToString());
// The redirect should have been processed and followed normally.
EXPECT_EQ(1, delegate().received_redirect_count());
}
TEST_F(DataReductionProxyInterceptorEndToEndTest, ResponseWithBypassAndRetry) {
// The first try gives a bypass.
MockRead initial_mock_reads[] = {
MockRead("HTTP/1.1 502 Bad Gateway\r\n"
"Via: 1.1 Chrome-Compression-Proxy\r\n"
"Chrome-Proxy: block-once\r\n\r\n"),
MockRead(""),
MockRead(net::SYNCHRONOUS, net::OK),
};
net::StaticSocketDataProvider initial_socket_data_provider(
initial_mock_reads, arraysize(initial_mock_reads), nullptr, 0);
mock_socket_factory()->AddSocketDataProvider(&initial_socket_data_provider);
// The retry after the bypass is successful.
MockRead retry_mock_reads[] = {
MockRead("HTTP/1.1 200 OK\r\n\r\n"),
MockRead(kBody.c_str()),
MockRead(net::SYNCHRONOUS, net::OK),
};
net::StaticSocketDataProvider retry_socket_data_provider(
retry_mock_reads, arraysize(retry_mock_reads), nullptr, 0);
mock_socket_factory()->AddSocketDataProvider(&retry_socket_data_provider);
scoped_ptr<net::URLRequest> request = CreateAndExecuteRequest(
GURL("http://foo.com"));
EXPECT_EQ(net::URLRequestStatus::SUCCESS, request->status().status());
EXPECT_EQ(200, request->GetResponseCode());
EXPECT_EQ(kBody, delegate().data_received());
EXPECT_FALSE(request->was_fetched_via_proxy());
// The bypassed response should have been intercepted before the response was
// processed, so only the final response after the retry should have been
// processed.
EXPECT_EQ(1, delegate().response_started_count());
}
TEST_F(DataReductionProxyInterceptorEndToEndTest, RedirectWithBypassAndRetry) {
MockRead mock_reads_array[][3] = {
// First, get a redirect without a via header, which should be retried
// using the fallback proxy.
{
MockRead("HTTP/1.1 302 Found\r\n"
"Location: http://bar.com/\r\n\r\n"),
MockRead(""),
MockRead(net::SYNCHRONOUS, net::OK),
},
// Same as before, but through the fallback proxy. Now both proxies are
// bypassed, and the request should be retried over direct.
{
MockRead("HTTP/1.1 302 Found\r\n"
"Location: http://baz.com/\r\n\r\n"),
MockRead(""),
MockRead(net::SYNCHRONOUS, net::OK),
},
// Finally, a successful response is received.
{
MockRead("HTTP/1.1 200 OK\r\n\r\n"),
MockRead(kBody.c_str()),
MockRead(net::SYNCHRONOUS, net::OK),
},
};
ScopedVector<net::SocketDataProvider> socket_data_providers;
for (MockRead* mock_reads : mock_reads_array) {
socket_data_providers.push_back(
new net::StaticSocketDataProvider(mock_reads, 3, nullptr, 0));
mock_socket_factory()->AddSocketDataProvider(socket_data_providers.back());
}
scoped_ptr<net::URLRequest> request =
CreateAndExecuteRequest(GURL("http://foo.com"));
EXPECT_EQ(net::URLRequestStatus::SUCCESS, request->status().status());
EXPECT_EQ(200, request->GetResponseCode());
EXPECT_EQ(kBody, delegate().data_received());
EXPECT_FALSE(request->was_fetched_via_proxy());
// Each of the redirects should have been intercepted before being followed.
EXPECT_EQ(0, delegate().received_redirect_count());
EXPECT_EQ(std::vector<GURL>(1, GURL("http://foo.com")), request->url_chain());
}
} // namespace
} // namespace data_reduction_proxy } // namespace data_reduction_proxy
...@@ -9,12 +9,17 @@ ...@@ -9,12 +9,17 @@
#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_config_test_utils.h" #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_config_test_utils.h"
#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_configurator_test_utils.h" #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_configurator_test_utils.h"
#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_interceptor.h" #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_interceptor.h"
#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.h"
#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_prefs.h" #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_prefs.h"
#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.h" #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_settings.h"
#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_statistics_prefs.h" #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_statistics_prefs.h"
#include "components/data_reduction_proxy/core/common/data_reduction_proxy_event_store.h" #include "components/data_reduction_proxy/core/common/data_reduction_proxy_event_store.h"
#include "components/data_reduction_proxy/core/common/data_reduction_proxy_params.h" #include "components/data_reduction_proxy/core/common/data_reduction_proxy_params.h"
#include "components/data_reduction_proxy/core/common/data_reduction_proxy_params_test_utils.h" #include "components/data_reduction_proxy/core/common/data_reduction_proxy_params_test_utils.h"
#include "net/socket/socket_test_util.h"
#include "net/url_request/url_request_context_storage.h"
#include "net/url_request/url_request_intercepting_job_factory.h"
#include "net/url_request/url_request_job_factory_impl.h"
#include "net/url_request/url_request_test_util.h" #include "net/url_request/url_request_test_util.h"
namespace data_reduction_proxy { namespace data_reduction_proxy {
...@@ -56,6 +61,7 @@ DataReductionProxyTestContext::Builder::Builder() ...@@ -56,6 +61,7 @@ DataReductionProxyTestContext::Builder::Builder()
params_definitions_(0), params_definitions_(0),
client_(Client::UNKNOWN), client_(Client::UNKNOWN),
request_context_(nullptr), request_context_(nullptr),
mock_socket_factory_(nullptr),
use_mock_config_(false), use_mock_config_(false),
use_test_configurator_(false), use_test_configurator_(false),
use_mock_service_(false), use_mock_service_(false),
...@@ -82,6 +88,13 @@ DataReductionProxyTestContext::Builder::WithURLRequestContext( ...@@ -82,6 +88,13 @@ DataReductionProxyTestContext::Builder::WithURLRequestContext(
return *this; return *this;
} }
DataReductionProxyTestContext::Builder&
DataReductionProxyTestContext::Builder::WithMockClientSocketFactory(
net::MockClientSocketFactory* mock_socket_factory) {
mock_socket_factory_ = mock_socket_factory;
return *this;
}
DataReductionProxyTestContext::Builder& DataReductionProxyTestContext::Builder&
DataReductionProxyTestContext::Builder::WithClient(Client client) { DataReductionProxyTestContext::Builder::WithClient(Client client) {
client_ = client; client_ = client;
...@@ -127,7 +140,13 @@ DataReductionProxyTestContext::Builder::Build() { ...@@ -127,7 +140,13 @@ DataReductionProxyTestContext::Builder::Build() {
request_context_getter = new net::TrivialURLRequestContextGetter( request_context_getter = new net::TrivialURLRequestContextGetter(
request_context_, task_runner); request_context_, task_runner);
} else { } else {
request_context_getter = new net::TestURLRequestContextGetter(task_runner); scoped_ptr<net::TestURLRequestContext> test_request_context(
new net::TestURLRequestContext(true));
if (mock_socket_factory_)
test_request_context->set_client_socket_factory(mock_socket_factory_);
test_request_context->Init();
request_context_getter = new net::TestURLRequestContextGetter(
task_runner, test_request_context.Pass());
} }
scoped_ptr<DataReductionProxyEventStore> event_store( scoped_ptr<DataReductionProxyEventStore> event_store(
...@@ -176,8 +195,8 @@ DataReductionProxyTestContext::Builder::Build() { ...@@ -176,8 +195,8 @@ DataReductionProxyTestContext::Builder::Build() {
scoped_ptr<DataReductionProxyTestContext> test_context( scoped_ptr<DataReductionProxyTestContext> test_context(
new DataReductionProxyTestContext( new DataReductionProxyTestContext(
loop.Pass(), task_runner, pref_service.Pass(), net_log.Pass(), loop.Pass(), task_runner, pref_service.Pass(), net_log.Pass(),
request_context_getter, io_data.Pass(), settings.Pass(), request_context_getter, mock_socket_factory_, io_data.Pass(),
test_context_flags)); settings.Pass(), test_context_flags));
if (!skip_settings_initialization_) if (!skip_settings_initialization_)
test_context->InitSettingsWithoutCheck(); test_context->InitSettingsWithoutCheck();
...@@ -191,6 +210,7 @@ DataReductionProxyTestContext::DataReductionProxyTestContext( ...@@ -191,6 +210,7 @@ DataReductionProxyTestContext::DataReductionProxyTestContext(
scoped_ptr<TestingPrefServiceSimple> simple_pref_service, scoped_ptr<TestingPrefServiceSimple> simple_pref_service,
scoped_ptr<net::CapturingNetLog> net_log, scoped_ptr<net::CapturingNetLog> net_log,
scoped_refptr<net::URLRequestContextGetter> request_context_getter, scoped_refptr<net::URLRequestContextGetter> request_context_getter,
net::MockClientSocketFactory* mock_socket_factory,
scoped_ptr<TestDataReductionProxyIOData> io_data, scoped_ptr<TestDataReductionProxyIOData> io_data,
scoped_ptr<DataReductionProxySettings> settings, scoped_ptr<DataReductionProxySettings> settings,
unsigned int test_context_flags) unsigned int test_context_flags)
...@@ -200,6 +220,7 @@ DataReductionProxyTestContext::DataReductionProxyTestContext( ...@@ -200,6 +220,7 @@ DataReductionProxyTestContext::DataReductionProxyTestContext(
simple_pref_service_(simple_pref_service.Pass()), simple_pref_service_(simple_pref_service.Pass()),
net_log_(net_log.Pass()), net_log_(net_log.Pass()),
request_context_getter_(request_context_getter), request_context_getter_(request_context_getter),
mock_socket_factory_(mock_socket_factory),
io_data_(io_data.Pass()), io_data_(io_data.Pass()),
settings_(settings.Pass()) { settings_(settings.Pass()) {
} }
...@@ -249,6 +270,51 @@ DataReductionProxyTestContext::CreateDataReductionProxyServiceInternal() { ...@@ -249,6 +270,51 @@ DataReductionProxyTestContext::CreateDataReductionProxyServiceInternal() {
} }
} }
void DataReductionProxyTestContext::AttachToURLRequestContext(
net::URLRequestContextStorage* request_context_storage) const {
DCHECK(request_context_storage);
// |request_context_storage| takes ownership of the network delegate.
request_context_storage->set_network_delegate(
io_data()->CreateNetworkDelegate(
scoped_ptr<net::NetworkDelegate>(new net::TestNetworkDelegate()),
true).release());
// |request_context_storage| takes ownership of the job factory.
request_context_storage->set_job_factory(
new net::URLRequestInterceptingJobFactory(
scoped_ptr<net::URLRequestJobFactory>(
new net::URLRequestJobFactoryImpl()),
io_data()->CreateInterceptor().Pass()));
}
void DataReductionProxyTestContext::
EnableDataReductionProxyWithSecureProxyCheckSuccess() {
DCHECK(mock_socket_factory_);
// This won't actually update the proxy config when using a test configurator.
DCHECK(!(test_context_flags_ &
DataReductionProxyTestContext::USE_TEST_CONFIGURATOR));
// |settings_| needs to have been initialized, since a
// |DataReductionProxyService| is needed in order to issue the secure proxy
// check.
DCHECK(data_reduction_proxy_service());
// Enable the Data Reduction Proxy, simulating a successful secure proxy
// check.
net::MockRead mock_reads[] = {
net::MockRead("HTTP/1.1 200 OK\r\n\r\n"),
net::MockRead("OK"),
net::MockRead(net::SYNCHRONOUS, net::OK),
};
net::StaticSocketDataProvider socket_data_provider(
mock_reads, arraysize(mock_reads), nullptr, 0);
mock_socket_factory_->AddSocketDataProvider(&socket_data_provider);
// Set the pref to cause the secure proxy check to be issued.
pref_service()->SetBoolean(prefs::kDataReductionProxyEnabled, true);
RunUntilIdle();
}
TestDataReductionProxyConfigurator* TestDataReductionProxyConfigurator*
DataReductionProxyTestContext::test_configurator() const { DataReductionProxyTestContext::test_configurator() const {
DCHECK(test_context_flags_ & DCHECK(test_context_flags_ &
......
...@@ -21,9 +21,11 @@ class SingleThreadTaskRunner; ...@@ -21,9 +21,11 @@ class SingleThreadTaskRunner;
} }
namespace net { namespace net {
class MockClientSocketFactory;
class NetLog; class NetLog;
class URLRequestContext; class URLRequestContext;
class URLRequestContextGetter; class URLRequestContextGetter;
class URLRequestContextStorage;
} }
namespace data_reduction_proxy { namespace data_reduction_proxy {
...@@ -94,6 +96,15 @@ class DataReductionProxyTestContext { ...@@ -94,6 +96,15 @@ class DataReductionProxyTestContext {
// owned by the caller. // owned by the caller.
Builder& WithURLRequestContext(net::URLRequestContext* request_context); Builder& WithURLRequestContext(net::URLRequestContext* request_context);
// Specifies a |net::MockClientSocketFactory| to use. The
// |mock_socket_factory| is owned by the caller. If a non-NULL
// |request_context_| is also specified, then the caller is responsible for
// attaching |mock_socket_factory| to |request_context_|. Otherwise,
// |mock_socket_factory| will be attached to the dummy
// |net::URLRequestContext| generated during Build().
Builder& WithMockClientSocketFactory(
net::MockClientSocketFactory* mock_socket_factory);
// Specifies the use of |MockDataReductionProxyConfig| instead of // Specifies the use of |MockDataReductionProxyConfig| instead of
// |TestDataReductionProxyConfig|. // |TestDataReductionProxyConfig|.
Builder& WithMockConfig(); Builder& WithMockConfig();
...@@ -117,6 +128,7 @@ class DataReductionProxyTestContext { ...@@ -117,6 +128,7 @@ class DataReductionProxyTestContext {
unsigned int params_definitions_; unsigned int params_definitions_;
Client client_; Client client_;
net::URLRequestContext* request_context_; net::URLRequestContext* request_context_;
net::MockClientSocketFactory* mock_socket_factory_;
bool use_mock_config_; bool use_mock_config_;
bool use_test_configurator_; bool use_test_configurator_;
...@@ -139,6 +151,19 @@ class DataReductionProxyTestContext { ...@@ -139,6 +151,19 @@ class DataReductionProxyTestContext {
// SkipSettingsInitialization. // SkipSettingsInitialization.
scoped_ptr<DataReductionProxyService> CreateDataReductionProxyService(); scoped_ptr<DataReductionProxyService> CreateDataReductionProxyService();
// This creates a |DataReductionProxyNetworkDelegate| and
// |DataReductionProxyInterceptor|, using them in the |net::URLRequestContext|
// for |request_context_storage|. |request_context_storage| takes ownership of
// the created objects.
void AttachToURLRequestContext(
net::URLRequestContextStorage* request_context_storage) const;
// Enable the Data Reduction Proxy, simulating a successful secure proxy
// check. This can only be called if not built with WithTestConfigurator,
// |settings_| has been initialized, and |this| was built with a
// |net::MockClientSocketFactory| specified.
void EnableDataReductionProxyWithSecureProxyCheckSuccess();
// Returns the underlying |TestDataReductionProxyConfigurator|. This can only // Returns the underlying |TestDataReductionProxyConfigurator|. This can only
// be called if built with WithTestConfigurator. // be called if built with WithTestConfigurator.
TestDataReductionProxyConfigurator* test_configurator() const; TestDataReductionProxyConfigurator* test_configurator() const;
...@@ -210,6 +235,7 @@ class DataReductionProxyTestContext { ...@@ -210,6 +235,7 @@ class DataReductionProxyTestContext {
scoped_ptr<TestingPrefServiceSimple> simple_pref_service, scoped_ptr<TestingPrefServiceSimple> simple_pref_service,
scoped_ptr<net::CapturingNetLog> net_log, scoped_ptr<net::CapturingNetLog> net_log,
scoped_refptr<net::URLRequestContextGetter> request_context_getter, scoped_refptr<net::URLRequestContextGetter> request_context_getter,
net::MockClientSocketFactory* mock_socket_factory,
scoped_ptr<TestDataReductionProxyIOData> io_data, scoped_ptr<TestDataReductionProxyIOData> io_data,
scoped_ptr<DataReductionProxySettings> settings, scoped_ptr<DataReductionProxySettings> settings,
unsigned int test_context_flags); unsigned int test_context_flags);
...@@ -227,6 +253,9 @@ class DataReductionProxyTestContext { ...@@ -227,6 +253,9 @@ class DataReductionProxyTestContext {
scoped_ptr<TestingPrefServiceSimple> simple_pref_service_; scoped_ptr<TestingPrefServiceSimple> simple_pref_service_;
scoped_ptr<net::CapturingNetLog> net_log_; scoped_ptr<net::CapturingNetLog> net_log_;
scoped_refptr<net::URLRequestContextGetter> request_context_getter_; scoped_refptr<net::URLRequestContextGetter> request_context_getter_;
// Non-owned pointer. Will be NULL if |this| was built without specifying a
// |net::MockClientSocketFactory|.
net::MockClientSocketFactory* mock_socket_factory_;
scoped_ptr<TestDataReductionProxyIOData> io_data_; scoped_ptr<TestDataReductionProxyIOData> io_data_;
scoped_ptr<DataReductionProxySettings> settings_; scoped_ptr<DataReductionProxySettings> settings_;
......
...@@ -33,6 +33,7 @@ ...@@ -33,6 +33,7 @@
#include "net/socket/socket_test_util.h" #include "net/socket/socket_test_util.h"
#include "net/url_request/url_request.h" #include "net/url_request/url_request.h"
#include "net/url_request/url_request_context_getter.h" #include "net/url_request/url_request_context_getter.h"
#include "net/url_request/url_request_context_storage.h"
#include "net/url_request/url_request_intercepting_job_factory.h" #include "net/url_request/url_request_intercepting_job_factory.h"
#include "net/url_request/url_request_interceptor.h" #include "net/url_request/url_request_interceptor.h"
#include "net/url_request/url_request_job_factory_impl.h" #include "net/url_request/url_request_job_factory_impl.h"
...@@ -554,11 +555,11 @@ TEST_F(DataReductionProxyUsageStatsTest, RequestCompletionErrorCodes) { ...@@ -554,11 +555,11 @@ TEST_F(DataReductionProxyUsageStatsTest, RequestCompletionErrorCodes) {
class DataReductionProxyUsageStatsEndToEndTest : public testing::Test { class DataReductionProxyUsageStatsEndToEndTest : public testing::Test {
public: public:
DataReductionProxyUsageStatsEndToEndTest() DataReductionProxyUsageStatsEndToEndTest()
: context_(true) {} : context_(true), context_storage_(&context_) {}
~DataReductionProxyUsageStatsEndToEndTest() override { ~DataReductionProxyUsageStatsEndToEndTest() override {
test_context_->io_data()->ShutdownOnUIThread(); drp_test_context_->io_data()->ShutdownOnUIThread();
test_context_->RunUntilIdle(); drp_test_context_->RunUntilIdle();
} }
void SetUp() override { void SetUp() override {
...@@ -566,33 +567,18 @@ class DataReductionProxyUsageStatsEndToEndTest : public testing::Test { ...@@ -566,33 +567,18 @@ class DataReductionProxyUsageStatsEndToEndTest : public testing::Test {
// test bypassed bytes due to proxy fallbacks. This way, a test just needs // test bypassed bytes due to proxy fallbacks. This way, a test just needs
// to cause one proxy fallback in order for the data reduction proxy to be // to cause one proxy fallback in order for the data reduction proxy to be
// fully bypassed. // fully bypassed.
test_context_ = drp_test_context_ =
DataReductionProxyTestContext::Builder() DataReductionProxyTestContext::Builder()
.WithParamsFlags(DataReductionProxyParams::kAllowed) .WithParamsFlags(DataReductionProxyParams::kAllowed)
.WithParamsDefinitions(TestDataReductionProxyParams::HAS_ORIGIN) .WithParamsDefinitions(
TestDataReductionProxyParams::HAS_EVERYTHING &
~TestDataReductionProxyParams::HAS_DEV_ORIGIN &
~TestDataReductionProxyParams::HAS_DEV_FALLBACK_ORIGIN)
.WithURLRequestContext(&context_) .WithURLRequestContext(&context_)
.SkipSettingsInitialization() .WithMockClientSocketFactory(&mock_socket_factory_)
.Build(); .Build();
test_context_->pref_service()->SetBoolean(prefs::kDataReductionProxyEnabled, drp_test_context_->AttachToURLRequestContext(&context_storage_);
true);
test_context_->InitSettings();
network_delegate_ = test_context_->io_data()->CreateNetworkDelegate(
scoped_ptr<net::NetworkDelegate>(new net::TestNetworkDelegate()), true);
context_.set_network_delegate(network_delegate_.get());
context_.set_client_socket_factory(&mock_socket_factory_); context_.set_client_socket_factory(&mock_socket_factory_);
job_factory_.reset(new net::URLRequestInterceptingJobFactory(
scoped_ptr<net::URLRequestJobFactory>(
new net::URLRequestJobFactoryImpl()),
test_context_->io_data()->CreateInterceptor().Pass()));
context_.set_job_factory(job_factory_.get());
test_context_->configurator()->Enable(false, true,
config()->Origin().ToURI(),
std::string(), std::string());
test_context_->RunUntilIdle();
} }
// Create and execute a fake request using the data reduction proxy stack. // Create and execute a fake request using the data reduction proxy stack.
...@@ -640,7 +626,7 @@ class DataReductionProxyUsageStatsEndToEndTest : public testing::Test { ...@@ -640,7 +626,7 @@ class DataReductionProxyUsageStatsEndToEndTest : public testing::Test {
request->set_method("GET"); request->set_method("GET");
request->SetLoadFlags(net::LOAD_NORMAL); request->SetLoadFlags(net::LOAD_NORMAL);
request->Start(); request->Start();
test_context_->RunUntilIdle(); drp_test_context_->RunUntilIdle();
} }
void set_proxy_service(net::ProxyService* proxy_service) { void set_proxy_service(net::ProxyService* proxy_service) {
...@@ -652,11 +638,11 @@ class DataReductionProxyUsageStatsEndToEndTest : public testing::Test { ...@@ -652,11 +638,11 @@ class DataReductionProxyUsageStatsEndToEndTest : public testing::Test {
} }
const DataReductionProxySettings* settings() const { const DataReductionProxySettings* settings() const {
return test_context_->settings(); return drp_test_context_->settings();
} }
DataReductionProxyConfig* config() const { DataReductionProxyConfig* config() const {
return test_context_->config(); return drp_test_context_->config();
} }
void ClearBadProxies() { void ClearBadProxies() {
...@@ -665,6 +651,7 @@ class DataReductionProxyUsageStatsEndToEndTest : public testing::Test { ...@@ -665,6 +651,7 @@ class DataReductionProxyUsageStatsEndToEndTest : public testing::Test {
void InitializeContext() { void InitializeContext() {
context_.Init(); context_.Init();
drp_test_context_->EnableDataReductionProxyWithSecureProxyCheckSuccess();
} }
void ExpectOtherBypassedBytesHistogramsEmpty( void ExpectOtherBypassedBytesHistogramsEmpty(
...@@ -723,10 +710,9 @@ class DataReductionProxyUsageStatsEndToEndTest : public testing::Test { ...@@ -723,10 +710,9 @@ class DataReductionProxyUsageStatsEndToEndTest : public testing::Test {
private: private:
net::TestDelegate delegate_; net::TestDelegate delegate_;
net::MockClientSocketFactory mock_socket_factory_; net::MockClientSocketFactory mock_socket_factory_;
scoped_ptr<DataReductionProxyNetworkDelegate> network_delegate_;
scoped_ptr<net::URLRequestJobFactory> job_factory_;
net::TestURLRequestContext context_; net::TestURLRequestContext context_;
scoped_ptr<DataReductionProxyTestContext> test_context_; net::URLRequestContextStorage context_storage_;
scoped_ptr<DataReductionProxyTestContext> drp_test_context_;
}; };
TEST_F(DataReductionProxyUsageStatsEndToEndTest, BypassedBytesNoRetry) { TEST_F(DataReductionProxyUsageStatsEndToEndTest, BypassedBytesNoRetry) {
......
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