diff options
author | battre@chromium.org <battre@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-03-14 14:50:51 +0000 |
---|---|---|
committer | battre@chromium.org <battre@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2011-03-14 14:50:51 +0000 |
commit | 14cc3d37e9e0d888e2ac4f2c40424031238e7fa2 (patch) | |
tree | 3859c7bcb9f3f47c3f05640d88f478e4242e393a /chrome/browser/extensions/extension_proxy_api.cc | |
parent | a9f0e3b4f0dd5874bb69a8c0b5248225d165c55b (diff) | |
download | chromium_src-14cc3d37e9e0d888e2ac4f2c40424031238e7fa2.zip chromium_src-14cc3d37e9e0d888e2ac4f2c40424031238e7fa2.tar.gz chromium_src-14cc3d37e9e0d888e2ac4f2c40424031238e7fa2.tar.bz2 |
Implement a PreferenceTransformerInterface and ProxyPreferenceTransformer.
These two classes shall factor out the transformation of preference representations so that the transformation can be used for subscription mechanisms as well.
BUG=73994
TEST=none (trybots stay green)
Review URL: http://codereview.chromium.org/6673020
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@78028 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/extensions/extension_proxy_api.cc')
-rw-r--r-- | chrome/browser/extensions/extension_proxy_api.cc | 460 |
1 files changed, 246 insertions, 214 deletions
diff --git a/chrome/browser/extensions/extension_proxy_api.cc b/chrome/browser/extensions/extension_proxy_api.cc index d4ed2f9..b237bf2 100644 --- a/chrome/browser/extensions/extension_proxy_api.cc +++ b/chrome/browser/extensions/extension_proxy_api.cc @@ -144,151 +144,18 @@ void ExtensionProxyEventRouter::OnProxyError( } } -bool SetProxySettingsFunction::GetProxyServer( - const DictionaryValue* dict, - net::ProxyServer::Scheme default_scheme, - net::ProxyServer* proxy_server) { - std::string scheme_string; // optional. - // 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; - - // TODO(battre): handle UTF-8 in hostnames (http://crbug.com/72692) - string16 host16; - if (!dict->GetString(kProxyCfgRuleHost, &host16)) { - LOG(ERROR) << "Could not parse a 'rules.*.host' entry."; - return false; - } - if (!IsStringASCII(host16)) { - error_ = ExtensionErrorUtils::FormatErrorMessage( - "Invalid 'rules.???.host' entry '*'. 'host' field supports only ASCII " - "URLs (encode URLs in Punycode format).", - UTF16ToUTF8(host16)); - return false; - } - std::string host = UTF16ToASCII(host16); - - int port; // optional. - if (!dict->GetInteger(kProxyCfgRulePort, &port)) - port = net::ProxyServer::GetDefaultPortForScheme(scheme); - - *proxy_server = net::ProxyServer(scheme, net::HostPortPair(host, port)); - - return true; -} - -bool SetProxySettingsFunction::GetProxyRules(DictionaryValue* proxy_rules, - std::string* out) { - if (!proxy_rules) - return false; - - // Local data into which the parameters will be parsed. has_proxy describes - // whether a setting was found for the scheme; proxy_dict holds the - // DictionaryValues which in turn contain proxy server descriptions, and - // proxy_server holds ProxyServer structs containing those descriptions. - bool has_proxy[SCHEME_MAX + 1]; - DictionaryValue* proxy_dict[SCHEME_MAX + 1]; - net::ProxyServer proxy_server[SCHEME_MAX + 1]; - - // Looking for all possible proxy types is inefficient if we have a - // singleProxy that will supersede per-URL proxies, but it's worth it to keep - // the code simple and extensible. - for (size_t i = 0; i <= SCHEME_MAX; ++i) { - has_proxy[i] = proxy_rules->GetDictionary(field_name[i], &proxy_dict[i]); - if (has_proxy[i]) { - net::ProxyServer::Scheme default_scheme = net::ProxyServer::SCHEME_HTTP; - if (!GetProxyServer(proxy_dict[i], default_scheme, &proxy_server[i])) { - // Don't set |error_| here, as GetProxyServer takes care of that. - return false; - } - } - } - - // Handle case that only singleProxy is specified. - if (has_proxy[SCHEME_ALL]) { - for (size_t i = 1; i <= SCHEME_MAX; ++i) { - if (has_proxy[i]) { - error_ = ExtensionErrorUtils::FormatErrorMessage( - "Proxy rule for * and * cannot be set at the same time.", - field_name[SCHEME_ALL], field_name[i]); - return false; - } - } - *out = proxy_server[SCHEME_ALL].ToURI(); - return true; - } - - // Handle case that anything but singleProxy is specified. - - // Build the proxy preference string. - std::string proxy_pref; - for (size_t i = 1; i <= SCHEME_MAX; ++i) { - if (has_proxy[i]) { - // http=foopy:4010;ftp=socks5://foopy2:80 - if (!proxy_pref.empty()) - proxy_pref.append(";"); - proxy_pref.append(scheme_name[i]); - proxy_pref.append("="); - proxy_pref.append(proxy_server[i].ToURI()); - } - } - - *out = proxy_pref; - return true; -} - -bool SetProxySettingsFunction::JoinUrlList( - 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)) { - LOG(ERROR) << "'rules.bypassList' could not be parsed."; - return false; - } - if (!IsStringASCII(entry)) { - error_ = "'rules.bypassList' supports only ASCII URLs " - "(encode URLs in Punycode format)."; - return false; - } - result.append(UTF16ToASCII(entry)); - } - *out = result; - return true; +ProxyPreferenceTransformer::ProxyPreferenceTransformer() { } -bool SetProxySettingsFunction::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)) { - LOG(ERROR) << "'rules.bypassList' not be parsed."; - return false; - } - - return JoinUrlList(bypass_list, ",", out); +ProxyPreferenceTransformer::~ProxyPreferenceTransformer() { } -bool SetProxySettingsFunction::RunImpl() { - DictionaryValue* details = NULL; - EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(1, &details)); - - DictionaryValue* proxy_config = NULL; - EXTENSION_FUNCTION_VALIDATE(details->GetDictionary("value", &proxy_config)); +Value* ProxyPreferenceTransformer::ExtensionToBrowserPref( + const Value* extension_pref, + std::string* error) { + CHECK(extension_pref->IsType(Value::TYPE_DICTIONARY)); + const DictionaryValue* proxy_config = + static_cast<const DictionaryValue*>(extension_pref); std::string proxy_mode; // We can safely assume that this is ASCII due to the allowed enumeration @@ -297,7 +164,7 @@ bool SetProxySettingsFunction::RunImpl() { ProxyPrefs::ProxyMode mode_enum; if (!ProxyPrefs::StringToProxyMode(proxy_mode, &mode_enum)) { LOG(ERROR) << "Invalid mode for proxy settings: " << proxy_mode; - return false; + return NULL; } DictionaryValue* pac_dict = NULL; @@ -309,12 +176,12 @@ bool SetProxySettingsFunction::RunImpl() { pac_dict->HasKey(kProxyCfgPacScriptUrl) && !pac_dict->GetString(kProxyCfgPacScriptUrl, &pac_url16)) { LOG(ERROR) << "'pacScript.url' could not be parsed."; - return false; + return NULL; } if (!IsStringASCII(pac_url16)) { - error_ = "'pacScript.url' supports only ASCII URLs " + *error = "'pacScript.url' supports only ASCII URLs " "(encode URLs in Punycode format)."; - return false; + return NULL; } std::string pac_url = UTF16ToASCII(pac_url16); @@ -323,26 +190,26 @@ bool SetProxySettingsFunction::RunImpl() { pac_dict->HasKey(kProxyCfgPacScriptData) && !pac_dict->GetString(kProxyCfgPacScriptData, &pac_data16)) { LOG(ERROR) << "'pacScript.data' could not be parsed."; - return false; + return NULL; } if (!IsStringASCII(pac_data16)) { - error_ = "'pacScript.data' supports only ASCII code" + *error = "'pacScript.data' supports only ASCII code" "(encode URLs in Punycode format)."; - return false; + return NULL; } std::string pac_data = UTF16ToASCII(pac_data16); DictionaryValue* proxy_rules = NULL; proxy_config->GetDictionary(kProxyCfgRules, &proxy_rules); std::string proxy_rules_string; - if (proxy_rules && !GetProxyRules(proxy_rules, &proxy_rules_string)) { + if (proxy_rules && !GetProxyRules(proxy_rules, &proxy_rules_string, error)) { // Do not set error message as GetProxyRules does that. - return false; + return NULL; } std::string bypass_list; - if (proxy_rules && !GetBypassList(proxy_rules, &bypass_list)) { + if (proxy_rules && !GetBypassList(proxy_rules, &bypass_list, error)) { LOG(ERROR) << "Invalid 'bypassList' specified."; - return false; + return NULL; } DictionaryValue* result_proxy_config = NULL; @@ -355,29 +222,29 @@ bool SetProxySettingsFunction::RunImpl() { break; case ProxyPrefs::MODE_PAC_SCRIPT: { if (!pac_dict) { - error_ = "Proxy mode 'pac_script' requires a 'pacScript' field."; - return false; + *error = "Proxy mode 'pac_script' requires a 'pacScript' field."; + return NULL; } std::string url; if (!pac_url.empty()) { url = pac_url; } else if (!pac_data.empty()) { if (!CreateDataURLFromPACScript(pac_data, &url)) { - error_ = "Internal error, at base64 encoding of 'pacScript.data'."; - return false; + *error = "Internal error, at base64 encoding of 'pacScript.data'."; + return NULL; } } else { - error_ = "Proxy mode 'pac_script' requires a 'pacScript' field with " + *error = "Proxy mode 'pac_script' requires a 'pacScript' field with " "either a 'url' field or a 'data' field."; - return false; + return NULL; } result_proxy_config = ProxyConfigDictionary::CreatePacScript(url); break; } case ProxyPrefs::MODE_FIXED_SERVERS: { if (!proxy_rules) { - error_ = "Proxy mode 'fixed_servers' requires a 'rules' field."; - return false; + *error = "Proxy mode 'fixed_servers' requires a 'rules' field."; + return NULL; } result_proxy_config = ProxyConfigDictionary::CreateFixedServers( proxy_rules_string, bypass_list); @@ -390,51 +257,24 @@ bool SetProxySettingsFunction::RunImpl() { NOTREACHED(); } if (!result_proxy_config) - return false; - - details->Set("value", result_proxy_config); - return SetPreferenceFunction::RunImpl(); + return NULL; + return result_proxy_config; } -bool GetProxySettingsFunction::RunImpl() { - if (!GetPreferenceFunction::RunImpl()) - return false; - - DCHECK(result_->IsType(Value::TYPE_DICTIONARY)); - - DictionaryValue* result_dict_ = static_cast<DictionaryValue*>(result_.get()); - - // This is how it is stored in the PrefStores: - DictionaryValue* proxy_prefs = NULL; - if (!result_dict_->GetDictionary(kProxyCfgValue, &proxy_prefs)) { - LOG(ERROR) << "Received invalid configuration."; - return false; - } - - // This is how it is presented to the API caller: - scoped_ptr<DictionaryValue> out(new DictionaryValue); - - if (!ConvertToApiFormat(proxy_prefs, out.get())) { - // Do not set error message as ConvertToApiFormat does that. - return false; - } - - result_dict_->Set(kProxyCfgValue, out.release()); - return true; -} - -bool GetProxySettingsFunction::ConvertToApiFormat( - const DictionaryValue* proxy_prefs, - DictionaryValue* api_proxy_config) { - ProxyConfigDictionary dict(proxy_prefs); +Value* ProxyPreferenceTransformer::BrowserToExtensionPref( + const Value* browser_pref) { + CHECK(browser_pref->IsType(Value::TYPE_DICTIONARY)); + ProxyConfigDictionary dict(static_cast<const DictionaryValue*>(browser_pref)); ProxyPrefs::ProxyMode mode; if (!dict.GetMode(&mode)) { LOG(ERROR) << "Cannot determine proxy mode."; return false; } - api_proxy_config->SetString(kProxyCfgMode, - ProxyPrefs::ProxyModeToString(mode)); + + scoped_ptr<DictionaryValue> extension_pref(new DictionaryValue); + extension_pref->SetString(kProxyCfgMode, + ProxyPrefs::ProxyModeToString(mode)); switch (mode) { case ProxyPrefs::MODE_DIRECT: @@ -445,21 +285,21 @@ bool GetProxySettingsFunction::ConvertToApiFormat( case ProxyPrefs::MODE_PAC_SCRIPT: { std::string pac_url; if (!dict.GetPacUrl(&pac_url)) { - error_ = "Invalid proxy configuration. Missing PAC URL."; - return false; + LOG(ERROR) << "Invalid proxy configuration. Missing PAC URL."; + return NULL; } DictionaryValue* pac_dict = new DictionaryValue; if (pac_url.find("data") == 0) { std::string pac_data; if (!CreatePACScriptFromDataURL(pac_url, &pac_data)) { - error_ = "Cannot decode base64-encoded PAC data URL."; - return false; + LOG(ERROR) << "Cannot decode base64-encoded PAC data URL."; + return NULL; } pac_dict->SetString(kProxyCfgPacScriptData, pac_data); } else { pac_dict->SetString(kProxyCfgPacScriptUrl, pac_url); } - api_proxy_config->Set(kProxyCfgPacScript, pac_dict); + extension_pref->Set(kProxyCfgPacScript, pac_dict); break; } case ProxyPrefs::MODE_FIXED_SERVERS: { @@ -467,40 +307,185 @@ bool GetProxySettingsFunction::ConvertToApiFormat( std::string proxy_servers; if (!dict.GetProxyServer(&proxy_servers)) { - error_ = "Missing proxy servers in configuration."; - return false; + LOG(ERROR) << "Missing proxy servers in configuration."; + return NULL; } if (!ParseRules(proxy_servers, rules_dict.get())) { - error_ = "Could not parse proxy rules."; - return false; + LOG(ERROR) << "Could not parse proxy rules."; + return NULL; } bool hasBypassList = dict.HasBypassList(); if (hasBypassList) { std::string bypass_list_string; if (!dict.GetBypassList(&bypass_list_string)) { - error_ = "Invalid bypassList in configuration."; - return false; + LOG(ERROR) << "Invalid bypassList in configuration."; + return NULL; } ListValue* bypass_list = NULL; if (TokenizeToStringList(bypass_list_string, ",;", &bypass_list)) { rules_dict->Set(kProxyCfgBypassList, bypass_list); } else { - error_ = "Error parsing bypassList " + bypass_list_string; - return false; + LOG(ERROR) << "Error parsing bypassList " << bypass_list_string; + return NULL; } } - api_proxy_config->Set(kProxyCfgRules, rules_dict.release()); + extension_pref->Set(kProxyCfgRules, rules_dict.release()); break; } case ProxyPrefs::kModeCount: NOTREACHED(); } + return extension_pref.release(); +} + +bool ProxyPreferenceTransformer::GetProxyServer( + const DictionaryValue* dict, + net::ProxyServer::Scheme default_scheme, + net::ProxyServer* proxy_server, + std::string* error) { + std::string scheme_string; // optional. + // 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; + + // TODO(battre): handle UTF-8 in hostnames (http://crbug.com/72692) + string16 host16; + if (!dict->GetString(kProxyCfgRuleHost, &host16)) { + LOG(ERROR) << "Could not parse a 'rules.*.host' entry."; + return false; + } + if (!IsStringASCII(host16)) { + *error = ExtensionErrorUtils::FormatErrorMessage( + "Invalid 'rules.???.host' entry '*'. 'host' field supports only ASCII " + "URLs (encode URLs in Punycode format).", + UTF16ToUTF8(host16)); + return false; + } + std::string host = UTF16ToASCII(host16); + + int port; // optional. + if (!dict->GetInteger(kProxyCfgRulePort, &port)) + port = net::ProxyServer::GetDefaultPortForScheme(scheme); + + *proxy_server = net::ProxyServer(scheme, net::HostPortPair(host, port)); + + return true; +} + +bool ProxyPreferenceTransformer::GetProxyRules(DictionaryValue* proxy_rules, + std::string* out, + std::string* error) { + if (!proxy_rules) + return false; + + // Local data into which the parameters will be parsed. has_proxy describes + // whether a setting was found for the scheme; proxy_dict holds the + // DictionaryValues which in turn contain proxy server descriptions, and + // proxy_server holds ProxyServer structs containing those descriptions. + bool has_proxy[SCHEME_MAX + 1]; + DictionaryValue* proxy_dict[SCHEME_MAX + 1]; + net::ProxyServer proxy_server[SCHEME_MAX + 1]; + + // Looking for all possible proxy types is inefficient if we have a + // singleProxy that will supersede per-URL proxies, but it's worth it to keep + // the code simple and extensible. + for (size_t i = 0; i <= SCHEME_MAX; ++i) { + has_proxy[i] = proxy_rules->GetDictionary(field_name[i], &proxy_dict[i]); + if (has_proxy[i]) { + net::ProxyServer::Scheme default_scheme = net::ProxyServer::SCHEME_HTTP; + if (!GetProxyServer(proxy_dict[i], default_scheme, + &proxy_server[i], error)) { + // Don't set |error| here, as GetProxyServer takes care of that. + return false; + } + } + } + + // Handle case that only singleProxy is specified. + if (has_proxy[SCHEME_ALL]) { + for (size_t i = 1; i <= SCHEME_MAX; ++i) { + if (has_proxy[i]) { + *error = ExtensionErrorUtils::FormatErrorMessage( + "Proxy rule for * and * cannot be set at the same time.", + field_name[SCHEME_ALL], field_name[i]); + return false; + } + } + *out = proxy_server[SCHEME_ALL].ToURI(); + return true; + } + + // Handle case that anything but singleProxy is specified. + + // Build the proxy preference string. + std::string proxy_pref; + for (size_t i = 1; i <= SCHEME_MAX; ++i) { + if (has_proxy[i]) { + // http=foopy:4010;ftp=socks5://foopy2:80 + if (!proxy_pref.empty()) + proxy_pref.append(";"); + proxy_pref.append(scheme_name[i]); + proxy_pref.append("="); + proxy_pref.append(proxy_server[i].ToURI()); + } + } + + *out = proxy_pref; + return true; +} + +bool ProxyPreferenceTransformer::JoinUrlList(ListValue* list, + const std::string& joiner, + std::string* out, + std::string* error) { + 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)) { + LOG(ERROR) << "'rules.bypassList' could not be parsed."; + return false; + } + if (!IsStringASCII(entry)) { + *error = "'rules.bypassList' supports only ASCII URLs " + "(encode URLs in Punycode format)."; + return false; + } + result.append(UTF16ToASCII(entry)); + } + *out = result; return true; } -bool GetProxySettingsFunction::ParseRules(const std::string& rules, - DictionaryValue* out) const { +bool ProxyPreferenceTransformer::GetBypassList(DictionaryValue* proxy_rules, + std::string* out, + std::string* error) { + if (!proxy_rules) + return false; + + ListValue* bypass_list; + if (!proxy_rules->HasKey(kProxyCfgBypassList)) { + *out = ""; + return true; + } + if (!proxy_rules->GetList(kProxyCfgBypassList, &bypass_list)) { + LOG(ERROR) << "'rules.bypassList' not be parsed."; + return false; + } + + return JoinUrlList(bypass_list, ",", out, error); +} + +bool ProxyPreferenceTransformer::ParseRules(const std::string& rules, + DictionaryValue* out) const { net::ProxyConfig::ProxyRules config; config.ParseFromString(rules); switch (config.type) { @@ -535,7 +520,7 @@ bool GetProxySettingsFunction::ParseRules(const std::string& rules, return true; } -DictionaryValue* GetProxySettingsFunction::ConvertToDictionary( +DictionaryValue* ProxyPreferenceTransformer::ConvertToDictionary( const net::ProxyServer& proxy) const { DictionaryValue* out = new DictionaryValue; switch (proxy.scheme()) { @@ -560,3 +545,50 @@ DictionaryValue* GetProxySettingsFunction::ConvertToDictionary( out->SetInteger(kProxyCfgRulePort, proxy.host_port_pair().port()); return out; } + +SetProxySettingsFunction::~SetProxySettingsFunction() { +} + +bool SetProxySettingsFunction::RunImpl() { + DictionaryValue* details = NULL; + EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(1, &details)); + + DictionaryValue* proxy_config = NULL; + EXTENSION_FUNCTION_VALIDATE(details->GetDictionary("value", &proxy_config)); + + Value* result_proxy_config = + transformer.ExtensionToBrowserPref(proxy_config, &error_); + + if (!result_proxy_config) + return false; + + details->Set("value", result_proxy_config); + return SetPreferenceFunction::RunImpl(); +} + +GetProxySettingsFunction::~GetProxySettingsFunction() { +} + +bool GetProxySettingsFunction::RunImpl() { + if (!GetPreferenceFunction::RunImpl()) + return false; + + DCHECK(result_->IsType(Value::TYPE_DICTIONARY)); + + DictionaryValue* result_dict_ = static_cast<DictionaryValue*>(result_.get()); + + // This is how it is stored in the PrefStores: + DictionaryValue* proxy_prefs = NULL; + if (!result_dict_->GetDictionary(kProxyCfgValue, &proxy_prefs)) { + LOG(ERROR) << "Received invalid configuration."; + return false; + } + + Value* result_proxy_config = transformer.BrowserToExtensionPref(proxy_prefs); + + if (!result_proxy_config) + return false; + + result_dict_->Set(kProxyCfgValue, result_proxy_config); + return true; +} |