- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / browser / extensions / api / proxy / proxy_api.cc
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.
4
5 // Implementation of the Chrome Extensions Proxy Settings API.
6
7 #include "chrome/browser/extensions/api/proxy/proxy_api.h"
8
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 "chrome/browser/prefs/proxy_config_dictionary.h"
18 #include "net/base/net_errors.h"
19
20 namespace extensions {
21
22 namespace helpers = proxy_api_helpers;
23 namespace keys = proxy_api_constants;
24
25 // static
26 ProxyEventRouter* ProxyEventRouter::GetInstance() {
27   return Singleton<ProxyEventRouter>::get();
28 }
29
30 ProxyEventRouter::ProxyEventRouter() {
31 }
32
33 ProxyEventRouter::~ProxyEventRouter() {
34 }
35
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);
46
47   if (profile) {
48     event_router->DispatchEventToRenderers(
49         keys::kProxyEventOnProxyError, args.Pass(), profile, true, GURL());
50   } else {
51     event_router->BroadcastEventToRenderers(
52         keys::kProxyEventOnProxyError, args.Pass(), GURL());
53   }
54 }
55
56 void ProxyEventRouter::OnPACScriptError(
57     EventRouterForwarder* event_router,
58     void* profile,
59     int line_number,
60     const string16& error) {
61   scoped_ptr<base::ListValue> args(new base::ListValue());
62   base::DictionaryValue* dict = new base::DictionaryValue();
63   dict->SetBoolean(keys::kProxyEventFatal, false);
64   dict->SetString(keys::kProxyEventError,
65                   net::ErrorToString(net::ERR_PAC_SCRIPT_FAILED));
66   std::string error_msg;
67   if (line_number != -1) {
68     base::SStringPrintf(
69         &error_msg, "line: %d: %s", line_number, UTF16ToUTF8(error).c_str());
70   } else {
71     error_msg = UTF16ToUTF8(error);
72   }
73   dict->SetString(keys::kProxyEventDetails, error_msg);
74   args->Append(dict);
75
76   if (profile) {
77     event_router->DispatchEventToRenderers(
78         keys::kProxyEventOnProxyError, args.Pass(), profile, true, GURL());
79   } else {
80     event_router->BroadcastEventToRenderers(
81         keys::kProxyEventOnProxyError, args.Pass(), GURL());
82   }
83 }
84
85 ProxyPrefTransformer::ProxyPrefTransformer() {
86 }
87
88 ProxyPrefTransformer::~ProxyPrefTransformer() {
89 }
90
91 Value* ProxyPrefTransformer::ExtensionToBrowserPref(const Value* extension_pref,
92                                                     std::string* error,
93                                                     bool* bad_message) {
94   // When ExtensionToBrowserPref is called, the format of |extension_pref|
95   // has been verified already by the extension API to match the schema
96   // defined in the extension API JSON.
97   CHECK(extension_pref->IsType(Value::TYPE_DICTIONARY));
98   const base::DictionaryValue* config =
99       static_cast<const base::DictionaryValue*>(extension_pref);
100
101   // Extract the various pieces of information passed to
102   // chrome.proxy.settings.set(). Several of these strings will
103   // remain blank no respective values have been passed to set().
104   // If a values has been passed to set but could not be parsed, we bail
105   // out and return NULL.
106   ProxyPrefs::ProxyMode mode_enum;
107   bool pac_mandatory;
108   std::string pac_url;
109   std::string pac_data;
110   std::string proxy_rules_string;
111   std::string bypass_list;
112   if (!helpers::GetProxyModeFromExtensionPref(
113           config, &mode_enum, error, bad_message) ||
114       !helpers::GetPacMandatoryFromExtensionPref(
115           config, &pac_mandatory, error, bad_message) ||
116       !helpers::GetPacUrlFromExtensionPref(
117           config, &pac_url, error, bad_message) ||
118       !helpers::GetPacDataFromExtensionPref(
119           config, &pac_data, error, bad_message) ||
120       !helpers::GetProxyRulesStringFromExtensionPref(
121           config, &proxy_rules_string, error, bad_message) ||
122       !helpers::GetBypassListFromExtensionPref(
123           config, &bypass_list, error, bad_message)) {
124     return NULL;
125   }
126
127   return helpers::CreateProxyConfigDict(
128       mode_enum, pac_mandatory, pac_url, pac_data, proxy_rules_string,
129       bypass_list, error);
130 }
131
132 Value* ProxyPrefTransformer::BrowserToExtensionPref(const Value* browser_pref) {
133   CHECK(browser_pref->IsType(Value::TYPE_DICTIONARY));
134
135   // This is a dictionary wrapper that exposes the proxy configuration stored in
136   // the browser preferences.
137   ProxyConfigDictionary config(
138       static_cast<const base::DictionaryValue*>(browser_pref));
139
140   ProxyPrefs::ProxyMode mode;
141   if (!config.GetMode(&mode)) {
142     LOG(ERROR) << "Cannot determine proxy mode.";
143     return NULL;
144   }
145
146   // Build a new ProxyConfig instance as defined in the extension API.
147   scoped_ptr<base::DictionaryValue> extension_pref(new base::DictionaryValue);
148
149   extension_pref->SetString(keys::kProxyConfigMode,
150                             ProxyPrefs::ProxyModeToString(mode));
151
152   switch (mode) {
153     case ProxyPrefs::MODE_DIRECT:
154     case ProxyPrefs::MODE_AUTO_DETECT:
155     case ProxyPrefs::MODE_SYSTEM:
156       // These modes have no further parameters.
157       break;
158     case ProxyPrefs::MODE_PAC_SCRIPT: {
159       // A PAC URL either point to a PAC script or contain a base64 encoded
160       // PAC script. In either case we build a PacScript dictionary as defined
161       // in the extension API.
162       base::DictionaryValue* pac_dict = helpers::CreatePacScriptDict(config);
163       if (!pac_dict)
164         return NULL;
165       extension_pref->Set(keys::kProxyConfigPacScript, pac_dict);
166       break;
167     }
168     case ProxyPrefs::MODE_FIXED_SERVERS: {
169       // Build ProxyRules dictionary according to the extension API.
170       base::DictionaryValue* proxy_rules_dict =
171           helpers::CreateProxyRulesDict(config);
172       if (!proxy_rules_dict)
173         return NULL;
174       extension_pref->Set(keys::kProxyConfigRules, proxy_rules_dict);
175       break;
176     }
177     case ProxyPrefs::kModeCount:
178       NOTREACHED();
179   }
180   return extension_pref.release();
181 }
182
183 }  // namespace extensions