OLD | NEW |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 Loading... |
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 } |
OLD | NEW |