1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #ifndef COMPONENTS_DATA_REDUCTION_PROXY_BROWSER_DATA_REDUCTION_PROXY_SETTINGS_H_
6 #define COMPONENTS_DATA_REDUCTION_PROXY_BROWSER_DATA_REDUCTION_PROXY_SETTINGS_H_
10 #include "base/basictypes.h"
11 #include "base/compiler_specific.h"
12 #include "base/gtest_prod_util.h"
13 #include "base/memory/scoped_ptr.h"
14 #include "base/prefs/pref_member.h"
15 #include "base/threading/thread_checker.h"
16 #include "components/data_reduction_proxy/browser/data_reduction_proxy_configurator.h"
17 #include "net/base/network_change_notifier.h"
18 #include "net/url_request/url_fetcher_delegate.h"
23 class AuthChallengeInfo;
26 class HttpNetworkSession;
27 class HttpResponseHeaders;
29 class URLRequestContextGetter;
32 namespace data_reduction_proxy {
34 // The number of days of bandwidth usage statistics that are tracked.
35 const unsigned int kNumDaysInHistory = 60;
37 // The number of days of bandwidth usage statistics that are presented.
38 const unsigned int kNumDaysInHistorySummary = 30;
40 COMPILE_ASSERT(kNumDaysInHistorySummary <= kNumDaysInHistory,
41 DataReductionProxySettings_summary_too_long);
43 // Values of the UMA DataReductionProxy.StartupState histogram.
44 // This enum must remain synchronized with DataReductionProxyStartupState
45 // in metrics/histograms/histograms.xml.
46 enum ProxyStartupState {
47 PROXY_NOT_AVAILABLE = 0,
50 PROXY_STARTUP_STATE_COUNT,
53 // Values of the UMA DataReductionProxy.ProbeURL histogram.
54 // This enum must remain synchronized with
55 // DataReductionProxyProbeURLFetchResult in metrics/histograms/histograms.xml.
56 // TODO(marq): Rename these histogram buckets with s/DISABLED/RESTRICTED/, so
57 // their names match the behavior they track.
58 enum ProbeURLFetchResult {
59 // The probe failed because the Internet was disconnected.
60 INTERNET_DISCONNECTED = 0,
62 // The probe failed for any other reason, and as a result, the proxy was
64 FAILED_PROXY_DISABLED,
66 // The probe failed, but the proxy was already restricted.
67 FAILED_PROXY_ALREADY_DISABLED,
69 // THe probe succeeded, and as a result the proxy was restricted.
70 SUCCEEDED_PROXY_ENABLED,
72 // The probe succeeded, but the proxy was already restricted.
73 SUCCEEDED_PROXY_ALREADY_ENABLED,
75 // This must always be last.
76 PROBE_URL_FETCH_RESULT_COUNT
79 // Central point for configuring the data reduction proxy.
80 // This object lives on the UI thread and all of its methods are expected to
81 // be called from there.
82 // TODO(marq): Convert this to be a KeyedService with an
83 // associated factory class, and refactor the Java call sites accordingly.
84 class DataReductionProxySettings
85 : public net::URLFetcherDelegate,
86 public net::NetworkChangeNotifier::IPAddressObserver {
88 typedef std::vector<long long> ContentLengthList;
89 // TODO(marq): Consider instead using a std::pair instead of a vector.
90 typedef std::vector<GURL> DataReductionProxyList;
92 // Returns true of the data reduction proxy origin is set on the command line.
93 static bool IsProxyOriginSetOnCommandLine();
95 // Returns true if the data reduction proxy key is set on the command line.
96 static bool IsProxyKeySetOnCommandLine();
98 // Returns true if this application instance is part of the data reduction
99 // proxy field trial, or if it a proxy origin is set in flags. This is a
100 // convenience method for platforms like Chrome on Android and iOS, to
101 // determine if the data reduction proxy is allowed.
102 static bool IsIncludedInFieldTrialOrFlags();
104 static void SetAllowed(bool allowed);
105 static void SetPromoAllowed(bool promo_allowed);
107 DataReductionProxySettings();
108 virtual ~DataReductionProxySettings();
110 // Set and get the key to be used for data reduction proxy authentication.
111 void set_key(const std::string& key) {
115 const std::string& key() const {
119 // Initializes the data reduction proxy with profile and local state prefs,
120 // and a |UrlRequestContextGetter| for canary probes. The caller must ensure
121 // that all parameters remain alive for the lifetime of the
122 // |DataReductionProxySettings| instance.
123 void InitDataReductionProxySettings(
125 PrefService* local_state_prefs,
126 net::URLRequestContextGetter* url_request_context_getter);
128 // Initializes the data reduction proxy with profile and local state prefs,
129 // a |UrlRequestContextGetter| for canary probes, and a proxy configurator.
130 // The caller must ensure that all parameters remain alive for the lifetime of
131 // the |DataReductionProxySettings| instance.
132 // TODO(marq): Remove when iOS supports the new interface above.
133 void InitDataReductionProxySettings(
135 PrefService* local_state_prefs,
136 net::URLRequestContextGetter* url_request_context_getter,
137 scoped_ptr<DataReductionProxyConfigurator> config);
139 // Sets the logic the embedder uses to set the networking configuration that
140 // causes traffic to be proxied.
141 void SetProxyConfigurator(
142 scoped_ptr<DataReductionProxyConfigurator> configurator);
144 // If proxy authentication is compiled in, pre-cache an authentication
145 // |key| for all configured proxies in |session|.
146 static void InitDataReductionProxySession(net::HttpNetworkSession* session,
147 const std::string& key);
149 // Returns true if the data reduction proxy is allowed to be used. This could
150 // return false, for example, if this instance is not part of the field trial,
151 // or if the proxy name is not configured via gyp.
152 static bool IsDataReductionProxyAllowed();
154 // Returns true if a screen promoting the data reduction proxy is allowed to
155 // be shown. Logic that decides when to show the promo should check its
156 // availability. This would return false if not part of a separate field
157 // trial that governs the use of the promotion.
158 static bool IsDataReductionProxyPromoAllowed();
160 // Returns true if preconnect advisory hinting is enabled by command line
161 // flag or Finch trial.
162 static bool IsPreconnectHintingAllowed();
164 // Returns the URL of the data reduction proxy.
165 static std::string GetDataReductionProxyOrigin();
167 // Returns the URL of the fallback data reduction proxy.
168 static std::string GetDataReductionProxyFallback();
170 // Returns a vector of GURLs for all configured proxies.
171 static DataReductionProxyList GetDataReductionProxies();
173 // Returns true if |auth_info| represents an authentication challenge from
174 // a compatible, configured proxy.
175 static bool IsAcceptableAuthChallenge(net::AuthChallengeInfo* auth_info);
177 // Returns a UTF16 string suitable for use as an authentication token in
178 // response to the challenge represented by |auth_info|. If the token can't
179 // be correctly generated for |auth_info|, returns an empty UTF16 string.
180 base::string16 GetTokenForAuthChallenge(net::AuthChallengeInfo* auth_info);
182 // Returns true if the proxy is enabled.
183 bool IsDataReductionProxyEnabled();
185 // Returns true if the proxy is managed by an adminstrator's policy.
186 bool IsDataReductionProxyManaged();
188 // Enables or disables the data reduction proxy. If a probe URL is available,
189 // and a probe request fails at some point, the proxy won't be used until a
191 void SetDataReductionProxyEnabled(bool enabled);
193 // If |allowed|, the fallback proxy will be included in the proxy
195 void set_fallback_allowed(bool allowed) {
196 fallback_allowed_ = allowed;
199 bool fallback_allowed() const {
200 return fallback_allowed_;
203 // Returns the time in microseconds that the last update was made to the
204 // daily original and received content lengths.
205 int64 GetDataReductionLastUpdateTime();
207 // Returns a vector containing the total size of all HTTP content that was
208 // received over the last |kNumDaysInHistory| before any compression by the
209 // data reduction proxy. Each element in the vector contains one day of data.
210 ContentLengthList GetDailyOriginalContentLengths();
212 // Returns an vector containing the aggregate received HTTP content in the
213 // last |kNumDaysInHistory| days.
214 ContentLengthList GetDailyReceivedContentLengths();
216 // net::URLFetcherDelegate:
217 virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE;
220 void InitPrefMembers();
222 virtual net::URLFetcher* GetURLFetcher();
224 // Virtualized for unit test support.
225 virtual PrefService* GetOriginalProfilePrefs();
226 virtual PrefService* GetLocalStatePrefs();
228 void GetContentLengths(unsigned int days,
229 int64* original_content_length,
230 int64* received_content_length,
231 int64* last_update_time);
232 ContentLengthList GetDailyContentLengths(const char* pref_name);
234 // Sets the proxy configs, enabling or disabling the proxy according to
235 // the value of |enabled|. If |restricted| is true, only enable the fallback
236 // proxy. |at_startup| is true when this method is called from
237 // InitDataReductionProxySettings.
238 virtual void SetProxyConfigs(bool enabled, bool restricted, bool at_startup);
240 // Metrics methods. Subclasses should override if they wish to provide
241 // alternate methods.
242 virtual void RecordDataReductionInit();
244 virtual void AddDefaultProxyBypassRules();
246 // Writes a warning to the log that is used in backend processing of
247 // customer feedback. Virtual so tests can mock it for verification.
248 virtual void LogProxyState(bool enabled, bool restricted, bool at_startup);
250 // Virtualized for mocking
251 virtual void RecordProbeURLFetchResult(
252 data_reduction_proxy::ProbeURLFetchResult result);
253 virtual void RecordStartupState(
254 data_reduction_proxy::ProxyStartupState state);
256 DataReductionProxyConfigurator* config() {
257 return config_.get();
261 friend class DataReductionProxySettingsTestBase;
262 friend class DataReductionProxySettingsTest;
263 FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsTest,
264 TestAuthenticationInit);
265 FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsTest,
266 TestAuthHashGeneration);
267 FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsTest,
268 TestAuthHashGenerationWithOriginSetViaSwitch);
269 FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsTest,
270 TestResetDataReductionStatistics);
271 FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsTest,
272 TestIsProxyEnabledOrManaged);
273 FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsTest,
275 FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsTest,
276 TestGetDailyContentLengths);
277 FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsTest,
278 TestMaybeActivateDataReductionProxy);
279 FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsTest,
280 TestOnIPAddressChanged);
281 FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsTest,
282 TestOnProxyEnabledPrefChange);
283 FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsTest,
284 TestInitDataReductionProxyOn);
285 FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsTest,
286 TestInitDataReductionProxyOff);
287 FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsTest,
289 FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsTest,
290 CheckInitMetricsWhenNotAllowed);
292 // NetworkChangeNotifier::IPAddressObserver:
293 virtual void OnIPAddressChanged() OVERRIDE;
295 // Underlying implementation of InitDataReductionProxySession(), factored
296 // out to be testable without creating a full HttpNetworkSession.
297 static void InitDataReductionAuthentication(net::HttpAuthCache* auth_cache,
298 const std::string& key);
300 void OnProxyEnabledPrefChange();
302 void ResetDataReductionStatistics();
304 void MaybeActivateDataReductionProxy(bool at_startup);
306 // Requests the proxy probe URL, if one is set. If unable to do so, disables
307 // the proxy, if enabled. Otherwise enables the proxy if disabled by a probe
309 void ProbeWhetherDataReductionProxyIsAvailable();
310 std::string GetProxyCheckURL();
312 // Returns a UTF16 string that's the hash of the configured authentication
313 // |key| and |salt|. Returns an empty UTF16 string if no key is configured or
314 // the data reduction proxy feature isn't available.
315 static base::string16 AuthHashForSalt(int64 salt, const std::string& key);
317 static bool allowed_;
318 static bool promo_allowed_;
321 bool restricted_by_carrier_;
322 bool enabled_by_user_;
324 scoped_ptr<net::URLFetcher> fetcher_;
325 BooleanPrefMember spdy_proxy_auth_enabled_;
328 PrefService* local_state_prefs_;
330 net::URLRequestContextGetter* url_request_context_getter_;
332 scoped_ptr<DataReductionProxyConfigurator> config_;
334 base::ThreadChecker thread_checker_;
336 bool fallback_allowed_;
338 DISALLOW_COPY_AND_ASSIGN(DataReductionProxySettings);
341 } // namespace data_reduction_proxy
343 #endif // COMPONENTS_DATA_REDUCTION_PROXY_BROWSER_DATA_REDUCTION_PROXY_SETTINGS_H_