Home | History | Annotate | Download | only in spdyproxy
      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 
     18 class PrefService;
     19 
     20 namespace net {
     21 class AuthChallengeInfo;
     22 class HostPortPair;
     23 class HttpAuthCache;
     24 class HttpNetworkSession;
     25 class HttpResponseHeaders;
     26 class URLFetcher;
     27 }
     28 
     29 namespace spdyproxy {
     30 
     31 // The number of days of bandwidth usage statistics that are tracked.
     32 const unsigned int kNumDaysInHistory = 60;
     33 
     34 // The number of days of bandwidth usage statistics that are presented.
     35 const unsigned int kNumDaysInHistorySummary = 30;
     36 
     37 COMPILE_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.
     47 class 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