summaryrefslogtreecommitdiffstats
path: root/components/data_reduction_proxy/browser/data_reduction_proxy_settings.h
blob: cf0abe105c15062a070d8d7c6abddb28db2e692d (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
// Copyright 2014 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 COMPONENTS_DATA_REDUCTION_PROXY_BROWSER_DATA_REDUCTION_PROXY_SETTINGS_H_
#define COMPONENTS_DATA_REDUCTION_PROXY_BROWSER_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 "base/threading/thread_checker.h"
#include "components/data_reduction_proxy/browser/data_reduction_proxy_configurator.h"
#include "components/data_reduction_proxy/browser/data_reduction_proxy_params.h"
#include "net/base/network_change_notifier.h"
#include "net/url_request/url_fetcher_delegate.h"

class PrefService;

namespace net {
class AuthChallengeInfo;
class HostPortPair;
class HttpAuthCache;
class HttpNetworkSession;
class HttpResponseHeaders;
class URLFetcher;
class URLRequestContextGetter;
}

namespace data_reduction_proxy {

// 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);

  // Values of the UMA DataReductionProxy.StartupState histogram.
  // This enum must remain synchronized with DataReductionProxyStartupState
  // in metrics/histograms/histograms.xml.
  enum ProxyStartupState {
    PROXY_NOT_AVAILABLE = 0,
    PROXY_DISABLED,
    PROXY_ENABLED,
    PROXY_STARTUP_STATE_COUNT,
  };

  // Values of the UMA DataReductionProxy.ProbeURL histogram.
  // This enum must remain synchronized with
  // DataReductionProxyProbeURLFetchResult in metrics/histograms/histograms.xml.
  // TODO(marq): Rename these histogram buckets with s/DISABLED/RESTRICTED/, so
  //     their names match the behavior they track.
  enum ProbeURLFetchResult {
    // The probe failed because the Internet was disconnected.
    INTERNET_DISCONNECTED = 0,

    // The probe failed for any other reason, and as a result, the proxy was
    // disabled.
    FAILED_PROXY_DISABLED,

    // The probe failed, but the proxy was already restricted.
    FAILED_PROXY_ALREADY_DISABLED,

    // THe probe succeeded, and as a result the proxy was restricted.
    SUCCEEDED_PROXY_ENABLED,

    // The probe succeeded, but the proxy was already restricted.
    SUCCEEDED_PROXY_ALREADY_ENABLED,

    // This must always be last.
    PROBE_URL_FETCH_RESULT_COUNT
  };

// 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.
// TODO(marq): Convert this to be a KeyedService with an
// associated factory class, and refactor the Java call sites accordingly.
class DataReductionProxySettings
    : public net::URLFetcherDelegate,
      public net::NetworkChangeNotifier::IPAddressObserver {
 public:
  typedef std::vector<long long> ContentLengthList;

  static bool IsProxyKeySetOnCommandLine();

  DataReductionProxySettings(DataReductionProxyParams* params);
  virtual ~DataReductionProxySettings();

  DataReductionProxyParams* params() const {
    return params_.get();
  }

  // Initializes the data reduction proxy with profile and local state prefs,
  // and a |UrlRequestContextGetter| for canary probes. The caller must ensure
  // that all parameters remain alive for the lifetime of the
  // |DataReductionProxySettings| instance.
  void InitDataReductionProxySettings(
      PrefService* prefs,
      PrefService* local_state_prefs,
      net::URLRequestContextGetter* url_request_context_getter);

  // Initializes the data reduction proxy with profile and local state prefs,
  // a |UrlRequestContextGetter| for canary probes, and a proxy configurator.
  // The caller must ensure that all parameters remain alive for the lifetime of
  // the |DataReductionProxySettings| instance.
  // TODO(marq): Remove when iOS supports the new interface above.
  void InitDataReductionProxySettings(
      PrefService* prefs,
      PrefService* local_state_prefs,
      net::URLRequestContextGetter* url_request_context_getter,
      scoped_ptr<DataReductionProxyConfigurator> configurator);

  // Sets the logic the embedder uses to set the networking configuration that
  // causes traffic to be proxied.
  void SetProxyConfigurator(
      scoped_ptr<DataReductionProxyConfigurator> configurator);

  // If proxy authentication is compiled in, pre-cache authentication
  // keys for all configured proxies in |session|.
  static void InitDataReductionProxySession(
      net::HttpNetworkSession* session,
      const DataReductionProxyParams* params);

  // Returns true if |auth_info| represents an authentication challenge from
  // a compatible, configured proxy.
  bool IsAcceptableAuthChallenge(net::AuthChallengeInfo* auth_info);

  // Returns a UTF16 string suitable for use as an authentication token in
  // response to the challenge represented by |auth_info|. If the token can't
  // be correctly generated for |auth_info|, returns an empty UTF16 string.
  base::string16 GetTokenForAuthChallenge(net::AuthChallengeInfo* auth_info);

  // Returns true if the proxy is enabled.
  bool IsDataReductionProxyEnabled();

  // Returns true if the alternative proxy is enabled.
  bool IsDataReductionProxyAlternativeEnabled();

  // 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);

  // Enables or disables the alternative data reduction proxy configuration.
  void SetDataReductionProxyAlternativeEnabled(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();

  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| and |alternative_enabled|. Use the alternative
  // configuration only if |enabled| and |alternative_enabled| are true. If
  // |restricted| is true, only enable the fallback proxy. |at_startup| is true
  // when this method is called from InitDataReductionProxySettings.
  virtual void SetProxyConfigs(bool enabled,
                               bool alternative_enabled,
                               bool restricted,
                               bool at_startup);

  // Metrics method. Subclasses should override if they wish to provide
  // alternatives.
  virtual void RecordDataReductionInit();

  virtual void AddDefaultProxyBypassRules();

  // Writes a warning to the log that is used in backend processing of
  // customer feedback. Virtual so tests can mock it for verification.
  virtual void LogProxyState(bool enabled, bool restricted, bool at_startup);

  // Virtualized for mocking
  virtual void RecordProbeURLFetchResult(
      data_reduction_proxy::ProbeURLFetchResult result);
  virtual void RecordStartupState(
      data_reduction_proxy::ProxyStartupState state);

  DataReductionProxyConfigurator* configurator() {
    return configurator_.get();
  }

  // Reset params for tests.
  void ResetParamsForTest(DataReductionProxyParams* params);

 private:
  friend class DataReductionProxySettingsTestBase;
  friend class DataReductionProxySettingsTest;
  FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsTest,
                           TestAuthenticationInit);
  FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsTest,
                           TestAuthHashGeneration);
  FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsTest,
                           TestAuthHashGenerationWithOriginSetViaSwitch);
  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);
  FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsTest,
                           CheckInitMetricsWhenNotAllowed);
  FRIEND_TEST_ALL_PREFIXES(DataReductionProxySettingsTest,
                           TestSetProxyConfigs);

  // NetworkChangeNotifier::IPAddressObserver:
  virtual void OnIPAddressChanged() OVERRIDE;

  // Underlying implementation of InitDataReductionProxySession(), factored
  // out to be testable without creating a full HttpNetworkSession.
  static void InitDataReductionAuthentication(
      net::HttpAuthCache* auth_cache,
      const DataReductionProxyParams* params);

  void OnProxyEnabledPrefChange();
  void OnProxyAlternativeEnabledPrefChange();

  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();

  // Returns a UTF16 string that's the hash of the configured authentication
  // |key| and |salt|. Returns an empty UTF16 string if no key is configured or
  // the data reduction proxy feature isn't available.
  static base::string16 AuthHashForSalt(int64 salt,
                                        const std::string& key);

  std::string key_;
  bool restricted_by_carrier_;
  bool enabled_by_user_;

  scoped_ptr<net::URLFetcher> fetcher_;
  BooleanPrefMember spdy_proxy_auth_enabled_;
  BooleanPrefMember data_reduction_proxy_alternative_enabled_;

  PrefService* prefs_;
  PrefService* local_state_prefs_;

  net::URLRequestContextGetter* url_request_context_getter_;

  scoped_ptr<DataReductionProxyConfigurator> configurator_;

  base::ThreadChecker thread_checker_;

  scoped_ptr<DataReductionProxyParams> params_;

  DISALLOW_COPY_AND_ASSIGN(DataReductionProxySettings);
};

}  // namespace data_reduction_proxy

#endif  // COMPONENTS_DATA_REDUCTION_PROXY_BROWSER_DATA_REDUCTION_PROXY_SETTINGS_H_