Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(62)

Side by Side Diff: net/proxy/proxy_config.cc

Issue 12315019: Change ProxyRules to handle ProxyLists rather than just single ProxyServer instances. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "net/proxy/proxy_config.h" 5 #include "net/proxy/proxy_config.h"
6 6
7 #include "base/logging.h" 7 #include "base/logging.h"
8 #include "base/string_util.h" 8 #include "base/string_util.h"
9 #include "base/strings/string_tokenizer.h" 9 #include "base/strings/string_tokenizer.h"
10 #include "base/values.h" 10 #include "base/values.h"
11 #include "net/proxy/proxy_info.h" 11 #include "net/proxy/proxy_info.h"
12 12
13 namespace net { 13 namespace net {
14 14
15 namespace { 15 namespace {
16 16
17 // If |proxy| is valid, sets it in |dict| under the key |name|. 17 // If |proxies| is non-empty, sets it in |dict| under the key |name|.
18 void AddProxyToValue(const char* name, 18 void AddProxyListToValue(const char* name,
19 const ProxyServer& proxy, 19 const ProxyList& proxies,
eroman 2013/03/01 00:05:13 fix indentation.
marq_use_my_chromium_address 2013/03/04 18:04:20 Done.
20 base::DictionaryValue* dict) { 20 base::DictionaryValue* dict) {
21 if (proxy.is_valid()) 21 if (!proxies.IsEmpty())
22 dict->SetString(name, proxy.ToURI()); 22 dict->SetString(name, proxies.ToPacString());
23 } 23 }
24 24
25 } // namespace 25 } // namespace
26 26
27 ProxyConfig::ProxyRules::ProxyRules() 27 ProxyConfig::ProxyRules::ProxyRules()
28 : reverse_bypass(false), 28 : reverse_bypass(false),
29 type(TYPE_NO_RULES) { 29 type(TYPE_NO_RULES) {
30 } 30 }
31 31
32 ProxyConfig::ProxyRules::~ProxyRules() { 32 ProxyConfig::ProxyRules::~ProxyRules() {
33 } 33 }
34 34
35 void ProxyConfig::ProxyRules::Apply(const GURL& url, ProxyInfo* result) const { 35 void ProxyConfig::ProxyRules::Apply(const GURL& url, ProxyInfo* result) const {
36 if (empty()) { 36 if (empty()) {
37 result->UseDirect(); 37 result->UseDirect();
38 return; 38 return;
39 } 39 }
40 40
41 bool bypass_proxy = bypass_rules.Matches(url); 41 bool bypass_proxy = bypass_rules.Matches(url);
42 if (reverse_bypass) 42 if (reverse_bypass)
43 bypass_proxy = !bypass_proxy; 43 bypass_proxy = !bypass_proxy;
44 if (bypass_proxy) { 44 if (bypass_proxy) {
45 result->UseDirectWithBypassedProxy(); 45 result->UseDirectWithBypassedProxy();
46 return; 46 return;
47 } 47 }
48 48
49 switch (type) { 49 switch (type) {
50 case ProxyRules::TYPE_SINGLE_PROXY: { 50 case ProxyRules::TYPE_SINGLE_PROXY: {
51 result->UseProxyServer(single_proxy); 51 result->UseProxyList(single_proxies);
52 return; 52 return;
53 } 53 }
54 case ProxyRules::TYPE_PROXY_PER_SCHEME: { 54 case ProxyRules::TYPE_PROXY_PER_SCHEME: {
55 const ProxyServer* entry = MapUrlSchemeToProxy(url.scheme()); 55 const ProxyList* entry = MapUrlSchemeToProxy(url.scheme());
56 if (entry) { 56 if (entry) {
57 result->UseProxyServer(*entry); 57 result->UseProxyList(*entry);
58 } else { 58 } else {
59 // We failed to find a matching proxy server for the current URL 59 // We failed to find a matching proxy server for the current URL
60 // scheme. Default to direct. 60 // scheme. Default to direct.
61 result->UseDirect(); 61 result->UseDirect();
62 } 62 }
63 return; 63 return;
64 } 64 }
65 default: { 65 default: {
66 result->UseDirect(); 66 result->UseDirect();
67 NOTREACHED(); 67 NOTREACHED();
68 return; 68 return;
69 } 69 }
70 } 70 }
71 } 71 }
72 72
73 void ProxyConfig::ProxyRules::ParseFromString(const std::string& proxy_rules) { 73 void ProxyConfig::ProxyRules::ParseFromString(const std::string& proxy_rules) {
74 // Reset. 74 // Reset.
75 type = TYPE_NO_RULES; 75 type = TYPE_NO_RULES;
76 single_proxy = ProxyServer(); 76 single_proxies = ProxyList();
77 proxy_for_http = ProxyServer(); 77 proxies_for_http = ProxyList();
78 proxy_for_https = ProxyServer(); 78 proxies_for_https = ProxyList();
79 proxy_for_ftp = ProxyServer(); 79 proxies_for_ftp = ProxyList();
80 fallback_proxy = ProxyServer(); 80 fallback_proxies = ProxyList();
81 81
82 base::StringTokenizer proxy_server_list(proxy_rules, ";"); 82 base::StringTokenizer proxy_server_list(proxy_rules, ";");
83 while (proxy_server_list.GetNext()) { 83 while (proxy_server_list.GetNext()) {
84 base::StringTokenizer proxy_server_for_scheme( 84 base::StringTokenizer proxy_server_for_scheme(
85 proxy_server_list.token_begin(), proxy_server_list.token_end(), "="); 85 proxy_server_list.token_begin(), proxy_server_list.token_end(), "=");
86 86
87 while (proxy_server_for_scheme.GetNext()) { 87 while (proxy_server_for_scheme.GetNext()) {
88 std::string url_scheme = proxy_server_for_scheme.token(); 88 std::string url_scheme = proxy_server_for_scheme.token();
89 89
90
eroman 2013/03/01 00:05:13 Remove this extra line
marq_use_my_chromium_address 2013/03/04 18:04:20 Done.
90 // If we fail to get the proxy server here, it means that 91 // If we fail to get the proxy server here, it means that
91 // this is a regular proxy server configuration, i.e. proxies 92 // this is a regular proxy server configuration, i.e. proxies
92 // are not configured per protocol. 93 // are not configured per protocol.
93 if (!proxy_server_for_scheme.GetNext()) { 94 if (!proxy_server_for_scheme.GetNext()) {
94 if (type == TYPE_PROXY_PER_SCHEME) 95 if (type == TYPE_PROXY_PER_SCHEME)
95 continue; // Unexpected. 96 continue; // Unexpected.
96 single_proxy = ProxyServer::FromURI(url_scheme, 97 single_proxies.SetSingleProxyServer(
eroman 2013/03/01 00:05:13 This should support comma separated list like the
marq_use_my_chromium_address 2013/03/04 18:04:20 Done.
97 ProxyServer::SCHEME_HTTP); 98 ProxyServer::FromURI(url_scheme, ProxyServer::SCHEME_HTTP));
98 type = TYPE_SINGLE_PROXY; 99 type = TYPE_SINGLE_PROXY;
99 return; 100 return;
100 } 101 }
101 102
102 // Trim whitespace off the url scheme. 103 // Trim whitespace off the url scheme.
103 TrimWhitespaceASCII(url_scheme, TRIM_ALL, &url_scheme); 104 TrimWhitespaceASCII(url_scheme, TRIM_ALL, &url_scheme);
104 105
105 // Add it to the per-scheme mappings (if supported scheme). 106 // Add it to the per-scheme mappings (if supported scheme).
106 type = TYPE_PROXY_PER_SCHEME; 107 type = TYPE_PROXY_PER_SCHEME;
107 ProxyServer* entry = MapUrlSchemeToProxyNoFallback(url_scheme); 108 ProxyList* entry = MapUrlSchemeToProxyNoFallback(url_scheme);
108 ProxyServer::Scheme default_scheme = ProxyServer::SCHEME_HTTP; 109 ProxyServer::Scheme default_scheme = ProxyServer::SCHEME_HTTP;
109 110
110 // socks=XXX is inconsistent with the other formats, since "socks" 111 // socks=XXX is inconsistent with the other formats, since "socks"
111 // is not a URL scheme. Rather this means "for everything else, send 112 // is not a URL scheme. Rather this means "for everything else, send
112 // it to the SOCKS proxy server XXX". 113 // it to the SOCKS proxy server XXX".
113 if (url_scheme == "socks") { 114 if (url_scheme == "socks") {
114 DCHECK(!entry); 115 DCHECK(!entry);
115 entry = &fallback_proxy; 116 entry = &fallback_proxies;
117 // Note that here 'socks' is understood to be SOCKS4, even though
118 // 'socks' maps to SOCKS5 in ProxyServer::GetSchemeFromURIInternal.
116 default_scheme = ProxyServer::SCHEME_SOCKS4; 119 default_scheme = ProxyServer::SCHEME_SOCKS4;
117 } 120 }
118 121
119 if (entry) { 122 if (entry) {
120 *entry = ProxyServer::FromURI(proxy_server_for_scheme.token(), 123 // Add each entry from the uri list in turn
eroman 2013/03/01 00:05:13 See comment above -- I believe this should be extr
marq_use_my_chromium_address 2013/03/04 18:04:20 Done.
121 default_scheme); 124 base::StringTokenizer proxy_uri_list(
125 proxy_server_for_scheme.token(), ",");
126 while (proxy_uri_list.GetNext()) {
127 std::string proxy_uri = proxy_uri_list.token();
128 entry->AddProxyServer(
129 ProxyServer::FromURI(proxy_uri, default_scheme));
130 }
122 } 131 }
123 } 132 }
124 } 133 }
125 } 134 }
126 135
127 const ProxyServer* ProxyConfig::ProxyRules::MapUrlSchemeToProxy( 136 const ProxyList* ProxyConfig::ProxyRules::MapUrlSchemeToProxy(
128 const std::string& url_scheme) const { 137 const std::string& url_scheme) const {
129 const ProxyServer* proxy_server = 138 const ProxyList* proxy_server_list =
130 const_cast<ProxyRules*>(this)->MapUrlSchemeToProxyNoFallback(url_scheme); 139 const_cast<ProxyRules*>(this)->MapUrlSchemeToProxyNoFallback(url_scheme);
131 if (proxy_server && proxy_server->is_valid()) 140 if (proxy_server_list && !proxy_server_list->IsEmpty())
132 return proxy_server; 141 return proxy_server_list;
133 if (fallback_proxy.is_valid()) 142 if (!fallback_proxies.IsEmpty())
134 return &fallback_proxy; 143 return &fallback_proxies;
135 return NULL; // No mapping for this scheme. Use direct. 144 return NULL; // No mapping for this scheme. Use direct.
136 } 145 }
137 146
138 bool ProxyConfig::ProxyRules::Equals(const ProxyRules& other) const { 147 bool ProxyConfig::ProxyRules::Equals(const ProxyRules& other) const {
139 return type == other.type && 148 return type == other.type &&
140 single_proxy == other.single_proxy && 149 single_proxies.Equals(other.single_proxies) &&
141 proxy_for_http == other.proxy_for_http && 150 proxies_for_http.Equals(other.proxies_for_http) &&
142 proxy_for_https == other.proxy_for_https && 151 proxies_for_https.Equals(other.proxies_for_https) &&
143 proxy_for_ftp == other.proxy_for_ftp && 152 proxies_for_ftp.Equals(other.proxies_for_ftp) &&
144 fallback_proxy == other.fallback_proxy &&
145 bypass_rules.Equals(other.bypass_rules) && 153 bypass_rules.Equals(other.bypass_rules) &&
146 reverse_bypass == other.reverse_bypass; 154 reverse_bypass == other.reverse_bypass;
147 } 155 }
148 156
149 ProxyServer* ProxyConfig::ProxyRules::MapUrlSchemeToProxyNoFallback( 157 ProxyList* ProxyConfig::ProxyRules::MapUrlSchemeToProxyNoFallback(
150 const std::string& scheme) { 158 const std::string& scheme) {
151 DCHECK_EQ(TYPE_PROXY_PER_SCHEME, type); 159 DCHECK_EQ(TYPE_PROXY_PER_SCHEME, type);
152 if (scheme == "http") 160 if (scheme == "http")
153 return &proxy_for_http; 161 return &proxies_for_http;
154 if (scheme == "https") 162 if (scheme == "https")
155 return &proxy_for_https; 163 return &proxies_for_https;
156 if (scheme == "ftp") 164 if (scheme == "ftp")
157 return &proxy_for_ftp; 165 return &proxies_for_ftp;
158 return NULL; // No mapping for this scheme. 166 return NULL; // No mapping for this scheme.
159 } 167 }
160 168
161 ProxyConfig::ProxyConfig() 169 ProxyConfig::ProxyConfig()
162 : auto_detect_(false), pac_mandatory_(false), 170 : auto_detect_(false), pac_mandatory_(false),
163 source_(PROXY_CONFIG_SOURCE_UNKNOWN), id_(kInvalidConfigID) { 171 source_(PROXY_CONFIG_SOURCE_UNKNOWN), id_(kInvalidConfigID) {
164 } 172 }
165 173
166 ProxyConfig::ProxyConfig(const ProxyConfig& config) 174 ProxyConfig::ProxyConfig(const ProxyConfig& config)
167 : auto_detect_(config.auto_detect_), 175 : auto_detect_(config.auto_detect_),
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
212 if (has_pac_url()) { 220 if (has_pac_url()) {
213 dict->SetString("pac_url", pac_url_.possibly_invalid_spec()); 221 dict->SetString("pac_url", pac_url_.possibly_invalid_spec());
214 if (pac_mandatory_) 222 if (pac_mandatory_)
215 dict->SetBoolean("pac_mandatory", pac_mandatory_); 223 dict->SetBoolean("pac_mandatory", pac_mandatory_);
216 } 224 }
217 225
218 // Output the manual settings. 226 // Output the manual settings.
219 if (proxy_rules_.type != ProxyRules::TYPE_NO_RULES) { 227 if (proxy_rules_.type != ProxyRules::TYPE_NO_RULES) {
220 switch (proxy_rules_.type) { 228 switch (proxy_rules_.type) {
221 case ProxyRules::TYPE_SINGLE_PROXY: 229 case ProxyRules::TYPE_SINGLE_PROXY:
222 AddProxyToValue("single_proxy", proxy_rules_.single_proxy, dict); 230 AddProxyListToValue("single_proxies",
231 proxy_rules_.single_proxies, dict);
223 break; 232 break;
224 case ProxyRules::TYPE_PROXY_PER_SCHEME: { 233 case ProxyRules::TYPE_PROXY_PER_SCHEME: {
225 base::DictionaryValue* dict2 = new base::DictionaryValue(); 234 base::DictionaryValue* dict2 = new base::DictionaryValue();
226 AddProxyToValue("http", proxy_rules_.proxy_for_http, dict2); 235 AddProxyListToValue("http", proxy_rules_.proxies_for_http, dict2);
227 AddProxyToValue("https", proxy_rules_.proxy_for_https, dict2); 236 AddProxyListToValue("https", proxy_rules_.proxies_for_https, dict2);
228 AddProxyToValue("ftp", proxy_rules_.proxy_for_ftp, dict2); 237 AddProxyListToValue("ftp", proxy_rules_.proxies_for_ftp, dict2);
229 AddProxyToValue("fallback", proxy_rules_.fallback_proxy, dict2); 238 AddProxyListToValue("fallback", proxy_rules_.fallback_proxies, dict2);
230 dict->Set("proxy_per_scheme", dict2); 239 dict->Set("proxy_per_scheme", dict2);
231 break; 240 break;
232 } 241 }
233 default: 242 default:
234 NOTREACHED(); 243 NOTREACHED();
235 } 244 }
236 245
237 // Output the bypass rules. 246 // Output the bypass rules.
238 const ProxyBypassRules& bypass = proxy_rules_.bypass_rules; 247 const ProxyBypassRules& bypass = proxy_rules_.bypass_rules;
239 if (!bypass.rules().empty()) { 248 if (!bypass.rules().empty()) {
(...skipping 12 matching lines...) Expand all
252 } 261 }
253 } 262 }
254 263
255 // Output the source. 264 // Output the source.
256 dict->SetString("source", ProxyConfigSourceToString(source_)); 265 dict->SetString("source", ProxyConfigSourceToString(source_));
257 266
258 return dict; 267 return dict;
259 } 268 }
260 269
261 } // namespace net 270 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698