Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / chrome / browser / extensions / api / proxy / proxy_api.cc
blob148500709c6d66f79cb8456b008c5b40c223eed6
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 // Implementation of the Chrome Extensions Proxy Settings API.
7 #include "chrome/browser/extensions/api/proxy/proxy_api.h"
9 #include "base/json/json_writer.h"
10 #include "base/strings/stringprintf.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "base/values.h"
13 #include "chrome/browser/extensions/api/proxy/proxy_api_constants.h"
14 #include "chrome/browser/extensions/api/proxy/proxy_api_helpers.h"
15 #include "chrome/browser/extensions/event_router_forwarder.h"
16 #include "chrome/browser/extensions/extension_service.h"
17 #include "components/proxy_config/proxy_config_dictionary.h"
18 #include "net/base/net_errors.h"
20 namespace extensions {
22 namespace helpers = proxy_api_helpers;
23 namespace keys = proxy_api_constants;
25 // static
26 ProxyEventRouter* ProxyEventRouter::GetInstance() {
27 return base::Singleton<ProxyEventRouter>::get();
30 ProxyEventRouter::ProxyEventRouter() {
33 ProxyEventRouter::~ProxyEventRouter() {
36 void ProxyEventRouter::OnProxyError(
37 EventRouterForwarder* event_router,
38 void* profile,
39 int error_code) {
40 scoped_ptr<base::ListValue> args(new base::ListValue());
41 base::DictionaryValue* dict = new base::DictionaryValue();
42 dict->SetBoolean(keys::kProxyEventFatal, true);
43 dict->SetString(keys::kProxyEventError, net::ErrorToString(error_code));
44 dict->SetString(keys::kProxyEventDetails, std::string());
45 args->Append(dict);
47 if (profile) {
48 event_router->DispatchEventToRenderers(events::PROXY_ON_PROXY_ERROR,
49 keys::kProxyEventOnProxyError,
50 args.Pass(), profile, true, GURL());
51 } else {
52 event_router->BroadcastEventToRenderers(events::PROXY_ON_PROXY_ERROR,
53 keys::kProxyEventOnProxyError,
54 args.Pass(), GURL());
58 void ProxyEventRouter::OnPACScriptError(
59 EventRouterForwarder* event_router,
60 void* profile,
61 int line_number,
62 const base::string16& error) {
63 scoped_ptr<base::ListValue> args(new base::ListValue());
64 base::DictionaryValue* dict = new base::DictionaryValue();
65 dict->SetBoolean(keys::kProxyEventFatal, false);
66 dict->SetString(keys::kProxyEventError,
67 net::ErrorToString(net::ERR_PAC_SCRIPT_FAILED));
68 std::string error_msg;
69 if (line_number != -1) {
70 base::SStringPrintf(&error_msg,
71 "line: %d: %s",
72 line_number, base::UTF16ToUTF8(error).c_str());
73 } else {
74 error_msg = base::UTF16ToUTF8(error);
76 dict->SetString(keys::kProxyEventDetails, error_msg);
77 args->Append(dict);
79 if (profile) {
80 event_router->DispatchEventToRenderers(events::PROXY_ON_PROXY_ERROR,
81 keys::kProxyEventOnProxyError,
82 args.Pass(), profile, true, GURL());
83 } else {
84 event_router->BroadcastEventToRenderers(events::PROXY_ON_PROXY_ERROR,
85 keys::kProxyEventOnProxyError,
86 args.Pass(), GURL());
90 ProxyPrefTransformer::ProxyPrefTransformer() {
93 ProxyPrefTransformer::~ProxyPrefTransformer() {
96 base::Value* ProxyPrefTransformer::ExtensionToBrowserPref(
97 const base::Value* extension_pref,
98 std::string* error,
99 bool* bad_message) {
100 // When ExtensionToBrowserPref is called, the format of |extension_pref|
101 // has been verified already by the extension API to match the schema
102 // defined in the extension API JSON.
103 CHECK(extension_pref->IsType(base::Value::TYPE_DICTIONARY));
104 const base::DictionaryValue* config =
105 static_cast<const base::DictionaryValue*>(extension_pref);
107 // Extract the various pieces of information passed to
108 // chrome.proxy.settings.set(). Several of these strings will
109 // remain blank no respective values have been passed to set().
110 // If a values has been passed to set but could not be parsed, we bail
111 // out and return NULL.
112 ProxyPrefs::ProxyMode mode_enum;
113 bool pac_mandatory;
114 std::string pac_url;
115 std::string pac_data;
116 std::string proxy_rules_string;
117 std::string bypass_list;
118 if (!helpers::GetProxyModeFromExtensionPref(
119 config, &mode_enum, error, bad_message) ||
120 !helpers::GetPacMandatoryFromExtensionPref(
121 config, &pac_mandatory, error, bad_message) ||
122 !helpers::GetPacUrlFromExtensionPref(
123 config, &pac_url, error, bad_message) ||
124 !helpers::GetPacDataFromExtensionPref(
125 config, &pac_data, error, bad_message) ||
126 !helpers::GetProxyRulesStringFromExtensionPref(
127 config, &proxy_rules_string, error, bad_message) ||
128 !helpers::GetBypassListFromExtensionPref(
129 config, &bypass_list, error, bad_message)) {
130 return NULL;
133 return helpers::CreateProxyConfigDict(
134 mode_enum, pac_mandatory, pac_url, pac_data, proxy_rules_string,
135 bypass_list, error);
138 base::Value* ProxyPrefTransformer::BrowserToExtensionPref(
139 const base::Value* browser_pref) {
140 CHECK(browser_pref->IsType(base::Value::TYPE_DICTIONARY));
142 // This is a dictionary wrapper that exposes the proxy configuration stored in
143 // the browser preferences.
144 ProxyConfigDictionary config(
145 static_cast<const base::DictionaryValue*>(browser_pref));
147 ProxyPrefs::ProxyMode mode;
148 if (!config.GetMode(&mode)) {
149 LOG(ERROR) << "Cannot determine proxy mode.";
150 return NULL;
153 // Build a new ProxyConfig instance as defined in the extension API.
154 scoped_ptr<base::DictionaryValue> extension_pref(new base::DictionaryValue);
156 extension_pref->SetString(keys::kProxyConfigMode,
157 ProxyPrefs::ProxyModeToString(mode));
159 switch (mode) {
160 case ProxyPrefs::MODE_DIRECT:
161 case ProxyPrefs::MODE_AUTO_DETECT:
162 case ProxyPrefs::MODE_SYSTEM:
163 // These modes have no further parameters.
164 break;
165 case ProxyPrefs::MODE_PAC_SCRIPT: {
166 // A PAC URL either point to a PAC script or contain a base64 encoded
167 // PAC script. In either case we build a PacScript dictionary as defined
168 // in the extension API.
169 base::DictionaryValue* pac_dict = helpers::CreatePacScriptDict(config);
170 if (!pac_dict)
171 return NULL;
172 extension_pref->Set(keys::kProxyConfigPacScript, pac_dict);
173 break;
175 case ProxyPrefs::MODE_FIXED_SERVERS: {
176 // Build ProxyRules dictionary according to the extension API.
177 base::DictionaryValue* proxy_rules_dict =
178 helpers::CreateProxyRulesDict(config);
179 if (!proxy_rules_dict)
180 return NULL;
181 extension_pref->Set(keys::kProxyConfigRules, proxy_rules_dict);
182 break;
184 case ProxyPrefs::kModeCount:
185 NOTREACHED();
187 return extension_pref.release();
190 } // namespace extensions