Index: chrome/browser/extensions/extension_proxy_api.cc |
diff --git a/chrome/browser/extensions/extension_proxy_api.cc b/chrome/browser/extensions/extension_proxy_api.cc |
index f816528b6b769a23ceb7109a23cdb197965da0bd..6256b39bdd91b81c0320dbbda677f0291fc5b156 100644 |
--- a/chrome/browser/extensions/extension_proxy_api.cc |
+++ b/chrome/browser/extensions/extension_proxy_api.cc |
@@ -5,6 +5,7 @@ |
#include "chrome/browser/extensions/extension_proxy_api.h" |
#include "base/string_util.h" |
+#include "base/string_tokenizer.h" |
#include "base/values.h" |
#include "chrome/browser/prefs/proxy_config_dictionary.h" |
#include "chrome/browser/profiles/profile.h" |
@@ -49,6 +50,7 @@ const char kProxyCfgPacScriptUrl[] = "url"; |
const char kProxyCfgRules[] = "rules"; |
const char kProxyCfgRuleHost[] = "host"; |
const char kProxyCfgRulePort[] = "port"; |
+const char kProxyCfgBypassList[] = "bypassList"; |
const char kProxyCfgScheme[] = "scheme"; |
COMPILE_ASSERT(SCHEME_MAX == SCHEME_SOCKS, SCHEME_MAX_must_equal_SCHEME_SOCKS); |
@@ -58,6 +60,35 @@ COMPILE_ASSERT(arraysize(scheme_name) == SCHEME_MAX + 1, |
scheme_name_array_is_wrong_size); |
COMPILE_ASSERT(SCHEME_ALL == 0, singleProxy_must_be_first_option); |
+bool TokenizeToStringList( |
+ const std::string& in, const std::string& delims, ListValue** out) { |
+ scoped_ptr<ListValue> result(new ListValue); |
+ StringTokenizer entries(in, delims); |
+ while (entries.GetNext()) { |
+ result->Append(Value::CreateStringValue(entries.token())); |
+ } |
+ *out = result.release(); |
+ return true; |
+} |
+ |
+bool JoinStringList( |
+ ListValue* list, const std::string& joiner, std::string* out) { |
+ std::string result; |
+ for (size_t i = 0; i < list->GetSize(); ++i) { |
+ if (!result.empty()) |
+ result.append(joiner); |
+ // TODO(battre): handle UTF-8 (http://crbug.com/72692) |
+ string16 entry; |
+ if (!list->GetString(i, &entry)) |
+ return false; |
+ if (!IsStringASCII(entry)) |
+ return false; |
+ result.append(UTF16ToASCII(entry)); |
+ } |
+ *out = result; |
+ return true; |
+} |
+ |
// Converts a proxy server description |dict| as passed by the API caller |
// (e.g. for the http proxy in the rules element) and converts it to a |
// ProxyServer. Returns true if successful. |
@@ -65,16 +96,22 @@ bool GetProxyServer(const DictionaryValue* dict, |
net::ProxyServer::Scheme default_scheme, |
net::ProxyServer* proxy_server) { |
std::string scheme_string; // optional. |
- dict->GetString(kProxyCfgScheme, &scheme_string); |
+ // We can safely assume that this is ASCII due to the allowed enumeration |
+ // values specified in extension_api.json. |
+ dict->GetStringASCII(kProxyCfgScheme, &scheme_string); |
net::ProxyServer::Scheme scheme = |
net::ProxyServer::GetSchemeFromURI(scheme_string); |
if (scheme == net::ProxyServer::SCHEME_INVALID) |
scheme = default_scheme; |
- std::string host; |
- if (!dict->GetString(kProxyCfgRuleHost, &host)) |
+ // TODO(battre): handle UTF-8 in hostnames (http://crbug.com/72692) |
+ string16 host16; |
+ if (!dict->GetString(kProxyCfgRuleHost, &host16)) |
return false; |
+ if (!IsStringASCII(host16)) |
+ return false; |
+ std::string host = UTF16ToASCII(host16); |
int port; // optional. |
if (!dict->GetInteger(kProxyCfgRulePort, &port)) |
@@ -146,6 +183,25 @@ bool GetProxyRules(DictionaryValue* proxy_rules, std::string* out) { |
return true; |
} |
+// Creates a string of the "bypassList" entries of a ProxyRules object (see API |
+// documentation) by joining the elements with commas. |
+// Returns true if successful (i.e. string could be delivered or no "bypassList" |
+// exists in the |proxy_rules|). |
+bool GetBypassList(DictionaryValue* proxy_rules, std::string* out) { |
+ if (!proxy_rules) |
+ return false; |
+ |
+ ListValue* bypass_list; |
+ if (!proxy_rules->HasKey(kProxyCfgBypassList)) { |
+ *out = ""; |
+ return true; |
+ } |
+ if (!proxy_rules->GetList(kProxyCfgBypassList, &bypass_list)) |
+ return false; |
+ |
+ return JoinStringList(bypass_list, ",", out); |
+} |
+ |
} // namespace |
void ProxySettingsFunction::ApplyPreference(const char* pref_path, |
@@ -180,7 +236,9 @@ bool UseCustomProxySettingsFunction::RunImpl() { |
} |
std::string proxy_mode; |
- proxy_config->GetString(kProxyCfgMode, &proxy_mode); |
+ // We can safely assume that this is ASCII due to the allowed enumeration |
+ // values specified in extension_api.json. |
+ proxy_config->GetStringASCII(kProxyCfgMode, &proxy_mode); |
ProxyPrefs::ProxyMode mode_enum; |
if (!ProxyPrefs::StringToProxyMode(proxy_mode, &mode_enum)) { |
LOG(ERROR) << "Invalid mode for proxy settings: " << proxy_mode << ". " |
@@ -190,12 +248,18 @@ bool UseCustomProxySettingsFunction::RunImpl() { |
DictionaryValue* pac_dict = NULL; |
proxy_config->GetDictionary(kProxyCfgPacScript, &pac_dict); |
- std::string pac_url; |
- if (pac_dict && !pac_dict->GetString(kProxyCfgPacScriptUrl, &pac_url)) { |
+ // TODO(battre): Handle UTF-8 URLs (http://crbug.com/72692) |
+ string16 pac_url16; |
+ if (pac_dict && !pac_dict->GetString(kProxyCfgPacScriptUrl, &pac_url16)) { |
LOG(ERROR) << "'pacScript' requires a 'url' field. " |
<< "Setting custom proxy settings failed."; |
return false; |
} |
+ if (!IsStringASCII(pac_url16)) { |
+ LOG(ERROR) << "Only ASCII URLs are supported, yet"; |
+ return false; |
+ } |
+ std::string pac_url = UTF16ToASCII(pac_url16); |
DictionaryValue* proxy_rules = NULL; |
proxy_config->GetDictionary(kProxyCfgRules, &proxy_rules); |
@@ -205,9 +269,12 @@ bool UseCustomProxySettingsFunction::RunImpl() { |
<< "Setting custom proxy settings failed."; |
return false; |
} |
- |
- // not supported, yet. |
std::string bypass_list; |
+ if (proxy_rules && !GetBypassList(proxy_rules, &bypass_list)) { |
+ LOG(ERROR) << "Invalid 'bypassList' specified. " |
+ << "Setting custom proxy settings failed."; |
+ return false; |
+ } |
DictionaryValue* result_proxy_config = NULL; |
switch (mode_enum) { |
@@ -315,18 +382,34 @@ bool GetCurrentProxySettingsFunction::ConvertToApiFormat( |
break; |
} |
case ProxyPrefs::MODE_FIXED_SERVERS: { |
- // TODO(battre): Handle bypass list. |
+ scoped_ptr<DictionaryValue> rules_dict(new DictionaryValue); |
+ |
std::string proxy_servers; |
if (!dict.GetProxyServer(&proxy_servers)) { |
- LOG(ERROR) << "Missing proxy servers"; |
+ LOG(ERROR) << "Missing proxy servers in configuration"; |
return false; |
} |
- DictionaryValue* rules_dict = new DictionaryValue; |
- if (!ParseRules(proxy_servers, rules_dict)) { |
+ if (!ParseRules(proxy_servers, rules_dict.get())) { |
LOG(ERROR) << "Could not parse proxy rules"; |
return false; |
} |
- api_proxy_config->Set(kProxyCfgRules, rules_dict); |
+ |
+ bool hasBypassList = dict.HasBypassList(); |
+ if (hasBypassList) { |
+ std::string bypass_list_string; |
+ if (!dict.GetBypassList(&bypass_list_string)) { |
+ LOG(ERROR) << "Invalid bypassList in configuration"; |
+ return false; |
+ } |
+ ListValue* bypass_list = NULL; |
+ if (TokenizeToStringList(bypass_list_string, ",;", &bypass_list)) { |
+ rules_dict->Set(kProxyCfgBypassList, bypass_list); |
+ } else { |
+ LOG(ERROR) << "Error parsing bypassList " << bypass_list_string; |
+ return false; |
+ } |
+ } |
+ api_proxy_config->Set(kProxyCfgRules, rules_dict.release()); |
break; |
} |
case ProxyPrefs::kModeCount: |