• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright (c) 2011 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/extension_proxy_api.h"
8 
9 #include "base/json/json_writer.h"
10 #include "base/values.h"
11 #include "chrome/browser/extensions/extension_event_router_forwarder.h"
12 #include "chrome/browser/extensions/extension_proxy_api_constants.h"
13 #include "chrome/browser/extensions/extension_proxy_api_helpers.h"
14 #include "chrome/browser/extensions/extension_service.h"
15 #include "chrome/browser/prefs/proxy_config_dictionary.h"
16 #include "net/base/net_errors.h"
17 
18 namespace helpers = extension_proxy_api_helpers;
19 namespace keys = extension_proxy_api_constants;
20 
21 // static
GetInstance()22 ExtensionProxyEventRouter* ExtensionProxyEventRouter::GetInstance() {
23   return Singleton<ExtensionProxyEventRouter>::get();
24 }
25 
ExtensionProxyEventRouter()26 ExtensionProxyEventRouter::ExtensionProxyEventRouter() {
27 }
28 
~ExtensionProxyEventRouter()29 ExtensionProxyEventRouter::~ExtensionProxyEventRouter() {
30 }
31 
OnProxyError(ExtensionEventRouterForwarder * event_router,ProfileId profile_id,int error_code)32 void ExtensionProxyEventRouter::OnProxyError(
33     ExtensionEventRouterForwarder* event_router,
34     ProfileId profile_id,
35     int error_code) {
36   ListValue args;
37   DictionaryValue* dict = new DictionaryValue();
38   dict->SetBoolean(keys::kProxyEventFatal, true);
39   dict->SetString(keys::kProxyEventError, net::ErrorToString(error_code));
40   dict->SetString(keys::kProxyEventDetails, "");
41   args.Append(dict);
42 
43   std::string json_args;
44   base::JSONWriter::Write(&args, false, &json_args);
45 
46   if (profile_id != Profile::kInvalidProfileId) {
47     event_router->DispatchEventToRenderers(
48         keys::kProxyEventOnProxyError, json_args, profile_id, true, GURL());
49   } else {
50     event_router->BroadcastEventToRenderers(
51         keys::kProxyEventOnProxyError, json_args, GURL());
52   }
53 }
54 
ProxyPrefTransformer()55 ProxyPrefTransformer::ProxyPrefTransformer() {
56 }
57 
~ProxyPrefTransformer()58 ProxyPrefTransformer::~ProxyPrefTransformer() {
59 }
60 
ExtensionToBrowserPref(const Value * extension_pref,std::string * error)61 Value* ProxyPrefTransformer::ExtensionToBrowserPref(const Value* extension_pref,
62                                                     std::string* error) {
63   // When ExtensionToBrowserPref is called, the format of |extension_pref|
64   // has been verified already by the extension API to match the schema
65   // defined in chrome/common/extensions/api/extension_api.json.
66   CHECK(extension_pref->IsType(Value::TYPE_DICTIONARY));
67   const DictionaryValue* config =
68       static_cast<const DictionaryValue*>(extension_pref);
69 
70   // Extract the various pieces of information passed to
71   // chrome.experimental.proxy.settings.set(). Several of these strings will
72   // remain blank no respective values have been passed to set().
73   // If a values has been passed to set but could not be parsed, we bail
74   // out and return NULL.
75   ProxyPrefs::ProxyMode mode_enum;
76   std::string pac_url;
77   std::string pac_data;
78   std::string proxy_rules_string;
79   std::string bypass_list;
80   if (!helpers::GetProxyModeFromExtensionPref(config, &mode_enum, error) ||
81       !helpers::GetPacUrlFromExtensionPref(config, &pac_url, error) ||
82       !helpers::GetPacDataFromExtensionPref(config, &pac_data, error) ||
83       !helpers::GetProxyRulesStringFromExtensionPref(
84           config, &proxy_rules_string, error) ||
85       !helpers::GetBypassListFromExtensionPref(config, &bypass_list, error)) {
86     return NULL;
87   }
88 
89   return helpers::CreateProxyConfigDict(
90       mode_enum, pac_url, pac_data, proxy_rules_string, bypass_list, error);
91 }
92 
BrowserToExtensionPref(const Value * browser_pref)93 Value* ProxyPrefTransformer::BrowserToExtensionPref(const Value* browser_pref) {
94   CHECK(browser_pref->IsType(Value::TYPE_DICTIONARY));
95 
96   // This is a dictionary wrapper that exposes the proxy configuration stored in
97   // the browser preferences.
98   ProxyConfigDictionary config(
99       static_cast<const DictionaryValue*>(browser_pref));
100 
101   ProxyPrefs::ProxyMode mode;
102   if (!config.GetMode(&mode)) {
103     LOG(ERROR) << "Cannot determine proxy mode.";
104     return NULL;
105   }
106 
107   // Build a new ProxyConfig instance as defined in the extension API.
108   scoped_ptr<DictionaryValue> extension_pref(new DictionaryValue);
109 
110   extension_pref->SetString(keys::kProxyConfigMode,
111                             ProxyPrefs::ProxyModeToString(mode));
112 
113   switch (mode) {
114     case ProxyPrefs::MODE_DIRECT:
115     case ProxyPrefs::MODE_AUTO_DETECT:
116     case ProxyPrefs::MODE_SYSTEM:
117       // These modes have no further parameters.
118       break;
119     case ProxyPrefs::MODE_PAC_SCRIPT: {
120       // A PAC URL either point to a PAC script or contain a base64 encoded
121       // PAC script. In either case we build a PacScript dictionary as defined
122       // in the extension API.
123       DictionaryValue* pac_dict = helpers::CreatePacScriptDict(config);
124       if (!pac_dict)
125         return NULL;
126       extension_pref->Set(keys::kProxyConfigPacScript, pac_dict);
127       break;
128     }
129     case ProxyPrefs::MODE_FIXED_SERVERS: {
130       // Build ProxyRules dictionary according to the extension API.
131       DictionaryValue* proxy_rules_dict = helpers::CreateProxyRulesDict(config);
132       if (!proxy_rules_dict)
133         return NULL;
134       extension_pref->Set(keys::kProxyConfigRules, proxy_rules_dict);
135       break;
136     }
137     case ProxyPrefs::kModeCount:
138       NOTREACHED();
139   }
140   return extension_pref.release();
141 }
142