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_PARAMS_H_
6#define COMPONENTS_DATA_REDUCTION_PROXY_BROWSER_DATA_REDUCTION_PROXY_PARAMS_H_
7
8#include <string>
9#include <utility>
10#include <vector>
11
12#include "base/memory/scoped_ptr.h"
13#include "net/base/host_port_pair.h"
14#include "net/proxy/proxy_retry_info.h"
15#include "url/gurl.h"
16
17namespace base {
18class TimeDelta;
19}
20
21namespace net {
22class ProxyConfig;
23class URLRequest;
24}
25
26namespace data_reduction_proxy {
27
28// Contains information about a given proxy server. |proxy_servers| contains
29// the configured data reduction proxy servers. |is_fallback|, |is_alternative|
30// and |is_ssl| note whether the given proxy is a fallback, an alternative,
31// or a proxy for ssl; these are not mutually exclusive.
32struct DataReductionProxyTypeInfo {
33  DataReductionProxyTypeInfo();
34  ~DataReductionProxyTypeInfo();
35  std::pair<GURL, GURL> proxy_servers;
36  bool is_fallback;
37  bool is_alternative;
38  bool is_ssl;
39};
40
41// Provides initialization parameters. Proxy origins, and the probe url are
42// are taken from flags if available and from preprocessor constants otherwise.
43// The DataReductionProxySettings class and others use this class to determine
44// the necessary DNS names to configure use of the data reduction proxy.
45class DataReductionProxyParams {
46 public:
47  // Flags used during construction that specify if the data reduction proxy
48  // is allowed to be used, if the fallback proxy is allowed to be used, if
49  // an alternative set of proxies is allowed to be used, if the promotion is
50  // allowed to be shown, and if this instance is part of a holdback experiment.
51  static const unsigned int kAllowed = (1 << 0);
52  static const unsigned int kFallbackAllowed = (1 << 1);
53  static const unsigned int kAlternativeAllowed = (1 << 2);
54  static const unsigned int kAlternativeFallbackAllowed = (1 << 3);
55  static const unsigned int kPromoAllowed = (1 << 4);
56  static const unsigned int kHoldback = (1 << 5);
57
58  typedef std::vector<GURL> DataReductionProxyList;
59
60  // Returns true if this client is part of field trial to use an alternative
61  // configuration for the data reduction proxy.
62  static bool IsIncludedInAlternativeFieldTrial();
63
64  // Returns true if this client is part of the field trial that should display
65  // a promotion for the data reduction proxy.
66  static bool IsIncludedInPromoFieldTrial();
67
68  // Returns true if this client is part of a field trial that uses preconnect
69  // hinting.
70  static bool IsIncludedInPreconnectHintingFieldTrial();
71
72  // Returns true if this client is part of a field trial that bypasses the
73  // proxy if the request resource type is on the critical path (e.g. HTML).
74  static bool IsIncludedInCriticalPathBypassFieldTrial();
75
76  // Returns true if this client is part of a field trial that runs a holdback
77  // experiment. A holdback experiment is one in which a fraction of browser
78  // instances will not be configured to use the data reduction proxy even if
79  // users have enabled it to be used. The UI will not indicate that a holdback
80  // is in effect.
81  static bool IsIncludedInHoldbackFieldTrial();
82
83  // Returns true if this client is part of a field trial that removes the
84  // |MISSING_VIA_HEADER_OTHER| proxy bypass case. This experiment changes proxy
85  // bypass logic to not trigger a proxy bypass when a response with a non-4xx
86  // response code is expected to have a data reduction proxy via header, but
87  // the data reduction proxy via header is missing.
88  static bool IsIncludedInRemoveMissingViaHeaderOtherBypassFieldTrial();
89
90  // Constructs configuration parameters. If |kAllowed|, then the standard
91  // data reduction proxy configuration is allowed to be used. If
92  // |kfallbackAllowed| a fallback proxy can be used if the primary proxy is
93  // bypassed or disabled. If |kAlternativeAllowed| then an alternative proxy
94  // configuration is allowed to be used. This alternative configuration would
95  // replace the primary and fallback proxy configurations if enabled. Finally
96  // if |kPromoAllowed|, the client may show a promotion for the data reduction
97  // proxy.
98  //
99  // A standard configuration has a primary proxy, and a fallback proxy for
100  // HTTP traffic. The alternative configuration has a different primary and
101  // fallback proxy for HTTP traffic, and an SSL proxy.
102  explicit DataReductionProxyParams(int flags);
103
104  // Creates a copy of the configuration parameters.
105  scoped_ptr<DataReductionProxyParams> Clone();
106
107  virtual ~DataReductionProxyParams();
108
109  // Returns true if a data reduction proxy was used for the given |request|.
110  // If true, |proxy_info.proxy_servers.first| will contain the name of the
111  // proxy that was used. |proxy_info.proxy_servers.second| will contain the
112  // name of the data reduction proxy server that would be used if
113  // |proxy_info.proxy_server.first| is bypassed, if one exists. In addition,
114  // |proxy_info| will note if the proxy used was a fallback, an alternative,
115  // or a proxy for ssl; these are not mutually exclusive. |proxy_info| can be
116  // NULL if the caller isn't interested in its values.
117  virtual bool WasDataReductionProxyUsed(
118      const net::URLRequest* request,
119      DataReductionProxyTypeInfo* proxy_info) const;
120
121  // Returns true if the specified |host_port_pair| matches a data reduction
122  // proxy. If true, |proxy_info.proxy_servers.first| will contain the name of
123  // the proxy that matches. |proxy_info.proxy_servers.second| will contain the
124  // name of the data reduction proxy server that would be used if
125  // |proxy_info.proxy_server.first| is bypassed, if one exists. In addition,
126  // |proxy_info| will note if the proxy was a fallback, an alternative, or a
127  // proxy for ssl; these are not mutually exclusive. |proxy_info| can be NULL
128  // if the caller isn't interested in its values. Virtual for testing.
129  virtual bool IsDataReductionProxy(
130      const net::HostPortPair& host_port_pair,
131      DataReductionProxyTypeInfo* proxy_info) const;
132
133  // Returns true if this request would be bypassed by the data request proxy
134  // based on applying the |data_reduction_proxy_config| param rules to the
135  // request URL.
136  bool IsBypassedByDataReductionProxyLocalRules(
137      const net::URLRequest& request,
138      const net::ProxyConfig& data_reduction_proxy_config) const;
139
140  // Checks if all configured data reduction proxies are in the retry map.
141  // Returns true if the request is bypassed by all configured data reduction
142  // proxies and returns the bypass delay in delay_seconds (if not NULL). If
143  // there are no configured data reduction proxies, returns false. If
144  // the request is bypassed by more than one proxy, delay_seconds returns
145  // the shortest delay.
146  bool AreDataReductionProxiesBypassed(const net::URLRequest& request,
147                                       base::TimeDelta* min_retry_delay) const;
148
149  // Checks if all configured data reduction proxies are in the retry map.
150  // Returns true if the request is bypassed by all configured data reduction
151  // proxies and returns the bypass delay in delay_seconds (if not NULL). If
152  // there are no configured data reduction proxies, returns false. If
153  // the request is bypassed by more than one proxy, delay_seconds returns
154  // the shortest delay.
155  bool AreProxiesBypassed(const net::ProxyRetryInfoMap& retry_map,
156                          bool is_https,
157                          base::TimeDelta* min_retry_delay) const;
158
159  // Returns the data reduction proxy primary origin.
160  const GURL& origin() const {
161    return origin_;
162  }
163
164  // Returns the data reduction proxy fallback origin.
165  const GURL& fallback_origin() const {
166    return fallback_origin_;
167  }
168
169  // Returns the data reduction proxy ssl origin that is used with the
170  // alternative proxy configuration.
171  const GURL& ssl_origin() const {
172    return ssl_origin_;
173  }
174
175  // Returns the alternative data reduction proxy primary origin.
176  const GURL& alt_origin() const {
177    return alt_origin_;
178  }
179
180  // Returns the alternative data reduction proxy fallback origin.
181  const GURL& alt_fallback_origin() const {
182    return alt_fallback_origin_;
183  }
184
185  // Returns the URL to probe to decide if the primary origin should be used.
186  const GURL& probe_url() const {
187    return probe_url_;
188  }
189
190  // Returns the URL to fetch to warm the data reduction proxy connection.
191  const GURL& warmup_url() const {
192    return warmup_url_;
193  }
194
195  // Returns true if the data reduction proxy configuration may be used.
196  bool allowed() const {
197    return allowed_;
198  }
199
200  // Returns true if the fallback proxy may be used.
201  bool fallback_allowed() const {
202    return fallback_allowed_;
203  }
204
205  // Returns true if the alternative data reduction proxy configuration may be
206  // used.
207  bool alternative_allowed() const {
208    return alt_allowed_;
209  }
210
211  // Returns true if the alternative fallback data reduction proxy
212  // configuration may be used.
213  bool alternative_fallback_allowed() const {
214    return alt_fallback_allowed_;
215  }
216
217  // Returns true if the data reduction proxy promo may be shown.
218  // This is idependent of whether the data reduction proxy is allowed.
219  // TODO(bengr): maybe tie to whether proxy is allowed.
220  bool promo_allowed() const {
221    return promo_allowed_;
222  }
223
224  // Returns true if the data reduction proxy should not actually use the
225  // proxy if enabled.
226  bool holdback() const {
227    return holdback_;
228  }
229
230  // Given |allowed_|, |fallback_allowed_|, and |alt_allowed_|, returns the
231  // list of data reduction proxies that may be used.
232  DataReductionProxyList GetAllowedProxies() const;
233
234  // Returns true if any proxy origins are set on the command line.
235  bool is_configured_on_command_line() const {
236    return configured_on_command_line_;
237  }
238
239 protected:
240  // Test constructor that optionally won't call Init();
241  DataReductionProxyParams(int flags,
242                           bool should_call_init);
243
244  DataReductionProxyParams(const DataReductionProxyParams& params);
245
246  // Initialize the values of the proxies, and probe URL, from command
247  // line flags and preprocessor constants, and check that there are
248  // corresponding definitions for the allowed configurations.
249  bool Init(bool allowed,
250            bool fallback_allowed,
251            bool alt_allowed,
252            bool alt_fallback_allowed);
253
254  // Initialize the values of the proxies, and probe URL from command
255  // line flags and preprocessor constants.
256  void InitWithoutChecks();
257
258  // Returns the corresponding string from preprocessor constants if defined,
259  // and an empty string otherwise.
260  virtual std::string GetDefaultDevOrigin() const;
261  virtual std::string GetDefaultDevFallbackOrigin() const;
262  virtual std::string GetDefaultOrigin() const;
263  virtual std::string GetDefaultFallbackOrigin() const;
264  virtual std::string GetDefaultSSLOrigin() const;
265  virtual std::string GetDefaultAltOrigin() const;
266  virtual std::string GetDefaultAltFallbackOrigin() const;
267  virtual std::string GetDefaultProbeURL() const;
268  virtual std::string GetDefaultWarmupURL() const;
269
270 private:
271  // Checks if the primary and fallback data reduction proxies are in the retry
272  // map. Returns true if the request is bypassed by both data reduction
273  // proxies and returns the shortest bypass delay in delay_seconds (if not
274  // NULL). If the fallback proxy is not valid, returns true if primary proxy
275  // was bypassed and returns its bypass delay.
276  bool ArePrimaryAndFallbackBypassed(const net::ProxyRetryInfoMap& retry_map,
277                                     const GURL& primary,
278                                     const GURL& fallback,
279                                     base::TimeDelta* min_retry_delay) const;
280
281  DataReductionProxyParams& operator=(const DataReductionProxyParams& params);
282
283  GURL origin_;
284  GURL fallback_origin_;
285  GURL ssl_origin_;
286  GURL alt_origin_;
287  GURL alt_fallback_origin_;
288  GURL probe_url_;
289  GURL warmup_url_;
290
291  bool allowed_;
292  bool fallback_allowed_;
293  bool alt_allowed_;
294  bool alt_fallback_allowed_;
295  bool promo_allowed_;
296  bool holdback_;
297
298  bool configured_on_command_line_;
299};
300
301}  // namespace data_reduction_proxy
302#endif  // COMPONENTS_DATA_REDUCTION_PROXY_BROWSER_DATA_REDUCTION_PROXY_PARAMS_H_
303