1// Copyright (c) 2012 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 NET_PROXY_PROXY_CONFIG_H_
6#define NET_PROXY_PROXY_CONFIG_H_
7
8#include <string>
9
10#include "net/base/net_export.h"
11#include "net/proxy/proxy_bypass_rules.h"
12#include "net/proxy/proxy_config_source.h"
13#include "net/proxy/proxy_list.h"
14#include "net/proxy/proxy_server.h"
15#include "url/gurl.h"
16
17namespace base {
18class Value;
19}
20
21namespace net {
22
23class ProxyInfo;
24
25// ProxyConfig describes a user's proxy settings.
26//
27// There are two categories of proxy settings:
28//   (1) Automatic (indicates the methods to obtain a PAC script)
29//   (2) Manual (simple set of proxy servers per scheme, and bypass patterns)
30//
31// When both automatic and manual settings are specified, the Automatic ones
32// take precedence over the manual ones.
33//
34// For more details see:
35// http://www.chromium.org/developers/design-documents/proxy-settings-fallback
36class NET_EXPORT ProxyConfig {
37 public:
38  // ProxyRules describes the "manual" proxy settings.
39  // TODO(eroman): Turn this into a class.
40  // TODO(marq): Update the enum names; "TYPE_SINGLE_PROXY" really means
41  //             the same set of proxies are used for all requests.
42  struct NET_EXPORT ProxyRules {
43    enum Type {
44      TYPE_NO_RULES,
45      TYPE_SINGLE_PROXY,
46      TYPE_PROXY_PER_SCHEME,
47    };
48
49    // Note that the default of TYPE_NO_RULES results in direct connections
50    // being made when using this ProxyConfig.
51    ProxyRules();
52    ~ProxyRules();
53
54    bool empty() const {
55      return type == TYPE_NO_RULES;
56    }
57
58    // Sets |result| with the proxies to use for |url| based on the current
59    // rules.
60    void Apply(const GURL& url, ProxyInfo* result) const;
61
62    // Parses the rules from a string, indicating which proxies to use.
63    //
64    //   proxy-uri = [<proxy-scheme>"://"]<proxy-host>[":"<proxy-port>]
65    //
66    //   proxy-uri-list = <proxy-uri>[","<proxy-uri-list>]
67    //
68    //   url-scheme = "http" | "https" | "ftp" | "socks"
69    //
70    //   scheme-proxies = [<url-scheme>"="]<proxy-uri-list>
71    //
72    //   proxy-rules = scheme-proxies[";"<scheme-proxies>]
73    //
74    // Thus, the proxy-rules string should be a semicolon-separated list of
75    // ordered proxies that apply to a particular URL scheme. Unless specified,
76    // the proxy scheme for proxy-uris is assumed to be http.
77    //
78    // Some special cases:
79    //  * If the scheme is omitted from the first proxy list, that list applies
80    //    to all URL schemes and subsequent lists are ignored.
81    //  * If a scheme is omitted from any proxy list after a list where a scheme
82    //    has been provided, the list without a scheme is ignored.
83    //  * If the url-scheme is set to 'socks', that sets a fallback list that
84    //    to all otherwise unspecified url-schemes, however the default proxy-
85    //    scheme for proxy urls in the 'socks' list is understood to be
86    //    socks4:// if unspecified.
87    //
88    // For example:
89    //   "http=foopy:80;ftp=foopy2"  -- use HTTP proxy "foopy:80" for http://
90    //                                  URLs, and HTTP proxy "foopy2:80" for
91    //                                  ftp:// URLs.
92    //   "foopy:80"                  -- use HTTP proxy "foopy:80" for all URLs.
93    //   "foopy:80,bar,direct://"    -- use HTTP proxy "foopy:80" for all URLs,
94    //                                  failing over to "bar" if "foopy:80" is
95    //                                  unavailable, and after that using no
96    //                                  proxy.
97    //   "socks4://foopy"            -- use SOCKS v4 proxy "foopy:1080" for all
98    //                                  URLs.
99    //   "http=foop,socks5://bar.com -- use HTTP proxy "foopy" for http URLs,
100    //                                  and fail over to the SOCKS5 proxy
101    //                                  "bar.com" if "foop" is unavailable.
102    //   "http=foopy,direct://       -- use HTTP proxy "foopy" for http URLs,
103    //                                  and use no proxy if "foopy" is
104    //                                  unavailable.
105    //   "http=foopy;socks=foopy2   --  use HTTP proxy "foopy" for http URLs,
106    //                                  and use socks4://foopy2 for all other
107    //                                  URLs.
108    void ParseFromString(const std::string& proxy_rules);
109
110    // Returns one of {&proxies_for_http, &proxies_for_https, &proxies_for_ftp,
111    // &fallback_proxies}, or NULL if there is no proxy to use.
112    // Should only call this if the type is TYPE_PROXY_PER_SCHEME.
113    const ProxyList* MapUrlSchemeToProxyList(
114        const std::string& url_scheme) const;
115
116    // Returns true if |*this| describes the same configuration as |other|.
117    bool Equals(const ProxyRules& other) const;
118
119    // Exceptions for when not to use a proxy.
120    ProxyBypassRules bypass_rules;
121
122    // Reverse the meaning of |bypass_rules|.
123    bool reverse_bypass;
124
125    Type type;
126
127    // Set if |type| is TYPE_SINGLE_PROXY.
128    ProxyList single_proxies;
129
130    // Set if |type| is TYPE_PROXY_PER_SCHEME.
131    ProxyList proxies_for_http;
132    ProxyList proxies_for_https;
133    ProxyList proxies_for_ftp;
134
135    // Used when a fallback has been defined and the url to be proxied doesn't
136    // match any of the standard schemes.
137    ProxyList fallback_proxies;
138
139   private:
140    // Returns one of {&proxies_for_http, &proxies_for_https, &proxies_for_ftp}
141    // or NULL if it is a scheme that we don't have a mapping for. Should only
142    // call this if the type is TYPE_PROXY_PER_SCHEME. Intentionally returns
143    // NULL for "ws" and "wss" as those are handled specially by
144    // GetProxyListForWebSocketScheme().
145    ProxyList* MapUrlSchemeToProxyListNoFallback(const std::string& scheme);
146
147    // Returns the first of {&fallback_proxies, &proxies_for_https,
148    // &proxies_for_http} that is non-empty, or NULL.
149    const ProxyList* GetProxyListForWebSocketScheme() const;
150  };
151
152  typedef int ID;
153
154  // Indicates an invalid proxy config.
155  static const ID kInvalidConfigID = 0;
156
157  ProxyConfig();
158  ProxyConfig(const ProxyConfig& config);
159  ~ProxyConfig();
160  ProxyConfig& operator=(const ProxyConfig& config);
161
162  // Used to numerically identify this configuration.
163  ID id() const { return id_; }
164  void set_id(ID id) { id_ = id; }
165  bool is_valid() const { return id_ != kInvalidConfigID; }
166
167  // Returns true if the given config is equivalent to this config.  The
168  // comparison ignores differences in |id()| and |source()|.
169  bool Equals(const ProxyConfig& other) const;
170
171  // Returns true if this config contains any "automatic" settings. See the
172  // class description for what that means.
173  bool HasAutomaticSettings() const;
174
175  void ClearAutomaticSettings();
176
177  // Creates a Value dump of this configuration. The caller is responsible for
178  // deleting the returned value.
179  base::DictionaryValue* ToValue() const;
180
181  ProxyRules& proxy_rules() {
182    return proxy_rules_;
183  }
184
185  const ProxyRules& proxy_rules() const {
186    return proxy_rules_;
187  }
188
189  void set_pac_url(const GURL& url) {
190    pac_url_ = url;
191  }
192
193  const GURL& pac_url() const {
194    return pac_url_;
195  }
196
197  void set_pac_mandatory(bool enable_pac_mandatory) {
198    pac_mandatory_ = enable_pac_mandatory;
199  }
200
201  bool pac_mandatory() const {
202    return pac_mandatory_;
203  }
204
205  bool has_pac_url() const {
206    return pac_url_.is_valid();
207  }
208
209  void set_auto_detect(bool enable_auto_detect) {
210    auto_detect_ = enable_auto_detect;
211  }
212
213  bool auto_detect() const {
214    return auto_detect_;
215  }
216
217  void set_source(ProxyConfigSource source) {
218    source_ = source;
219  }
220
221  ProxyConfigSource source() const {
222    return source_;
223  }
224
225  // Helpers to construct some common proxy configurations.
226
227  static ProxyConfig CreateDirect() {
228    return ProxyConfig();
229  }
230
231  static ProxyConfig CreateAutoDetect() {
232    ProxyConfig config;
233    config.set_auto_detect(true);
234    return config;
235  }
236
237  static ProxyConfig CreateFromCustomPacURL(const GURL& pac_url) {
238    ProxyConfig config;
239    config.set_pac_url(pac_url);
240    // By default fall back to direct connection in case PAC script fails.
241    config.set_pac_mandatory(false);
242    return config;
243  }
244
245 private:
246  // True if the proxy configuration should be auto-detected.
247  bool auto_detect_;
248
249  // If non-empty, indicates the URL of the proxy auto-config file to use.
250  GURL pac_url_;
251
252  // If true, blocks all traffic in case fetching the pac script from |pac_url_|
253  // fails. Only valid if |pac_url_| is non-empty.
254  bool pac_mandatory_;
255
256  // Manual proxy settings.
257  ProxyRules proxy_rules_;
258
259  // Source of proxy settings.
260  ProxyConfigSource source_;
261
262  ID id_;
263};
264
265}  // namespace net
266
267
268
269#endif  // NET_PROXY_PROXY_CONFIG_H_
270