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

Side by Side Diff: chrome/browser/extensions/extension_proxy_api.cc

Issue 6469030: Support bypassList in Proxy Settings API. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Addressed comments Created 9 years, 10 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 | Annotate | Revision Log
« no previous file with comments | « no previous file | chrome/browser/extensions/extension_proxy_apitest.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. 1 // Copyright (c) 2011 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 "chrome/browser/extensions/extension_proxy_api.h" 5 #include "chrome/browser/extensions/extension_proxy_api.h"
6 6
7 #include "base/string_util.h" 7 #include "base/string_util.h"
8 #include "base/string_tokenizer.h"
8 #include "base/values.h" 9 #include "base/values.h"
9 #include "chrome/browser/prefs/proxy_config_dictionary.h" 10 #include "chrome/browser/prefs/proxy_config_dictionary.h"
10 #include "chrome/browser/profiles/profile.h" 11 #include "chrome/browser/profiles/profile.h"
11 #include "chrome/browser/extensions/extension_service.h" 12 #include "chrome/browser/extensions/extension_service.h"
12 #include "chrome/common/pref_names.h" 13 #include "chrome/common/pref_names.h"
13 #include "net/proxy/proxy_config.h" 14 #include "net/proxy/proxy_config.h"
14 15
15 namespace { 16 namespace {
16 17
17 // The scheme for which to use a manually specified proxy, not of the proxy URI 18 // The scheme for which to use a manually specified proxy, not of the proxy URI
(...skipping 24 matching lines...) Expand all
42 "ftp", 43 "ftp",
43 "socks" }; 44 "socks" };
44 45
45 // String literals in dictionaries used to communicate with extension. 46 // String literals in dictionaries used to communicate with extension.
46 const char kProxyCfgMode[] = "mode"; 47 const char kProxyCfgMode[] = "mode";
47 const char kProxyCfgPacScript[] = "pacScript"; 48 const char kProxyCfgPacScript[] = "pacScript";
48 const char kProxyCfgPacScriptUrl[] = "url"; 49 const char kProxyCfgPacScriptUrl[] = "url";
49 const char kProxyCfgRules[] = "rules"; 50 const char kProxyCfgRules[] = "rules";
50 const char kProxyCfgRuleHost[] = "host"; 51 const char kProxyCfgRuleHost[] = "host";
51 const char kProxyCfgRulePort[] = "port"; 52 const char kProxyCfgRulePort[] = "port";
53 const char kProxyCfgBypassList[] = "bypassList";
52 const char kProxyCfgScheme[] = "scheme"; 54 const char kProxyCfgScheme[] = "scheme";
53 55
54 COMPILE_ASSERT(SCHEME_MAX == SCHEME_SOCKS, SCHEME_MAX_must_equal_SCHEME_SOCKS); 56 COMPILE_ASSERT(SCHEME_MAX == SCHEME_SOCKS, SCHEME_MAX_must_equal_SCHEME_SOCKS);
55 COMPILE_ASSERT(arraysize(field_name) == SCHEME_MAX + 1, 57 COMPILE_ASSERT(arraysize(field_name) == SCHEME_MAX + 1,
56 field_name_array_is_wrong_size); 58 field_name_array_is_wrong_size);
57 COMPILE_ASSERT(arraysize(scheme_name) == SCHEME_MAX + 1, 59 COMPILE_ASSERT(arraysize(scheme_name) == SCHEME_MAX + 1,
58 scheme_name_array_is_wrong_size); 60 scheme_name_array_is_wrong_size);
59 COMPILE_ASSERT(SCHEME_ALL == 0, singleProxy_must_be_first_option); 61 COMPILE_ASSERT(SCHEME_ALL == 0, singleProxy_must_be_first_option);
60 62
63 bool TokenizeToStringList(
64 const std::string& in, const std::string& delims, ListValue** out) {
65 scoped_ptr<ListValue> result(new ListValue);
66 StringTokenizer entries(in, delims);
67 while (entries.GetNext()) {
68 result->Append(Value::CreateStringValue(entries.token()));
69 }
70 *out = result.release();
71 return true;
72 }
73
74 bool JoinStringList(
75 ListValue* list, const std::string& joiner, std::string* out) {
76 std::string result;
77 for (size_t i = 0; i < list->GetSize(); ++i) {
78 if (!result.empty())
79 result.append(joiner);
80 // TODO(battre): handle UTF-8 (http://crbug.com/72692)
81 string16 entry;
82 if (!list->GetString(i, &entry))
83 return false;
84 if (!IsStringASCII(entry))
85 return false;
86 result.append(UTF16ToASCII(entry));
87 }
88 *out = result;
89 return true;
90 }
91
61 // Converts a proxy server description |dict| as passed by the API caller 92 // Converts a proxy server description |dict| as passed by the API caller
62 // (e.g. for the http proxy in the rules element) and converts it to a 93 // (e.g. for the http proxy in the rules element) and converts it to a
63 // ProxyServer. Returns true if successful. 94 // ProxyServer. Returns true if successful.
64 bool GetProxyServer(const DictionaryValue* dict, 95 bool GetProxyServer(const DictionaryValue* dict,
65 net::ProxyServer::Scheme default_scheme, 96 net::ProxyServer::Scheme default_scheme,
66 net::ProxyServer* proxy_server) { 97 net::ProxyServer* proxy_server) {
67 std::string scheme_string; // optional. 98 std::string scheme_string; // optional.
68 dict->GetString(kProxyCfgScheme, &scheme_string); 99 // We can safely assume that this is ASCII due to the allowed enumeration
100 // values specified in extension_api.json.
101 dict->GetStringASCII(kProxyCfgScheme, &scheme_string);
69 102
70 net::ProxyServer::Scheme scheme = 103 net::ProxyServer::Scheme scheme =
71 net::ProxyServer::GetSchemeFromURI(scheme_string); 104 net::ProxyServer::GetSchemeFromURI(scheme_string);
72 if (scheme == net::ProxyServer::SCHEME_INVALID) 105 if (scheme == net::ProxyServer::SCHEME_INVALID)
73 scheme = default_scheme; 106 scheme = default_scheme;
74 107
75 std::string host; 108 // TODO(battre): handle UTF-8 in hostnames (http://crbug.com/72692)
76 if (!dict->GetString(kProxyCfgRuleHost, &host)) 109 string16 host16;
110 if (!dict->GetString(kProxyCfgRuleHost, &host16))
77 return false; 111 return false;
112 if (!IsStringASCII(host16))
113 return false;
114 std::string host = UTF16ToASCII(host16);
78 115
79 int port; // optional. 116 int port; // optional.
80 if (!dict->GetInteger(kProxyCfgRulePort, &port)) 117 if (!dict->GetInteger(kProxyCfgRulePort, &port))
81 port = net::ProxyServer::GetDefaultPortForScheme(scheme); 118 port = net::ProxyServer::GetDefaultPortForScheme(scheme);
82 119
83 *proxy_server = net::ProxyServer(scheme, net::HostPortPair(host, port)); 120 *proxy_server = net::ProxyServer(scheme, net::HostPortPair(host, port));
84 121
85 return true; 122 return true;
86 } 123 }
87 124
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
139 proxy_pref.append(scheme_name[i]); 176 proxy_pref.append(scheme_name[i]);
140 proxy_pref.append("="); 177 proxy_pref.append("=");
141 proxy_pref.append(proxy_server[i].ToURI()); 178 proxy_pref.append(proxy_server[i].ToURI());
142 } 179 }
143 } 180 }
144 181
145 *out = proxy_pref; 182 *out = proxy_pref;
146 return true; 183 return true;
147 } 184 }
148 185
186 // Creates a string of the "bypassList" entries of a ProxyRules object (see API
187 // documentation) by joining the elements with commas.
188 // Returns true if successful (i.e. string could be delivered or no "bypassList"
189 // exists in the |proxy_rules|).
190 bool GetBypassList(DictionaryValue* proxy_rules, std::string* out) {
191 if (!proxy_rules)
192 return false;
193
194 ListValue* bypass_list;
195 if (!proxy_rules->HasKey(kProxyCfgBypassList)) {
196 *out = "";
197 return true;
198 }
199 if (!proxy_rules->GetList(kProxyCfgBypassList, &bypass_list))
200 return false;
201
202 return JoinStringList(bypass_list, ",", out);
203 }
204
149 } // namespace 205 } // namespace
150 206
151 void ProxySettingsFunction::ApplyPreference(const char* pref_path, 207 void ProxySettingsFunction::ApplyPreference(const char* pref_path,
152 Value* pref_value, 208 Value* pref_value,
153 bool incognito) { 209 bool incognito) {
154 Profile* use_profile = profile(); 210 Profile* use_profile = profile();
155 if (use_profile->IsOffTheRecord()) 211 if (use_profile->IsOffTheRecord())
156 use_profile = use_profile->GetOriginalProfile(); 212 use_profile = use_profile->GetOriginalProfile();
157 213
158 use_profile->GetExtensionService()->extension_prefs()-> 214 use_profile->GetExtensionService()->extension_prefs()->
(...skipping 14 matching lines...) Expand all
173 bool UseCustomProxySettingsFunction::RunImpl() { 229 bool UseCustomProxySettingsFunction::RunImpl() {
174 DictionaryValue* proxy_config; 230 DictionaryValue* proxy_config;
175 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &proxy_config)); 231 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &proxy_config));
176 232
177 bool incognito = false; // Optional argument, defaults to false. 233 bool incognito = false; // Optional argument, defaults to false.
178 if (HasOptionalArgument(1)) { 234 if (HasOptionalArgument(1)) {
179 EXTENSION_FUNCTION_VALIDATE(args_->GetBoolean(1, &incognito)); 235 EXTENSION_FUNCTION_VALIDATE(args_->GetBoolean(1, &incognito));
180 } 236 }
181 237
182 std::string proxy_mode; 238 std::string proxy_mode;
183 proxy_config->GetString(kProxyCfgMode, &proxy_mode); 239 // We can safely assume that this is ASCII due to the allowed enumeration
240 // values specified in extension_api.json.
241 proxy_config->GetStringASCII(kProxyCfgMode, &proxy_mode);
184 ProxyPrefs::ProxyMode mode_enum; 242 ProxyPrefs::ProxyMode mode_enum;
185 if (!ProxyPrefs::StringToProxyMode(proxy_mode, &mode_enum)) { 243 if (!ProxyPrefs::StringToProxyMode(proxy_mode, &mode_enum)) {
186 LOG(ERROR) << "Invalid mode for proxy settings: " << proxy_mode << ". " 244 LOG(ERROR) << "Invalid mode for proxy settings: " << proxy_mode << ". "
187 << "Setting custom proxy settings failed."; 245 << "Setting custom proxy settings failed.";
188 return false; 246 return false;
189 } 247 }
190 248
191 DictionaryValue* pac_dict = NULL; 249 DictionaryValue* pac_dict = NULL;
192 proxy_config->GetDictionary(kProxyCfgPacScript, &pac_dict); 250 proxy_config->GetDictionary(kProxyCfgPacScript, &pac_dict);
193 std::string pac_url; 251 // TODO(battre): Handle UTF-8 URLs (http://crbug.com/72692)
194 if (pac_dict && !pac_dict->GetString(kProxyCfgPacScriptUrl, &pac_url)) { 252 string16 pac_url16;
253 if (pac_dict && !pac_dict->GetString(kProxyCfgPacScriptUrl, &pac_url16)) {
195 LOG(ERROR) << "'pacScript' requires a 'url' field. " 254 LOG(ERROR) << "'pacScript' requires a 'url' field. "
196 << "Setting custom proxy settings failed."; 255 << "Setting custom proxy settings failed.";
197 return false; 256 return false;
198 } 257 }
258 if (!IsStringASCII(pac_url16)) {
259 LOG(ERROR) << "Only ASCII URLs are supported, yet";
260 return false;
261 }
262 std::string pac_url = UTF16ToASCII(pac_url16);
199 263
200 DictionaryValue* proxy_rules = NULL; 264 DictionaryValue* proxy_rules = NULL;
201 proxy_config->GetDictionary(kProxyCfgRules, &proxy_rules); 265 proxy_config->GetDictionary(kProxyCfgRules, &proxy_rules);
202 std::string proxy_rules_string; 266 std::string proxy_rules_string;
203 if (proxy_rules && !GetProxyRules(proxy_rules, &proxy_rules_string)) { 267 if (proxy_rules && !GetProxyRules(proxy_rules, &proxy_rules_string)) {
204 LOG(ERROR) << "Invalid 'rules' specified. " 268 LOG(ERROR) << "Invalid 'rules' specified. "
205 << "Setting custom proxy settings failed."; 269 << "Setting custom proxy settings failed.";
206 return false; 270 return false;
207 } 271 }
272 std::string bypass_list;
273 if (proxy_rules && !GetBypassList(proxy_rules, &bypass_list)) {
274 LOG(ERROR) << "Invalid 'bypassList' specified. "
275 << "Setting custom proxy settings failed.";
276 return false;
277 }
208 278
209 // not supported, yet.
210 std::string bypass_list;
211
212 DictionaryValue* result_proxy_config = NULL; 279 DictionaryValue* result_proxy_config = NULL;
213 switch (mode_enum) { 280 switch (mode_enum) {
214 case ProxyPrefs::MODE_DIRECT: 281 case ProxyPrefs::MODE_DIRECT:
215 result_proxy_config = ProxyConfigDictionary::CreateDirect(); 282 result_proxy_config = ProxyConfigDictionary::CreateDirect();
216 break; 283 break;
217 case ProxyPrefs::MODE_AUTO_DETECT: 284 case ProxyPrefs::MODE_AUTO_DETECT:
218 result_proxy_config = ProxyConfigDictionary::CreateAutoDetect(); 285 result_proxy_config = ProxyConfigDictionary::CreateAutoDetect();
219 break; 286 break;
220 case ProxyPrefs::MODE_PAC_SCRIPT: { 287 case ProxyPrefs::MODE_PAC_SCRIPT: {
221 if (!pac_dict) { 288 if (!pac_dict) {
(...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after
308 if (!dict.GetPacUrl(&pac_url)) { 375 if (!dict.GetPacUrl(&pac_url)) {
309 LOG(ERROR) << "Missing pac url"; 376 LOG(ERROR) << "Missing pac url";
310 return false; 377 return false;
311 } 378 }
312 DictionaryValue* pac_dict = new DictionaryValue; 379 DictionaryValue* pac_dict = new DictionaryValue;
313 pac_dict->SetString(kProxyCfgPacScriptUrl, pac_url); 380 pac_dict->SetString(kProxyCfgPacScriptUrl, pac_url);
314 api_proxy_config->Set(kProxyCfgPacScript, pac_dict); 381 api_proxy_config->Set(kProxyCfgPacScript, pac_dict);
315 break; 382 break;
316 } 383 }
317 case ProxyPrefs::MODE_FIXED_SERVERS: { 384 case ProxyPrefs::MODE_FIXED_SERVERS: {
318 // TODO(battre): Handle bypass list. 385 scoped_ptr<DictionaryValue> rules_dict(new DictionaryValue);
386
319 std::string proxy_servers; 387 std::string proxy_servers;
320 if (!dict.GetProxyServer(&proxy_servers)) { 388 if (!dict.GetProxyServer(&proxy_servers)) {
321 LOG(ERROR) << "Missing proxy servers"; 389 LOG(ERROR) << "Missing proxy servers in configuration";
322 return false; 390 return false;
323 } 391 }
324 DictionaryValue* rules_dict = new DictionaryValue; 392 if (!ParseRules(proxy_servers, rules_dict.get())) {
325 if (!ParseRules(proxy_servers, rules_dict)) {
326 LOG(ERROR) << "Could not parse proxy rules"; 393 LOG(ERROR) << "Could not parse proxy rules";
327 return false; 394 return false;
328 } 395 }
329 api_proxy_config->Set(kProxyCfgRules, rules_dict); 396
397 bool hasBypassList = dict.HasBypassList();
398 if (hasBypassList) {
399 std::string bypass_list_string;
400 if (!dict.GetBypassList(&bypass_list_string)) {
401 LOG(ERROR) << "Invalid bypassList in configuration";
402 return false;
403 }
404 ListValue* bypass_list = NULL;
405 if (TokenizeToStringList(bypass_list_string, ",;", &bypass_list)) {
406 rules_dict->Set(kProxyCfgBypassList, bypass_list);
407 } else {
408 LOG(ERROR) << "Error parsing bypassList " << bypass_list_string;
409 return false;
410 }
411 }
412 api_proxy_config->Set(kProxyCfgRules, rules_dict.release());
330 break; 413 break;
331 } 414 }
332 case ProxyPrefs::kModeCount: 415 case ProxyPrefs::kModeCount:
333 NOTREACHED(); 416 NOTREACHED();
334 } 417 }
335 return true; 418 return true;
336 } 419 }
337 420
338 bool GetCurrentProxySettingsFunction::ParseRules(const std::string& rules, 421 bool GetCurrentProxySettingsFunction::ParseRules(const std::string& rules,
339 DictionaryValue* out) const { 422 DictionaryValue* out) const {
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after
389 break; 472 break;
390 case net::ProxyServer::SCHEME_DIRECT: 473 case net::ProxyServer::SCHEME_DIRECT:
391 case net::ProxyServer::SCHEME_INVALID: 474 case net::ProxyServer::SCHEME_INVALID:
392 NOTREACHED(); 475 NOTREACHED();
393 return out; 476 return out;
394 } 477 }
395 out->SetString(kProxyCfgRuleHost, proxy.host_port_pair().host()); 478 out->SetString(kProxyCfgRuleHost, proxy.host_port_pair().host());
396 out->SetInteger(kProxyCfgRulePort, proxy.host_port_pair().port()); 479 out->SetInteger(kProxyCfgRulePort, proxy.host_port_pair().port());
397 return out; 480 return out;
398 } 481 }
OLDNEW
« no previous file with comments | « no previous file | chrome/browser/extensions/extension_proxy_apitest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698