diff options
author | marq@chromium.org <marq@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-10-19 18:25:36 +0000 |
---|---|---|
committer | marq@chromium.org <marq@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2013-10-19 18:25:36 +0000 |
commit | e6a236465d06825473f8e4e1aaf0eb3ab679c55c (patch) | |
tree | 6e81b00e1a6e41923a44fa549e7dfea20d2fb411 | |
parent | d12cc5eb9f07b73701a42ebceefed4780a7e20b6 (diff) | |
download | chromium_src-e6a236465d06825473f8e4e1aaf0eb3ab679c55c.zip chromium_src-e6a236465d06825473f8e4e1aaf0eb3ab679c55c.tar.gz chromium_src-e6a236465d06825473f8e4e1aaf0eb3ab679c55c.tar.bz2 |
This is the reorganization that's a necessary precursor to implementing the HTTP fallback for M32.
Here's what's changed:
- There's now a DataReductionProxySettings base class that DataReductionProxySettingsAndroid inherits from. All functionality that's not platform-specific is now in the superclass.
- In general, DataReductionProxySettingsAndroid methods that accept or return Java types are now wrappers which call a superclass method with the same name but a different method signature.
- Many private methods moved to protected so the subclasses can use them.
- This implementation assumes fixed proxy configuiration is the default, and DataReductionProxySettingsAndroid overrides that to use an inline PAC data URL. Some method names have changed accordingly.
- The UMA used by DataReductionProxySettingsAndroid are obsolete but haven't been corrected; the superclass uses the current correct UMA. The |at_startup| param for SetProxyConfigs() is only provided to support these older histograms and isn't used in the superclass implementation.
- Unit tests were also factored apart. There's some duplicated code in the test classes that I'll clean up later.
- I moved to using defined(SPDY_PROXY_AUTH_ORIGIN) as the preprocessor gate for data reduction proxy features, rather than defined(OS_ANDROID) || defined(OS_IOS). However, I suspect we will actually want to move to an independent flag (DATA_REDUCTION_PROXY_FEATURE_AVAILABLE or something if we want to keep the authentication stuff separate. Regardless, we should move away from platform-specific flags.
I tried to keep functional changes to a minimum; I believe this is the extent of them:
- LOG()s were either removed or turned to D/VLOG()s.
- The probe URL isn't blocked in the configs; instead the probe request sets LOAD_BYPASS_PROXY
- Host-level bypasses use the system proxy bypass list rather than (on Android) adding more PAC clauses.
- URL pattern bypasses are still supported on Android; in the base class they are converted into host bypasses (so bypassing foo.bar.com/baz/* will just bypass all of foo.bar.com instead).
- Profiles are fetched by the non-deprecated GetLastUsedProfile()
- By default, RFC1918 and RFC4193 private addresses are bypassed.
- By default, http://www.google.com/complete/search* is not bypassed; however, it is on Android.
- The bug in GetProxyCheckURL where the proxy server URL is returned when the probe URL is set on the command line is fixed.
I expect the API will evolve further as the HTTP fallback is implemented and the class is integrated with other platforms.
Review URL: https://codereview.chromium.org/27221002
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@229608 0039d316-1c4b-4281-b951-d872f2087c98
12 files changed, 1326 insertions, 779 deletions
diff --git a/chrome/browser/net/spdyproxy/OWNERS b/chrome/browser/net/spdyproxy/OWNERS index 845f1d7..a46d1ea 100644 --- a/chrome/browser/net/spdyproxy/OWNERS +++ b/chrome/browser/net/spdyproxy/OWNERS @@ -1 +1,2 @@ bengr@chromium.org +marq@chromium.org diff --git a/chrome/browser/net/spdyproxy/data_reduction_proxy_settings.cc b/chrome/browser/net/spdyproxy/data_reduction_proxy_settings.cc new file mode 100644 index 0000000..4318d77 --- /dev/null +++ b/chrome/browser/net/spdyproxy/data_reduction_proxy_settings.cc @@ -0,0 +1,464 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/net/spdyproxy/data_reduction_proxy_settings.h" + +#include "base/bind.h" +#include "base/command_line.h" +#include "base/metrics/field_trial.h" +#include "base/metrics/histogram.h" +#include "base/prefs/pref_member.h" +#include "base/prefs/pref_service.h" +#include "base/strings/string_number_conversions.h" +#include "base/strings/string_util.h" +#include "base/strings/stringprintf.h" +#include "base/strings/utf_string_conversions.h" +#include "chrome/browser/browser_process.h" +#include "chrome/browser/prefs/proxy_prefs.h" +#include "chrome/browser/prefs/scoped_user_pref_update.h" +#include "chrome/browser/profiles/profile.h" +#include "chrome/browser/profiles/profile_manager.h" +#include "chrome/common/chrome_switches.h" +#include "chrome/common/pref_names.h" +#include "net/base/host_port_pair.h" +#include "net/base/load_flags.h" +#include "net/base/net_errors.h" +#include "net/url_request/url_fetcher.h" +#include "net/url_request/url_fetcher_delegate.h" +#include "net/url_request/url_request_status.h" +#include "url/gurl.h" + +using base::FieldTrialList; +using base::StringPrintf; + +namespace { + +// Key of the UMA DataReductionProxy.StartupState histogram. +const char kUMAProxyStartupStateHistogram[] = + "DataReductionProxy.StartupState"; +// Values of the UMA DataReductionProxy.StartupState histogram. +enum ProxyStartupState { + PROXY_NOT_AVAILABLE = 0, + PROXY_DISABLED, + PROXY_ENABLED, + PROXY_STARTUP_STATE_COUNT, +}; + +const char kEnabled[] = "Enabled"; + +int64 GetInt64PrefValue(const ListValue& list_value, size_t index) { + int64 val = 0; + std::string pref_value; + bool rv = list_value.GetString(index, &pref_value); + DCHECK(rv); + if (rv) { + rv = base::StringToInt64(pref_value, &val); + DCHECK(rv); + } + return val; +} + +} // namespace + +DataReductionProxySettings::DataReductionProxySettings() + : has_turned_on_(false), + has_turned_off_(false), + disabled_by_carrier_(false), + enabled_by_user_(false) { +} + +DataReductionProxySettings::~DataReductionProxySettings() { + if (IsDataReductionProxyAllowed()) + spdy_proxy_auth_enabled_.Destroy(); +} + +void DataReductionProxySettings::InitPrefMembers() { + spdy_proxy_auth_enabled_.Init( + prefs::kSpdyProxyAuthEnabled, + GetOriginalProfilePrefs(), + base::Bind(&DataReductionProxySettings::OnProxyEnabledPrefChange, + base::Unretained(this))); +} + +void DataReductionProxySettings::InitDataReductionProxySettings() { + // Disable the proxy if it is not allowed to be used. + if (!IsDataReductionProxyAllowed()) + return; + + InitPrefMembers(); + + AddDefaultProxyBypassRules(); + net::NetworkChangeNotifier::AddIPAddressObserver(this); + + const CommandLine& command_line = *CommandLine::ForCurrentProcess(); + + // Setting the kEnableSpdyProxyAuth switch has the same effect as enabling + // the feature via settings, in that once set, the preference will be sticky + // across instances of Chrome. Disabling the feature can only be done through + // the settings menu. + RecordDataReductionInit(); + if (spdy_proxy_auth_enabled_.GetValue() || + command_line.HasSwitch(switches::kEnableSpdyProxyAuth)) { + MaybeActivateDataReductionProxy(true); + } else { + // This is logged so we can use this information in user feedback. + LogProxyState(false /* enabled */, true /* at startup */); + } +} + +void DataReductionProxySettings::AddHostPatternToBypass( + const std::string& pattern) { + bypass_rules_.push_back(pattern); +} + +void DataReductionProxySettings::AddURLPatternToBypass( + const std::string& pattern) { + size_t pos = pattern.find("/"); + if (pattern.find("/", pos + 1) == pos + 1) + pos = pattern.find("/", pos + 2); + + std::string host_pattern; + if (pos != std::string::npos) + host_pattern = pattern.substr(0, pos); + else + host_pattern = pattern; + + AddHostPatternToBypass(host_pattern); +} + +bool DataReductionProxySettings::IsDataReductionProxyAllowed() { + return IsProxyOriginSetOnCommandLine() || + (FieldTrialList::FindFullName("DataCompressionProxyRollout") == kEnabled); +} + +bool DataReductionProxySettings::IsDataReductionProxyPromoAllowed() { + return IsProxyOriginSetOnCommandLine() || + (IsDataReductionProxyAllowed() && + FieldTrialList::FindFullName("DataCompressionProxyPromoVisibility") == + kEnabled); +} + +std::string DataReductionProxySettings::GetDataReductionProxyOrigin() { + const CommandLine& command_line = *CommandLine::ForCurrentProcess(); + if (command_line.HasSwitch(switches::kSpdyProxyAuthOrigin)) + return command_line.GetSwitchValueASCII(switches::kSpdyProxyAuthOrigin); +#if defined(SPDY_PROXY_AUTH_ORIGIN) + return SPDY_PROXY_AUTH_ORIGIN; +#else + return std::string(); +#endif +} + +std::string DataReductionProxySettings::GetDataReductionProxyAuth() { + if (!IsDataReductionProxyAllowed()) + return std::string(); + const CommandLine& command_line = *CommandLine::ForCurrentProcess(); + if (command_line.HasSwitch(switches::kSpdyProxyAuthOrigin)) { + // If an origin is provided via a switch, then only consider the value + // that is provided by a switch. Do not use the preprocessor constant. + // Don't expose SPDY_PROXY_AUTH_VALUE to a proxy passed in via the command + // line. + if (command_line.HasSwitch(switches::kSpdyProxyAuthValue)) + return command_line.GetSwitchValueASCII(switches::kSpdyProxyAuthValue); + return std::string(); + } +#if defined(SPDY_PROXY_AUTH_VALUE) + return SPDY_PROXY_AUTH_VALUE; +#else + return std::string(); +#endif +} + +bool DataReductionProxySettings::IsDataReductionProxyEnabled() { + return spdy_proxy_auth_enabled_.GetValue(); +} + +bool DataReductionProxySettings::IsDataReductionProxyManaged() { + return spdy_proxy_auth_enabled_.IsManaged(); +} + +void DataReductionProxySettings::SetDataReductionProxyEnabled(bool enabled) { + // Prevent configuring the proxy when it is not allowed to be used. + if (!IsDataReductionProxyAllowed()) + return; + + spdy_proxy_auth_enabled_.SetValue(enabled); + OnProxyEnabledPrefChange(); +} + +int64 DataReductionProxySettings::GetDataReductionLastUpdateTime() { + PrefService* local_state = GetLocalStatePrefs(); + int64 last_update_internal = + local_state->GetInt64(prefs::kDailyHttpContentLengthLastUpdateDate); + base::Time last_update = base::Time::FromInternalValue(last_update_internal); + return static_cast<int64>(last_update.ToJsTime()); +} + +std::vector<long long> +DataReductionProxySettings::GetDailyOriginalContentLengths() { + return GetDailyContentLengths(prefs::kDailyHttpOriginalContentLength); +} + +std::vector<long long> +DataReductionProxySettings::GetDailyReceivedContentLengths() { + return GetDailyContentLengths(prefs::kDailyHttpReceivedContentLength); +} + +void DataReductionProxySettings::OnURLFetchComplete( + const net::URLFetcher* source) { + net::URLRequestStatus status = source->GetStatus(); + if (status.status() == net::URLRequestStatus::FAILED && + status.error() == net::ERR_INTERNET_DISCONNECTED) { + return; + } + + std::string response; + source->GetResponseAsString(&response); + + if ("OK" == response.substr(0, 2)) { + DVLOG(1) << "The data reduction proxy is not blocked."; + + if (enabled_by_user_ && disabled_by_carrier_) { + // The user enabled the proxy, but sometime previously in the session, + // the network operator had blocked the proxy. Now that the network + // operator is unblocking it, configure it to the user's desires. + SetProxyConfigs(true, false); + } + disabled_by_carrier_ = false; + return; + } + DVLOG(1) << "The data reduction proxy is blocked."; + + if (enabled_by_user_ && !disabled_by_carrier_) { + // Disable the proxy. + SetProxyConfigs(false, false); + } + disabled_by_carrier_ = true; +} + +std::string DataReductionProxySettings::GetDataReductionProxyOriginHostPort() { + std::string spdy_proxy = GetDataReductionProxyOrigin(); + if (spdy_proxy.empty()) { + DLOG(ERROR) << "A SPDY proxy has not been set."; + return spdy_proxy; + } + // Remove a trailing slash from the proxy string if one exists as well as + // leading HTTPS scheme. + return net::HostPortPair::FromURL(GURL(spdy_proxy)).ToString(); +} + +void DataReductionProxySettings::OnIPAddressChanged() { + if (enabled_by_user_) { + DCHECK(IsDataReductionProxyAllowed()); + ProbeWhetherDataReductionProxyIsAvailable(); + } +} + +void DataReductionProxySettings::OnProxyEnabledPrefChange() { + if (!IsDataReductionProxyAllowed()) + return; + MaybeActivateDataReductionProxy(false); +} + +void DataReductionProxySettings::AddDefaultProxyBypassRules() { + // localhost + AddHostPatternToBypass("<local>"); + // RFC1918 private addresses. + AddHostPatternToBypass("10.0.0.0/8"); + AddHostPatternToBypass("172.16.0.0/12"); + AddHostPatternToBypass("192.168.0.0/16"); + // RFC4193 private addresses. + AddHostPatternToBypass("fc00::/7"); +} + +void DataReductionProxySettings::LogProxyState(bool enabled, bool at_startup) { + // This must stay a LOG(WARNING); the output is used in processing customer + // feedback. + const char kAtStartup[] = "at startup"; + const char kByUser[] = "by user action"; + const char kOn[] = "ON"; + const char kOff[] = "OFF"; + + LOG(WARNING) << "SPDY proxy " << (enabled ? kOn : kOff) + << " " << (at_startup ? kAtStartup : kByUser); +} + +PrefService* DataReductionProxySettings::GetOriginalProfilePrefs() { + return g_browser_process->profile_manager()->GetLastUsedProfile()-> + GetOriginalProfile()->GetPrefs(); +} + +PrefService* DataReductionProxySettings::GetLocalStatePrefs() { + return g_browser_process->local_state(); +} + +bool DataReductionProxySettings::IsProxyOriginSetOnCommandLine() { + const CommandLine& command_line = *CommandLine::ForCurrentProcess(); + return command_line.HasSwitch(switches::kSpdyProxyAuthOrigin); +} + +void DataReductionProxySettings::ResetDataReductionStatistics() { + PrefService* prefs = GetLocalStatePrefs(); + if (!prefs) + return; + ListPrefUpdate original_update(prefs, prefs::kDailyHttpOriginalContentLength); + ListPrefUpdate received_update(prefs, prefs::kDailyHttpReceivedContentLength); + original_update->Clear(); + received_update->Clear(); + for (size_t i = 0; i < spdyproxy::kNumDaysInHistory; ++i) { + original_update->AppendString(base::Int64ToString(0)); + received_update->AppendString(base::Int64ToString(0)); + } +} + +void DataReductionProxySettings::MaybeActivateDataReductionProxy( + bool at_startup) { + PrefService* prefs = GetOriginalProfilePrefs(); + + // TODO(marq): Consider moving this so stats are wiped the first time the + // proxy settings are actually (not maybe) turned on. + if (spdy_proxy_auth_enabled_.GetValue() && + !prefs->GetBoolean(prefs::kSpdyProxyAuthWasEnabledBefore)) { + prefs->SetBoolean(prefs::kSpdyProxyAuthWasEnabledBefore, true); + ResetDataReductionStatistics(); + } + + std::string spdy_proxy_origin = GetDataReductionProxyOriginHostPort(); + + // Configure use of the data reduction proxy if it is enabled and the proxy + // origin is non-empty. + enabled_by_user_= + spdy_proxy_auth_enabled_.GetValue() && !spdy_proxy_origin.empty(); + SetProxyConfigs(enabled_by_user_ && !disabled_by_carrier_, at_startup); + + // Check if the proxy has been disabled explicitly by the carrier. + if (enabled_by_user_) + ProbeWhetherDataReductionProxyIsAvailable(); +} + +void DataReductionProxySettings::SetProxyConfigs(bool enabled, + bool at_startup) { + LogProxyState(enabled, at_startup); + PrefService* prefs = GetOriginalProfilePrefs(); + DCHECK(prefs); + DictionaryPrefUpdate update(prefs, prefs::kProxy); + base::DictionaryValue* dict = update.Get(); + if (enabled) { + std::string proxy_server_config = + "http=" + GetDataReductionProxyOrigin() + ",direct://;"; + dict->SetString("server", proxy_server_config); + dict->SetString("mode", + ProxyModeToString(ProxyPrefs::MODE_FIXED_SERVERS)); + dict->SetString("bypass_list", JoinString(bypass_rules_, ", ")); + } else { + dict->SetString("mode", ProxyModeToString(ProxyPrefs::MODE_SYSTEM)); + dict->SetString("server", ""); + dict->SetString("bypass_list", ""); + } +} + +// Metrics methods +void DataReductionProxySettings::RecordDataReductionInit() { + ProxyStartupState state = PROXY_NOT_AVAILABLE; + if (IsDataReductionProxyAllowed()) + state = IsDataReductionProxyEnabled() ? PROXY_ENABLED : PROXY_DISABLED; + UMA_HISTOGRAM_ENUMERATION(kUMAProxyStartupStateHistogram, + state, + PROXY_STARTUP_STATE_COUNT); +} + +DataReductionProxySettings::ContentLengthList +DataReductionProxySettings::GetDailyContentLengths(const char* pref_name) { + DataReductionProxySettings::ContentLengthList content_lengths; + const ListValue* list_value = GetLocalStatePrefs()->GetList(pref_name); + if (list_value->GetSize() == spdyproxy::kNumDaysInHistory) { + for (size_t i = 0; i < spdyproxy::kNumDaysInHistory; ++i) { + content_lengths.push_back(GetInt64PrefValue(*list_value, i)); + } + } + return content_lengths; + } + +void DataReductionProxySettings::GetContentLengths( + unsigned int days, + int64* original_content_length, + int64* received_content_length, + int64* last_update_time) { + DCHECK_LE(days, spdyproxy::kNumDaysInHistory); + PrefService* local_state = GetLocalStatePrefs(); + if (!local_state) { + *original_content_length = 0L; + *received_content_length = 0L; + *last_update_time = 0L; + return; + } + + const ListValue* original_list = + local_state->GetList(prefs::kDailyHttpOriginalContentLength); + const ListValue* received_list = + local_state->GetList(prefs::kDailyHttpReceivedContentLength); + + if (original_list->GetSize() != spdyproxy::kNumDaysInHistory || + received_list->GetSize() != spdyproxy::kNumDaysInHistory) { + *original_content_length = 0L; + *received_content_length = 0L; + *last_update_time = 0L; + return; + } + + int64 orig = 0L; + int64 recv = 0L; + // Include days from the end of the list going backwards. + for (size_t i = spdyproxy::kNumDaysInHistory - days; + i < spdyproxy::kNumDaysInHistory; ++i) { + orig += GetInt64PrefValue(*original_list, i); + recv += GetInt64PrefValue(*received_list, i); + } + *original_content_length = orig; + *received_content_length = recv; + *last_update_time = + local_state->GetInt64(prefs::kDailyHttpContentLengthLastUpdateDate); +} + +std::string DataReductionProxySettings::GetProxyCheckURL() { + if (!IsDataReductionProxyAllowed()) + return std::string(); + const CommandLine& command_line = *CommandLine::ForCurrentProcess(); + if (command_line.HasSwitch(switches::kDataReductionProxyProbeURL)) { + return command_line.GetSwitchValueASCII( + switches::kDataReductionProxyProbeURL); + } +#if defined(DATA_REDUCTION_PROXY_PROBE_URL) + return DATA_REDUCTION_PROXY_PROBE_URL; +#else + return std::string(); +#endif +} + +net::URLFetcher* DataReductionProxySettings::GetURLFetcher() { + std::string url = GetProxyCheckURL(); + if (url.empty()) + return NULL; + net::URLFetcher* fetcher = net::URLFetcher::Create(GURL(url), + net::URLFetcher::GET, + this); + fetcher->SetLoadFlags(net::LOAD_DISABLE_CACHE); + fetcher->SetLoadFlags(net::LOAD_BYPASS_PROXY); + Profile* profile = g_browser_process->profile_manager()-> + GetDefaultProfile(); + fetcher->SetRequestContext(profile->GetRequestContext()); + // Configure max retries to be at most kMaxRetries times for 5xx errors. + static const int kMaxRetries = 5; + fetcher->SetMaxRetriesOn5xx(kMaxRetries); + return fetcher; +} + +void +DataReductionProxySettings::ProbeWhetherDataReductionProxyIsAvailable() { + net::URLFetcher* fetcher = GetURLFetcher(); + if (!fetcher) + return; + fetcher_.reset(fetcher); + fetcher_->Start(); +} diff --git a/chrome/browser/net/spdyproxy/data_reduction_proxy_settings.h b/chrome/browser/net/spdyproxy/data_reduction_proxy_settings.h new file mode 100644 index 0000000..f066d66 --- /dev/null +++ b/chrome/browser/net/spdyproxy/data_reduction_proxy_settings.h @@ -0,0 +1,207 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_NET_SPDYPROXY_DATA_REDUCTION_PROXY_SETTINGS_H_ +#define CHROME_BROWSER_NET_SPDYPROXY_DATA_REDUCTION_PROXY_SETTINGS_H_ + +#include <vector> + +#include "base/basictypes.h" +#include "base/compiler_specific.h" +#include "base/gtest_prod_util.h" +#include "base/memory/scoped_ptr.h" +#include "base/prefs/pref_member.h" +#include "net/base/network_change_notifier.h" +#include "net/url_request/url_fetcher_delegate.h" + +class PrefService; + +namespace net { +class URLFetcher; +} + +namespace spdyproxy { + +// The number of days of bandwidth usage statistics that are tracked. +const unsigned int kNumDaysInHistory = 60; + +// The number of days of bandwidth usage statistics that are presented. +const unsigned int kNumDaysInHistorySummary = 30; + +COMPILE_ASSERT(kNumDaysInHistorySummary <= kNumDaysInHistory, + DataReductionProxySettings_summary_too_long); + +} // namespace spdyproxy + +// Central point for configuring the data reduction proxy. +// This object lives on the UI thread and all of its methods are expected to +// be called from there. +class DataReductionProxySettings + : public net::URLFetcherDelegate, + public net::NetworkChangeNotifier::IPAddressObserver { + public: + typedef std::vector<long long> ContentLengthList; + + DataReductionProxySettings(); + virtual ~DataReductionProxySettings(); + + void InitDataReductionProxySettings(); + + // Add a host pattern to bypass. This should follow the same syntax used + // in net::ProxyBypassRules; that is, a hostname pattern, a hostname suffix + // pattern, an IP literal, a CIDR block, or the magic string '<local>'. + // Bypass settings persist for the life of this object and are applied + // each time the proxy is enabled, but are not updated while it is enabled. + void AddHostPatternToBypass(const std::string& pattern); + + // Add a URL pattern to bypass the proxy. The base implementation strips + // everything in |pattern| after the first single slash and then treats it + // as a hostname pattern. Subclasses may implement other semantics. + virtual void AddURLPatternToBypass(const std::string& pattern); + + // Returns true if the data reduction proxy is allowed to be used on this + // instance of Chrome. This could return false, for example, if this instance + // is not part of the field trial, or if the proxy name is not configured + // via gyp. + bool IsDataReductionProxyAllowed(); + + // Returns true if a screen promoting the data reduction proxy is allowed to + // be shown. Logic that decides when to show the promo should check its + // availability. This would return false if not part of a separate field + // trial that governs the use of the promotion. + bool IsDataReductionProxyPromoAllowed(); + + // Returns the URL of the data reduction proxy. + std::string GetDataReductionProxyOrigin(); + + // Returns a configuration string for the proxy. + std::string GetDataReductionProxyAuth(); + + // Returns true if the proxy is enabled. + bool IsDataReductionProxyEnabled(); + + // Returns true if the proxy is managed by an adminstrator's policy. + bool IsDataReductionProxyManaged(); + + // Enables or disables the data reduction proxy. If a probe URL is available, + // and a probe request fails at some point, the proxy won't be used until a + // probe succeeds. + void SetDataReductionProxyEnabled(bool enabled); + + // Returns the time in microseconds that the last update was made to the + // daily original and received content lengths. + int64 GetDataReductionLastUpdateTime(); + + // Returns a vector containing the total size of all HTTP content that was + // received over the last |kNumDaysInHistory| before any compression by the + // data reduction proxy. Each element in the vector contains one day of data. + ContentLengthList GetDailyOriginalContentLengths(); + + // Returns an vector containing the aggregate received HTTP content in the + // last |kNumDaysInHistory| days. + ContentLengthList GetDailyReceivedContentLengths(); + + // net::URLFetcherDelegate: + virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE; + + protected: + void InitPrefMembers(); + virtual net::URLFetcher* GetURLFetcher(); + + // Virtualized for unit test support. + virtual PrefService* GetOriginalProfilePrefs(); + virtual PrefService* GetLocalStatePrefs(); + + std::string GetDataReductionProxyOriginHostPort(); + + bool IsProxyOriginSetOnCommandLine(); + void GetContentLengths(unsigned int days, + int64* original_content_length, + int64* received_content_length, + int64* last_update_time); + ContentLengthList GetDailyContentLengths(const char* pref_name); + + // Sets the proxy configs, enabling or disabling the proxy according to + // the value of |enabled|. |at_startup| is true when this method is called + // from InitDataReductionProxySettings. + virtual void SetProxyConfigs(bool enabled, bool at_startup); + + // Metrics methods. Subclasses should override if they wish to provide + // alternate methods. + virtual void RecordDataReductionInit(); + + virtual void AddDefaultProxyBypassRules(); + + // Writes a warning to the log that is used in backend processing of + // customer feedback. + void LogProxyState(bool enabled, bool at_startup); + + bool HasTurnedOn() { return has_turned_on_; } + bool HasTurnedOff() { return has_turned_off_; } + // Note that these flags may only be toggled to true, never back to false. + void SetHasTurnedOn() { has_turned_on_ = true; } + void SetHasTurnedOff() { has_turned_off_ = true; } + + // Accessor for unit tests. + std::vector<std::string> BypassRules() { return bypass_rules_;} + + private: + friend class DataReductionProxySettingsTestBase; + friend class DataReductionProxySettingsTest; + FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsTest, + TestResetDataReductionStatistics); + FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsTest, + TestIsProxyEnabledOrManaged); + FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsTest, + TestContentLengths); + FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsTest, + TestGetDailyContentLengths); + FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsTest, + TestMaybeActivateDataReductionProxy); + FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsTest, + TestOnIPAddressChanged); + FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsTest, + TestOnProxyEnabledPrefChange); + FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsTest, + TestInitDataReductionProxyOn); + FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsTest, + TestInitDataReductionProxyOff); + FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsTest, + TestBypassList); + + // NetworkChangeNotifier::IPAddressObserver: + virtual void OnIPAddressChanged() OVERRIDE; + + void OnProxyEnabledPrefChange(); + + void ResetDataReductionStatistics(); + + void MaybeActivateDataReductionProxy(bool at_startup); + + // Requests the proxy probe URL, if one is set. If unable to do so, disables + // the proxy, if enabled. Otherwise enables the proxy if disabled by a probe + // failure. + void ProbeWhetherDataReductionProxyIsAvailable(); + std::string GetProxyCheckURL(); + + std::vector<std::string> bypass_rules_; + + // Indicate whether a user has turned on the data reduction proxy previously + // in this session. + bool has_turned_on_; + + // Indicate whether a user has turned off the data reduction proxy previously + // in this session. + bool has_turned_off_; + + bool disabled_by_carrier_; + bool enabled_by_user_; + + scoped_ptr<net::URLFetcher> fetcher_; + BooleanPrefMember spdy_proxy_auth_enabled_; + + DISALLOW_COPY_AND_ASSIGN(DataReductionProxySettings); +}; + +#endif // CHROME_BROWSER_NET_SPDYPROXY_DATA_REDUCTION_PROXY_SETTINGS_H_ diff --git a/chrome/browser/net/spdyproxy/data_reduction_proxy_settings_android.cc b/chrome/browser/net/spdyproxy/data_reduction_proxy_settings_android.cc index be70d92..2c23fbf 100644 --- a/chrome/browser/net/spdyproxy/data_reduction_proxy_settings_android.cc +++ b/chrome/browser/net/spdyproxy/data_reduction_proxy_settings_android.cc @@ -41,7 +41,6 @@ using base::android::ScopedJavaLocalRef; using base::FieldTrialList; using base::StringPrintf; - namespace { // The C++ definition of enum SpdyProxyAuthState defined in @@ -56,205 +55,80 @@ enum { NUM_SPDY_PROXY_AUTH_STATE }; -const char kEnabled[] = "Enabled"; - -bool IsProxyOriginSetOnCommandLine() { - const CommandLine& command_line = *CommandLine::ForCurrentProcess(); - return command_line.HasSwitch(switches::kSpdyProxyAuthOrigin); -} - -bool IsProxyAllowed() { - return IsProxyOriginSetOnCommandLine() || - (FieldTrialList::FindFullName("DataCompressionProxyRollout") == kEnabled); -} - -bool IsProxyPromoAllowed() { - return IsProxyOriginSetOnCommandLine() || - (IsProxyAllowed() && - FieldTrialList::FindFullName("DataCompressionProxyPromoVisibility") == - kEnabled); -} - -int64 GetInt64PrefValue(const ListValue& list_value, size_t index) { - int64 val = 0; - std::string pref_value; - bool rv = list_value.GetString(index, &pref_value); - DCHECK(rv); - if (rv) { - rv = base::StringToInt64(pref_value, &val); - DCHECK(rv); - } - return val; -} - -std::string GetProxyCheckURL(){ - if (!IsProxyAllowed()) - return std::string(); - const CommandLine& command_line = *CommandLine::ForCurrentProcess(); - if (command_line.HasSwitch(switches::kDataReductionProxyProbeURL)) { - return command_line.GetSwitchValueASCII(switches::kSpdyProxyAuthOrigin); - } -#if defined(DATA_REDUCTION_PROXY_PROBE_URL) - return DATA_REDUCTION_PROXY_PROBE_URL; -#else - return std::string(); -#endif -} - -std::string GetDataReductionProxyOriginInternal() { - const CommandLine& command_line = *CommandLine::ForCurrentProcess(); - if (command_line.HasSwitch(switches::kSpdyProxyAuthOrigin)) { - return command_line.GetSwitchValueASCII(switches::kSpdyProxyAuthOrigin); - } -#if defined(SPDY_PROXY_AUTH_ORIGIN) - return SPDY_PROXY_AUTH_ORIGIN; -#else - return std::string(); -#endif -} - -std::string GetDataReductionProxyOriginHostPort() { - std::string spdy_proxy = GetDataReductionProxyOriginInternal(); - if (spdy_proxy.empty()) { - DLOG(ERROR) << "A SPDY proxy has not been set."; - return spdy_proxy; - } - // Remove a trailing slash from the proxy string if one exists as well as - // leading HTTPS scheme. - return net::HostPortPair::FromURL(GURL(spdy_proxy)).ToString(); -} - } // namespace - DataReductionProxySettingsAndroid::DataReductionProxySettingsAndroid( - JNIEnv* env, jobject obj) - : has_turned_on_(false), - has_turned_off_(false), - disabled_by_carrier_(false), - enabled_by_user_(false) { + JNIEnv* env, jobject obj): DataReductionProxySettings() { } -DataReductionProxySettingsAndroid::~DataReductionProxySettingsAndroid() { - if (IsProxyAllowed()) - spdy_proxy_auth_enabled_.Destroy(); -} - -void DataReductionProxySettingsAndroid::InitPrefMembers() { - spdy_proxy_auth_enabled_.Init( - prefs::kSpdyProxyAuthEnabled, - GetOriginalProfilePrefs(), - base::Bind(&DataReductionProxySettingsAndroid::OnProxyEnabledPrefChange, - base::Unretained(this))); -} +DataReductionProxySettingsAndroid::~DataReductionProxySettingsAndroid() {} void DataReductionProxySettingsAndroid::InitDataReductionProxySettings( JNIEnv* env, jobject obj) { - // Disable the proxy if it is not allowed to be used. - if (!IsProxyAllowed()) - return; - - InitPrefMembers(); - - AddDefaultProxyBypassRules(); - net::NetworkChangeNotifier::AddIPAddressObserver(this); - - const CommandLine& command_line = *CommandLine::ForCurrentProcess(); - - // Setting the kEnableSpdyProxyAuth switch has the same effect as enabling - // the feature via settings, in that once set, the preference will be sticky - // across instances of Chrome. Disabling the feature can only be done through - // the settings menu. - UMA_HISTOGRAM_ENUMERATION("SpdyProxyAuth.State", CHROME_STARTUP, - NUM_SPDY_PROXY_AUTH_STATE); - if (spdy_proxy_auth_enabled_.GetValue() || - command_line.HasSwitch(switches::kEnableSpdyProxyAuth)) { - MaybeActivateDataReductionProxy(true); - } else { - LOG(WARNING) << "SPDY proxy OFF at startup."; - } + DataReductionProxySettings::InitDataReductionProxySettings(); } void DataReductionProxySettingsAndroid::BypassHostPattern( JNIEnv* env, jobject obj, jstring pattern) { - AddHostPatternToBypass(ConvertJavaStringToUTF8(env, pattern)); + DataReductionProxySettings::AddHostPatternToBypass( + ConvertJavaStringToUTF8(env, pattern)); } void DataReductionProxySettingsAndroid::BypassURLPattern( JNIEnv* env, jobject obj, jstring pattern) { AddURLPatternToBypass(ConvertJavaStringToUTF8(env, pattern)); } +void DataReductionProxySettingsAndroid::AddURLPatternToBypass( + const std::string& pattern) { + pac_bypass_rules_.push_back( + StringPrintf("shExpMatch(%s, '%s')", "url", pattern.c_str())); +} + jboolean DataReductionProxySettingsAndroid::IsDataReductionProxyAllowed( JNIEnv* env, jobject obj) { - return IsProxyAllowed(); + return DataReductionProxySettings::IsDataReductionProxyAllowed(); } jboolean DataReductionProxySettingsAndroid::IsDataReductionProxyPromoAllowed( JNIEnv* env, jobject obj) { - return IsProxyPromoAllowed(); + return DataReductionProxySettings::IsDataReductionProxyPromoAllowed(); } ScopedJavaLocalRef<jstring> DataReductionProxySettingsAndroid::GetDataReductionProxyOrigin( JNIEnv* env, jobject obj) { - return ConvertUTF8ToJavaString(env, GetDataReductionProxyOriginInternal()); + return ConvertUTF8ToJavaString( + env, DataReductionProxySettings::GetDataReductionProxyOrigin()); } ScopedJavaLocalRef<jstring> DataReductionProxySettingsAndroid::GetDataReductionProxyAuth( JNIEnv* env, jobject obj) { - if (!IsProxyAllowed()) - return ConvertUTF8ToJavaString(env, std::string()); - const CommandLine& command_line = *CommandLine::ForCurrentProcess(); - if (command_line.HasSwitch(switches::kSpdyProxyAuthOrigin)) { - // If an origin is provided via a switch, then only consider the value - // that is provided by a switch. Do not use the preprocessor constant. - // Don't expose SPDY_PROXY_AUTH_VALUE to a proxy passed in via the command - // line. - if (command_line.HasSwitch(switches::kSpdyProxyAuthValue)) { - return ConvertUTF8ToJavaString( - env, - command_line.GetSwitchValueASCII(switches::kSpdyProxyAuthValue)); - } - return ConvertUTF8ToJavaString(env, std::string()); - } -#if defined(SPDY_PROXY_AUTH_VALUE) - return ConvertUTF8ToJavaString(env, SPDY_PROXY_AUTH_VALUE); -#else - return ConvertUTF8ToJavaString(env, std::string()); -#endif + return ConvertUTF8ToJavaString( + env, DataReductionProxySettings::GetDataReductionProxyAuth()); } jboolean DataReductionProxySettingsAndroid::IsDataReductionProxyEnabled( JNIEnv* env, jobject obj) { - return spdy_proxy_auth_enabled_.GetValue(); + return DataReductionProxySettings::IsDataReductionProxyEnabled(); } jboolean DataReductionProxySettingsAndroid::IsDataReductionProxyManaged( JNIEnv* env, jobject obj) { - return spdy_proxy_auth_enabled_.IsManaged(); + return DataReductionProxySettings::IsDataReductionProxyManaged(); } void DataReductionProxySettingsAndroid::SetDataReductionProxyEnabled( JNIEnv* env, jobject obj, jboolean enabled) { - // Prevent configuring the proxy when it is not allowed to be used. - if (!IsProxyAllowed()) - return; - - spdy_proxy_auth_enabled_.SetValue(enabled); - OnProxyEnabledPrefChange(); + DataReductionProxySettings::SetDataReductionProxyEnabled(enabled); } jlong DataReductionProxySettingsAndroid::GetDataReductionLastUpdateTime( JNIEnv* env, jobject obj) { - PrefService* local_state = GetLocalStatePrefs(); - int64 last_update_internal = - local_state->GetInt64(prefs::kDailyHttpContentLengthLastUpdateDate); - base::Time last_update = base::Time::FromInternalValue(last_update_internal); - return static_cast<int64>(last_update.ToJsTime()); + return DataReductionProxySettings::GetDataReductionLastUpdateTime(); } base::android::ScopedJavaLocalRef<jobject> @@ -263,10 +137,11 @@ DataReductionProxySettingsAndroid::GetContentLengths(JNIEnv* env, int64 original_content_length; int64 received_content_length; int64 last_update_internal; - GetContentLengthsInternal(spdyproxy::kNumDaysInHistorySummary, - &original_content_length, - &received_content_length, - &last_update_internal); + DataReductionProxySettings::GetContentLengths( + spdyproxy::kNumDaysInHistorySummary, + &original_content_length, + &received_content_length, + &last_update_internal); return Java_ContentLengths_create(env, original_content_length, @@ -291,158 +166,37 @@ bool DataReductionProxySettingsAndroid::Register(JNIEnv* env) { return register_natives_impl_result; } -void DataReductionProxySettingsAndroid::OnURLFetchComplete( - const net::URLFetcher* source) { - net::URLRequestStatus status = source->GetStatus(); - if (status.status() == net::URLRequestStatus::FAILED && - status.error() == net::ERR_INTERNET_DISCONNECTED) { - return; - } - - std::string response; - source->GetResponseAsString(&response); - - if ("OK" == response.substr(0, 2)) { - DVLOG(1) << "The data reduction proxy is not blocked."; - - if (enabled_by_user_ && disabled_by_carrier_) { - // The user enabled the proxy, but sometime previously in the session, - // the network operator had blocked the proxy. Now that the network - // operator is unblocking it, configure it to the user's desires. - SetProxyPac(true, false); - } - disabled_by_carrier_ = false; - return; - } - DVLOG(1) << "The data reduction proxy is blocked."; - - if (enabled_by_user_ && !disabled_by_carrier_) { - // Disable the proxy. - SetProxyPac(false, false); - } - disabled_by_carrier_ = true; -} - -void DataReductionProxySettingsAndroid::OnIPAddressChanged() { - if (enabled_by_user_) { - DCHECK(IsProxyAllowed()); - ProbeWhetherDataReductionProxyIsAvailable(); - } -} - -void DataReductionProxySettingsAndroid::OnProxyEnabledPrefChange() { - if (!IsProxyAllowed()) - return; - MaybeActivateDataReductionProxy(false); +// Metrics methods -- obsolete; see crbug/241518 +void DataReductionProxySettingsAndroid::RecordDataReductionInit() { + UMA_HISTOGRAM_ENUMERATION("SpdyProxyAuth.State", CHROME_STARTUP, + NUM_SPDY_PROXY_AUTH_STATE); } void DataReductionProxySettingsAndroid::AddDefaultProxyBypassRules() { - // localhost - AddHostToBypass("localhost"); - AddHostPatternToBypass("localhost.*"); - AddHostToBypass("127.0.0.1"); - AddHostToBypass("::1"); - // TODO(bengr): revisit 192.168.*, 10.*, 172.16.0.0 - 172.31.255.255. The - // concern was that adding these and other rules would add to the processing - // time. + DataReductionProxySettings::AddDefaultProxyBypassRules(); // TODO(bengr): See http://crbug.com/169959. For some reason the data // reduction proxy is breaking the omnibox SearchProvider. Remove this rule // when this is fixed. AddURLPatternToBypass("http://www.google.com/complete/search*"); - - // Check for proxy availability - std::string proxy_check_url = GetProxyCheckURL(); - if (!proxy_check_url.empty()) { - AddURLPatternToBypass(GetProxyCheckURL()); - } -} - -void DataReductionProxySettingsAndroid::AddURLPatternToBypass( - const std::string& pattern) { - AddPatternToBypass("url", pattern); -} - -void DataReductionProxySettingsAndroid::AddHostPatternToBypass( - const std::string& pattern) { - AddPatternToBypass("host", pattern); -} - -void DataReductionProxySettingsAndroid::AddPatternToBypass( - const std::string& url_or_host, - const std::string& pattern) { - bypass_rules_.push_back( - StringPrintf("shExpMatch(%s, '%s')", - url_or_host.c_str(), pattern.c_str())); -} - -void DataReductionProxySettingsAndroid::AddHostToBypass( - const std::string& host) { - bypass_rules_.push_back( - StringPrintf("host == '%s'", host.c_str())); -} - -PrefService* DataReductionProxySettingsAndroid::GetOriginalProfilePrefs() { - return g_browser_process->profile_manager()->GetDefaultProfile()-> - GetOriginalProfile()->GetPrefs(); -} - -PrefService* DataReductionProxySettingsAndroid::GetLocalStatePrefs() { - return g_browser_process->local_state(); -} - -void DataReductionProxySettingsAndroid::ResetDataReductionStatistics() { - PrefService* prefs = GetLocalStatePrefs(); - if (!prefs) - return; - ListPrefUpdate original_update(prefs, prefs::kDailyHttpOriginalContentLength); - ListPrefUpdate received_update(prefs, prefs::kDailyHttpReceivedContentLength); - original_update->Clear(); - received_update->Clear(); - for (size_t i = 0; i < spdyproxy::kNumDaysInHistory; ++i) { - original_update->AppendString(base::Int64ToString(0)); - received_update->AppendString(base::Int64ToString(0)); - } -} - -void DataReductionProxySettingsAndroid::MaybeActivateDataReductionProxy( - bool at_startup) { - PrefService* prefs = GetOriginalProfilePrefs(); - - if (spdy_proxy_auth_enabled_.GetValue() && - !prefs->GetBoolean(prefs::kSpdyProxyAuthWasEnabledBefore)) { - prefs->SetBoolean(prefs::kSpdyProxyAuthWasEnabledBefore, true); - ResetDataReductionStatistics(); - } - - std::string spdy_proxy_origin = GetDataReductionProxyOriginHostPort(); - - // Configure use of the data reduction proxy if it is enabled and the proxy - // origin is non-empty. - enabled_by_user_= - spdy_proxy_auth_enabled_.GetValue() && !spdy_proxy_origin.empty(); - SetProxyPac(enabled_by_user_ && !disabled_by_carrier_, at_startup); - - // Check if the proxy has been disabled explicitly by the carrier. - if (enabled_by_user_) - ProbeWhetherDataReductionProxyIsAvailable(); } -void DataReductionProxySettingsAndroid::SetProxyPac(bool enable_spdy_proxy, - bool at_startup) { - PrefService* prefs = GetOriginalProfilePrefs(); - DCHECK(prefs); +void DataReductionProxySettingsAndroid::SetProxyConfigs(bool enabled, + bool at_startup) { // Keys duplicated from proxy_config_dictionary.cc // TODO(bengr): Move these to proxy_config_dictionary.h and reuse them here. const char kProxyMode[] = "mode"; const char kProxyPacURL[] = "pac_url"; - const char kAtStartup[] = "at startup"; - const char kByUser[] = "by user action"; + const char kProxyBypassList[] = "bypass_list"; + + LogProxyState(enabled, at_startup); + PrefService* prefs = GetOriginalProfilePrefs(); + DCHECK(prefs); DictionaryPrefUpdate update(prefs, prefs::kProxy); - DictionaryValue* dict = update.Get(); - if (enable_spdy_proxy) { - LOG(WARNING) << "SPDY proxy ON " << (at_startup ? kAtStartup : kByUser); + base::DictionaryValue* dict = update.Get(); + // TODO(marq): All of the UMA in here are obsolete. + if (enabled) { // Convert to a data URI and update the PAC settings. std::string base64_pac; base::Base64Encode(GetProxyPacScript(), &base64_pac); @@ -452,135 +206,72 @@ void DataReductionProxySettingsAndroid::SetProxyPac(bool enable_spdy_proxy, base64_pac); dict->SetString(kProxyMode, ProxyModeToString(ProxyPrefs::MODE_PAC_SCRIPT)); + dict->SetString(kProxyBypassList, JoinString(BypassRules(), ", ")); if (at_startup) { UMA_HISTOGRAM_ENUMERATION("SpdyProxyAuth.State", SPDY_PROXY_AUTH_ON_AT_STARTUP, NUM_SPDY_PROXY_AUTH_STATE); - } else if (!has_turned_on_) { + } else if (!DataReductionProxySettings::HasTurnedOn()) { // SPDY proxy auth is turned on by user action for the first time in // this session. UMA_HISTOGRAM_ENUMERATION("SpdyProxyAuth.State", SPDY_PROXY_AUTH_ON_BY_USER, NUM_SPDY_PROXY_AUTH_STATE); - has_turned_on_ = true; + DataReductionProxySettings::SetHasTurnedOn(); } } else { - LOG(WARNING) << "SPDY proxy OFF " << (at_startup ? kAtStartup : kByUser); dict->SetString(kProxyMode, ProxyModeToString(ProxyPrefs::MODE_SYSTEM)); dict->SetString(kProxyPacURL, ""); + dict->SetString(kProxyBypassList, ""); - if (!at_startup && !has_turned_off_) { + if (!at_startup && !DataReductionProxySettings::HasTurnedOff()) { UMA_HISTOGRAM_ENUMERATION("SpdyProxyAuth.State", SPDY_PROXY_AUTH_OFF_BY_USER, NUM_SPDY_PROXY_AUTH_STATE); - has_turned_off_ = true; + DataReductionProxySettings::SetHasTurnedOff(); } } } ScopedJavaLocalRef<jlongArray> DataReductionProxySettingsAndroid::GetDailyContentLengths( - JNIEnv* env, const char* pref_name) { + JNIEnv* env, const char* pref_name) { jlongArray result = env->NewLongArray(spdyproxy::kNumDaysInHistory); - PrefService* local_state = GetLocalStatePrefs(); - if (!local_state) - return ScopedJavaLocalRef<jlongArray>(env, result); - - const ListValue* list_value = local_state->GetList(pref_name); - if (list_value->GetSize() != spdyproxy::kNumDaysInHistory) - return ScopedJavaLocalRef<jlongArray>(env, result); - - jlong jval[spdyproxy::kNumDaysInHistory]; - for (size_t i = 0; i < spdyproxy::kNumDaysInHistory; ++i) { - jval[i] = GetInt64PrefValue(*list_value, i); - } - env->SetLongArrayRegion(result, 0, spdyproxy::kNumDaysInHistory, jval); - return ScopedJavaLocalRef<jlongArray>(env, result); -} -void DataReductionProxySettingsAndroid::GetContentLengthsInternal( - unsigned int days, - int64* original_content_length, - int64* received_content_length, - int64* last_update_time) { - DCHECK_LE(days, spdyproxy::kNumDaysInHistory); - PrefService* local_state = GetLocalStatePrefs(); - if (!local_state) { - *original_content_length = 0L; - *received_content_length = 0L; - *last_update_time = 0L; - return; - } + DataReductionProxySettings::ContentLengthList lengths = + DataReductionProxySettings::GetDailyContentLengths(pref_name); - const ListValue* original_list = - local_state->GetList(prefs::kDailyHttpOriginalContentLength); - const ListValue* received_list = - local_state->GetList(prefs::kDailyHttpReceivedContentLength); - - if (original_list->GetSize() != spdyproxy::kNumDaysInHistory || - received_list->GetSize() != spdyproxy::kNumDaysInHistory) { - *original_content_length = 0L; - *received_content_length = 0L; - *last_update_time = 0L; - return; + if (!lengths.empty()) { + DCHECK_EQ(lengths.size(), spdyproxy::kNumDaysInHistory); + env->SetLongArrayRegion(result, 0, lengths.size(), &lengths[0]); + return ScopedJavaLocalRef<jlongArray>(env, result); } - int64 orig = 0L; - int64 recv = 0L; - // Include days from the end of the list going backwards. - for (size_t i = spdyproxy::kNumDaysInHistory - days; - i < spdyproxy::kNumDaysInHistory; ++i) { - orig += GetInt64PrefValue(*original_list, i); - recv += GetInt64PrefValue(*received_list, i); - } - *original_content_length = orig; - *received_content_length = recv; - *last_update_time = - local_state->GetInt64(prefs::kDailyHttpContentLengthLastUpdateDate); -} - -net::URLFetcher* DataReductionProxySettingsAndroid::GetURLFetcher() { - std::string url = GetProxyCheckURL(); - if (url.empty()) - return NULL; - net::URLFetcher* fetcher = net::URLFetcher::Create(GURL(url), - net::URLFetcher::GET, - this); - fetcher->SetLoadFlags(net::LOAD_DISABLE_CACHE); - Profile* profile = g_browser_process->profile_manager()-> - GetDefaultProfile(); - fetcher->SetRequestContext(profile->GetRequestContext()); - // Configure max retries to be at most kMaxRetries times for 5xx errors. - static const int kMaxRetries = 5; - fetcher->SetMaxRetriesOn5xx(kMaxRetries); - return fetcher; -} - -void -DataReductionProxySettingsAndroid::ProbeWhetherDataReductionProxyIsAvailable() { - net::URLFetcher* fetcher = GetURLFetcher(); - if (!fetcher) - return; - fetcher_.reset(fetcher); - fetcher_->Start(); + return ScopedJavaLocalRef<jlongArray>(env, result); } // TODO(bengr): Replace with our own ProxyResolver. std::string DataReductionProxySettingsAndroid::GetProxyPacScript() { - std::string bypass_clause = "(" + JoinString(bypass_rules_, ") || (") + ")"; + // Compose the PAC-only bypass code; these will be URL patterns that + // are matched by regular expression. Host bypasses are handled outside + // of the PAC file using the regular proxy bypass list configs. + std::string bypass_clause = + "(" + JoinString(pac_bypass_rules_, ") || (") + ")"; // Generate a proxy PAC that falls back to direct loading when the proxy is // unavailable and only process HTTP traffic. (With a statically configured // proxy, proxy failures will simply result in a connection error presented to // users.) + std::string proxy_host = + DataReductionProxySettings::GetDataReductionProxyOriginHostPort(); std::string pac = "function FindProxyForURL(url, host) {" " if (" + bypass_clause + ") {" " return 'DIRECT';" " } " " if (url.substring(0, 5) == 'http:') {" - " return 'HTTPS " + GetDataReductionProxyOriginHostPort() + + " return 'HTTPS " + proxy_host + "; DIRECT';" " }" " return 'DIRECT';" @@ -594,5 +285,3 @@ static jint Init(JNIEnv* env, jobject obj) { new DataReductionProxySettingsAndroid(env, obj); return reinterpret_cast<jint>(settings); } - - diff --git a/chrome/browser/net/spdyproxy/data_reduction_proxy_settings_android.h b/chrome/browser/net/spdyproxy/data_reduction_proxy_settings_android.h index 3e28e73..10a0020 100644 --- a/chrome/browser/net/spdyproxy/data_reduction_proxy_settings_android.h +++ b/chrome/browser/net/spdyproxy/data_reduction_proxy_settings_android.h @@ -13,185 +13,82 @@ #include "base/gtest_prod_util.h" #include "base/memory/scoped_ptr.h" #include "base/prefs/pref_member.h" -#include "net/base/network_change_notifier.h" -#include "net/url_request/url_fetcher_delegate.h" +#include "chrome/browser/net/spdyproxy/data_reduction_proxy_settings.h" -using base::android::ScopedJavaLocalRef; - -class PrefService; - -namespace net { -class URLFetcher; -} - -namespace spdyproxy { - -// The number of days of bandwidth usage statistics that are tracked. -const unsigned int kNumDaysInHistory = 60; - -// The number of days of bandwidth usage statistics that are presented. -const unsigned int kNumDaysInHistorySummary = 30; -COMPILE_ASSERT(kNumDaysInHistorySummary <= kNumDaysInHistory, - DataReductionProxySettings_summary_too_long); +using base::android::ScopedJavaLocalRef; -} // namespace spdyproxy // Central point for configuring the data reduction proxy on Android. // This object lives on the UI thread and all of its methods are expected to // be called from there. -class DataReductionProxySettingsAndroid - : public net::URLFetcherDelegate, - public net::NetworkChangeNotifier::IPAddressObserver { +class DataReductionProxySettingsAndroid : public DataReductionProxySettings { public: DataReductionProxySettingsAndroid(JNIEnv* env, jobject obj); virtual ~DataReductionProxySettingsAndroid(); void InitDataReductionProxySettings(JNIEnv* env, jobject obj); - // Add a host or URL pattern to bypass the proxy, respectively. Wildcards - // should be compatible with the JavaScript function shExpMatch, which can be - // used in proxy PAC resolution. These function must only be called before the - // proxy is used. + void BypassHostPattern(JNIEnv* env, jobject obj, jstring pattern); + // Add a URL pattern to bypass the proxy. Wildcards + // should be compatible with the JavaScript function shExpMatch, which can be + // used in proxy PAC resolution. These functions must only be called before + // the proxy is used. void BypassURLPattern(JNIEnv* env, jobject obj, jstring pattern); - // Returns true if the data reduction proxy is allowed to be used on this - // instance of Chrome. This could return false, for example, if this instance - // is not part of the field trial, or if the proxy name is not configured - // via gyp. - jboolean IsDataReductionProxyAllowed(JNIEnv* env, jobject obj); + virtual void AddURLPatternToBypass(const std::string& pattern) OVERRIDE; - // Returns true if a screen promoting the data reduction proxy is allowed to - // be shown. Logic that decides when to show the promo should check its - // availability. This would return false if not part of a separate field - // trial that governs the use of the promotion. + // JNI wrapper interfaces to the indentically-named superclass methods. + jboolean IsDataReductionProxyAllowed(JNIEnv* env, jobject obj); jboolean IsDataReductionProxyPromoAllowed(JNIEnv* env, jobject obj); - - // Returns the origin of the data reduction proxy. ScopedJavaLocalRef<jstring> GetDataReductionProxyOrigin(JNIEnv* env, jobject obj); - - // Returns a configuration string for the proxy. ScopedJavaLocalRef<jstring> GetDataReductionProxyAuth(JNIEnv* env, jobject obj); - - // Returns true if the proxy is enabled. jboolean IsDataReductionProxyEnabled(JNIEnv* env, jobject obj); - - // Returns true if the proxy is managed by an adminstrator's policy. jboolean IsDataReductionProxyManaged(JNIEnv* env, jobject obj); - - // Enables or disables the data reduction proxy. If a probe URL is available, - // and a probe request fails at some point, the proxy won't be used until a - // probe succeeds. void SetDataReductionProxyEnabled(JNIEnv* env, jobject obj, jboolean enabled); - // Returns the time in microseconds that the last update was made to the - // daily original and received content lengths. jlong GetDataReductionLastUpdateTime(JNIEnv* env, jobject obj); - - // Return a Java |ContentLengths| object containing the total number of bytes - // of all received content, before and after compression by the data - // reduction proxy. - base::android::ScopedJavaLocalRef<jobject> GetContentLengths(JNIEnv* env, - jobject obj); - - // Returns an array containing the total size of all HTTP content that was - // received over the last |kNumDaysInHistory| before any compression by the - // data reduction proxy. Each element in the array contains one day of data. ScopedJavaLocalRef<jlongArray> GetDailyOriginalContentLengths(JNIEnv* env, jobject obj); - - // Returns an array containing the aggregate received HTTP content in the last - // |kNumDaysInHistory| days. ScopedJavaLocalRef<jlongArray> GetDailyReceivedContentLengths(JNIEnv* env, jobject obj); + // Return a Java |ContentLengths| object wrapping the results of a call to + // DataReductionProxySettings::GetContentLengths. + base::android::ScopedJavaLocalRef<jobject> GetContentLengths(JNIEnv* env, + jobject obj); + // Registers the native methods to be call from Java. static bool Register(JNIEnv* env); - // net::URLFetcherDelegate: - virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE; - protected: - void InitPrefMembers(); - virtual net::URLFetcher* GetURLFetcher(); - virtual PrefService* GetOriginalProfilePrefs(); - virtual PrefService* GetLocalStatePrefs(); + // DataReductionProxySettings overrides. + virtual void AddDefaultProxyBypassRules() OVERRIDE; + + // Configures the proxy settings by generating a data URL containing a PAC + // file. + virtual void SetProxyConfigs(bool enabled, bool at_startup) OVERRIDE; + + virtual void RecordDataReductionInit() OVERRIDE; private: friend class DataReductionProxySettingsAndroidTest; FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsAndroidTest, - TestBypassRules); - FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsAndroidTest, - TestResetDataReductionStatistics); - FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsAndroidTest, - TestIsProxyEnabledOrManaged); + TestBypassPACRules); FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsAndroidTest, TestSetProxyPac); FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsAndroidTest, TestGetDailyContentLengths); - FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsAndroidTest, - TestContentLengthsInternal); - FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsAndroidTest, - TestMaybeActivateDataReductionProxy); - FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsAndroidTest, - TestOnIPAddressChanged); - FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsAndroidTest, - TestOnProxyEnabledPrefChange); - FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsAndroidTest, - TestInitDataReductionProxyOn); - FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsAndroidTest, - TestInitDataReductionProxyOff); - // NetworkChangeNotifier::IPAddressObserver: - virtual void OnIPAddressChanged() OVERRIDE; - - void OnProxyEnabledPrefChange(); - - void AddDefaultProxyBypassRules(); - void AddURLPatternToBypass(const std::string& pattern); - void AddHostPatternToBypass(const std::string& pattern); - void AddPatternToBypass(const std::string& url_or_host, - const std::string& pattern); - void AddHostToBypass(const std::string& host); - - void ResetDataReductionStatistics(); - - void MaybeActivateDataReductionProxy(bool at_startup); - void SetProxyPac(bool enable_spdy_proxy, bool at_startup); - ScopedJavaLocalRef<jlongArray> GetDailyContentLengths(JNIEnv* env, const char* pref_name); - void GetContentLengthsInternal(unsigned int days, - int64* original_content_length, - int64* received_content_length, - int64* last_update_time); - - // Requests the proxy probe URL, if one is set. If unable to do so, disables - // the proxy, if enabled. Otherwise enables the proxy if disabled by a probe - // failure. - void ProbeWhetherDataReductionProxyIsAvailable(); - std::string GetProxyPacScript(); - std::vector<std::string> bypass_rules_; - - // Indicate whether a user has turned on the data reduction proxy previously - // in this session. - bool has_turned_on_; - - // Indicate whether a user has turned off the data reduction proxy previously - // in this session. - bool has_turned_off_; - - bool disabled_by_carrier_; - bool enabled_by_user_; - - scoped_ptr<net::URLFetcher> fetcher_; - BooleanPrefMember spdy_proxy_auth_enabled_; + std::vector<std::string> pac_bypass_rules_; DISALLOW_COPY_AND_ASSIGN(DataReductionProxySettingsAndroid); }; diff --git a/chrome/browser/net/spdyproxy/data_reduction_proxy_settings_ios.cc b/chrome/browser/net/spdyproxy/data_reduction_proxy_settings_ios.cc new file mode 100644 index 0000000..6a0df92 --- /dev/null +++ b/chrome/browser/net/spdyproxy/data_reduction_proxy_settings_ios.cc @@ -0,0 +1,9 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/net/spdyproxy/data_reduction_proxy_settings_ios.h" + +DataReductionProxySettingsIOS::DataReductionProxySettingsIOS() + : DataReductionProxySettings() { +} diff --git a/chrome/browser/net/spdyproxy/data_reduction_proxy_settings_ios.h b/chrome/browser/net/spdyproxy/data_reduction_proxy_settings_ios.h new file mode 100644 index 0000000..be5bf42 --- /dev/null +++ b/chrome/browser/net/spdyproxy/data_reduction_proxy_settings_ios.h @@ -0,0 +1,22 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_NET_SPDYPROXY_DATA_REDUCTION_PROXY_SETTINGS_IOS_H_ +#define CHROME_BROWSER_NET_SPDYPROXY_DATA_REDUCTION_PROXY_SETTINGS_IOS_H_ + +#include "chrome/browser/net/spdyproxy/data_reduction_proxy_settings.h" + +// Central point for configuring the data reduction proxy on iOS. +// This object lives on the UI thread and all of its methods are expected to +// be called from there. +class DataReductionProxySettingsIOS : DataReductionProxySettings { + public: + DataReductionProxySettingsIOS(); + virtual ~DataReductionProxySettingsIOS() {} + + private: + DISALLOW_COPY_AND_ASSIGN(DataReductionProxySettingsIOS); +}; + +#endif // CHROME_BROWSER_NET_SPDYPROXY_DATA_REDUCTION_PROXY_SETTINGS_IOS_H_ diff --git a/chrome/browser/net/spdyproxy/data_reduction_proxy_settings_unittest.cc b/chrome/browser/net/spdyproxy/data_reduction_proxy_settings_unittest.cc new file mode 100644 index 0000000..9a96db8 --- /dev/null +++ b/chrome/browser/net/spdyproxy/data_reduction_proxy_settings_unittest.cc @@ -0,0 +1,419 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include "chrome/browser/net/spdyproxy/data_reduction_proxy_settings_unittest.h" + +#include "base/command_line.h" +#include "base/metrics/field_trial.h" +#include "base/prefs/pref_registry_simple.h" +#include "base/prefs/pref_service.h" +#include "base/prefs/testing_pref_service.h" +#include "base/strings/string_number_conversions.h" +#include "chrome/browser/net/spdyproxy/data_reduction_proxy_settings.h" +#include "chrome/browser/prefs/proxy_prefs.h" +#include "chrome/browser/prefs/scoped_user_pref_update.h" +#include "chrome/common/chrome_switches.h" +#include "chrome/common/metrics/variations/variations_util.h" +#include "chrome/common/pref_names.h" +#include "components/variations/entropy_provider.h" +#include "net/url_request/test_url_fetcher_factory.h" +#include "testing/gtest/include/gtest/gtest.h" +#include "url/gurl.h" + +const char kDataReductionProxyOrigin[] = "https://foo:443/"; +const char kDataReductionProxyOriginHostPort[] = "foo:443"; +const char kDataReductionProxyAuth[] = "12345"; + +const char kProbeURLWithOKResponse[] = "http://ok.org/"; +const char kProbeURLWithBadResponse[] = "http://bad.org/"; +const char kProbeURLWithNoResponse[] = "http://no.org/"; + +class TestDataReductionProxySettings + : public DataReductionProxySettings { + public: + TestDataReductionProxySettings(PrefService* profile_prefs, + PrefService* local_state_prefs) + : DataReductionProxySettings(), + success_(false), + fake_fetcher_request_count_(0), + profile_prefs_(profile_prefs), + local_state_prefs_(local_state_prefs) { + } + + // DataReductionProxySettings implementation: + virtual net::URLFetcher* GetURLFetcher() OVERRIDE { + if (test_url_.empty()) + return NULL; + net::URLFetcher* fetcher = + new net::FakeURLFetcher(GURL(test_url_), this, response_, success_); + fake_fetcher_request_count_++; + return fetcher; + } + + virtual PrefService* GetOriginalProfilePrefs() OVERRIDE { + return profile_prefs_; + } + + virtual PrefService* GetLocalStatePrefs() OVERRIDE { + return local_state_prefs_; + } + + void set_probe_result(const std::string& test_url, + const std::string& response, + bool success) { + test_url_ = test_url; + response_ = response; + success_ = success; + } + + const int fake_fetcher_request_count() { + return fake_fetcher_request_count_; + } + + private: + std::string test_url_; + std::string response_; + bool success_; + int fake_fetcher_request_count_; + PrefService* profile_prefs_; + PrefService* local_state_prefs_; +}; + +DataReductionProxySettingsTestBase::DataReductionProxySettingsTestBase() + : testing::Test() { +} + +DataReductionProxySettingsTestBase::~DataReductionProxySettingsTestBase() {} + +void DataReductionProxySettingsTestBase::AddProxyToCommandLine() { + CommandLine::ForCurrentProcess()->AppendSwitchASCII( + switches::kSpdyProxyAuthOrigin, kDataReductionProxyOrigin); + CommandLine::ForCurrentProcess()->AppendSwitchASCII( + switches::kSpdyProxyAuthValue, kDataReductionProxyAuth); +} + +// testing::Test implementation: +void DataReductionProxySettingsTestBase::SetUp() { + PrefRegistrySimple* registry = pref_service_.registry(); + registry->RegisterListPref(prefs::kDailyHttpOriginalContentLength); + registry->RegisterListPref(prefs::kDailyHttpReceivedContentLength); + registry->RegisterInt64Pref( + prefs::kDailyHttpContentLengthLastUpdateDate, 0L); + registry->RegisterDictionaryPref(prefs::kProxy); + registry->RegisterBooleanPref(prefs::kSpdyProxyAuthEnabled, false); + registry->RegisterBooleanPref(prefs::kSpdyProxyAuthWasEnabledBefore, false); + ResetSettings(); + + ListPrefUpdate original_update(&pref_service_, + prefs::kDailyHttpOriginalContentLength); + ListPrefUpdate received_update(&pref_service_, + prefs::kDailyHttpReceivedContentLength); + for (int64 i = 0; i < spdyproxy::kNumDaysInHistory; i++) { + original_update->Insert(0, new StringValue(base::Int64ToString(2 * i))); + received_update->Insert(0, new StringValue(base::Int64ToString(i))); + } + last_update_time_ = base::Time::Now().LocalMidnight(); + pref_service_.SetInt64( + prefs::kDailyHttpContentLengthLastUpdateDate, + last_update_time_.ToInternalValue()); +} + +void DataReductionProxySettingsTestBase::CheckProxyPref( + const std::string& expected_servers, + const std::string& expected_mode) { + const DictionaryValue* dict = pref_service_.GetDictionary(prefs::kProxy); + std::string mode; + std::string server; + dict->GetString("mode", &mode); + ASSERT_EQ(expected_mode, mode); + dict->GetString("server", &server); + ASSERT_EQ(expected_servers, server); +} + +void DataReductionProxySettingsTestBase::CheckProxyConfigs( + bool expected_enabled) { + if (expected_enabled) { + std::string servers = + "http=" + Settings()->GetDataReductionProxyOrigin() + ",direct://;"; + CheckProxyPref(servers, + ProxyModeToString(ProxyPrefs::MODE_FIXED_SERVERS)); + } else { + CheckProxyPref(std::string(), ProxyModeToString(ProxyPrefs::MODE_SYSTEM)); + } +} + +void DataReductionProxySettingsTestBase::CheckProbe(bool initially_enabled, + const std::string& probe_url, + const std::string& response, + bool request_success, + bool expected_enabled) { + pref_service_.SetBoolean(prefs::kSpdyProxyAuthEnabled, initially_enabled); + SetProbeResult(probe_url, response, request_success); + Settings()->MaybeActivateDataReductionProxy(false); + base::MessageLoop::current()->RunUntilIdle(); + CheckProxyConfigs(expected_enabled); +} + +void DataReductionProxySettingsTestBase::CheckProbeOnIPChange( + const std::string& probe_url, + const std::string& response, + bool request_success, + bool expected_enabled) { + SetProbeResult(probe_url, response, request_success); + Settings()->OnIPAddressChanged(); + base::MessageLoop::current()->RunUntilIdle(); + CheckProxyConfigs(expected_enabled); +} + +void DataReductionProxySettingsTestBase::CheckOnPrefChange( + bool enabled, + const std::string& probe_url, + const std::string& response, + bool request_success, + bool expected_enabled) { + SetProbeResult(probe_url, response, request_success); + pref_service_.SetBoolean(prefs::kSpdyProxyAuthEnabled, enabled); + base::MessageLoop::current()->RunUntilIdle(); + CheckProxyConfigs(expected_enabled); +} + +void DataReductionProxySettingsTestBase::CheckInitDataReductionProxy( + bool enabled_at_startup) { + AddProxyToCommandLine(); + base::MessageLoop loop(base::MessageLoop::TYPE_UI); + pref_service_.SetBoolean(prefs::kSpdyProxyAuthEnabled, enabled_at_startup); + SetProbeResult(kProbeURLWithOKResponse, "OK", true); + Settings()->InitDataReductionProxySettings(); + base::MessageLoop::current()->RunUntilIdle(); + if (enabled_at_startup) { + CheckProxyConfigs(enabled_at_startup); + } else { + // This presumes the proxy preference hadn't been set up by Chrome. + CheckProxyPref(std::string(), std::string()); + } +} + +class DataReductionProxySettingsTest: + public DataReductionProxySettingsTestBase { + public: + virtual void ResetSettings() OVERRIDE { + settings_.reset(new TestDataReductionProxySettings(&pref_service_, + &pref_service_)); + } + + virtual TestDataReductionProxySettings* Settings() OVERRIDE { + return settings_.get(); + } + + virtual void SetProbeResult(const std::string& test_url, + const std::string& response, + bool success) OVERRIDE { + settings_->set_probe_result(test_url, response, success); + } + + scoped_ptr<TestDataReductionProxySettings> settings_; +}; + +TEST_F(DataReductionProxySettingsTest, TestGetDataReductionProxyOrigin) { + AddProxyToCommandLine(); + // SetUp() adds the origin to the command line, which should be returned here. + std::string result = settings_->GetDataReductionProxyOrigin(); + EXPECT_EQ(kDataReductionProxyOrigin, result); +} + +TEST_F(DataReductionProxySettingsTest, TestGetDataReductionProxyAuth) { + AddProxyToCommandLine(); + // SetUp() adds the auth string to the command line, which should be returned + // here. + std::string result = settings_->GetDataReductionProxyAuth(); + EXPECT_EQ(kDataReductionProxyAuth, result); +} + +// Test that the auth value set by preprocessor directive is not returned +// when an origin is set via a switch. This test only does anything useful in +// Chrome builds. +TEST_F(DataReductionProxySettingsTest, + TestGetDataReductionProxyAuthWithOriginSetViaSwitch) { + CommandLine::ForCurrentProcess()->AppendSwitchASCII( + switches::kSpdyProxyAuthOrigin, kDataReductionProxyOrigin); + std::string result = settings_->GetDataReductionProxyAuth(); + EXPECT_EQ("", result); +} + +TEST_F(DataReductionProxySettingsTest, TestIsProxyEnabledOrManaged) { + settings_->InitPrefMembers(); + EXPECT_FALSE(settings_->IsDataReductionProxyEnabled()); + EXPECT_FALSE(settings_->IsDataReductionProxyManaged()); + + pref_service_.SetBoolean(prefs::kSpdyProxyAuthEnabled, true); + EXPECT_TRUE(settings_->IsDataReductionProxyEnabled()); + EXPECT_FALSE(settings_->IsDataReductionProxyManaged()); + + pref_service_.SetManagedPref(prefs::kSpdyProxyAuthEnabled, + base::Value::CreateBooleanValue(true)); + EXPECT_TRUE(settings_->IsDataReductionProxyEnabled()); + EXPECT_TRUE(settings_->IsDataReductionProxyManaged()); +} + +TEST_F(DataReductionProxySettingsTest, TestResetDataReductionStatistics) { + int64 original_content_length; + int64 received_content_length; + int64 last_update_time; + settings_->ResetDataReductionStatistics(); + settings_->GetContentLengths(spdyproxy::kNumDaysInHistory, + &original_content_length, + &received_content_length, + &last_update_time); + EXPECT_EQ(0L, original_content_length); + EXPECT_EQ(0L, received_content_length); + EXPECT_EQ(last_update_time_.ToInternalValue(), last_update_time); +} + +TEST_F(DataReductionProxySettingsTest, TestContentLengths) { + int64 original_content_length; + int64 received_content_length; + int64 last_update_time; + + // Request |kNumDaysInHistory| days. + settings_->GetContentLengths(spdyproxy::kNumDaysInHistory, + &original_content_length, + &received_content_length, + &last_update_time); + const unsigned int days = spdyproxy::kNumDaysInHistory; + // Received content length history values are 0 to |kNumDaysInHistory - 1|. + int64 expected_total_received_content_length = (days - 1L) * days / 2; + // Original content length history values are 0 to + // |2 * (kNumDaysInHistory - 1)|. + long expected_total_original_content_length = (days - 1L) * days; + EXPECT_EQ(expected_total_original_content_length, original_content_length); + EXPECT_EQ(expected_total_received_content_length, received_content_length); + EXPECT_EQ(last_update_time_.ToInternalValue(), last_update_time); + + // Request |kNumDaysInHistory - 1| days. + settings_->GetContentLengths(spdyproxy::kNumDaysInHistory - 1, + &original_content_length, + &received_content_length, + &last_update_time); + expected_total_received_content_length -= (days - 1); + expected_total_original_content_length -= 2 * (days - 1); + EXPECT_EQ(expected_total_original_content_length, original_content_length); + EXPECT_EQ(expected_total_received_content_length, received_content_length); + + // Request 0 days. + settings_->GetContentLengths(0, + &original_content_length, + &received_content_length, + &last_update_time); + expected_total_received_content_length = 0; + expected_total_original_content_length = 0; + EXPECT_EQ(expected_total_original_content_length, original_content_length); + EXPECT_EQ(expected_total_received_content_length, received_content_length); + + // Request 1 day. First day had 0 bytes so should be same as 0 days. + settings_->GetContentLengths(1, + &original_content_length, + &received_content_length, + &last_update_time); + EXPECT_EQ(expected_total_original_content_length, original_content_length); + EXPECT_EQ(expected_total_received_content_length, received_content_length); +} + +TEST_F(DataReductionProxySettingsTest, TestMaybeActivateDataReductionProxy) { + AddProxyToCommandLine(); + settings_->InitPrefMembers(); + // TODO(bengr): Test enabling/disabling while a probe is outstanding. + base::MessageLoop loop(base::MessageLoop::TYPE_UI); + // The proxy is enabled initially. + // Request succeeded but with bad response, expect proxy to be disabled. + CheckProbe(true, kProbeURLWithBadResponse, "Bad", true, false); + // Request succeeded with valid response, expect proxy to be enabled. + CheckProbe(true, kProbeURLWithOKResponse, "OK", true, true); + // Request failed, expect proxy to be disabled. + CheckProbe(true, kProbeURLWithNoResponse, "", false, false); + + // The proxy is disabled initially. Probes should not be emitted to change + // state. + EXPECT_EQ(3, settings_->fake_fetcher_request_count()); + CheckProbe(false, kProbeURLWithOKResponse, "OK", true, false); + EXPECT_EQ(3, settings_->fake_fetcher_request_count()); +} + +TEST_F(DataReductionProxySettingsTest, TestOnIPAddressChanged) { + AddProxyToCommandLine(); + base::MessageLoop loop(base::MessageLoop::TYPE_UI); + // The proxy is enabled initially. + settings_->enabled_by_user_ = true; + settings_->SetProxyConfigs(true, true); + // IP address change triggers a probe that succeeds. Proxy remains enabled. + CheckProbeOnIPChange(kProbeURLWithOKResponse, "OK", true, true); + // IP address change triggers a probe that fails. Proxy is disabled. + CheckProbeOnIPChange(kProbeURLWithBadResponse, "Bad", true, false); + // IP address change triggers a probe that fails. Proxy remains disabled. + CheckProbeOnIPChange(kProbeURLWithBadResponse, "Bad", true, false); + // IP address change triggers a probe that succeed. Proxy is enabled. + CheckProbeOnIPChange(kProbeURLWithBadResponse, "OK", true, true); + EXPECT_EQ(4, settings_->fake_fetcher_request_count()); +} + +TEST_F(DataReductionProxySettingsTest, TestOnProxyEnabledPrefChange) { + AddProxyToCommandLine(); + settings_->InitPrefMembers(); + base::MessageLoop loop(base::MessageLoop::TYPE_UI); + // The proxy is enabled initially. + settings_->enabled_by_user_ = true; + settings_->SetProxyConfigs(true, true); + // The pref is disabled, so correspondingly should be the proxy. + CheckOnPrefChange(false, kProbeURLWithOKResponse, "OK", true, false); + // The pref is enabled, so correspondingly should be the proxy. + CheckOnPrefChange(true, kProbeURLWithOKResponse, "OK", true, true); + EXPECT_EQ(1, settings_->fake_fetcher_request_count()); +} + +TEST_F(DataReductionProxySettingsTest, TestInitDataReductionProxyOn) { + CheckInitDataReductionProxy(true); +} + +TEST_F(DataReductionProxySettingsTest, TestInitDataReductionProxyOff) { + CheckInitDataReductionProxy(false); +} + +TEST_F(DataReductionProxySettingsTest, TestGetDailyContentLengths) { + DataReductionProxySettings::ContentLengthList result = + settings_->GetDailyContentLengths(prefs::kDailyHttpOriginalContentLength); + + ASSERT_FALSE(result.empty()); + ASSERT_EQ(spdyproxy::kNumDaysInHistory, result.size()); + + for (size_t i = 0; i < spdyproxy::kNumDaysInHistory; ++i) { + long expected_length = + static_cast<long>((spdyproxy::kNumDaysInHistory - 1 - i) * 2); + ASSERT_EQ(expected_length, result[i]); + } +} + +TEST_F(DataReductionProxySettingsTest, TestBypassList) { + settings_->AddHostPatternToBypass("http://www.google.com"); + settings_->AddHostPatternToBypass("fefe:13::abc/33"); + settings_->AddURLPatternToBypass("foo.org/images/*"); + settings_->AddURLPatternToBypass("http://foo.com/*"); + settings_->AddURLPatternToBypass("http://baz.com:22/bar/*"); + settings_->AddURLPatternToBypass("http://*bat.com/bar/*"); + + std::string expected[] = { + "http://www.google.com", + "fefe:13::abc/33", + "foo.org", + "http://foo.com", + "http://baz.com:22", + "http://*bat.com" + }; + + ASSERT_EQ(settings_->bypass_rules_.size(), 6u); + int i = 0; + for (std::vector<std::string>::iterator it = settings_->bypass_rules_.begin(); + it != settings_->bypass_rules_.end(); ++it) { + EXPECT_EQ(expected[i++], *it); + } +} + diff --git a/chrome/browser/net/spdyproxy/data_reduction_proxy_settings_unittest.h b/chrome/browser/net/spdyproxy/data_reduction_proxy_settings_unittest.h new file mode 100644 index 0000000..ea3e0851 --- /dev/null +++ b/chrome/browser/net/spdyproxy/data_reduction_proxy_settings_unittest.h @@ -0,0 +1,55 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#ifndef CHROME_BROWSER_NET_SPDYPROXY_DATA_REDUCTION_PROXY_SETTINGS_UNITTEST_H_ +#define CHROME_BROWSER_NET_SPDYPROXY_DATA_REDUCTION_PROXY_SETTINGS_UNITTEST_H_ + + +#include "base/metrics/field_trial.h" +#include "base/prefs/testing_pref_service.h" +#include "chrome/browser/net/spdyproxy/data_reduction_proxy_settings.h" +#include "testing/gtest/include/gtest/gtest.h" + +class PrefService; +class TestingPrefServiceSimple; + +class DataReductionProxySettingsTestBase : public testing::Test { + public: + DataReductionProxySettingsTestBase(); + virtual ~DataReductionProxySettingsTestBase(); + + void AddProxyToCommandLine(); + virtual void ResetSettings() = 0; + virtual DataReductionProxySettings* Settings() = 0; + virtual void SetProbeResult(const std::string& test_url, + const std::string& response, + bool success) = 0; + + virtual void SetUp() OVERRIDE; + void CheckProxyPref(const std::string& expected_servers, + const std::string& expected_mode); + void CheckProxyConfigs(bool expected_enabled); + void CheckProbe(bool initially_enabled, + const std::string& probe_url, + const std::string& response, + bool request_success, + bool expected_enabled); + void CheckProbeOnIPChange(const std::string& probe_url, + const std::string& response, + bool request_success, + bool expected_enabled); + void CheckOnPrefChange(bool enabled, + const std::string& probe_url, + const std::string& response, + bool request_success, + bool expected_enabled); + void CheckInitDataReductionProxy(bool enabled_at_startup); + + TestingPrefServiceSimple pref_service_; + base::Time last_update_time_; + // This is a singleton that will clear all set field trials on destruction. + scoped_ptr<base::FieldTrialList> field_trial_list_; +}; + +#endif // CHROME_BROWSER_NET_SPDYPROXY_DATA_REDUCTION_PROXY_SETTINGS_UNITTEST_H_ diff --git a/chrome/browser/net/spdyproxy/data_reduction_proxy_settings_unittest_android.cc b/chrome/browser/net/spdyproxy/data_reduction_proxy_settings_unittest_android.cc index d76bd17..4b2f79b 100644 --- a/chrome/browser/net/spdyproxy/data_reduction_proxy_settings_unittest_android.cc +++ b/chrome/browser/net/spdyproxy/data_reduction_proxy_settings_unittest_android.cc @@ -2,13 +2,15 @@ // Use of this source code is governed by a BSD-style license that can be // found in the LICENSE file. +#include "chrome/browser/net/spdyproxy/data_reduction_proxy_settings_unittest.h" + + #include "base/android/jni_android.h" #include "base/android/jni_string.h" #include "base/android/scoped_java_ref.h" #include "base/base64.h" #include "base/command_line.h" #include "base/metrics/field_trial.h" -#include "base/prefs/pref_registry_simple.h" #include "base/prefs/pref_service.h" #include "base/prefs/testing_pref_service.h" #include "base/strings/string_number_conversions.h" @@ -27,29 +29,26 @@ const char kDataReductionProxyOrigin[] = "https://foo:443/"; const char kDataReductionProxyOriginHostPort[] = "foo:443"; const char kDataReductionProxyAuth[] = "12345"; -const char kProbeURLWithOKResponse[] = "http://ok.org/"; -const char kProbeURLWithBadResponse[] = "http://bad.org/"; -const char kProbeURLWithNoResponse[] = "http://no.org/"; - class TestDataReductionProxySettingsAndroid : public DataReductionProxySettingsAndroid { public: - TestDataReductionProxySettingsAndroid(JNIEnv* env, jobject obj, + TestDataReductionProxySettingsAndroid(JNIEnv* env, + jobject obj, PrefService* profile_prefs, PrefService* local_state_prefs) - : DataReductionProxySettingsAndroid(env, obj), - success_(false), - fake_fetcher_request_count_(0), - profile_prefs_(profile_prefs), - local_state_prefs_(local_state_prefs) { + : DataReductionProxySettingsAndroid(env, obj), + success_(false), + fake_fetcher_request_count_(0), + profile_prefs_(profile_prefs), + local_state_prefs_(local_state_prefs) { } - // DataReductionProxySettingsAndroid implementation: + // DataReductionProxySettings implementation: virtual net::URLFetcher* GetURLFetcher() OVERRIDE { if (test_url_.empty()) return NULL; - net::URLFetcher* fetcher = new net::FakeURLFetcher(GURL(test_url_), this, - response_, success_); + net::URLFetcher* fetcher = + new net::FakeURLFetcher(GURL(test_url_), this, response_, success_); fake_fetcher_request_count_++; return fetcher; } @@ -82,46 +81,34 @@ class TestDataReductionProxySettingsAndroid PrefService* local_state_prefs_; }; -class DataReductionProxySettingsAndroidTest : public testing::Test { - protected: - void AddProxyToCommandLine() { - CommandLine::ForCurrentProcess()->AppendSwitchASCII( - switches::kSpdyProxyAuthOrigin, kDataReductionProxyOrigin); - CommandLine::ForCurrentProcess()->AppendSwitchASCII( - switches::kSpdyProxyAuthValue, kDataReductionProxyAuth); +class DataReductionProxySettingsAndroidTest + : public DataReductionProxySettingsTestBase { + public: + virtual void ResetSettings() OVERRIDE{ + settings_.reset(new TestDataReductionProxySettingsAndroid(NULL, NULL, + &pref_service_, + &pref_service_)); } - // testing::Test implementation: + virtual TestDataReductionProxySettingsAndroid* Settings() OVERRIDE { + return settings_.get(); + } + + virtual void SetProbeResult(const std::string& test_url, + const std::string& response, + bool success) OVERRIDE { + settings_->set_probe_result(test_url, response, success); + } + + // DataReductionProxySettingsTest implementation: virtual void SetUp() OVERRIDE { env_ = base::android::AttachCurrentThread(); DataReductionProxySettingsAndroid::Register(env_); - PrefRegistrySimple* registry = pref_service_.registry(); - registry->RegisterListPref(prefs::kDailyHttpOriginalContentLength); - registry->RegisterListPref(prefs::kDailyHttpReceivedContentLength); - registry->RegisterInt64Pref( - prefs::kDailyHttpContentLengthLastUpdateDate, 0L); - registry->RegisterDictionaryPref(prefs::kProxy); - registry->RegisterBooleanPref(prefs::kSpdyProxyAuthEnabled, false); - registry->RegisterBooleanPref(prefs::kSpdyProxyAuthWasEnabledBefore, false); - settings_.reset(new TestDataReductionProxySettingsAndroid(NULL, NULL, - &pref_service_, - &pref_service_)); - ListPrefUpdate original_update(&pref_service_, - prefs::kDailyHttpOriginalContentLength); - ListPrefUpdate received_update(&pref_service_, - prefs::kDailyHttpReceivedContentLength); - for (int64 i = 0; i < spdyproxy::kNumDaysInHistory; i++) { - original_update->Insert(0, new StringValue(base::Int64ToString(2 * i))); - received_update->Insert(0, new StringValue(base::Int64ToString(i))); - } - last_update_time_ = base::Time::Now().LocalMidnight(); - pref_service_.SetInt64( - prefs::kDailyHttpContentLengthLastUpdateDate, - last_update_time_.ToInternalValue()); + DataReductionProxySettingsTestBase::SetUp(); } - void CheckProxyPref(const std::string& expected_pac_url, - const std::string& expected_mode) { + void CheckProxyPacPref(const std::string& expected_pac_url, + const std::string& expected_mode) { const DictionaryValue* dict = pref_service_.GetDictionary(prefs::kProxy); std::string mode; std::string pac_url; @@ -131,68 +118,7 @@ class DataReductionProxySettingsAndroidTest : public testing::Test { ASSERT_EQ(expected_pac_url, pac_url); } - void CheckProxyPac(bool expected_enabled) { - if (expected_enabled) { - std::string pac; - base::Base64Encode(settings_->GetProxyPacScript(), &pac); - std::string expected_pac_url = - "data:application/x-ns-proxy-autoconfig;base64," + pac; - CheckProxyPref(expected_pac_url, - ProxyModeToString(ProxyPrefs::MODE_PAC_SCRIPT)); - } else { - CheckProxyPref(std::string(), ProxyModeToString(ProxyPrefs::MODE_SYSTEM)); - } - } - - void CheckProbe(bool initially_enabled, const std::string& probe_url, - const std::string& response, bool request_success, - bool expected_enabled) { - pref_service_.SetBoolean(prefs::kSpdyProxyAuthEnabled, initially_enabled); - settings_->set_probe_result(probe_url, response, request_success); - settings_->MaybeActivateDataReductionProxy(false); - base::MessageLoop::current()->RunUntilIdle(); - CheckProxyPac(expected_enabled); - } - - void CheckProbeOnIPChange(const std::string& probe_url, - const std::string& response, - bool request_success, - bool expected_enabled) { - settings_->set_probe_result(probe_url, response, request_success); - settings_->OnIPAddressChanged(); - base::MessageLoop::current()->RunUntilIdle(); - CheckProxyPac(expected_enabled); - } - - void CheckOnPrefChange(bool enabled, const std::string& probe_url, - const std::string& response, bool request_success, - bool expected_enabled) { - settings_->set_probe_result(probe_url, response, request_success); - pref_service_.SetBoolean(prefs::kSpdyProxyAuthEnabled, enabled); - base::MessageLoop::current()->RunUntilIdle(); - CheckProxyPac(expected_enabled); - } - - void CheckInitDataReductionProxy(bool enabled_at_startup) { - AddProxyToCommandLine(); - base::MessageLoop loop(base::MessageLoop::TYPE_UI); - pref_service_.SetBoolean(prefs::kSpdyProxyAuthEnabled, enabled_at_startup); - settings_->set_probe_result(kProbeURLWithOKResponse, "OK", true); - settings_->InitDataReductionProxySettings(NULL, NULL); - base::MessageLoop::current()->RunUntilIdle(); - if (enabled_at_startup) { - CheckProxyPac(enabled_at_startup); - } else { - // This presumes the proxy pref hadn't been set up by Chrome. - CheckProxyPref(std::string(), std::string()); - } - } - - TestingPrefServiceSimple pref_service_; scoped_ptr<TestDataReductionProxySettingsAndroid> settings_; - base::Time last_update_time_; - // This is a singleton that will clear all set field trials on destruction. - scoped_ptr<base::FieldTrialList> field_trial_list_; JNIEnv* env_; }; @@ -235,37 +161,16 @@ TEST_F(DataReductionProxySettingsAndroidTest, // Confirm that the bypass rule functions generate the intended JavaScript // code for the Proxy PAC. -TEST_F(DataReductionProxySettingsAndroidTest, TestBypassRules) { +TEST_F(DataReductionProxySettingsAndroidTest, TestBypassPACRules) { settings_->AddURLPatternToBypass("http://foo.com/*"); settings_->AddHostPatternToBypass("bar.com"); - settings_->AddHostToBypass("127.0.0.1"); - - std::string expected[] = { - "shExpMatch(url, 'http://foo.com/*')", - "shExpMatch(host, 'bar.com')", - "host == '127.0.0.1'" - }; - - int i = 0; - for (std::vector<std::string>::iterator it = settings_->bypass_rules_.begin(); - it != settings_->bypass_rules_.end(); ++it) { - EXPECT_EQ(expected[i++], *it); - } -} - -TEST_F(DataReductionProxySettingsAndroidTest, TestIsProxyEnabledOrManaged) { - settings_->InitPrefMembers(); - EXPECT_FALSE(settings_->IsDataReductionProxyEnabled(NULL, NULL)); - EXPECT_FALSE(settings_->IsDataReductionProxyManaged(NULL, NULL)); - pref_service_.SetBoolean(prefs::kSpdyProxyAuthEnabled, true); - EXPECT_TRUE(settings_->IsDataReductionProxyEnabled(NULL, NULL)); - EXPECT_FALSE(settings_->IsDataReductionProxyManaged(NULL, NULL)); + EXPECT_EQ(settings_->pac_bypass_rules_.size(), 1u); + EXPECT_EQ("shExpMatch(url, 'http://foo.com/*')", + settings_->pac_bypass_rules_[0]); - pref_service_.SetManagedPref(prefs::kSpdyProxyAuthEnabled, - base::Value::CreateBooleanValue(true)); - EXPECT_TRUE(settings_->IsDataReductionProxyEnabled(NULL, NULL)); - EXPECT_TRUE(settings_->IsDataReductionProxyManaged(NULL, NULL)); + EXPECT_EQ(settings_->BypassRules().size(), 1u); + EXPECT_EQ("bar.com", settings_->BypassRules()[0]); } TEST_F(DataReductionProxySettingsAndroidTest, TestSetProxyPac) { @@ -275,21 +180,20 @@ TEST_F(DataReductionProxySettingsAndroidTest, TestSetProxyPac) { std::string expected_pac_url = "data:application/x-ns-proxy-autoconfig;base64," + pac; // Test setting the PAC, without generating histograms. - settings_->has_turned_on_ = true; - settings_->SetProxyPac(true, false); - CheckProxyPref(expected_pac_url, - ProxyModeToString(ProxyPrefs::MODE_PAC_SCRIPT)); + settings_->SetHasTurnedOn(); + settings_->SetProxyConfigs(true, false); + CheckProxyPacPref(expected_pac_url, + ProxyModeToString(ProxyPrefs::MODE_PAC_SCRIPT)); // Test disabling the PAC, without generating histograms. - settings_->has_turned_off_ = true; - settings_->SetProxyPac(false, false); - CheckProxyPref(std::string(), ProxyModeToString(ProxyPrefs::MODE_SYSTEM)); + settings_->SetHasTurnedOff(); + settings_->SetProxyConfigs(false, false); + CheckProxyPacPref(std::string(), ProxyModeToString(ProxyPrefs::MODE_SYSTEM)); } TEST_F(DataReductionProxySettingsAndroidTest, TestGetDailyContentLengths) { - ScopedJavaLocalRef<jlongArray> result = - settings_->GetDailyContentLengths(env_, - prefs::kDailyHttpOriginalContentLength); + ScopedJavaLocalRef<jlongArray> result = settings_->GetDailyContentLengths( + env_, prefs::kDailyHttpOriginalContentLength); ASSERT_TRUE(result.obj()); jsize java_array_len = env_->GetArrayLength(result.obj()); @@ -303,133 +207,3 @@ TEST_F(DataReductionProxySettingsAndroidTest, TestGetDailyContentLengths) { } } -TEST_F(DataReductionProxySettingsAndroidTest, - TestResetDataReductionStatistics) { - int64 original_content_length; - int64 received_content_length; - int64 last_update_time; - settings_->ResetDataReductionStatistics(); - settings_->GetContentLengthsInternal(spdyproxy::kNumDaysInHistory, - &original_content_length, - &received_content_length, - &last_update_time); - EXPECT_EQ(0L, original_content_length); - EXPECT_EQ(0L, received_content_length); - EXPECT_EQ(last_update_time_.ToInternalValue(), last_update_time); -} - -TEST_F(DataReductionProxySettingsAndroidTest, TestContentLengthsInternal) { - int64 original_content_length; - int64 received_content_length; - int64 last_update_time; - - // Request |kNumDaysInHistory| days. - settings_->GetContentLengthsInternal(spdyproxy::kNumDaysInHistory, - &original_content_length, - &received_content_length, - &last_update_time); - const unsigned int days = spdyproxy::kNumDaysInHistory; - // Received content length history values are 0 to |kNumDaysInHistory - 1|. - int64 expected_total_received_content_length = (days - 1L) * days / 2; - // Original content length history values are 0 to - // |2 * (kNumDaysInHistory - 1)|. - long expected_total_original_content_length = (days - 1L) * days; - EXPECT_EQ(expected_total_original_content_length, original_content_length); - EXPECT_EQ(expected_total_received_content_length, received_content_length); - EXPECT_EQ(last_update_time_.ToInternalValue(), last_update_time); - - // Request |kNumDaysInHistory - 1| days. - settings_->GetContentLengthsInternal(spdyproxy::kNumDaysInHistory - 1, - &original_content_length, - &received_content_length, - &last_update_time); - expected_total_received_content_length -= (days - 1); - expected_total_original_content_length -= 2 * (days - 1); - EXPECT_EQ(expected_total_original_content_length, original_content_length); - EXPECT_EQ(expected_total_received_content_length, received_content_length); - - // Request 0 days. - settings_->GetContentLengthsInternal(0, - &original_content_length, - &received_content_length, - &last_update_time); - expected_total_received_content_length = 0; - expected_total_original_content_length = 0; - EXPECT_EQ(expected_total_original_content_length, original_content_length); - EXPECT_EQ(expected_total_received_content_length, received_content_length); - - // Request 1 day. First day had 0 bytes so should be same as 0 days. - settings_->GetContentLengthsInternal(1, - &original_content_length, - &received_content_length, - &last_update_time); - EXPECT_EQ(expected_total_original_content_length, original_content_length); - EXPECT_EQ(expected_total_received_content_length, received_content_length); -} - -TEST_F(DataReductionProxySettingsAndroidTest, - TestMaybeActivateDataReductionProxy) { - AddProxyToCommandLine(); - settings_->InitPrefMembers(); - // TODO(bengr): Test enabling/disabling while a probe is outstanding. - base::MessageLoop loop(base::MessageLoop::TYPE_UI); - // The proxy is enabled initially. - // Request succeeded but with bad response, expect proxy to be disabled. - CheckProbe(true, kProbeURLWithBadResponse, "Bad", true, false); - // Request succeeded with valid response, expect proxy to be enabled. - CheckProbe(true, kProbeURLWithOKResponse, "OK", true, true); - // Request failed, expect proxy to be disabled. - CheckProbe(true, kProbeURLWithNoResponse, "", false, false); - - // The proxy is disabled initially. Probes should not be emitted to change - // state. - EXPECT_EQ(3, settings_->fake_fetcher_request_count()); - CheckProbe(false, kProbeURLWithOKResponse, "OK", true, false); - EXPECT_EQ(3, settings_->fake_fetcher_request_count()); -} - -TEST_F(DataReductionProxySettingsAndroidTest, - TestOnIPAddressChanged) { - AddProxyToCommandLine(); - base::MessageLoop loop(base::MessageLoop::TYPE_UI); - // The proxy is enabled initially. - settings_->enabled_by_user_ = true; - settings_->SetProxyPac(true, true); - // IP address change triggers a probe that succeeds. Proxy remains enabled. - CheckProbeOnIPChange(kProbeURLWithOKResponse, "OK", true, true); - // IP address change triggers a probe that fails. Proxy is disabled. - CheckProbeOnIPChange(kProbeURLWithBadResponse, "Bad", true, false); - // IP address change triggers a probe that fails. Proxy remains disabled. - CheckProbeOnIPChange(kProbeURLWithBadResponse, "Bad", true, false); - // IP address change triggers a probe that succeed. Proxy is enabled. - CheckProbeOnIPChange(kProbeURLWithBadResponse, "OK", true, true); - EXPECT_EQ(4, settings_->fake_fetcher_request_count()); -} - -TEST_F(DataReductionProxySettingsAndroidTest, - TestOnProxyEnabledPrefChange) { - AddProxyToCommandLine(); - settings_->InitPrefMembers(); - base::MessageLoop loop(base::MessageLoop::TYPE_UI); - LOG(WARNING) << "Before init pref members"; - // The proxy is enabled initially. - settings_->enabled_by_user_ = true; - settings_->SetProxyPac(true, true); - LOG(WARNING) << "after set proxy pac"; - // The pref is disabled, so correspondingly should be the proxy. - CheckOnPrefChange(false, kProbeURLWithOKResponse, "OK", true, false); - // The pref is enabled, so correspondingly should be the proxy. - CheckOnPrefChange(true, kProbeURLWithOKResponse, "OK", true, true); - EXPECT_EQ(1, settings_->fake_fetcher_request_count()); -} - -TEST_F(DataReductionProxySettingsAndroidTest, - TestInitDataReductionProxyOn) { - CheckInitDataReductionProxy(true); -} - -TEST_F(DataReductionProxySettingsAndroidTest, - TestInitDataReductionProxyOff) { - CheckInitDataReductionProxy(false); -} - diff --git a/chrome/chrome_browser.gypi b/chrome/chrome_browser.gypi index 0090b52..3977081 100644 --- a/chrome/chrome_browser.gypi +++ b/chrome/chrome_browser.gypi @@ -1247,8 +1247,12 @@ 'browser/net/sdch_dictionary_fetcher.h', 'browser/net/service_providers_win.cc', 'browser/net/service_providers_win.h', + 'browser/net/spdyproxy/data_reduction_proxy_settings.cc', + 'browser/net/spdyproxy/data_reduction_proxy_settings.h', 'browser/net/spdyproxy/data_reduction_proxy_settings_android.cc', 'browser/net/spdyproxy/data_reduction_proxy_settings_android.h', + 'browser/net/spdyproxy/data_reduction_proxy_settings_ios.cc', + 'browser/net/spdyproxy/data_reduction_proxy_settings_ios.h', 'browser/net/spdyproxy/http_auth_handler_spdyproxy.cc', 'browser/net/spdyproxy/http_auth_handler_spdyproxy.h', 'browser/net/sqlite_server_bound_cert_store.cc', @@ -3154,6 +3158,8 @@ 'browser/chrome_browser_field_trials_mobile.h', 'browser/metrics/variations/variations_request_scheduler_mobile.cc', 'browser/metrics/variations/variations_request_scheduler_mobile.h', + 'browser/net/spdyproxy/data_reduction_proxy_settings.cc', + 'browser/net/spdyproxy/data_reduction_proxy_settings.h', ], }], ['OS=="android"', { diff --git a/chrome/chrome_tests_unit.gypi b/chrome/chrome_tests_unit.gypi index d2e53b9..aa6235d 100644 --- a/chrome/chrome_tests_unit.gypi +++ b/chrome/chrome_tests_unit.gypi @@ -1028,6 +1028,8 @@ 'browser/net/pref_proxy_config_tracker_impl_unittest.cc', 'browser/net/probe_message_unittest.cc', 'browser/net/proxy_policy_handler_unittest.cc', + 'browser/net/spdyproxy/data_reduction_proxy_settings_unittest.cc', + 'browser/net/spdyproxy/data_reduction_proxy_settings_unittest.h', 'browser/net/spdyproxy/data_reduction_proxy_settings_unittest_android.cc', 'browser/net/spdyproxy/http_auth_handler_spdyproxy_unittest.cc', 'browser/net/sqlite_server_bound_cert_store_unittest.cc', @@ -2256,7 +2258,7 @@ }], ['chromeos==1', { 'sources': [ - 'browser/ui/ash/multi_user_window_manager_unittest.cc', + 'browser/ui/ash/multi_user_window_manager_unittest.cc', ], 'sources!': [ 'browser/password_manager/native_backend_gnome_x_unittest.cc', @@ -2499,6 +2501,8 @@ 'tools/profile_reset/jtl_compiler.gyp:jtl_compiler_lib', ], 'sources!': [ + 'browser/net/spdyproxy/data_reduction_proxy_settings_unittest.cc', + 'browser/net/spdyproxy/data_reduction_proxy_settings_unittest.h', 'browser/web_resource/promo_resource_service_mobile_ntp_unittest.cc', ], }], |