Home | History | Annotate | Download | only in browser
      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 
     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 
    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