diff options
author | ryansturm <ryansturm@chromium.org> | 2016-02-22 16:10:21 -0800 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2016-02-23 00:11:18 +0000 |
commit | 7de050c68ce2a97c0165d09d06c89b8aff79fb77 (patch) | |
tree | c4a0af565f1c857da1bced1be3995b3e64b6ce99 /components/data_reduction_proxy | |
parent | 703186e524f56ea2f1f13dc87a4dd0aff3f8a9f0 (diff) | |
download | chromium_src-7de050c68ce2a97c0165d09d06c89b8aff79fb77.zip chromium_src-7de050c68ce2a97c0165d09d06c89b8aff79fb77.tar.gz chromium_src-7de050c68ce2a97c0165d09d06c89b8aff79fb77.tar.bz2 |
Moving proxy resolution logic out of NetworkDelegate and into ProxyDelegate for DataReductionProxy
This involves removing two methods off the NetworkDelegate interface (and four off LayeredNetworkDelegate). DataReductionProxy's logic for these two methods will be moved to the DataReductionProxyDelegate from the DataReductionProxyNetworkDelegate. This also involved cleaning up some unit tests and moving calls to use ProxyDelegate instead of NetworkDelegate where relevant.
Refactoring proxy related calls from NetworkDelegate to ProxyDelegate
BUG=583369
Review URL: https://codereview.chromium.org/1680893002
Cr-Commit-Position: refs/heads/master@{#376860}
Diffstat (limited to 'components/data_reduction_proxy')
13 files changed, 603 insertions, 410 deletions
diff --git a/components/data_reduction_proxy/content/browser/content_lofi_decider_unittest.cc b/components/data_reduction_proxy/content/browser/content_lofi_decider_unittest.cc index 7253c7b..7ac2171 100644 --- a/components/data_reduction_proxy/content/browser/content_lofi_decider_unittest.cc +++ b/components/data_reduction_proxy/content/browser/content_lofi_decider_unittest.cc @@ -78,8 +78,7 @@ class ContentLoFiDeciderTest : public testing::Test { scoped_ptr<net::NetworkDelegate>(new net::NetworkDelegateImpl()), test_context_->config(), test_context_->io_data()->request_options(), - test_context_->configurator(), - test_context_->net_log(), test_context_->event_creator())); + test_context_->configurator())); data_reduction_proxy_network_delegate_->InitIODataAndUMA( test_context_->io_data(), test_context_->io_data()->bypass_stats()); diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_bypass_protocol_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_bypass_protocol_unittest.cc index 7d378f7..aff833d 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_bypass_protocol_unittest.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_bypass_protocol_unittest.cc @@ -29,6 +29,7 @@ #include "net/base/load_flags.h" #include "net/base/network_change_notifier.h" #include "net/base/network_delegate.h" +#include "net/base/proxy_delegate.h" #include "net/http/http_response_headers.h" #include "net/http/http_transaction_test_util.h" #include "net/proxy/proxy_server.h" @@ -782,6 +783,8 @@ class DataReductionProxyBypassProtocolEndToEndTest : public testing::Test { .WithMockClientSocketFactory(mock_socket_factory_.get()) .WithURLRequestContext(context_.get()) .Build(); + proxy_delegate_ = drp_test_context_->io_data()->CreateProxyDelegate(); + context_->set_proxy_delegate(proxy_delegate_.get()); } void AttachToContextAndInit() { @@ -803,6 +806,7 @@ class DataReductionProxyBypassProtocolEndToEndTest : public testing::Test { scoped_ptr<net::TestURLRequestContext> context_; scoped_ptr<net::URLRequestContextStorage> storage_; scoped_ptr<net::MockClientSocketFactory> mock_socket_factory_; + scoped_ptr<net::ProxyDelegate> proxy_delegate_; scoped_ptr<DataReductionProxyTestContext> drp_test_context_; DISALLOW_COPY_AND_ASSIGN(DataReductionProxyBypassProtocolEndToEndTest); diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_bypass_stats_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_bypass_stats_unittest.cc index e1c1f46..0deda3d 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_bypass_stats_unittest.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_bypass_stats_unittest.cc @@ -29,6 +29,7 @@ #include "net/base/host_port_pair.h" #include "net/base/load_flags.h" #include "net/base/net_errors.h" +#include "net/base/proxy_delegate.h" #include "net/base/request_priority.h" #include "net/dns/mock_host_resolver.h" #include "net/http/http_response_headers.h" @@ -561,6 +562,8 @@ class DataReductionProxyBypassStatsEndToEndTest : public testing::Test { .Build(); drp_test_context_->AttachToURLRequestContext(&context_storage_); context_.set_client_socket_factory(&mock_socket_factory_); + proxy_delegate_ = drp_test_context_->io_data()->CreateProxyDelegate(); + context_.set_proxy_delegate(proxy_delegate_.get()); } // Create and execute a fake request using the data reduction proxy stack. @@ -699,6 +702,7 @@ class DataReductionProxyBypassStatsEndToEndTest : public testing::Test { net::MockClientSocketFactory mock_socket_factory_; net::TestURLRequestContext context_; net::URLRequestContextStorage context_storage_; + scoped_ptr<net::ProxyDelegate> proxy_delegate_; scoped_ptr<DataReductionProxyTestContext> drp_test_context_; }; diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_service_client_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_service_client_unittest.cc index f67548f..d3b9b1a 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_service_client_unittest.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_config_service_client_unittest.cc @@ -21,6 +21,7 @@ #include "base/time/time.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_delegate.h" #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_test_utils.h" #include "components/data_reduction_proxy/core/common/data_reduction_proxy_client_config_parser.h" #include "components/data_reduction_proxy/core/common/data_reduction_proxy_params.h" @@ -33,6 +34,7 @@ #include "net/proxy/proxy_server.h" #include "net/socket/socket_test_util.h" #include "net/url_request/url_request_context_storage.h" +#include "net/url_request/url_request_test_util.h" #include "testing/gmock/include/gmock/gmock.h" #include "testing/gtest/include/gtest/gtest.h" #include "url/gurl.h" @@ -132,8 +134,12 @@ class DataReductionProxyConfigServiceClientTest : public testing::Test { .WithMockRequestOptions() .WithTestConfigClient() .Build(); + context_->set_client_socket_factory(mock_socket_factory_.get()); test_context_->AttachToURLRequestContext(context_storage_.get()); + delegate_ = test_context_->io_data()->CreateProxyDelegate(); + context_->set_proxy_delegate(delegate_.get()); + context_->Init(); ResetBackoffEntryReleaseTime(); test_context_->test_config_client()->SetNow(base::Time::UnixEpoch()); @@ -143,11 +149,7 @@ class DataReductionProxyConfigServiceClientTest : public testing::Test { test_context_->test_config_client()->SetConfigServiceURL( GURL("http://configservice.com")); - delegate_.reset( - new DataReductionProxyDelegate(request_options(), config())); - ASSERT_NE(nullptr, context_->network_delegate()); - // Set up the various test ClientConfigs. ClientConfig config = CreateConfig(kSuccessSessionKey, kConfigRefreshDurationSeconds, 0, diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_delegate.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_delegate.cc index 462571b..4ab77a8 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_delegate.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_delegate.cc @@ -6,24 +6,42 @@ #include <cmath> +#include "base/metrics/histogram_macros.h" #include "base/metrics/sparse_histogram.h" +#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_bypass_stats.h" #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_config.h" +#include "components/data_reduction_proxy/core/browser/data_reduction_proxy_configurator.h" #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_request_options.h" +#include "components/data_reduction_proxy/core/common/data_reduction_proxy_event_creator.h" #include "components/data_reduction_proxy/core/common/data_reduction_proxy_params.h" #include "net/base/host_port_pair.h" +#include "net/base/net_util.h" #include "net/http/http_request_headers.h" #include "net/http/http_response_headers.h" #include "net/proxy/proxy_server.h" +#include "net/proxy/proxy_service.h" namespace data_reduction_proxy { DataReductionProxyDelegate::DataReductionProxyDelegate( DataReductionProxyRequestOptions* request_options, - DataReductionProxyConfig* config) + DataReductionProxyConfig* config, + const DataReductionProxyConfigurator* configurator, + DataReductionProxyEventCreator* event_creator, + DataReductionProxyBypassStats* bypass_stats, + net::NetLog* net_log) : request_options_(request_options), - config_(config) { + config_(config), + configurator_(configurator), + event_creator_(event_creator), + bypass_stats_(bypass_stats), + net_log_(net_log) { DCHECK(request_options); DCHECK(config); + DCHECK(configurator); + DCHECK(event_creator); + DCHECK(bypass_stats); + DCHECK(net_log); } DataReductionProxyDelegate::~DataReductionProxyDelegate() { @@ -34,6 +52,9 @@ void DataReductionProxyDelegate::OnResolveProxy( int load_flags, const net::ProxyService& proxy_service, net::ProxyInfo* result) { + DCHECK(result); + OnResolveProxyHandler(url, load_flags, configurator_->GetProxyConfig(), + proxy_service.proxy_retry_info(), config_, result); } void DataReductionProxyDelegate::OnTunnelConnectCompleted( @@ -48,6 +69,14 @@ void DataReductionProxyDelegate::OnTunnelConnectCompleted( void DataReductionProxyDelegate::OnFallback(const net::ProxyServer& bad_proxy, int net_error) { + if (bad_proxy.is_valid() && + config_->IsDataReductionProxy(bad_proxy.host_port_pair(), nullptr)) { + event_creator_->AddProxyFallbackEvent(net_log_, bad_proxy.ToURI(), + net_error); + } + + if (bypass_stats_) + bypass_stats_->OnProxyFallback(bad_proxy, net_error); } void DataReductionProxyDelegate::OnBeforeSendHeaders( @@ -80,4 +109,36 @@ void DataReductionProxyDelegate::OnTunnelHeadersReceived( const net::HttpResponseHeaders& response_headers) { } +void OnResolveProxyHandler(const GURL& url, + int load_flags, + const net::ProxyConfig& data_reduction_proxy_config, + const net::ProxyRetryInfoMap& proxy_retry_info, + const DataReductionProxyConfig* config, + net::ProxyInfo* result) { + DCHECK(config); + DCHECK(result->is_empty() || result->is_direct() || + !config->IsDataReductionProxy(result->proxy_server().host_port_pair(), + NULL)); + bool data_saver_proxy_used = true; + if (!result->proxy_server().is_direct() || result->proxy_list().size() != 1 || + url.SchemeIsWSOrWSS()) + return; + + if (data_reduction_proxy_config.is_valid()) { + net::ProxyInfo data_reduction_proxy_info; + data_reduction_proxy_config.proxy_rules().Apply(url, + &data_reduction_proxy_info); + data_reduction_proxy_info.DeprioritizeBadProxies(proxy_retry_info); + if (!data_reduction_proxy_info.proxy_server().is_direct()) + result->OverrideProxyList(data_reduction_proxy_info.proxy_list()); + } else { + data_saver_proxy_used = false; + } + if (config->enabled_by_user_and_reachable() && url.SchemeIsHTTPOrHTTPS() && + !url.SchemeIsCryptographic() && !net::IsLocalhost(url.host())) { + UMA_HISTOGRAM_BOOLEAN("DataReductionProxy.ConfigService.HTTPRequests", + data_saver_proxy_used); + } +} + } // namespace data_reduction_proxy diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_delegate.h b/components/data_reduction_proxy/core/browser/data_reduction_proxy_delegate.h index a9da5b9..4e45dff 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_delegate.h +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_delegate.h @@ -7,12 +7,15 @@ #include "base/macros.h" #include "net/base/proxy_delegate.h" +#include "net/proxy/proxy_retry_info.h" #include "url/gurl.h" namespace net { class HostPortPair; class HttpRequestHeaders; class HttpResponseHeaders; +class NetLog; +class ProxyConfig; class ProxyInfo; class ProxyServer; class ProxyService; @@ -21,7 +24,10 @@ class URLRequest; namespace data_reduction_proxy { +class DataReductionProxyBypassStats; class DataReductionProxyConfig; +class DataReductionProxyConfigurator; +class DataReductionProxyEventCreator; class DataReductionProxyRequestOptions; class DataReductionProxyDelegate : public net::ProxyDelegate { @@ -30,7 +36,11 @@ class DataReductionProxyDelegate : public net::ProxyDelegate { // outlives this class instance. explicit DataReductionProxyDelegate( DataReductionProxyRequestOptions* request_options, - DataReductionProxyConfig* config); + DataReductionProxyConfig* config, + const DataReductionProxyConfigurator* configurator, + DataReductionProxyEventCreator* event_creator, + DataReductionProxyBypassStats* bypass_stats, + net::NetLog* net_log); ~DataReductionProxyDelegate() override; @@ -57,10 +67,25 @@ class DataReductionProxyDelegate : public net::ProxyDelegate { private: DataReductionProxyRequestOptions* request_options_; const DataReductionProxyConfig* config_; + const DataReductionProxyConfigurator* configurator_; + DataReductionProxyEventCreator* event_creator_; + DataReductionProxyBypassStats* bypass_stats_; + net::NetLog* net_log_; DISALLOW_COPY_AND_ASSIGN(DataReductionProxyDelegate); }; +// Adds data reduction proxies to |result|, where applicable, if result +// otherwise uses a direct connection for |url|, and the data reduction proxy is +// not bypassed. Also, configures |result| to proceed directly to the origin if +// |result|'s current proxy is the data reduction proxy +// This is visible for test purposes. +void OnResolveProxyHandler(const GURL& url, + int load_flags, + const net::ProxyConfig& data_reduction_proxy_config, + const net::ProxyRetryInfoMap& proxy_retry_info, + const DataReductionProxyConfig* config, + net::ProxyInfo* result); } // namespace data_reduction_proxy #endif // COMPONENTS_DATA_REDUCTION_PROXY_CORE_BROWSER_DATA_REDUCTION_PROXY_DELEGATE_H_ diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_delegate_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_delegate_unittest.cc index 8bc9147..7c24d0c 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_delegate_unittest.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_delegate_unittest.cc @@ -4,17 +4,49 @@ #include "components/data_reduction_proxy/core/browser/data_reduction_proxy_delegate.h" +#include <stddef.h> +#include <stdint.h> + +#include <string> +#include <utility> #include <vector> +#include "base/command_line.h" #include "base/macros.h" +#include "base/memory/scoped_ptr.h" #include "base/message_loop/message_loop.h" #include "base/metrics/field_trial.h" +#include "base/numerics/safe_conversions.h" +#include "base/run_loop.h" +#include "base/strings/string_number_conversions.h" +#include "base/test/histogram_tester.h" +#include "base/test/mock_entropy_provider.h" +#include "base/time/time.h" +#include "base/values.h" +#include "build/build_config.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_metrics.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_network_delegate.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" +#include "components/data_reduction_proxy/core/common/data_reduction_proxy_headers_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 "components/data_reduction_proxy/core/common/data_reduction_proxy_switches.h" +#include "net/base/host_port_pair.h" +#include "net/base/load_flags.h" +#include "net/base/net_errors.h" +#include "net/base/proxy_delegate.h" +#include "net/http/http_request_headers.h" +#include "net/http/http_response_headers.h" +#include "net/http/http_util.h" +#include "net/proxy/proxy_config.h" #include "net/proxy/proxy_server.h" +#include "net/socket/socket_test_util.h" +#include "net/url_request/url_request.h" +#include "net/url_request/url_request_test_util.h" #include "testing/gtest/include/gtest/gtest.h" using testing::_; @@ -116,7 +148,11 @@ TEST(DataReductionProxyDelegate, IsTrustedSpdyProxy) { test_context->configurator(), test_context->event_creator())); DataReductionProxyDelegate delegate( - test_context->io_data()->request_options(), config.get()); + test_context->io_data()->request_options(), config.get(), + test_context->io_data()->configurator(), + test_context->io_data()->event_creator(), + test_context->io_data()->bypass_stats(), + test_context->io_data()->net_log()); base::FieldTrialList field_trial_list(nullptr); base::FieldTrialList::CreateFieldTrial( @@ -130,6 +166,440 @@ TEST(DataReductionProxyDelegate, IsTrustedSpdyProxy) { } } +#if defined(OS_ANDROID) +const Client kClient = Client::CHROME_ANDROID; +#elif defined(OS_IOS) +const Client kClient = Client::CHROME_IOS; +#elif defined(OS_MACOSX) +const Client kClient = Client::CHROME_MAC; +#elif defined(OS_CHROMEOS) +const Client kClient = Client::CHROME_CHROMEOS; +#elif defined(OS_LINUX) +const Client kClient = Client::CHROME_LINUX; +#elif defined(OS_WIN) +const Client kClient = Client::CHROME_WINDOWS; +#elif defined(OS_FREEBSD) +const Client kClient = Client::CHROME_FREEBSD; +#elif defined(OS_OPENBSD) +const Client kClient = Client::CHROME_OPENBSD; +#elif defined(OS_SOLARIS) +const Client kClient = Client::CHROME_SOLARIS; +#elif defined(OS_QNX) +const Client kClient = Client::CHROME_QNX; +#else +const Client kClient = Client::UNKNOWN; +#endif + +class TestLoFiUIService : public LoFiUIService { + public: + TestLoFiUIService() {} + ~TestLoFiUIService() override {} + + void OnLoFiReponseReceived(const net::URLRequest& request, + bool is_preview) override {} +}; + +class DataReductionProxyDelegateTest : public testing::Test { + public: + DataReductionProxyDelegateTest() + : context_(true), + context_storage_(&context_), + test_context_(DataReductionProxyTestContext::Builder() + .WithClient(kClient) + .WithMockClientSocketFactory(&mock_socket_factory_) + .WithURLRequestContext(&context_) + .Build()) { + context_.set_client_socket_factory(&mock_socket_factory_); + test_context_->AttachToURLRequestContext(&context_storage_); + + scoped_ptr<TestLoFiUIService> lofi_ui_service(new TestLoFiUIService()); + lofi_ui_service_ = lofi_ui_service.get(); + test_context_->io_data()->set_lofi_ui_service(std::move(lofi_ui_service)); + + proxy_delegate_ = test_context_->io_data()->CreateProxyDelegate(); + context_.set_proxy_delegate(proxy_delegate_.get()); + + context_.Init(); + + test_context_->EnableDataReductionProxyWithSecureProxyCheckSuccess(); + } + + // Each line in |response_headers| should end with "\r\n" and not '\0', and + // the last line should have a second "\r\n". + // An empty |response_headers| is allowed. It works by making this look like + // an HTTP/0.9 response, since HTTP/0.9 responses don't have headers. + scoped_ptr<net::URLRequest> FetchURLRequest( + const GURL& url, + net::HttpRequestHeaders* request_headers, + const std::string& response_headers, + int64_t response_content_length) { + const std::string response_body( + base::checked_cast<size_t>(response_content_length), ' '); + net::MockRead reads[] = {net::MockRead(response_headers.c_str()), + net::MockRead(response_body.c_str()), + net::MockRead(net::SYNCHRONOUS, net::OK)}; + net::StaticSocketDataProvider socket(reads, arraysize(reads), nullptr, 0); + mock_socket_factory_.AddSocketDataProvider(&socket); + + net::TestDelegate delegate; + scoped_ptr<net::URLRequest> request = + context_.CreateRequest(url, net::IDLE, &delegate); + if (request_headers) + request->SetExtraRequestHeaders(*request_headers); + + request->Start(); + base::RunLoop().RunUntilIdle(); + return request; + } + + int64_t total_received_bytes() const { + return GetSessionNetworkStatsInfoInt64("session_received_content_length"); + } + + int64_t total_original_received_bytes() const { + return GetSessionNetworkStatsInfoInt64("session_original_content_length"); + } + + net::MockClientSocketFactory* mock_socket_factory() { + return &mock_socket_factory_; + } + + net::TestURLRequestContext* context() { return &context_; } + + TestDataReductionProxyParams* params() const { + return test_context_->config()->test_params(); + } + + TestDataReductionProxyConfig* config() const { + return test_context_->config(); + } + + private: + int64_t GetSessionNetworkStatsInfoInt64(const char* key) const { + const DataReductionProxyNetworkDelegate* drp_network_delegate = + reinterpret_cast<const DataReductionProxyNetworkDelegate*>( + context_.network_delegate()); + + scoped_ptr<base::DictionaryValue> session_network_stats_info = + base::DictionaryValue::From(make_scoped_ptr( + drp_network_delegate->SessionNetworkStatsInfoToValue())); + EXPECT_TRUE(session_network_stats_info); + + std::string string_value; + EXPECT_TRUE(session_network_stats_info->GetString(key, &string_value)); + int64_t value = 0; + EXPECT_TRUE(base::StringToInt64(string_value, &value)); + return value; + } + + base::MessageLoopForIO message_loop_; + net::MockClientSocketFactory mock_socket_factory_; + net::TestURLRequestContext context_; + net::URLRequestContextStorage context_storage_; + + TestLoFiUIService* lofi_ui_service_; + scoped_ptr<net::ProxyDelegate> proxy_delegate_; + scoped_ptr<DataReductionProxyTestContext> test_context_; +}; + +TEST_F(DataReductionProxyDelegateTest, OnResolveProxyHandler) { + int load_flags = net::LOAD_NORMAL; + GURL url("http://www.google.com/"); + + // Data reduction proxy info + net::ProxyInfo data_reduction_proxy_info; + std::string data_reduction_proxy; + base::TrimString(params()->DefaultOrigin(), "/", &data_reduction_proxy); + data_reduction_proxy_info.UsePacString( + "PROXY " + + net::ProxyServer::FromURI(params()->DefaultOrigin(), + net::ProxyServer::SCHEME_HTTP) + .host_port_pair() + .ToString() + + "; DIRECT"); + EXPECT_FALSE(data_reduction_proxy_info.is_empty()); + + // Data reduction proxy config + net::ProxyConfig data_reduction_proxy_config; + data_reduction_proxy_config.proxy_rules().ParseFromString( + "http=" + data_reduction_proxy + ",direct://;"); + data_reduction_proxy_config.set_id(1); + + // Other proxy info + net::ProxyInfo other_proxy_info; + other_proxy_info.UseNamedProxy("proxy.com"); + EXPECT_FALSE(other_proxy_info.is_empty()); + + // Direct + net::ProxyInfo direct_proxy_info; + direct_proxy_info.UseDirect(); + EXPECT_TRUE(direct_proxy_info.is_direct()); + + // Empty retry info map + net::ProxyRetryInfoMap empty_proxy_retry_info; + + // Retry info map with the data reduction proxy; + net::ProxyRetryInfoMap data_reduction_proxy_retry_info; + net::ProxyRetryInfo retry_info; + retry_info.current_delay = base::TimeDelta::FromSeconds(1000); + retry_info.bad_until = base::TimeTicks().Now() + retry_info.current_delay; + retry_info.try_while_bad = false; + data_reduction_proxy_retry_info[data_reduction_proxy_info.proxy_server() + .ToURI()] = retry_info; + + net::ProxyInfo result; + // Another proxy is used. It should be used afterwards. + result.Use(other_proxy_info); + OnResolveProxyHandler(url, load_flags, data_reduction_proxy_config, + empty_proxy_retry_info, config(), &result); + EXPECT_EQ(other_proxy_info.proxy_server(), result.proxy_server()); + + // A direct connection is used. The data reduction proxy should be used + // afterwards. + // Another proxy is used. It should be used afterwards. + result.Use(direct_proxy_info); + net::ProxyConfig::ID prev_id = result.config_id(); + OnResolveProxyHandler(url, load_flags, data_reduction_proxy_config, + empty_proxy_retry_info, config(), &result); + EXPECT_EQ(data_reduction_proxy_info.proxy_server(), result.proxy_server()); + // Only the proxy list should be updated, not he proxy info. + EXPECT_EQ(result.config_id(), prev_id); + + // A direct connection is used, but the data reduction proxy is on the retry + // list. A direct connection should be used afterwards. + result.Use(direct_proxy_info); + prev_id = result.config_id(); + OnResolveProxyHandler(url, load_flags, data_reduction_proxy_config, + data_reduction_proxy_retry_info, config(), &result); + EXPECT_TRUE(result.proxy_server().is_direct()); + EXPECT_EQ(result.config_id(), prev_id); + + // Test that ws:// and wss:// URLs bypass the data reduction proxy. + result.UseDirect(); + OnResolveProxyHandler(GURL("ws://echo.websocket.org/"), load_flags, + data_reduction_proxy_config, empty_proxy_retry_info, + config(), &result); + EXPECT_TRUE(result.is_direct()); + + OnResolveProxyHandler(GURL("wss://echo.websocket.org/"), load_flags, + data_reduction_proxy_config, empty_proxy_retry_info, + config(), &result); + EXPECT_TRUE(result.is_direct()); + + // Without DataCompressionProxyCriticalBypass Finch trial set, the + // BYPASS_DATA_REDUCTION_PROXY load flag should be ignored. + OnResolveProxyHandler(url, load_flags, data_reduction_proxy_config, + empty_proxy_retry_info, config(), &result); + EXPECT_FALSE(result.is_direct()); + + OnResolveProxyHandler(url, load_flags, data_reduction_proxy_config, + empty_proxy_retry_info, config(), &other_proxy_info); + EXPECT_FALSE(other_proxy_info.is_direct()); +} + +// Verifies that requests that were not proxied through data saver proxy due to +// missing config are recorded properly. +TEST_F(DataReductionProxyDelegateTest, HTTPRequests) { + const struct { + std::string url; + bool enabled_by_user; + bool use_direct_proxy; + bool expect_histogram; + } tests[] = { + { + // Request should not be logged because data saver is disabled. + "http://www.example.com/", false, true, false, + }, + { + "http://www.example.com/", true, true, true, + }, + { + "http://www.example.com/", true, false, true, + }, + { + "http://www.example.com/", false, false, false, + }, + { + "https://www.example.com/", false, true, false, + }, + { + // Request should not be logged because request is HTTPS. + "https://www.example.com/", true, true, false, + }, + { + // Request to localhost should not be logged. + "http://127.0.0.1/", true, true, false, + }, + { + // Special use IPv4 address for testing purposes (RFC 5735). + "http://198.51.100.1/", true, true, true, + }, + }; + + for (size_t i = 0; i < arraysize(tests); ++i) { + base::HistogramTester histogram_tester; + GURL url(tests[i].url); + + net::ProxyInfo data_reduction_proxy_info; + + std::string data_reduction_proxy; + if (!tests[i].use_direct_proxy) { + base::TrimString(params()->DefaultOrigin(), "/", &data_reduction_proxy); + data_reduction_proxy_info.UsePacString( + "PROXY " + + net::ProxyServer::FromURI(params()->DefaultOrigin(), + net::ProxyServer::SCHEME_HTTP) + .host_port_pair() + .ToString() + + "; DIRECT"); + } + EXPECT_EQ(tests[i].use_direct_proxy, data_reduction_proxy_info.is_empty()); + + net::ProxyConfig data_reduction_proxy_config; + if (tests[i].use_direct_proxy) { + data_reduction_proxy_config = net::ProxyConfig::CreateDirect(); + + } else { + data_reduction_proxy_config.proxy_rules().ParseFromString( + "http=" + data_reduction_proxy + ",direct://;"); + data_reduction_proxy_config.set_id(1); + } + config()->SetStateForTest(tests[i].enabled_by_user /* enabled */, + false /* at_startup */); + + net::ProxyRetryInfoMap empty_proxy_retry_info; + + net::ProxyInfo direct_proxy_info; + direct_proxy_info.UseDirect(); + EXPECT_TRUE(direct_proxy_info.is_direct()); + + net::ProxyInfo result; + result.Use(direct_proxy_info); + OnResolveProxyHandler(url, net::LOAD_NORMAL, data_reduction_proxy_config, + empty_proxy_retry_info, config(), &result); + histogram_tester.ExpectTotalCount( + "DataReductionProxy.ConfigService.HTTPRequests", + tests[i].expect_histogram ? 1 : 0); + + if (tests[i].expect_histogram) { + histogram_tester.ExpectUniqueSample( + "DataReductionProxy.ConfigService.HTTPRequests", + tests[i].use_direct_proxy ? 0 : 1, 1); + } + } +} + +#if defined(OS_ANDROID) +#define MAYBE_OnCompletedInternalLoFi DISABLED_OnCompletedInternalLoFi +#else +#define MAYBE_OnCompletedInternalLoFi OnCompletedInternalLoFi +#endif + +#if defined(OS_ANDROID) +#define MAYBE_OnCompletedInternalLoFiPreview \ + DISABLED_OnCompletedInternalLoFiPreview +#else +#define MAYBE_OnCompletedInternalLoFiPreview OnCompletedInternalLoFiPreview +#endif + +TEST_F(DataReductionProxyDelegateTest, OnCompletedSizeFor200) { + int64_t baseline_received_bytes = total_received_bytes(); + int64_t baseline_original_received_bytes = total_original_received_bytes(); + + const char kDrpResponseHeaders[] = + "HTTP/1.1 200 OK\r\n" + "Date: Wed, 28 Nov 2007 09:40:09 GMT\r\n" + "Warning: 199 Misc-Agent \"some warning text\"\r\n" + "Via:\r\n" + "Via: 1.1 Chrome-Compression-Proxy-Suffix, 9.9 other-proxy\r\n" + "Via: 2.2 Chrome-Compression-Proxy\r\n" + "Warning: 214 Chrome-Compression-Proxy \"Transformation Applied\"\r\n" + "X-Original-Content-Length: 10000\r\n" + "Chrome-Proxy: q=low\r\n" + "Content-Length: 1000\r\n\r\n"; + + scoped_ptr<net::URLRequest> request = FetchURLRequest( + GURL("http://example.com/path/"), nullptr, kDrpResponseHeaders, 1000); + + EXPECT_EQ(request->GetTotalReceivedBytes(), + total_received_bytes() - baseline_received_bytes); + + const std::string raw_headers = net::HttpUtil::AssembleRawHeaders( + kDrpResponseHeaders, arraysize(kDrpResponseHeaders) - 1); + EXPECT_EQ(static_cast<int64_t>(raw_headers.size() + + 10000 /* original_response_body */), + total_original_received_bytes() - baseline_original_received_bytes); +} + +TEST_F(DataReductionProxyDelegateTest, OnCompletedSizeFor304) { + int64_t baseline_received_bytes = total_received_bytes(); + int64_t baseline_original_received_bytes = total_original_received_bytes(); + + const char kDrpResponseHeaders[] = + "HTTP/1.1 304 Not Modified\r\n" + "Via: 1.1 Chrome-Compression-Proxy\r\n" + "X-Original-Content-Length: 10000\r\n\r\n"; + + scoped_ptr<net::URLRequest> request = FetchURLRequest( + GURL("http://example.com/path/"), nullptr, kDrpResponseHeaders, 0); + + EXPECT_EQ(request->GetTotalReceivedBytes(), + total_received_bytes() - baseline_received_bytes); + + const std::string raw_headers = net::HttpUtil::AssembleRawHeaders( + kDrpResponseHeaders, arraysize(kDrpResponseHeaders) - 1); + EXPECT_EQ(static_cast<int64_t>(raw_headers.size() + + 10000 /* original_response_body */), + total_original_received_bytes() - baseline_original_received_bytes); +} + +TEST_F(DataReductionProxyDelegateTest, OnCompletedSizeForWriteError) { + int64_t baseline_received_bytes = total_received_bytes(); + int64_t baseline_original_received_bytes = total_original_received_bytes(); + + net::MockWrite writes[] = { + net::MockWrite("GET http://example.com/path/ HTTP/1.1\r\n" + "Host: example.com\r\n"), + net::MockWrite(net::ASYNC, net::ERR_ABORTED)}; + net::StaticSocketDataProvider socket(nullptr, 0, writes, arraysize(writes)); + mock_socket_factory()->AddSocketDataProvider(&socket); + + net::TestDelegate delegate; + scoped_ptr<net::URLRequest> request = context()->CreateRequest( + GURL("http://example.com/path/"), net::IDLE, &delegate); + request->Start(); + base::RunLoop().RunUntilIdle(); + + EXPECT_EQ(request->GetTotalReceivedBytes(), + total_received_bytes() - baseline_received_bytes); + EXPECT_EQ(request->GetTotalReceivedBytes(), + total_original_received_bytes() - baseline_original_received_bytes); +} + +TEST_F(DataReductionProxyDelegateTest, OnCompletedSizeForReadError) { + int64_t baseline_received_bytes = total_received_bytes(); + int64_t baseline_original_received_bytes = total_original_received_bytes(); + + net::MockRead reads[] = {net::MockRead("HTTP/1.1 200 OK\r\n" + "Via: 1.1 Chrome-Compression-Proxy\r\n" + "X-Original-Content-Length: 10000\r\n" + "Content-Length: 1000\r\n\r\n"), + net::MockRead(net::ASYNC, net::ERR_ABORTED)}; + net::StaticSocketDataProvider socket(reads, arraysize(reads), nullptr, 0); + mock_socket_factory()->AddSocketDataProvider(&socket); + + net::TestDelegate delegate; + scoped_ptr<net::URLRequest> request = context()->CreateRequest( + GURL("http://example.com/path/"), net::IDLE, &delegate); + request->Start(); + base::RunLoop().RunUntilIdle(); + + EXPECT_EQ(request->GetTotalReceivedBytes(), + total_received_bytes() - baseline_received_bytes); + EXPECT_EQ(request->GetTotalReceivedBytes(), + total_original_received_bytes() - baseline_original_received_bytes); +} + } // namespace -} // namespace data_reduction_proxy
\ No newline at end of file +} // namespace data_reduction_proxy diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_interceptor_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_interceptor_unittest.cc index 66f6a94..1966e07 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_interceptor_unittest.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_interceptor_unittest.cc @@ -289,6 +289,8 @@ class DataReductionProxyInterceptorEndToEndTest : public testing::Test { .Build(); drp_test_context_->AttachToURLRequestContext(&context_storage_); context_.set_client_socket_factory(&mock_socket_factory_); + proxy_delegate_ = drp_test_context_->io_data()->CreateProxyDelegate(); + context_.set_proxy_delegate(proxy_delegate_.get()); context_.Init(); drp_test_context_->EnableDataReductionProxyWithSecureProxyCheckSuccess(); @@ -330,6 +332,7 @@ class DataReductionProxyInterceptorEndToEndTest : public testing::Test { net::MockClientSocketFactory mock_socket_factory_; net::TestURLRequestContext context_; net::URLRequestContextStorage context_storage_; + scoped_ptr<net::ProxyDelegate> proxy_delegate_; scoped_ptr<DataReductionProxyTestContext> drp_test_context_; }; diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.cc index 5a86b16..8b74b49 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.cc @@ -149,8 +149,9 @@ DataReductionProxyIOData::DataReductionProxyIOData( base::Unretained(this)))); } - proxy_delegate_.reset( - new DataReductionProxyDelegate(request_options_.get(), config_.get())); + proxy_delegate_.reset(new DataReductionProxyDelegate( + request_options_.get(), config_.get(), configurator_.get(), + event_creator_.get(), bypass_stats_.get(), net_log_)); } DataReductionProxyIOData::DataReductionProxyIOData() @@ -221,13 +222,20 @@ DataReductionProxyIOData::CreateNetworkDelegate( scoped_ptr<DataReductionProxyNetworkDelegate> network_delegate( new DataReductionProxyNetworkDelegate( std::move(wrapped_network_delegate), config_.get(), - request_options_.get(), configurator_.get(), net_log_, - event_creator_.get())); + request_options_.get(), configurator_.get())); if (track_proxy_bypass_statistics) network_delegate->InitIODataAndUMA(this, bypass_stats_.get()); return network_delegate; } +scoped_ptr<DataReductionProxyDelegate> +DataReductionProxyIOData::CreateProxyDelegate() const { + DCHECK(io_task_runner_->BelongsToCurrentThread()); + return make_scoped_ptr(new DataReductionProxyDelegate( + request_options_.get(), config_.get(), configurator_.get(), + event_creator_.get(), bypass_stats_.get(), net_log_)); +} + // TODO(kundaji): Rename this method to something more descriptive. // Bug http://crbug/488190. void DataReductionProxyIOData::SetProxyPrefs(bool enabled, bool at_startup) { diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.h b/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.h index fd1ec20..fc2bd7e 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.h +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_io_data.h @@ -82,6 +82,8 @@ class DataReductionProxyIOData : public DataReductionProxyEventStorageDelegate { scoped_ptr<net::NetworkDelegate> wrapped_network_delegate, bool track_proxy_bypass_statistics); + scoped_ptr<DataReductionProxyDelegate> CreateProxyDelegate() const; + // Sets user defined preferences for how the Data Reduction Proxy // configuration should be set. |at_startup| is true only // when DataReductionProxySettings is initialized. diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.cc index af0a50a..b5710ac 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.cc @@ -15,10 +15,8 @@ #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_request_options.h" -#include "components/data_reduction_proxy/core/common/data_reduction_proxy_event_creator.h" #include "components/data_reduction_proxy/core/common/lofi_decider.h" #include "net/base/load_flags.h" -#include "net/base/net_util.h" #include "net/http/http_request_headers.h" #include "net/http/http_response_headers.h" #include "net/proxy/proxy_info.h" @@ -119,9 +117,7 @@ DataReductionProxyNetworkDelegate::DataReductionProxyNetworkDelegate( scoped_ptr<net::NetworkDelegate> network_delegate, DataReductionProxyConfig* config, DataReductionProxyRequestOptions* request_options, - const DataReductionProxyConfigurator* configurator, - net::NetLog* net_log, - DataReductionProxyEventCreator* event_creator) + const DataReductionProxyConfigurator* configurator) : LayeredNetworkDelegate(std::move(network_delegate)), total_received_bytes_(0), total_original_received_bytes_(0), @@ -129,14 +125,10 @@ DataReductionProxyNetworkDelegate::DataReductionProxyNetworkDelegate( data_reduction_proxy_bypass_stats_(nullptr), data_reduction_proxy_request_options_(request_options), data_reduction_proxy_io_data_(nullptr), - configurator_(configurator), - net_log_(net_log), - event_creator_(event_creator) { + configurator_(configurator) { DCHECK(data_reduction_proxy_config_); DCHECK(data_reduction_proxy_request_options_); DCHECK(configurator_); - DCHECK(net_log_); - DCHECK(event_creator_); } DataReductionProxyNetworkDelegate::~DataReductionProxyNetworkDelegate() { @@ -161,32 +153,6 @@ DataReductionProxyNetworkDelegate::SessionNetworkStatsInfoToValue() const { return dict; } -void DataReductionProxyNetworkDelegate::OnResolveProxyInternal( - const GURL& url, - int load_flags, - const net::ProxyService& proxy_service, - net::ProxyInfo* result) { - OnResolveProxyHandler(url, load_flags, configurator_->GetProxyConfig(), - proxy_service.proxy_retry_info(), - data_reduction_proxy_config_, result); -} - -void DataReductionProxyNetworkDelegate::OnProxyFallbackInternal( - const net::ProxyServer& bad_proxy, - int net_error) { - if (bad_proxy.is_valid() && - data_reduction_proxy_config_->IsDataReductionProxy( - bad_proxy.host_port_pair(), nullptr)) { - event_creator_->AddProxyFallbackEvent(net_log_, bad_proxy.ToURI(), - net_error); - } - - if (data_reduction_proxy_bypass_stats_) { - data_reduction_proxy_bypass_stats_->OnProxyFallback( - bad_proxy, net_error); - } -} - void DataReductionProxyNetworkDelegate::OnBeforeSendProxyHeadersInternal( net::URLRequest* request, const net::ProxyInfo& proxy_info, @@ -344,37 +310,6 @@ void DataReductionProxyNetworkDelegate::RecordContentLength( } } -void OnResolveProxyHandler(const GURL& url, - int load_flags, - const net::ProxyConfig& data_reduction_proxy_config, - const net::ProxyRetryInfoMap& proxy_retry_info, - const DataReductionProxyConfig* config, - net::ProxyInfo* result) { - DCHECK(config); - DCHECK(result->is_empty() || result->is_direct() || - !config->IsDataReductionProxy(result->proxy_server().host_port_pair(), - NULL)); - bool data_saver_proxy_used = true; - if (result->proxy_server().is_direct() && result->proxy_list().size() == 1 && - !url.SchemeIsWSOrWSS()) { - if (data_reduction_proxy_config.is_valid()) { - net::ProxyInfo data_reduction_proxy_info; - data_reduction_proxy_config.proxy_rules().Apply( - url, &data_reduction_proxy_info); - data_reduction_proxy_info.DeprioritizeBadProxies(proxy_retry_info); - if (!data_reduction_proxy_info.proxy_server().is_direct()) - result->OverrideProxyList(data_reduction_proxy_info.proxy_list()); - } else { - data_saver_proxy_used = false; - } - if (config->enabled_by_user_and_reachable() && url.SchemeIsHTTPOrHTTPS() && - !url.SchemeIsCryptographic() && !net::IsLocalhost(url.host())) { - UMA_HISTOGRAM_BOOLEAN("DataReductionProxy.ConfigService.HTTPRequests", - data_saver_proxy_used); - } - } -} - void DataReductionProxyNetworkDelegate::RecordLoFiTransformationType( LoFiTransformationType type) { UMA_HISTOGRAM_ENUMERATION("DataReductionProxy.LoFi.TransformationType", type, diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.h b/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.h index 4611e5e..37831b9 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.h +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate.h @@ -25,7 +25,6 @@ class Value; namespace net { class HttpResponseHeaders; class HttpRequestHeaders; -class NetLog; class NetworkDelegate; class ProxyConfig; class ProxyInfo; @@ -39,7 +38,7 @@ namespace data_reduction_proxy { class DataReductionProxyBypassStats; class DataReductionProxyConfig; class DataReductionProxyConfigurator; -class DataReductionProxyEventCreator; +class DataReductionProxyExperimentsStats; class DataReductionProxyIOData; class DataReductionProxyRequestOptions; @@ -62,19 +61,17 @@ class DataReductionProxyNetworkDelegate : public net::LayeredNetworkDelegate { // to the OnResolveProxyHandler and RecordBytesHistograms. typedef base::Callback<const net::ProxyConfig&()> ProxyConfigGetter; - // Constructs a DataReductionProxyNetworkdelegate object with the given - // |network_delegate|, |config|, |handler|, |configurator|, - // |net_log|, and |event_creator|. Takes ownership of and wraps the - // |network_delegate|, calling an internal implementation for each delegate - // method. For example, the implementation of OnHeadersReceived() calls - // OnHeadersReceivedInternal(). + // Constructs a DataReductionProxyNetworkDelegate object with the given + // |network_delegate|, |config|, |handler|, |configurator|, and + // |experiments_stats|. Takes ownership of + // and wraps the |network_delegate|, calling an internal implementation for + // each delegate method. For example, the implementation of + // OnHeadersReceived() calls OnHeadersReceivedInternal(). DataReductionProxyNetworkDelegate( scoped_ptr<net::NetworkDelegate> network_delegate, DataReductionProxyConfig* config, DataReductionProxyRequestOptions* handler, - const DataReductionProxyConfigurator* configurator, - net::NetLog* net_log, - DataReductionProxyEventCreator* event_creator); + const DataReductionProxyConfigurator* configurator); ~DataReductionProxyNetworkDelegate() override; // Initializes member variables to record data reduction proxy prefs and @@ -88,21 +85,6 @@ class DataReductionProxyNetworkDelegate : public net::LayeredNetworkDelegate { base::Value* SessionNetworkStatsInfoToValue() const; private: - // Called as the proxy is being resolved for |url|. Allows the delegate to - // override the proxy resolution decision made by ProxyService. The delegate - // may override the decision by modifying the ProxyInfo |result|. - void OnResolveProxyInternal(const GURL& url, - int load_flags, - const net::ProxyService& proxy_service, - net::ProxyInfo* result) override; - - // Called when use of |bad_proxy| fails due to |net_error|. |net_error| is - // the network error encountered, if any, and OK if the fallback was - // for a reason other than a network error (e.g. the proxy service was - // explicitly directed to skip a proxy). - void OnProxyFallbackInternal(const net::ProxyServer& bad_proxy, - int net_error) override; - // Called after a proxy connection. Allows the delegate to read/write // |headers| before they get sent out. |headers| is valid only until // OnCompleted or OnURLRequestDestroyed is called for this request. @@ -163,26 +145,8 @@ class DataReductionProxyNetworkDelegate : public net::LayeredNetworkDelegate { const DataReductionProxyConfigurator* configurator_; - net::NetLog* net_log_; - - DataReductionProxyEventCreator* event_creator_; - DISALLOW_COPY_AND_ASSIGN(DataReductionProxyNetworkDelegate); }; - -// Adds data reduction proxies to |result|, where applicable, if result -// otherwise uses a direct connection for |url|, and the data reduction proxy is -// not bypassed. Also, configures |result| to proceed directly to the origin if -// |result|'s current proxy is the data reduction proxy, the -// |net::LOAD_BYPASS_DATA_REDUCTION_PROXY| |load_flag| is set, and the -// DataCompressionProxyCriticalBypass Finch trial is set. -void OnResolveProxyHandler(const GURL& url, - int load_flags, - const net::ProxyConfig& data_reduction_proxy_config, - const net::ProxyRetryInfoMap& proxy_retry_info, - const DataReductionProxyConfig* config, - net::ProxyInfo* result); - } // namespace data_reduction_proxy #endif // COMPONENTS_DATA_REDUCTION_PROXY_CORE_BROWSER_DATA_REDUCTION_PROXY_NETWORK_DELEGATE_H_ diff --git a/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate_unittest.cc b/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate_unittest.cc index ae37c39..2e83377 100644 --- a/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate_unittest.cc +++ b/components/data_reduction_proxy/core/browser/data_reduction_proxy_network_delegate_unittest.cc @@ -561,192 +561,6 @@ TEST_F(DataReductionProxyNetworkDelegateTest, MAYBE_NetHistograms) { } } -TEST_F(DataReductionProxyNetworkDelegateTest, OnResolveProxyHandler) { - int load_flags = net::LOAD_NORMAL; - GURL url("http://www.google.com/"); - - // Data reduction proxy info - net::ProxyInfo data_reduction_proxy_info; - std::string data_reduction_proxy; - base::TrimString(params()->DefaultOrigin(), "/", &data_reduction_proxy); - data_reduction_proxy_info.UsePacString( - "PROXY " + - net::ProxyServer::FromURI( - params()->DefaultOrigin(), - net::ProxyServer::SCHEME_HTTP).host_port_pair().ToString() + - "; DIRECT"); - EXPECT_FALSE(data_reduction_proxy_info.is_empty()); - - // Data reduction proxy config - net::ProxyConfig data_reduction_proxy_config; - data_reduction_proxy_config.proxy_rules().ParseFromString( - "http=" + data_reduction_proxy + ",direct://;"); - data_reduction_proxy_config.set_id(1); - - // Other proxy info - net::ProxyInfo other_proxy_info; - other_proxy_info.UseNamedProxy("proxy.com"); - EXPECT_FALSE(other_proxy_info.is_empty()); - - // Direct - net::ProxyInfo direct_proxy_info; - direct_proxy_info.UseDirect(); - EXPECT_TRUE(direct_proxy_info.is_direct()); - - // Empty retry info map - net::ProxyRetryInfoMap empty_proxy_retry_info; - - // Retry info map with the data reduction proxy; - net::ProxyRetryInfoMap data_reduction_proxy_retry_info; - net::ProxyRetryInfo retry_info; - retry_info.current_delay = base::TimeDelta::FromSeconds(1000); - retry_info.bad_until = base::TimeTicks().Now() + retry_info.current_delay; - retry_info.try_while_bad = false; - data_reduction_proxy_retry_info[data_reduction_proxy_info.proxy_server() - .ToURI()] = retry_info; - - net::ProxyInfo result; - // Another proxy is used. It should be used afterwards. - result.Use(other_proxy_info); - OnResolveProxyHandler(url, load_flags, data_reduction_proxy_config, - empty_proxy_retry_info, config(), &result); - EXPECT_EQ(other_proxy_info.proxy_server(), result.proxy_server()); - - // A direct connection is used. The data reduction proxy should be used - // afterwards. - // Another proxy is used. It should be used afterwards. - result.Use(direct_proxy_info); - net::ProxyConfig::ID prev_id = result.config_id(); - OnResolveProxyHandler(url, load_flags, data_reduction_proxy_config, - empty_proxy_retry_info, config(), &result); - EXPECT_EQ(data_reduction_proxy_info.proxy_server(), result.proxy_server()); - // Only the proxy list should be updated, not he proxy info. - EXPECT_EQ(result.config_id(), prev_id); - - // A direct connection is used, but the data reduction proxy is on the retry - // list. A direct connection should be used afterwards. - result.Use(direct_proxy_info); - prev_id = result.config_id(); - OnResolveProxyHandler(url, load_flags, data_reduction_proxy_config, - data_reduction_proxy_retry_info, config(), &result); - EXPECT_TRUE(result.proxy_server().is_direct()); - EXPECT_EQ(result.config_id(), prev_id); - - // Test that ws:// and wss:// URLs bypass the data reduction proxy. - result.UseDirect(); - OnResolveProxyHandler(GURL("ws://echo.websocket.org/"), - load_flags, data_reduction_proxy_config, - empty_proxy_retry_info, config(), &result); - EXPECT_TRUE(result.is_direct()); - - OnResolveProxyHandler(GURL("wss://echo.websocket.org/"), - load_flags, data_reduction_proxy_config, - empty_proxy_retry_info, config(), &result); - EXPECT_TRUE(result.is_direct()); - - // Without DataCompressionProxyCriticalBypass Finch trial set, the - // BYPASS_DATA_REDUCTION_PROXY load flag should be ignored. - OnResolveProxyHandler(url, load_flags, data_reduction_proxy_config, - empty_proxy_retry_info, config(), &result); - EXPECT_FALSE(result.is_direct()); - - OnResolveProxyHandler(url, load_flags, data_reduction_proxy_config, - empty_proxy_retry_info, config(), &other_proxy_info); - EXPECT_FALSE(other_proxy_info.is_direct()); -} - -// Verifies that requests that were not proxied through data saver proxy due to -// missing config are recorded properly. -TEST_F(DataReductionProxyNetworkDelegateTest, HTTPRequests) { - const struct { - std::string url; - bool enabled_by_user; - bool use_direct_proxy; - bool expect_histogram; - } tests[] = { - { - // Request should not be logged because data saver is disabled. - "http://www.example.com/", false, true, false, - }, - { - "http://www.example.com/", true, true, true, - }, - { - "http://www.example.com/", true, false, true, - }, - { - "http://www.example.com/", false, false, false, - }, - { - "https://www.example.com/", false, true, false, - }, - { - // Request should not be logged because request is HTTPS. - "https://www.example.com/", true, true, false, - }, - { - // Request to localhost should not be logged. - "http://127.0.0.1/", true, true, false, - }, - { - // Special use IPv4 address for testing purposes (RFC 5735). - "http://198.51.100.1/", true, true, true, - }, - }; - - for (size_t i = 0; i < arraysize(tests); ++i) { - base::HistogramTester histogram_tester; - GURL url(tests[i].url); - - net::ProxyInfo data_reduction_proxy_info; - - std::string data_reduction_proxy; - if (!tests[i].use_direct_proxy) { - base::TrimString(params()->DefaultOrigin(), "/", &data_reduction_proxy); - data_reduction_proxy_info.UsePacString( - "PROXY " + - net::ProxyServer::FromURI(params()->DefaultOrigin(), - net::ProxyServer::SCHEME_HTTP) - .host_port_pair() - .ToString() + - "; DIRECT"); - } - EXPECT_EQ(tests[i].use_direct_proxy, data_reduction_proxy_info.is_empty()); - - net::ProxyConfig data_reduction_proxy_config; - if (tests[i].use_direct_proxy) { - data_reduction_proxy_config = net::ProxyConfig::CreateDirect(); - - } else { - data_reduction_proxy_config.proxy_rules().ParseFromString( - "http=" + data_reduction_proxy + ",direct://;"); - data_reduction_proxy_config.set_id(1); - } - config()->SetStateForTest(tests[i].enabled_by_user /* enabled */, - false /* at_startup */); - - net::ProxyRetryInfoMap empty_proxy_retry_info; - - net::ProxyInfo direct_proxy_info; - direct_proxy_info.UseDirect(); - EXPECT_TRUE(direct_proxy_info.is_direct()); - - net::ProxyInfo result; - result.Use(direct_proxy_info); - OnResolveProxyHandler(url, net::LOAD_NORMAL, data_reduction_proxy_config, - empty_proxy_retry_info, config(), &result); - histogram_tester.ExpectTotalCount( - "DataReductionProxy.ConfigService.HTTPRequests", - tests[i].expect_histogram ? 1 : 0); - - if (tests[i].expect_histogram) { - histogram_tester.ExpectUniqueSample( - "DataReductionProxy.ConfigService.HTTPRequests", - tests[i].use_direct_proxy ? 0 : 1, 1); - } - } -} - // Notify network delegate with a NULL request. TEST_F(DataReductionProxyNetworkDelegateTest, NullRequest) { net::HttpRequestHeaders headers; @@ -863,104 +677,6 @@ TEST_F(DataReductionProxyNetworkDelegateTest, 1); } -TEST_F(DataReductionProxyNetworkDelegateTest, OnCompletedSizeFor200) { - int64_t baseline_received_bytes = total_received_bytes(); - int64_t baseline_original_received_bytes = total_original_received_bytes(); - - const char kDrpResponseHeaders[] = - "HTTP/1.1 200 OK\r\n" - "Date: Wed, 28 Nov 2007 09:40:09 GMT\r\n" - "Warning: 199 Misc-Agent \"some warning text\"\r\n" - "Via:\r\n" - "Via: 1.1 Chrome-Compression-Proxy-Suffix, 9.9 other-proxy\r\n" - "Via: 2.2 Chrome-Compression-Proxy\r\n" - "Warning: 214 Chrome-Compression-Proxy \"Transformation Applied\"\r\n" - "X-Original-Content-Length: 10000\r\n" - "Chrome-Proxy: q=low\r\n" - "Content-Length: 1000\r\n\r\n"; - - scoped_ptr<net::URLRequest> request = FetchURLRequest( - GURL("http://example.com/path/"), nullptr, kDrpResponseHeaders, 1000); - - EXPECT_EQ(request->GetTotalReceivedBytes(), - total_received_bytes() - baseline_received_bytes); - - const std::string raw_headers = net::HttpUtil::AssembleRawHeaders( - kDrpResponseHeaders, arraysize(kDrpResponseHeaders) - 1); - EXPECT_EQ(static_cast<int64_t>(raw_headers.size() + - 10000 /* original_response_body */), - total_original_received_bytes() - baseline_original_received_bytes); -} - -TEST_F(DataReductionProxyNetworkDelegateTest, OnCompletedSizeFor304) { - int64_t baseline_received_bytes = total_received_bytes(); - int64_t baseline_original_received_bytes = total_original_received_bytes(); - - const char kDrpResponseHeaders[] = - "HTTP/1.1 304 Not Modified\r\n" - "Via: 1.1 Chrome-Compression-Proxy\r\n" - "X-Original-Content-Length: 10000\r\n\r\n"; - - scoped_ptr<net::URLRequest> request = FetchURLRequest( - GURL("http://example.com/path/"), nullptr, kDrpResponseHeaders, 0); - - EXPECT_EQ(request->GetTotalReceivedBytes(), - total_received_bytes() - baseline_received_bytes); - - const std::string raw_headers = net::HttpUtil::AssembleRawHeaders( - kDrpResponseHeaders, arraysize(kDrpResponseHeaders) - 1); - EXPECT_EQ(static_cast<int64_t>(raw_headers.size() + - 10000 /* original_response_body */), - total_original_received_bytes() - baseline_original_received_bytes); -} - -TEST_F(DataReductionProxyNetworkDelegateTest, OnCompletedSizeForWriteError) { - int64_t baseline_received_bytes = total_received_bytes(); - int64_t baseline_original_received_bytes = total_original_received_bytes(); - - net::MockWrite writes[] = { - net::MockWrite("GET http://example.com/path/ HTTP/1.1\r\n" - "Host: example.com\r\n"), - net::MockWrite(net::ASYNC, net::ERR_ABORTED)}; - net::StaticSocketDataProvider socket(nullptr, 0, writes, arraysize(writes)); - mock_socket_factory()->AddSocketDataProvider(&socket); - - net::TestDelegate delegate; - scoped_ptr<net::URLRequest> request = context()->CreateRequest( - GURL("http://example.com/path/"), net::IDLE, &delegate); - request->Start(); - base::RunLoop().RunUntilIdle(); - - EXPECT_EQ(request->GetTotalReceivedBytes(), - total_received_bytes() - baseline_received_bytes); - EXPECT_EQ(request->GetTotalReceivedBytes(), - total_original_received_bytes() - baseline_original_received_bytes); -} - -TEST_F(DataReductionProxyNetworkDelegateTest, OnCompletedSizeForReadError) { - int64_t baseline_received_bytes = total_received_bytes(); - int64_t baseline_original_received_bytes = total_original_received_bytes(); - - net::MockRead reads[] = {net::MockRead("HTTP/1.1 200 OK\r\n" - "Via: 1.1 Chrome-Compression-Proxy\r\n" - "X-Original-Content-Length: 10000\r\n" - "Content-Length: 1000\r\n\r\n"), - net::MockRead(net::ASYNC, net::ERR_ABORTED)}; - net::StaticSocketDataProvider socket(reads, arraysize(reads), nullptr, 0); - mock_socket_factory()->AddSocketDataProvider(&socket); - - net::TestDelegate delegate; - scoped_ptr<net::URLRequest> request = context()->CreateRequest( - GURL("http://example.com/path/"), net::IDLE, &delegate); - request->Start(); - base::RunLoop().RunUntilIdle(); - - EXPECT_EQ(request->GetTotalReceivedBytes(), - total_received_bytes() - baseline_received_bytes); - EXPECT_EQ(request->GetTotalReceivedBytes(), - total_original_received_bytes() - baseline_original_received_bytes); -} - } // namespace } // namespace data_reduction_proxy |