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

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: (Removed blank lines). 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,
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 }
24
25 // Split the |uri_list| on commas and add each entry to |proxy_list| in turn.
26 void AddProxyURIListToProxyList(std::string uri_list,
eroman 2013/03/05 01:55:55 const std::string& (Technically StringPiece would
marq_use_my_chromium_address 2013/03/05 22:52:40 Ack.
27 ProxyList* proxy_list,
28 ProxyServer::Scheme default_scheme) {
29 base::StringTokenizer proxy_uri_list(uri_list, ",");
30 while (proxy_uri_list.GetNext()) {
31 proxy_list->AddProxyServer(
32 ProxyServer::FromURI(proxy_uri_list.token(), default_scheme));
33 }
23 } 34 }
24 35
25 } // namespace 36 } // namespace
26 37
27 ProxyConfig::ProxyRules::ProxyRules() 38 ProxyConfig::ProxyRules::ProxyRules()
28 : reverse_bypass(false), 39 : reverse_bypass(false),
29 type(TYPE_NO_RULES) { 40 type(TYPE_NO_RULES) {
30 } 41 }
31 42
32 ProxyConfig::ProxyRules::~ProxyRules() { 43 ProxyConfig::ProxyRules::~ProxyRules() {
33 } 44 }
34 45
35 void ProxyConfig::ProxyRules::Apply(const GURL& url, ProxyInfo* result) const { 46 void ProxyConfig::ProxyRules::Apply(const GURL& url, ProxyInfo* result) const {
36 if (empty()) { 47 if (empty()) {
37 result->UseDirect(); 48 result->UseDirect();
38 return; 49 return;
39 } 50 }
40 51
41 bool bypass_proxy = bypass_rules.Matches(url); 52 bool bypass_proxy = bypass_rules.Matches(url);
42 if (reverse_bypass) 53 if (reverse_bypass)
43 bypass_proxy = !bypass_proxy; 54 bypass_proxy = !bypass_proxy;
44 if (bypass_proxy) { 55 if (bypass_proxy) {
45 result->UseDirectWithBypassedProxy(); 56 result->UseDirectWithBypassedProxy();
46 return; 57 return;
47 } 58 }
48 59
49 switch (type) { 60 switch (type) {
50 case ProxyRules::TYPE_SINGLE_PROXY: { 61 case ProxyRules::TYPE_SINGLE_PROXY: {
51 result->UseProxyServer(single_proxy); 62 result->UseProxyList(single_proxies);
52 return; 63 return;
53 } 64 }
54 case ProxyRules::TYPE_PROXY_PER_SCHEME: { 65 case ProxyRules::TYPE_PROXY_PER_SCHEME: {
55 const ProxyServer* entry = MapUrlSchemeToProxy(url.scheme()); 66 const ProxyList* entry = MapUrlSchemeToProxyList(url.scheme());
56 if (entry) { 67 if (entry) {
57 result->UseProxyServer(*entry); 68 result->UseProxyList(*entry);
58 } else { 69 } else {
59 // We failed to find a matching proxy server for the current URL 70 // We failed to find a matching proxy server for the current URL
60 // scheme. Default to direct. 71 // scheme. Default to direct.
61 result->UseDirect(); 72 result->UseDirect();
62 } 73 }
63 return; 74 return;
64 } 75 }
65 default: { 76 default: {
66 result->UseDirect(); 77 result->UseDirect();
67 NOTREACHED(); 78 NOTREACHED();
68 return; 79 return;
69 } 80 }
70 } 81 }
71 } 82 }
72 83
73 void ProxyConfig::ProxyRules::ParseFromString(const std::string& proxy_rules) { 84 void ProxyConfig::ProxyRules::ParseFromString(const std::string& proxy_rules) {
74 // Reset. 85 // Reset.
75 type = TYPE_NO_RULES; 86 type = TYPE_NO_RULES;
76 single_proxy = ProxyServer(); 87 single_proxies = ProxyList();
77 proxy_for_http = ProxyServer(); 88 proxies_for_http = ProxyList();
78 proxy_for_https = ProxyServer(); 89 proxies_for_https = ProxyList();
79 proxy_for_ftp = ProxyServer(); 90 proxies_for_ftp = ProxyList();
80 fallback_proxy = ProxyServer(); 91 fallback_proxies = ProxyList();
81 92
82 base::StringTokenizer proxy_server_list(proxy_rules, ";"); 93 base::StringTokenizer proxy_server_list(proxy_rules, ";");
83 while (proxy_server_list.GetNext()) { 94 while (proxy_server_list.GetNext()) {
84 base::StringTokenizer proxy_server_for_scheme( 95 base::StringTokenizer proxy_server_for_scheme(
85 proxy_server_list.token_begin(), proxy_server_list.token_end(), "="); 96 proxy_server_list.token_begin(), proxy_server_list.token_end(), "=");
86 97
87 while (proxy_server_for_scheme.GetNext()) { 98 while (proxy_server_for_scheme.GetNext()) {
88 std::string url_scheme = proxy_server_for_scheme.token(); 99 std::string url_scheme = proxy_server_for_scheme.token();
89 100
90 // If we fail to get the proxy server here, it means that 101 // If we fail to get the proxy server here, it means that
91 // this is a regular proxy server configuration, i.e. proxies 102 // this is a regular proxy server configuration, i.e. proxies
92 // are not configured per protocol. 103 // are not configured per protocol.
93 if (!proxy_server_for_scheme.GetNext()) { 104 if (!proxy_server_for_scheme.GetNext()) {
94 if (type == TYPE_PROXY_PER_SCHEME) 105 if (type == TYPE_PROXY_PER_SCHEME)
95 continue; // Unexpected. 106 continue; // Unexpected.
96 single_proxy = ProxyServer::FromURI(url_scheme, 107 AddProxyURIListToProxyList(url_scheme,
97 ProxyServer::SCHEME_HTTP); 108 &single_proxies,
109 ProxyServer::SCHEME_HTTP);
98 type = TYPE_SINGLE_PROXY; 110 type = TYPE_SINGLE_PROXY;
99 return; 111 return;
100 } 112 }
101 113
102 // Trim whitespace off the url scheme. 114 // Trim whitespace off the url scheme.
103 TrimWhitespaceASCII(url_scheme, TRIM_ALL, &url_scheme); 115 TrimWhitespaceASCII(url_scheme, TRIM_ALL, &url_scheme);
104 116
105 // Add it to the per-scheme mappings (if supported scheme). 117 // Add it to the per-scheme mappings (if supported scheme).
106 type = TYPE_PROXY_PER_SCHEME; 118 type = TYPE_PROXY_PER_SCHEME;
107 ProxyServer* entry = MapUrlSchemeToProxyNoFallback(url_scheme); 119 ProxyList* entry = MapUrlSchemeToProxyListNoFallback(url_scheme);
108 ProxyServer::Scheme default_scheme = ProxyServer::SCHEME_HTTP; 120 ProxyServer::Scheme default_scheme = ProxyServer::SCHEME_HTTP;
109 121
110 // socks=XXX is inconsistent with the other formats, since "socks" 122 // socks=XXX is inconsistent with the other formats, since "socks"
111 // is not a URL scheme. Rather this means "for everything else, send 123 // is not a URL scheme. Rather this means "for everything else, send
112 // it to the SOCKS proxy server XXX". 124 // it to the SOCKS proxy server XXX".
113 if (url_scheme == "socks") { 125 if (url_scheme == "socks") {
114 DCHECK(!entry); 126 DCHECK(!entry);
115 entry = &fallback_proxy; 127 entry = &fallback_proxies;
128 // Note that here 'socks' is understood to be SOCKS4, even though
129 // 'socks' maps to SOCKS5 in ProxyServer::GetSchemeFromURIInternal.
116 default_scheme = ProxyServer::SCHEME_SOCKS4; 130 default_scheme = ProxyServer::SCHEME_SOCKS4;
117 } 131 }
118 132
119 if (entry) { 133 if (entry) {
120 *entry = ProxyServer::FromURI(proxy_server_for_scheme.token(), 134 AddProxyURIListToProxyList(proxy_server_for_scheme.token(),
121 default_scheme); 135 entry,
136 default_scheme);
122 } 137 }
123 } 138 }
124 } 139 }
125 } 140 }
126 141
127 const ProxyServer* ProxyConfig::ProxyRules::MapUrlSchemeToProxy( 142 const ProxyList* ProxyConfig::ProxyRules::MapUrlSchemeToProxyList(
128 const std::string& url_scheme) const { 143 const std::string& url_scheme) const {
129 const ProxyServer* proxy_server = 144 const ProxyList* proxy_server_list = const_cast<ProxyRules*>(this)->
130 const_cast<ProxyRules*>(this)->MapUrlSchemeToProxyNoFallback(url_scheme); 145 MapUrlSchemeToProxyListNoFallback(url_scheme);
131 if (proxy_server && proxy_server->is_valid()) 146 if (proxy_server_list && !proxy_server_list->IsEmpty())
132 return proxy_server; 147 return proxy_server_list;
133 if (fallback_proxy.is_valid()) 148 if (!fallback_proxies.IsEmpty())
134 return &fallback_proxy; 149 return &fallback_proxies;
135 return NULL; // No mapping for this scheme. Use direct. 150 return NULL; // No mapping for this scheme. Use direct.
136 } 151 }
137 152
138 bool ProxyConfig::ProxyRules::Equals(const ProxyRules& other) const { 153 bool ProxyConfig::ProxyRules::Equals(const ProxyRules& other) const {
139 return type == other.type && 154 return type == other.type &&
140 single_proxy == other.single_proxy && 155 single_proxies.Equals(other.single_proxies) &&
141 proxy_for_http == other.proxy_for_http && 156 proxies_for_http.Equals(other.proxies_for_http) &&
142 proxy_for_https == other.proxy_for_https && 157 proxies_for_https.Equals(other.proxies_for_https) &&
143 proxy_for_ftp == other.proxy_for_ftp && 158 proxies_for_ftp.Equals(other.proxies_for_ftp) &&
144 fallback_proxy == other.fallback_proxy &&
145 bypass_rules.Equals(other.bypass_rules) && 159 bypass_rules.Equals(other.bypass_rules) &&
146 reverse_bypass == other.reverse_bypass; 160 reverse_bypass == other.reverse_bypass;
147 } 161 }
148 162
149 ProxyServer* ProxyConfig::ProxyRules::MapUrlSchemeToProxyNoFallback( 163 ProxyList* ProxyConfig::ProxyRules::MapUrlSchemeToProxyListNoFallback(
150 const std::string& scheme) { 164 const std::string& scheme) {
151 DCHECK_EQ(TYPE_PROXY_PER_SCHEME, type); 165 DCHECK_EQ(TYPE_PROXY_PER_SCHEME, type);
152 if (scheme == "http") 166 if (scheme == "http")
153 return &proxy_for_http; 167 return &proxies_for_http;
154 if (scheme == "https") 168 if (scheme == "https")
155 return &proxy_for_https; 169 return &proxies_for_https;
156 if (scheme == "ftp") 170 if (scheme == "ftp")
157 return &proxy_for_ftp; 171 return &proxies_for_ftp;
158 return NULL; // No mapping for this scheme. 172 return NULL; // No mapping for this scheme.
159 } 173 }
160 174
161 ProxyConfig::ProxyConfig() 175 ProxyConfig::ProxyConfig()
162 : auto_detect_(false), pac_mandatory_(false), 176 : auto_detect_(false), pac_mandatory_(false),
163 source_(PROXY_CONFIG_SOURCE_UNKNOWN), id_(kInvalidConfigID) { 177 source_(PROXY_CONFIG_SOURCE_UNKNOWN), id_(kInvalidConfigID) {
164 } 178 }
165 179
166 ProxyConfig::ProxyConfig(const ProxyConfig& config) 180 ProxyConfig::ProxyConfig(const ProxyConfig& config)
167 : auto_detect_(config.auto_detect_), 181 : auto_detect_(config.auto_detect_),
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
212 if (has_pac_url()) { 226 if (has_pac_url()) {
213 dict->SetString("pac_url", pac_url_.possibly_invalid_spec()); 227 dict->SetString("pac_url", pac_url_.possibly_invalid_spec());
214 if (pac_mandatory_) 228 if (pac_mandatory_)
215 dict->SetBoolean("pac_mandatory", pac_mandatory_); 229 dict->SetBoolean("pac_mandatory", pac_mandatory_);
216 } 230 }
217 231
218 // Output the manual settings. 232 // Output the manual settings.
219 if (proxy_rules_.type != ProxyRules::TYPE_NO_RULES) { 233 if (proxy_rules_.type != ProxyRules::TYPE_NO_RULES) {
220 switch (proxy_rules_.type) { 234 switch (proxy_rules_.type) {
221 case ProxyRules::TYPE_SINGLE_PROXY: 235 case ProxyRules::TYPE_SINGLE_PROXY:
222 AddProxyToValue("single_proxy", proxy_rules_.single_proxy, dict); 236 AddProxyListToValue("single_proxies",
237 proxy_rules_.single_proxies, dict);
223 break; 238 break;
224 case ProxyRules::TYPE_PROXY_PER_SCHEME: { 239 case ProxyRules::TYPE_PROXY_PER_SCHEME: {
225 base::DictionaryValue* dict2 = new base::DictionaryValue(); 240 base::DictionaryValue* dict2 = new base::DictionaryValue();
226 AddProxyToValue("http", proxy_rules_.proxy_for_http, dict2); 241 AddProxyListToValue("http", proxy_rules_.proxies_for_http, dict2);
227 AddProxyToValue("https", proxy_rules_.proxy_for_https, dict2); 242 AddProxyListToValue("https", proxy_rules_.proxies_for_https, dict2);
228 AddProxyToValue("ftp", proxy_rules_.proxy_for_ftp, dict2); 243 AddProxyListToValue("ftp", proxy_rules_.proxies_for_ftp, dict2);
229 AddProxyToValue("fallback", proxy_rules_.fallback_proxy, dict2); 244 AddProxyListToValue("fallback", proxy_rules_.fallback_proxies, dict2);
230 dict->Set("proxy_per_scheme", dict2); 245 dict->Set("proxy_per_scheme", dict2);
231 break; 246 break;
232 } 247 }
233 default: 248 default:
234 NOTREACHED(); 249 NOTREACHED();
235 } 250 }
236 251
237 // Output the bypass rules. 252 // Output the bypass rules.
238 const ProxyBypassRules& bypass = proxy_rules_.bypass_rules; 253 const ProxyBypassRules& bypass = proxy_rules_.bypass_rules;
239 if (!bypass.rules().empty()) { 254 if (!bypass.rules().empty()) {
(...skipping 12 matching lines...) Expand all
252 } 267 }
253 } 268 }
254 269
255 // Output the source. 270 // Output the source.
256 dict->SetString("source", ProxyConfigSourceToString(source_)); 271 dict->SetString("source", ProxyConfigSourceToString(source_));
257 272
258 return dict; 273 return dict;
259 } 274 }
260 275
261 } // namespace net 276 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698