1// Copyright 2013 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 CHROME_BROWSER_NET_SPDYPROXY_DATA_REDUCTION_PROXY_SETTINGS_H_
6#define CHROME_BROWSER_NET_SPDYPROXY_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 "net/base/network_change_notifier.h"
16#include "net/url_request/url_fetcher_delegate.h"
17
18class PrefService;
19
20namespace net {
21class AuthChallengeInfo;
22class HostPortPair;
23class HttpAuthCache;
24class HttpNetworkSession;
25class HttpResponseHeaders;
26class URLFetcher;
27}
28
29namespace spdyproxy {
30
31// The number of days of bandwidth usage statistics that are tracked.
32const unsigned int kNumDaysInHistory = 60;
33
34// The number of days of bandwidth usage statistics that are presented.
35const unsigned int kNumDaysInHistorySummary = 30;
36
37COMPILE_ASSERT(kNumDaysInHistorySummary <= kNumDaysInHistory,
38               DataReductionProxySettings_summary_too_long);
39
40}  // namespace spdyproxy
41
42// Central point for configuring the data reduction proxy.
43// This object lives on the UI thread and all of its methods are expected to
44// be called from there.
45// TODO(marq): Convert this to be a BrowserContextKeyedService with an
46// associated factory class, and refactor the Java call sites accordingly.
47class DataReductionProxySettings
48    : public net::URLFetcherDelegate,
49      public net::NetworkChangeNotifier::IPAddressObserver {
50 public:
51  typedef std::vector<long long> ContentLengthList;
52  // TODO(marq): Consider instead using a std::pair instead of a vector.
53  typedef std::vector<GURL> DataReductionProxyList;
54
55  DataReductionProxySettings();
56  virtual ~DataReductionProxySettings();
57
58  void InitDataReductionProxySettings();
59
60  // If proxy authentication is compiled in, pre-cache authentication
61  // keys for all configured proxies in |session|.
62  static void InitDataReductionProxySession(net::HttpNetworkSession* session);
63
64  // Add a host pattern to bypass. This should follow the same syntax used
65  // in net::ProxyBypassRules; that is, a hostname pattern, a hostname suffix
66  // pattern, an IP literal, a CIDR block, or the magic string '<local>'.
67  // Bypass settings persist for the life of this object and are applied
68  // each time the proxy is enabled, but are not updated while it is enabled.
69  void AddHostPatternToBypass(const std::string& pattern);
70
71  // Add a URL pattern to bypass the proxy. The base implementation strips
72  // everything in |pattern| after the first single slash and then treats it
73  // as a hostname pattern. Subclasses may implement other semantics.
74  virtual void AddURLPatternToBypass(const std::string& pattern);
75
76  // Returns true if the data reduction proxy is allowed to be used on this
77  // instance of Chrome. This could return false, for example, if this instance
78  // is not part of the field trial, or if the proxy name is not configured
79  // via gyp.
80  static bool IsDataReductionProxyAllowed();
81
82  // Returns true if a screen promoting the data reduction proxy is allowed to
83  // be shown. Logic that decides when to show the promo should check its
84  // availability. This would return false if not part of a separate field
85  // trial that governs the use of the promotion.
86  static bool IsDataReductionProxyPromoAllowed();
87
88  // Returns true if preconnect advisory hinting is enabled by command line
89  // flag or Finch trial.
90  static bool IsPreconnectHintingAllowed();
91
92  // Returns true if the Via header indicates that this request was fetched
93  // explicitly via the Chrome Proxy.
94  static bool WasFetchedViaProxy(const net::HttpResponseHeaders* headers);
95
96  // Returns the URL of the data reduction proxy.
97  static std::string GetDataReductionProxyOrigin();
98
99  // Returns the URL of the fallback data reduction proxy.
100  static std::string GetDataReductionProxyFallback();
101
102  // Returns a vector of GURLs for all configured proxies.
103  static DataReductionProxyList GetDataReductionProxies();
104
105  // Returns true if |auth_info| represents an authentication challenge from
106  // a compatible, configured proxy.
107  bool IsAcceptableAuthChallenge(net::AuthChallengeInfo* auth_info);
108
109  // Returns a UTF16 string suitable for use as an authentication token in
110  // response to the challenge represented by |auth_info|. If the token can't
111  // be correctly generated for |auth_info|, returns an empty UTF16 string.
112  base::string16 GetTokenForAuthChallenge(net::AuthChallengeInfo* auth_info);
113
114  // Returns true if the proxy is enabled.
115  bool IsDataReductionProxyEnabled();
116
117  // Returns true if the proxy is managed by an adminstrator's policy.
118  bool IsDataReductionProxyManaged();
119
120  // Enables or disables the data reduction proxy. If a probe URL is available,
121  // and a probe request fails at some point, the proxy won't be used until a
122  // probe succeeds.
123  void SetDataReductionProxyEnabled(bool enabled);
124
125  // Returns the time in microseconds that the last update was made to the
126  // daily original and received content lengths.
127  int64 GetDataReductionLastUpdateTime();
128
129  // Returns a vector containing the total size of all HTTP content that was
130  // received over the last |kNumDaysInHistory| before any compression by the
131  // data reduction proxy. Each element in the vector contains one day of data.
132  ContentLengthList GetDailyOriginalContentLengths();
133
134  // Returns an vector containing the aggregate received HTTP content in the
135  // last |kNumDaysInHistory| days.
136  ContentLengthList GetDailyReceivedContentLengths();
137
138  // net::URLFetcherDelegate:
139  virtual void OnURLFetchComplete(const net::URLFetcher* source) OVERRIDE;
140
141 protected:
142  void InitPrefMembers();
143
144  virtual net::URLFetcher* GetURLFetcher();
145
146  // Virtualized for unit test support.
147  virtual PrefService* GetOriginalProfilePrefs();
148  virtual PrefService* GetLocalStatePrefs();
149
150  void GetContentLengths(unsigned int days,
151                         int64* original_content_length,
152                         int64* received_content_length,
153                         int64* last_update_time);
154  ContentLengthList GetDailyContentLengths(const char* pref_name);
155
156  // Sets the proxy configs, enabling or disabling the proxy according to
157  // the value of |enabled|. If |restricted| is true, only enable the fallback
158  // proxy. |at_startup| is true when this method is called from
159  // InitDataReductionProxySettings.
160  virtual void SetProxyConfigs(bool enabled, bool restricted, bool at_startup);
161
162  // Metrics methods. Subclasses should override if they wish to provide
163  // alternate methods.
164  virtual void RecordDataReductionInit();
165
166  virtual void AddDefaultProxyBypassRules();
167
168  // Writes a warning to the log that is used in backend processing of
169  // customer feedback. Virtual so tests can mock it for verification.
170  virtual void LogProxyState(bool enabled, bool restricted, bool at_startup);
171
172  // Accessor for unit tests.
173  std::vector<std::string> BypassRules() { return bypass_rules_;}
174
175 private:
176  friend class DataReductionProxySettingsTestBase;
177  friend class DataReductionProxySettingsTest;
178  FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsTest,
179                           TestAuthenticationInit);
180  FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsTest,
181                           TestAuthHashGeneration);
182  FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsTest,
183                           TestAuthHashGenerationWithOriginSetViaSwitch);
184  FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsTest,
185                           TestResetDataReductionStatistics);
186  FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsTest,
187                           TestIsProxyEnabledOrManaged);
188  FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsTest,
189                           TestContentLengths);
190  FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsTest,
191                           TestGetDailyContentLengths);
192  FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsTest,
193                           TestMaybeActivateDataReductionProxy);
194  FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsTest,
195                           TestOnIPAddressChanged);
196  FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsTest,
197                           TestOnProxyEnabledPrefChange);
198  FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsTest,
199                           TestInitDataReductionProxyOn);
200  FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsTest,
201                           TestInitDataReductionProxyOff);
202  FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsTest,
203                           TestBypassList);
204
205  // NetworkChangeNotifier::IPAddressObserver:
206  virtual void OnIPAddressChanged() OVERRIDE;
207
208  // Underlying implementation of InitDataReductionProxySession(), factored
209  // out to be testable without creating a full HttpNetworkSession.
210  static void InitDataReductionAuthentication(net::HttpAuthCache* auth_cache);
211
212  void OnProxyEnabledPrefChange();
213
214  void ResetDataReductionStatistics();
215
216  void MaybeActivateDataReductionProxy(bool at_startup);
217
218  // Requests the proxy probe URL, if one is set.  If unable to do so, disables
219  // the proxy, if enabled. Otherwise enables the proxy if disabled by a probe
220  // failure.
221  void ProbeWhetherDataReductionProxyIsAvailable();
222  std::string GetProxyCheckURL();
223
224  // Returns a UTF16 string that's the hash of the configured authentication
225  // key and |salt|. Returns an empty UTF16 string if no key is configured or
226  // the data reduction proxy feature isn't available.
227  static base::string16 AuthHashForSalt(int64 salt);
228
229  std::vector<std::string> bypass_rules_;
230
231  bool restricted_by_carrier_;
232  bool enabled_by_user_;
233
234  scoped_ptr<net::URLFetcher> fetcher_;
235  BooleanPrefMember spdy_proxy_auth_enabled_;
236
237  DISALLOW_COPY_AND_ASSIGN(DataReductionProxySettings);
238};
239
240#endif  // CHROME_BROWSER_NET_SPDYPROXY_DATA_REDUCTION_PROXY_SETTINGS_H_
241