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