summaryrefslogtreecommitdiffstats
path: root/chrome/browser/extensions/extension_proxy_api.cc
diff options
context:
space:
mode:
authorbattre@chromium.org <battre@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-03-25 14:19:37 +0000
committerbattre@chromium.org <battre@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98>2011-03-25 14:19:37 +0000
commit16a3549ea2518117da7e41b422ab2a3930f33245 (patch)
tree89671daec300345a61099c666ff77dc6c3f753b1 /chrome/browser/extensions/extension_proxy_api.cc
parentb9b751f2681d39b11a692a655eb16a9e1e4eba97 (diff)
downloadchromium_src-16a3549ea2518117da7e41b422ab2a3930f33245.zip
chromium_src-16a3549ea2518117da7e41b422ab2a3930f33245.tar.gz
chromium_src-16a3549ea2518117da7e41b422ab2a3930f33245.tar.bz2
Cleanup of proxy settings api implementation.
BUG=none TEST=browser_tests --gtest_filter='ProxySettingsApiTest.*' remains green Review URL: http://codereview.chromium.org/6744001 git-svn-id: svn://svn.chromium.org/chrome/trunk/src@79397 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'chrome/browser/extensions/extension_proxy_api.cc')
-rw-r--r--chrome/browser/extensions/extension_proxy_api.cc566
1 files changed, 279 insertions, 287 deletions
diff --git a/chrome/browser/extensions/extension_proxy_api.cc b/chrome/browser/extensions/extension_proxy_api.cc
index 13a5049..129ceac 100644
--- a/chrome/browser/extensions/extension_proxy_api.cc
+++ b/chrome/browser/extensions/extension_proxy_api.cc
@@ -12,99 +12,45 @@
#include "base/values.h"
#include "chrome/browser/prefs/proxy_config_dictionary.h"
#include "chrome/browser/extensions/extension_event_router_forwarder.h"
+#include "chrome/browser/extensions/extension_proxy_api_constants.h"
#include "chrome/browser/extensions/extension_service.h"
#include "chrome/common/extensions/extension_error_utils.h"
#include "chrome/common/pref_names.h"
#include "net/base/net_errors.h"
#include "net/proxy/proxy_config.h"
+namespace keys = extension_proxy_api_constants;
+
namespace {
-// The scheme for which to use a manually specified proxy, not of the proxy URI
-// itself.
-enum {
- SCHEME_ALL = 0,
- SCHEME_HTTP,
- SCHEME_HTTPS,
- SCHEME_FTP,
- SCHEME_FALLBACK,
- SCHEME_MAX = SCHEME_FALLBACK // Keep this value up to date.
-};
-
-// The names of the JavaScript properties to extract from the proxy_rules.
-// These must be kept in sync with the SCHEME_* constants.
-const char* field_name[] = { "singleProxy",
- "proxyForHttp",
- "proxyForHttps",
- "proxyForFtp",
- "fallbackProxy" };
-
-// The names of the schemes to be used to build the preference value string
-// for manual proxy settings. These must be kept in sync with the SCHEME_*
-// constants.
-const char* scheme_name[] = { "*error*",
- "http",
- "https",
- "ftp",
- "socks" };
-
-// String literals in dictionaries used to communicate with extension.
-const char kProxyCfgMode[] = "mode";
-const char kProxyCfgPacScript[] = "pacScript";
-const char kProxyCfgPacScriptUrl[] = "url";
-const char kProxyCfgPacScriptData[] = "data";
-const char kProxyCfgRules[] = "rules";
-const char kProxyCfgRuleHost[] = "host";
-const char kProxyCfgRulePort[] = "port";
-const char kProxyCfgBypassList[] = "bypassList";
-const char kProxyCfgScheme[] = "scheme";
-const char kProxyCfgValue[] = "value";
-
-const char kProxyEventFatal[] = "fatal";
-const char kProxyEventError[] = "error";
-const char kProxyEventDetails[] = "details";
-const char kProxyEventOnProxyError[] = "experimental.proxy.onProxyError";
-
-
-const char kPACDataUrlPrefix[] =
- "data:application/x-ns-proxy-autoconfig;base64,";
-
-COMPILE_ASSERT(SCHEME_MAX == SCHEME_FALLBACK,
- SCHEME_MAX_must_equal_SCHEME_FALLBACK);
-COMPILE_ASSERT(arraysize(field_name) == SCHEME_MAX + 1,
- field_name_array_is_wrong_size);
-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(
+void TokenizeToStringList(
const std::string& in, const std::string& delims, ListValue** out) {
- scoped_ptr<ListValue> result(new ListValue);
+ *out = new ListValue;
StringTokenizer entries(in, delims);
- while (entries.GetNext()) {
- result->Append(Value::CreateStringValue(entries.token()));
- }
- *out = result.release();
- return true;
+ while (entries.GetNext())
+ (*out)->Append(Value::CreateStringValue(entries.token()));
}
bool CreateDataURLFromPACScript(const std::string& pac_script,
std::string* pac_script_url_base64_encoded) {
+ // Encode pac_script in base64.
std::string pac_script_base64_encoded;
if (!base::Base64Encode(pac_script, &pac_script_base64_encoded))
return false;
+ // Make it a correct data url.
*pac_script_url_base64_encoded =
- std::string(kPACDataUrlPrefix) + pac_script_base64_encoded;
+ std::string(keys::kPACDataUrlPrefix) + pac_script_base64_encoded;
return true;
}
bool CreatePACScriptFromDataURL(
const std::string& pac_script_url_base64_encoded, std::string* pac_script) {
- if (pac_script_url_base64_encoded.find(kPACDataUrlPrefix) != 0) {
+ if (pac_script_url_base64_encoded.find(keys::kPACDataUrlPrefix) != 0)
return false;
- }
+ // Strip constant data-url prefix.
std::string pac_script_base64_encoded =
- pac_script_url_base64_encoded.substr(strlen(kPACDataUrlPrefix));
+ pac_script_url_base64_encoded.substr(strlen(keys::kPACDataUrlPrefix));
+ // The rest is a base64 encoded PAC script.
return base::Base64Decode(pac_script_base64_encoded, pac_script);
}
@@ -127,9 +73,9 @@ void ExtensionProxyEventRouter::OnProxyError(
int error_code) {
ListValue args;
DictionaryValue* dict = new DictionaryValue();
- dict->SetBoolean(kProxyEventFatal, true);
- dict->SetString(kProxyEventError, net::ErrorToString(error_code));
- dict->SetString(kProxyEventDetails, "");
+ dict->SetBoolean(keys::kProxyEventFatal, true);
+ dict->SetString(keys::kProxyEventError, net::ErrorToString(error_code));
+ dict->SetString(keys::kProxyEventDetails, "");
args.Append(dict);
std::string json_args;
@@ -137,10 +83,10 @@ void ExtensionProxyEventRouter::OnProxyError(
if (profile_id != Profile::kInvalidProfileId) {
event_router->DispatchEventToRenderers(
- kProxyEventOnProxyError, json_args, profile_id, true, GURL());
+ keys::kProxyEventOnProxyError, json_args, profile_id, true, GURL());
} else {
event_router->BroadcastEventToRenderers(
- kProxyEventOnProxyError, json_args, GURL());
+ keys::kProxyEventOnProxyError, json_args, GURL());
}
}
@@ -150,204 +96,82 @@ ProxyPrefTransformer::ProxyPrefTransformer() {
ProxyPrefTransformer::~ProxyPrefTransformer() {
}
-Value* ProxyPrefTransformer::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);
+// Extension Pref -> Browser Pref conversion.
+
+bool ProxyPrefTransformer::GetProxyModeFromExtensionPref(
+ const DictionaryValue* proxy_config,
+ ProxyPrefs::ProxyMode* out,
+ std::string* error) const {
std::string 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)) {
+ proxy_config->GetStringASCII(keys::kProxyCfgMode, &proxy_mode);
+ if (!ProxyPrefs::StringToProxyMode(proxy_mode, out)) {
LOG(ERROR) << "Invalid mode for proxy settings: " << proxy_mode;
- return NULL;
+ return false;
}
+ return true;
+}
+bool ProxyPrefTransformer::GetPacUrlFromExtensionPref(
+ const DictionaryValue* proxy_config,
+ std::string* out,
+ std::string* error) const {
DictionaryValue* pac_dict = NULL;
- proxy_config->GetDictionary(kProxyCfgPacScript, &pac_dict);
+ proxy_config->GetDictionary(keys::kProxyCfgPacScript, &pac_dict);
+ if (!pac_dict)
+ return true;
// TODO(battre): Handle UTF-8 URLs (http://crbug.com/72692)
string16 pac_url16;
- if (pac_dict &&
- pac_dict->HasKey(kProxyCfgPacScriptUrl) &&
- !pac_dict->GetString(kProxyCfgPacScriptUrl, &pac_url16)) {
+ if (pac_dict->HasKey(keys::kProxyCfgPacScriptUrl) &&
+ !pac_dict->GetString(keys::kProxyCfgPacScriptUrl, &pac_url16)) {
LOG(ERROR) << "'pacScript.url' could not be parsed.";
- return NULL;
+ return false;
}
if (!IsStringASCII(pac_url16)) {
*error = "'pacScript.url' supports only ASCII URLs "
"(encode URLs in Punycode format).";
- return NULL;
+ return false;
}
- std::string pac_url = UTF16ToASCII(pac_url16);
+ *out = UTF16ToASCII(pac_url16);
+ return true;
+}
+
+bool ProxyPrefTransformer::GetPacDataFromExtensionPref(
+ const DictionaryValue* proxy_config,
+ std::string* out,
+ std::string* error) const {
+ DictionaryValue* pac_dict = NULL;
+ proxy_config->GetDictionary(keys::kProxyCfgPacScript, &pac_dict);
+ if (!pac_dict)
+ return true;
string16 pac_data16;
- if (pac_dict &&
- pac_dict->HasKey(kProxyCfgPacScriptData) &&
- !pac_dict->GetString(kProxyCfgPacScriptData, &pac_data16)) {
+ if (pac_dict->HasKey(keys::kProxyCfgPacScriptData) &&
+ !pac_dict->GetString(keys::kProxyCfgPacScriptData, &pac_data16)) {
LOG(ERROR) << "'pacScript.data' could not be parsed.";
- return NULL;
+ return false;
}
if (!IsStringASCII(pac_data16)) {
*error = "'pacScript.data' supports only ASCII code"
"(encode URLs in Punycode format).";
- 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, error)) {
- // Do not set error message as GetProxyRules does that.
- return NULL;
- }
- std::string bypass_list;
- if (proxy_rules && !GetBypassList(proxy_rules, &bypass_list, error)) {
- LOG(ERROR) << "Invalid 'bypassList' specified.";
- return NULL;
- }
-
- DictionaryValue* result_proxy_config = NULL;
- switch (mode_enum) {
- case ProxyPrefs::MODE_DIRECT:
- result_proxy_config = ProxyConfigDictionary::CreateDirect();
- break;
- case ProxyPrefs::MODE_AUTO_DETECT:
- result_proxy_config = ProxyConfigDictionary::CreateAutoDetect();
- break;
- case ProxyPrefs::MODE_PAC_SCRIPT: {
- if (!pac_dict) {
- *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 NULL;
- }
- } else {
- *error = "Proxy mode 'pac_script' requires a 'pacScript' field with "
- "either a 'url' field or a 'data' field.";
- 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 NULL;
- }
- result_proxy_config = ProxyConfigDictionary::CreateFixedServers(
- proxy_rules_string, bypass_list);
- break;
- }
- case ProxyPrefs::MODE_SYSTEM:
- result_proxy_config = ProxyConfigDictionary::CreateSystem();
- break;
- case ProxyPrefs::kModeCount:
- NOTREACHED();
- }
- if (!result_proxy_config)
- return NULL;
- return result_proxy_config;
-}
-
-Value* ProxyPrefTransformer::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 NULL;
- }
-
- scoped_ptr<DictionaryValue> extension_pref(new DictionaryValue);
- extension_pref->SetString(kProxyCfgMode,
- ProxyPrefs::ProxyModeToString(mode));
-
- switch (mode) {
- case ProxyPrefs::MODE_DIRECT:
- case ProxyPrefs::MODE_AUTO_DETECT:
- case ProxyPrefs::MODE_SYSTEM:
- // These modes have no further parameters.
- break;
- case ProxyPrefs::MODE_PAC_SCRIPT: {
- std::string pac_url;
- if (!dict.GetPacUrl(&pac_url)) {
- 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)) {
- LOG(ERROR) << "Cannot decode base64-encoded PAC data URL.";
- return NULL;
- }
- pac_dict->SetString(kProxyCfgPacScriptData, pac_data);
- } else {
- pac_dict->SetString(kProxyCfgPacScriptUrl, pac_url);
- }
- extension_pref->Set(kProxyCfgPacScript, pac_dict);
- break;
- }
- case ProxyPrefs::MODE_FIXED_SERVERS: {
- scoped_ptr<DictionaryValue> rules_dict(new DictionaryValue);
-
- std::string proxy_servers;
- if (!dict.GetProxyServer(&proxy_servers)) {
- LOG(ERROR) << "Missing proxy servers in configuration.";
- return NULL;
- }
- if (!ParseRules(proxy_servers, rules_dict.get())) {
- 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)) {
- 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 {
- LOG(ERROR) << "Error parsing bypassList " << bypass_list_string;
- return NULL;
- }
- }
- extension_pref->Set(kProxyCfgRules, rules_dict.release());
- break;
- }
- case ProxyPrefs::kModeCount:
- NOTREACHED();
+ return false;
}
- return extension_pref.release();
+ *out = UTF16ToASCII(pac_data16);
+ return true;
}
bool ProxyPrefTransformer::GetProxyServer(
const DictionaryValue* dict,
net::ProxyServer::Scheme default_scheme,
net::ProxyServer* proxy_server,
- std::string* error) {
+ std::string* error) const {
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);
+ dict->GetStringASCII(keys::kProxyCfgScheme, &scheme_string);
net::ProxyServer::Scheme scheme =
net::ProxyServer::GetSchemeFromURI(scheme_string);
@@ -356,7 +180,7 @@ bool ProxyPrefTransformer::GetProxyServer(
// TODO(battre): handle UTF-8 in hostnames (http://crbug.com/72692)
string16 host16;
- if (!dict->GetString(kProxyCfgRuleHost, &host16)) {
+ if (!dict->GetString(keys::kProxyCfgRuleHost, &host16)) {
LOG(ERROR) << "Could not parse a 'rules.*.host' entry.";
return false;
}
@@ -370,7 +194,7 @@ bool ProxyPrefTransformer::GetProxyServer(
std::string host = UTF16ToASCII(host16);
int port; // optional.
- if (!dict->GetInteger(kProxyCfgRulePort, &port))
+ if (!dict->GetInteger(keys::kProxyCfgRulePort, &port))
port = net::ProxyServer::GetDefaultPortForScheme(scheme);
*proxy_server = net::ProxyServer(scheme, net::HostPortPair(host, port));
@@ -378,25 +202,29 @@ bool ProxyPrefTransformer::GetProxyServer(
return true;
}
-bool ProxyPrefTransformer::GetProxyRules(DictionaryValue* proxy_rules,
- std::string* out,
- std::string* error) {
+bool ProxyPrefTransformer::GetProxyRulesStringFromExtensionPref(
+ const DictionaryValue* proxy_config,
+ std::string* out,
+ std::string* error) const {
+ DictionaryValue* proxy_rules = NULL;
+ proxy_config->GetDictionary(keys::kProxyCfgRules, &proxy_rules);
if (!proxy_rules)
- return false;
+ return true;
// 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];
+ bool has_proxy[keys::SCHEME_MAX + 1];
+ DictionaryValue* proxy_dict[keys::SCHEME_MAX + 1];
+ net::ProxyServer proxy_server[keys::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]);
+ for (size_t i = 0; i <= keys::SCHEME_MAX; ++i) {
+ has_proxy[i] = proxy_rules->GetDictionary(keys::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,
@@ -408,16 +236,16 @@ bool ProxyPrefTransformer::GetProxyRules(DictionaryValue* proxy_rules,
}
// Handle case that only singleProxy is specified.
- if (has_proxy[SCHEME_ALL]) {
- for (size_t i = 1; i <= SCHEME_MAX; ++i) {
+ if (has_proxy[keys::SCHEME_ALL]) {
+ for (size_t i = 1; i <= keys::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]);
+ keys::field_name[keys::SCHEME_ALL], keys::field_name[i]);
return false;
}
}
- *out = proxy_server[SCHEME_ALL].ToURI();
+ *out = proxy_server[keys::SCHEME_ALL].ToURI();
return true;
}
@@ -425,12 +253,12 @@ bool ProxyPrefTransformer::GetProxyRules(DictionaryValue* proxy_rules,
// Build the proxy preference string.
std::string proxy_pref;
- for (size_t i = 1; i <= SCHEME_MAX; ++i) {
+ for (size_t i = 1; i <= keys::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(keys::scheme_name[i]);
proxy_pref.append("=");
proxy_pref.append(proxy_server[i].ToURI());
}
@@ -443,7 +271,7 @@ bool ProxyPrefTransformer::GetProxyRules(DictionaryValue* proxy_rules,
bool ProxyPrefTransformer::JoinUrlList(ListValue* list,
const std::string& joiner,
std::string* out,
- std::string* error) {
+ std::string* error) const {
std::string result;
for (size_t i = 0; i < list->GetSize(); ++i) {
if (!result.empty())
@@ -465,18 +293,21 @@ bool ProxyPrefTransformer::JoinUrlList(ListValue* list,
return true;
}
-bool ProxyPrefTransformer::GetBypassList(DictionaryValue* proxy_rules,
- std::string* out,
- std::string* error) {
+bool ProxyPrefTransformer::GetBypassListFromExtensionPref(
+ const DictionaryValue* proxy_config,
+ std::string *out,
+ std::string* error) const {
+ DictionaryValue* proxy_rules = NULL;
+ proxy_config->GetDictionary(keys::kProxyCfgRules, &proxy_rules);
if (!proxy_rules)
- return false;
+ return true;
ListValue* bypass_list;
- if (!proxy_rules->HasKey(kProxyCfgBypassList)) {
+ if (!proxy_rules->HasKey(keys::kProxyCfgBypassList)) {
*out = "";
return true;
}
- if (!proxy_rules->GetList(kProxyCfgBypassList, &bypass_list)) {
+ if (!proxy_rules->GetList(keys::kProxyCfgBypassList, &bypass_list)) {
LOG(ERROR) << "'rules.bypassList' not be parsed.";
return false;
}
@@ -484,64 +315,225 @@ bool ProxyPrefTransformer::GetBypassList(DictionaryValue* proxy_rules,
return JoinUrlList(bypass_list, ",", out, error);
}
-bool ProxyPrefTransformer::ParseRules(const std::string& rules,
- DictionaryValue* out) const {
- net::ProxyConfig::ProxyRules config;
- config.ParseFromString(rules);
+Value* ProxyPrefTransformer::ExtensionToBrowserPref(
+ ProxyPrefs::ProxyMode mode_enum,
+ const std::string& pac_url,
+ const std::string& pac_data,
+ const std::string& proxy_rules_string,
+ const std::string& bypass_list,
+ std::string* error) const {
+ DictionaryValue* result_proxy_config = NULL;
+ switch (mode_enum) {
+ case ProxyPrefs::MODE_DIRECT:
+ result_proxy_config = ProxyConfigDictionary::CreateDirect();
+ break;
+ case ProxyPrefs::MODE_AUTO_DETECT:
+ result_proxy_config = ProxyConfigDictionary::CreateAutoDetect();
+ break;
+ case ProxyPrefs::MODE_PAC_SCRIPT: {
+ 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 NULL;
+ }
+ } else {
+ *error = "Proxy mode 'pac_script' requires a 'pacScript' field with "
+ "either a 'url' field or a 'data' field.";
+ return NULL;
+ }
+ result_proxy_config = ProxyConfigDictionary::CreatePacScript(url);
+ break;
+ }
+ case ProxyPrefs::MODE_FIXED_SERVERS: {
+ if (proxy_rules_string.empty()) {
+ *error = "Proxy mode 'fixed_servers' requires a 'rules' field.";
+ return NULL;
+ }
+ result_proxy_config = ProxyConfigDictionary::CreateFixedServers(
+ proxy_rules_string, bypass_list);
+ break;
+ }
+ case ProxyPrefs::MODE_SYSTEM:
+ result_proxy_config = ProxyConfigDictionary::CreateSystem();
+ break;
+ case ProxyPrefs::kModeCount:
+ NOTREACHED();
+ }
+ if (!result_proxy_config)
+ return NULL;
+ return result_proxy_config;
+}
+
+Value* ProxyPrefTransformer::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);
+
+ ProxyPrefs::ProxyMode mode_enum;
+ std::string pac_url;
+ std::string pac_data;
+ std::string proxy_rules_string;
+ std::string bypass_list;
+ if (!GetProxyModeFromExtensionPref(proxy_config, &mode_enum, error) ||
+ !GetPacUrlFromExtensionPref(proxy_config, &pac_url, error) ||
+ !GetPacDataFromExtensionPref(proxy_config, &pac_data, error) ||
+ !GetProxyRulesStringFromExtensionPref(proxy_config, &proxy_rules_string,
+ error) ||
+ !GetBypassListFromExtensionPref(proxy_config, &bypass_list, error))
+ return NULL;
+
+ return ExtensionToBrowserPref(mode_enum, pac_url, pac_data,
+ proxy_rules_string, bypass_list, error);
+}
+
+
+// Browser Pref -> Extension Pref conversion.
+
+Value* ProxyPrefTransformer::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 NULL;
+ }
+
+ scoped_ptr<DictionaryValue> extension_pref(new DictionaryValue);
+ extension_pref->SetString(keys::kProxyCfgMode,
+ ProxyPrefs::ProxyModeToString(mode));
+
+ switch (mode) {
+ case ProxyPrefs::MODE_DIRECT:
+ case ProxyPrefs::MODE_AUTO_DETECT:
+ case ProxyPrefs::MODE_SYSTEM:
+ // These modes have no further parameters.
+ break;
+ case ProxyPrefs::MODE_PAC_SCRIPT: {
+ std::string pac_url;
+ if (!dict.GetPacUrl(&pac_url)) {
+ 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)) {
+ LOG(ERROR) << "Cannot decode base64-encoded PAC data URL.";
+ return NULL;
+ }
+ pac_dict->SetString(keys::kProxyCfgPacScriptData, pac_data);
+ } else {
+ pac_dict->SetString(keys::kProxyCfgPacScriptUrl, pac_url);
+ }
+ extension_pref->Set(keys::kProxyCfgPacScript, pac_dict);
+ break;
+ }
+ case ProxyPrefs::MODE_FIXED_SERVERS: {
+ scoped_ptr<DictionaryValue> rules_dict(new DictionaryValue);
+
+ std::string proxy_servers;
+ if (!dict.GetProxyServer(&proxy_servers)) {
+ LOG(ERROR) << "Missing proxy servers in configuration.";
+ return NULL;
+ }
+ net::ProxyConfig::ProxyRules config;
+ config.ParseFromString(proxy_servers);
+ if (!ConvertProxyRules(config, rules_dict.get())) {
+ 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)) {
+ LOG(ERROR) << "Invalid bypassList in configuration.";
+ return NULL;
+ }
+ ListValue* bypass_list = NULL;
+ TokenizeToStringList(bypass_list_string, ",;", &bypass_list);
+ rules_dict->Set(keys::kProxyCfgBypassList, bypass_list);
+ }
+ extension_pref->Set(keys::kProxyCfgRules, rules_dict.release());
+ break;
+ }
+ case ProxyPrefs::kModeCount:
+ NOTREACHED();
+ }
+ return extension_pref.release();
+}
+
+bool ProxyPrefTransformer::ConvertProxyRules(
+ const net::ProxyConfig::ProxyRules& config,
+ DictionaryValue* extension_proxy_rules) const {
+ DictionaryValue* extension_proxy_server = NULL;
switch (config.type) {
case net::ProxyConfig::ProxyRules::TYPE_NO_RULES:
return false;
case net::ProxyConfig::ProxyRules::TYPE_SINGLE_PROXY:
if (config.single_proxy.is_valid()) {
- out->Set(field_name[SCHEME_ALL],
- ConvertToDictionary(config.single_proxy));
+ ConvertProxyServer(config.single_proxy, &extension_proxy_server);
+ extension_proxy_rules->Set(keys::field_name[keys::SCHEME_ALL],
+ extension_proxy_server);
}
break;
case net::ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME:
if (config.proxy_for_http.is_valid()) {
- out->Set(field_name[SCHEME_HTTP],
- ConvertToDictionary(config.proxy_for_http));
+ ConvertProxyServer(config.proxy_for_http, &extension_proxy_server);
+ extension_proxy_rules->Set(keys::field_name[keys::SCHEME_HTTP],
+ extension_proxy_server);
}
if (config.proxy_for_https.is_valid()) {
- out->Set(field_name[SCHEME_HTTPS],
- ConvertToDictionary(config.proxy_for_https));
+ ConvertProxyServer(config.proxy_for_https, &extension_proxy_server);
+ extension_proxy_rules->Set(keys::field_name[keys::SCHEME_HTTPS],
+ extension_proxy_server);
}
if (config.proxy_for_ftp.is_valid()) {
- out->Set(field_name[SCHEME_FTP],
- ConvertToDictionary(config.proxy_for_ftp));
+ ConvertProxyServer(config.proxy_for_ftp, &extension_proxy_server);
+ extension_proxy_rules->Set(keys::field_name[keys::SCHEME_FTP],
+ extension_proxy_server);
}
if (config.fallback_proxy.is_valid()) {
- out->Set(field_name[SCHEME_FALLBACK],
- ConvertToDictionary(config.fallback_proxy));
+ ConvertProxyServer(config.fallback_proxy, &extension_proxy_server);
+ extension_proxy_rules->Set(keys::field_name[keys::SCHEME_FALLBACK],
+ extension_proxy_server);
}
- COMPILE_ASSERT(SCHEME_MAX == 4, SCHEME_FORGOTTEN);
break;
}
+ COMPILE_ASSERT(keys::SCHEME_MAX == 4, SCHEME_FORGOTTEN);
return true;
}
-DictionaryValue* ProxyPrefTransformer::ConvertToDictionary(
- const net::ProxyServer& proxy) const {
- DictionaryValue* out = new DictionaryValue;
+void ProxyPrefTransformer::ConvertProxyServer(
+ const net::ProxyServer& proxy,
+ DictionaryValue** extension_proxy_server) const {
+ scoped_ptr<DictionaryValue> out(new DictionaryValue);
switch (proxy.scheme()) {
case net::ProxyServer::SCHEME_HTTP:
- out->SetString(kProxyCfgScheme, "http");
+ out->SetString(keys::kProxyCfgScheme, "http");
break;
case net::ProxyServer::SCHEME_HTTPS:
- out->SetString(kProxyCfgScheme, "https");
+ out->SetString(keys::kProxyCfgScheme, "https");
break;
case net::ProxyServer::SCHEME_SOCKS4:
- out->SetString(kProxyCfgScheme, "socks4");
+ out->SetString(keys::kProxyCfgScheme, "socks4");
break;
case net::ProxyServer::SCHEME_SOCKS5:
- out->SetString(kProxyCfgScheme, "socks5");
+ out->SetString(keys::kProxyCfgScheme, "socks5");
break;
case net::ProxyServer::SCHEME_DIRECT:
case net::ProxyServer::SCHEME_INVALID:
NOTREACHED();
- return out;
+ return;
}
- out->SetString(kProxyCfgRuleHost, proxy.host_port_pair().host());
- out->SetInteger(kProxyCfgRulePort, proxy.host_port_pair().port());
- return out;
+ out->SetString(keys::kProxyCfgRuleHost, proxy.host_port_pair().host());
+ out->SetInteger(keys::kProxyCfgRulePort, proxy.host_port_pair().port());
+ (*extension_proxy_server) = out.release();
}