• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
4 
5 #ifndef COMPONENTS_DATA_REDUCTION_PROXY_BROWSER_DATA_REDUCTION_PROXY_SETTINGS_H_
6 #define COMPONENTS_DATA_REDUCTION_PROXY_BROWSER_DATA_REDUCTION_PROXY_SETTINGS_H_
7 
8 #include <vector>
9 
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 "components/data_reduction_proxy/browser/data_reduction_proxy_params.h"
18 #include "net/base/network_change_notifier.h"
19 #include "net/url_request/url_fetcher_delegate.h"
20 
21 class PrefService;
22 
23 namespace net {
24 class AuthChallengeInfo;
25 class HostPortPair;
26 class HttpAuthCache;
27 class HttpNetworkSession;
28 class HttpResponseHeaders;
29 class URLFetcher;
30 class URLRequestContextGetter;
31 }
32 
33 namespace data_reduction_proxy {
34 
35 // The number of days of bandwidth usage statistics that are tracked.
36 const unsigned int kNumDaysInHistory = 60;
37 
38 // The number of days of bandwidth usage statistics that are presented.
39 const unsigned int kNumDaysInHistorySummary = 30;
40 
41 COMPILE_ASSERT(kNumDaysInHistorySummary <= kNumDaysInHistory,
42                DataReductionProxySettings_summary_too_long);
43 
44 // Values of the UMA DataReductionProxy.StartupState histogram.
45 // This enum must remain synchronized with DataReductionProxyStartupState
46 // in metrics/histograms/histograms.xml.
47 enum ProxyStartupState {
48   PROXY_NOT_AVAILABLE = 0,
49   PROXY_DISABLED,
50   PROXY_ENABLED,
51   PROXY_STARTUP_STATE_COUNT,
52 };
53 
54 // Values of the UMA DataReductionProxy.ProbeURL histogram.
55 // This enum must remain synchronized with
56 // DataReductionProxyProbeURLFetchResult in metrics/histograms/histograms.xml.
57 // TODO(marq): Rename these histogram buckets with s/DISABLED/RESTRICTED/, so
58 //     their names match the behavior they track.
59 enum ProbeURLFetchResult {
60   // The probe failed because the Internet was disconnected.
61   INTERNET_DISCONNECTED = 0,
62 
63   // The probe failed for any other reason, and as a result, the proxy was
64   // disabled.
65   FAILED_PROXY_DISABLED,
66 
67   // The probe failed, but the proxy was already restricted.
68   FAILED_PROXY_ALREADY_DISABLED,
69 
70   // The probe succeeded, and as a result the proxy was restricted.
71   SUCCEEDED_PROXY_ENABLED,
72 
73   // The probe succeeded, but the proxy was already restricted.
74   SUCCEEDED_PROXY_ALREADY_ENABLED,
75 
76   // This must always be last.
77   PROBE_URL_FETCH_RESULT_COUNT
78 };
79 
80 // Central point for configuring the data reduction proxy.
81 // This object lives on the UI thread and all of its methods are expected to
82 // be called from there.
83 // TODO(marq): Convert this to be a KeyedService with an
84 // associated factory class, and refactor the Java call sites accordingly.
85 class DataReductionProxySettings
86     : public net::URLFetcherDelegate,
87       public net::NetworkChangeNotifier::IPAddressObserver {
88  public:
89   typedef std::vector<long long> ContentLengthList;
90 
91   static bool IsProxyKeySetOnCommandLine();
92 
93   DataReductionProxySettings(DataReductionProxyParams* params);
94   virtual ~DataReductionProxySettings();
95 
params()96   DataReductionProxyParams* params() const {
97     return params_.get();
98   }
99 
100   // Initializes the data reduction proxy with profile and local state prefs,
101   // and a |UrlRequestContextGetter| for canary probes. The caller must ensure
102   // that all parameters remain alive for the lifetime of the
103   // |DataReductionProxySettings| instance.
104   void InitDataReductionProxySettings(
105       PrefService* prefs,
106       PrefService* local_state_prefs,
107       net::URLRequestContextGetter* url_request_context_getter);
108 
109   // Initializes the data reduction proxy with profile and local state prefs,
110   // a |UrlRequestContextGetter| for canary probes, and a proxy configurator.
111   // The caller must ensure that all parameters remain alive for the lifetime of
112   // the |DataReductionProxySettings| instance.
113   // TODO(marq): Remove when iOS supports the new interface above.
114   void InitDataReductionProxySettings(
115       PrefService* prefs,
116       PrefService* local_state_prefs,
117       net::URLRequestContextGetter* url_request_context_getter,
118       scoped_ptr<DataReductionProxyConfigurator> configurator);
119 
120   // Sets the logic the embedder uses to set the networking configuration that
121   // causes traffic to be proxied.
122   void SetProxyConfigurator(
123       scoped_ptr<DataReductionProxyConfigurator> configurator);
124 
125   // If proxy authentication is compiled in, pre-cache authentication
126   // keys for all configured proxies in |session|.
127   static void InitDataReductionProxySession(
128       net::HttpNetworkSession* session,
129       const DataReductionProxyParams* params);
130 
131   // Returns true if |auth_info| represents an authentication challenge from
132   // a compatible, configured proxy.
133   bool IsAcceptableAuthChallenge(net::AuthChallengeInfo* auth_info);
134 
135   // Returns a UTF16 string suitable for use as an authentication token in
136   // response to the challenge represented by |auth_info|. If the token can't
137   // be correctly generated for |auth_info|, returns an empty UTF16 string.
138   base::string16 GetTokenForAuthChallenge(net::AuthChallengeInfo* auth_info);
139 
140   // Returns true if the proxy is enabled.
141   bool IsDataReductionProxyEnabled();
142 
143   // Returns true if the alternative proxy is enabled.
144   bool IsDataReductionProxyAlternativeEnabled() const;
145 
146   // Returns true if the proxy is managed by an adminstrator's policy.
147   bool IsDataReductionProxyManaged();
148 
149   // Enables or disables the data reduction proxy. If a probe URL is available,
150   // and a probe request fails at some point, the proxy won't be used until a
151   // probe succeeds.
152   void SetDataReductionProxyEnabled(bool enabled);
153 
154   // Enables or disables the alternative data reduction proxy configuration.
155   void SetDataReductionProxyAlternativeEnabled(bool enabled);
156 
157   // Returns the time in microseconds that the last update was made to the
158   // daily original and received content lengths.
159   int64 GetDataReductionLastUpdateTime();
160 
161   // Returns a vector containing the total size of all HTTP content that was
162   // received over the last |kNumDaysInHistory| before any compression by the
163   // data reduction proxy. Each element in the vector contains one day of data.
164   ContentLengthList GetDailyOriginalContentLengths();
165 
166   // Returns an vector containing the aggregate received HTTP content in the
167   // last |kNumDaysInHistory| days.
168   ContentLengthList GetDailyReceivedContentLengths();
169 
170   // net::URLFetcherDelegate:
171   virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE;
172 
173  protected:
174   void InitPrefMembers();
175 
176   // Returns a fetcher for the probe to check if OK for the proxy to use SPDY.
177   // Virtual for testing.
178   virtual net::URLFetcher* GetURLFetcherForAvailabilityCheck();
179 
180   // Returns a fetcher to warm up the connection to the data reduction proxy.
181   // Virtual for testing.
182   virtual net::URLFetcher* GetURLFetcherForWarmup();
183 
184   // Virtualized for unit test support.
185   virtual PrefService* GetOriginalProfilePrefs();
186   virtual PrefService* GetLocalStatePrefs();
187 
188   void GetContentLengths(unsigned int days,
189                          int64* original_content_length,
190                          int64* received_content_length,
191                          int64* last_update_time);
192   ContentLengthList GetDailyContentLengths(const char* pref_name);
193 
194   // Sets the proxy configs, enabling or disabling the proxy according to
195   // the value of |enabled| and |alternative_enabled|. Use the alternative
196   // configuration only if |enabled| and |alternative_enabled| are true. If
197   // |restricted| is true, only enable the fallback proxy. |at_startup| is true
198   // when this method is called from InitDataReductionProxySettings.
199   virtual void SetProxyConfigs(bool enabled,
200                                bool alternative_enabled,
201                                bool restricted,
202                                bool at_startup);
203 
204   // Metrics method. Subclasses should override if they wish to provide
205   // alternatives.
206   virtual void RecordDataReductionInit();
207 
208   virtual void AddDefaultProxyBypassRules();
209 
210   // Writes a warning to the log that is used in backend processing of
211   // customer feedback. Virtual so tests can mock it for verification.
212   virtual void LogProxyState(bool enabled, bool restricted, bool at_startup);
213 
214   // Virtualized for mocking
215   virtual void RecordProbeURLFetchResult(
216       data_reduction_proxy::ProbeURLFetchResult result);
217   virtual void RecordStartupState(
218       data_reduction_proxy::ProxyStartupState state);
219 
configurator()220   DataReductionProxyConfigurator* configurator() {
221     return configurator_.get();
222   }
223 
224   // Reset params for tests.
225   void ResetParamsForTest(DataReductionProxyParams* params);
226 
227  private:
228   friend class DataReductionProxySettingsTestBase;
229   friend class DataReductionProxySettingsTest;
230   FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsTest,
231                            TestAuthenticationInit);
232   FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsTest,
233                            TestAuthHashGeneration);
234   FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsTest,
235                            TestAuthHashGenerationWithOriginSetViaSwitch);
236   FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsTest,
237                            TestResetDataReductionStatistics);
238   FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsTest,
239                            TestIsProxyEnabledOrManaged);
240   FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsTest,
241                            TestContentLengths);
242   FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsTest,
243                            TestGetDailyContentLengths);
244   FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsTest,
245                            TestMaybeActivateDataReductionProxy);
246   FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsTest,
247                            TestOnIPAddressChanged);
248   FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsTest,
249                            TestOnProxyEnabledPrefChange);
250   FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsTest,
251                            TestInitDataReductionProxyOn);
252   FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsTest,
253                            TestInitDataReductionProxyOff);
254   FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsTest,
255                            TestBypassList);
256   FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsTest,
257                            CheckInitMetricsWhenNotAllowed);
258   FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsTest,
259                            TestSetProxyConfigs);
260 
261   // NetworkChangeNotifier::IPAddressObserver:
262   virtual void OnIPAddressChanged() OVERRIDE;
263 
264   // Underlying implementation of InitDataReductionProxySession(), factored
265   // out to be testable without creating a full HttpNetworkSession.
266   static void InitDataReductionAuthentication(
267       net::HttpAuthCache* auth_cache,
268       const DataReductionProxyParams* params);
269 
270   void OnProxyEnabledPrefChange();
271   void OnProxyAlternativeEnabledPrefChange();
272 
273   void ResetDataReductionStatistics();
274 
275   void MaybeActivateDataReductionProxy(bool at_startup);
276 
277   // Requests the proxy probe URL, if one is set.  If unable to do so, disables
278   // the proxy, if enabled. Otherwise enables the proxy if disabled by a probe
279   // failure.
280   void ProbeWhetherDataReductionProxyIsAvailable();
281 
282   // Warms the connection to the data reduction proxy.
283   void WarmProxyConnection();
284 
285   // Generic method to get a URL fetcher.
286   net::URLFetcher* GetBaseURLFetcher(const GURL& gurl, int load_flags);
287 
288   // Returns a UTF16 string that's the hash of the configured authentication
289   // |key| and |salt|. Returns an empty UTF16 string if no key is configured or
290   // the data reduction proxy feature isn't available.
291   static base::string16 AuthHashForSalt(int64 salt,
292                                         const std::string& key);
293 
294   std::string key_;
295   bool restricted_by_carrier_;
296   bool enabled_by_user_;
297 
298   scoped_ptr<net::URLFetcher> fetcher_;
299   scoped_ptr<net::URLFetcher> warmup_fetcher_;
300 
301   BooleanPrefMember spdy_proxy_auth_enabled_;
302   BooleanPrefMember data_reduction_proxy_alternative_enabled_;
303 
304   PrefService* prefs_;
305   PrefService* local_state_prefs_;
306 
307   net::URLRequestContextGetter* url_request_context_getter_;
308 
309   scoped_ptr<DataReductionProxyConfigurator> configurator_;
310 
311   base::ThreadChecker thread_checker_;
312 
313   scoped_ptr<DataReductionProxyParams> params_;
314 
315   DISALLOW_COPY_AND_ASSIGN(DataReductionProxySettings);
316 };
317 
318 }  // namespace data_reduction_proxy
319 
320 #endif  // COMPONENTS_DATA_REDUCTION_PROXY_BROWSER_DATA_REDUCTION_PROXY_SETTINGS_H_
321