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