OLD | NEW |
1 // Copyright (c) 2011 The Chromium Authors. All rights reserved. | 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 | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "chrome/browser/extensions/extension_proxy_api.h" | 5 #include "chrome/browser/extensions/extension_proxy_api.h" |
6 | 6 |
7 #include "base/string_util.h" | 7 #include "base/string_util.h" |
8 #include "base/values.h" | 8 #include "base/values.h" |
9 #include "chrome/browser/prefs/proxy_config_dictionary.h" | 9 #include "chrome/browser/prefs/proxy_config_dictionary.h" |
10 #include "chrome/browser/profiles/profile.h" | 10 #include "chrome/browser/profiles/profile.h" |
11 #include "chrome/browser/extensions/extension_service.h" | 11 #include "chrome/browser/extensions/extension_service.h" |
12 #include "chrome/common/pref_names.h" | 12 #include "chrome/common/pref_names.h" |
13 #include "net/base/host_port_pair.h" | 13 #include "net/proxy/proxy_config.h" |
14 #include "net/proxy/proxy_server.h" | |
15 | 14 |
16 namespace { | 15 namespace { |
17 | 16 |
18 // The scheme for which to use a manually specified proxy, not of the proxy URI | 17 // The scheme for which to use a manually specified proxy, not of the proxy URI |
19 // itself. | 18 // itself. |
20 enum { | 19 enum { |
21 SCHEME_ALL = 0, | 20 SCHEME_ALL = 0, |
22 SCHEME_HTTP, | 21 SCHEME_HTTP, |
23 SCHEME_HTTPS, | 22 SCHEME_HTTPS, |
24 SCHEME_FTP, | 23 SCHEME_FTP, |
(...skipping 11 matching lines...) Expand all Loading... |
36 | 35 |
37 // The names of the schemes to be used to build the preference value string | 36 // The names of the schemes to be used to build the preference value string |
38 // for manual proxy settings. These must be kept in sync with the SCHEME_* | 37 // for manual proxy settings. These must be kept in sync with the SCHEME_* |
39 // constants. | 38 // constants. |
40 const char* scheme_name[] = { "*error*", | 39 const char* scheme_name[] = { "*error*", |
41 "http", | 40 "http", |
42 "https", | 41 "https", |
43 "ftp", | 42 "ftp", |
44 "socks" }; | 43 "socks" }; |
45 | 44 |
| 45 // String literals in dictionaries used to communicate with extension. |
| 46 const char kProxyCfgMode[] = "mode"; |
| 47 const char kProxyCfgPacScript[] = "pacScript"; |
| 48 const char kProxyCfgPacScriptUrl[] = "url"; |
| 49 const char kProxyCfgRules[] = "rules"; |
| 50 const char kProxyCfgRuleHost[] = "host"; |
| 51 const char kProxyCfgRulePort[] = "port"; |
| 52 const char kProxyCfgScheme[] = "scheme"; |
| 53 |
46 COMPILE_ASSERT(SCHEME_MAX == SCHEME_SOCKS, SCHEME_MAX_must_equal_SCHEME_SOCKS); | 54 COMPILE_ASSERT(SCHEME_MAX == SCHEME_SOCKS, SCHEME_MAX_must_equal_SCHEME_SOCKS); |
47 COMPILE_ASSERT(arraysize(field_name) == SCHEME_MAX + 1, | 55 COMPILE_ASSERT(arraysize(field_name) == SCHEME_MAX + 1, |
48 field_name_array_is_wrong_size); | 56 field_name_array_is_wrong_size); |
49 COMPILE_ASSERT(arraysize(scheme_name) == SCHEME_MAX + 1, | 57 COMPILE_ASSERT(arraysize(scheme_name) == SCHEME_MAX + 1, |
50 scheme_name_array_is_wrong_size); | 58 scheme_name_array_is_wrong_size); |
51 COMPILE_ASSERT(SCHEME_ALL == 0, singleProxy_must_be_first_option); | 59 COMPILE_ASSERT(SCHEME_ALL == 0, singleProxy_must_be_first_option); |
52 | 60 |
53 // Converts a proxy server description |dict| as passed by the API caller | 61 // Converts a proxy server description |dict| as passed by the API caller |
54 // (e.g. for the http proxy in the rules element) and converts it to a | 62 // (e.g. for the http proxy in the rules element) and converts it to a |
55 // ProxyServer. Returns true if successful. | 63 // ProxyServer. Returns true if successful. |
56 bool GetProxyServer(const DictionaryValue* dict, | 64 bool GetProxyServer(const DictionaryValue* dict, |
57 net::ProxyServer::Scheme default_scheme, | 65 net::ProxyServer::Scheme default_scheme, |
58 net::ProxyServer* proxy_server) { | 66 net::ProxyServer* proxy_server) { |
59 std::string scheme_string; // optional. | 67 std::string scheme_string; // optional. |
60 dict->GetString("scheme", &scheme_string); | 68 dict->GetString(kProxyCfgScheme, &scheme_string); |
61 | 69 |
62 net::ProxyServer::Scheme scheme = | 70 net::ProxyServer::Scheme scheme = |
63 net::ProxyServer::GetSchemeFromURI(scheme_string); | 71 net::ProxyServer::GetSchemeFromURI(scheme_string); |
64 if (scheme == net::ProxyServer::SCHEME_INVALID) | 72 if (scheme == net::ProxyServer::SCHEME_INVALID) |
65 scheme = default_scheme; | 73 scheme = default_scheme; |
66 | 74 |
67 std::string host; | 75 std::string host; |
68 if (!dict->GetString("host", &host)) | 76 if (!dict->GetString(kProxyCfgRuleHost, &host)) |
69 return false; | 77 return false; |
70 | 78 |
71 int port; // optional. | 79 int port; // optional. |
72 if (!dict->GetInteger("port", &port)) | 80 if (!dict->GetInteger(kProxyCfgRulePort, &port)) |
73 port = net::ProxyServer::GetDefaultPortForScheme(scheme); | 81 port = net::ProxyServer::GetDefaultPortForScheme(scheme); |
74 | 82 |
75 *proxy_server = net::ProxyServer(scheme, net::HostPortPair(host, port)); | 83 *proxy_server = net::ProxyServer(scheme, net::HostPortPair(host, port)); |
76 | 84 |
77 return true; | 85 return true; |
78 } | 86 } |
79 | 87 |
80 // Converts a proxy "rules" element passed by the API caller into a proxy | 88 // Converts a proxy "rules" element passed by the API caller into a proxy |
81 // configuration string that can be used by the proxy subsystem (see | 89 // configuration string that can be used by the proxy subsystem (see |
82 // proxy_config.h). Returns true if successful. | 90 // proxy_config.h). Returns true if successful. |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
136 | 144 |
137 *out = proxy_pref; | 145 *out = proxy_pref; |
138 return true; | 146 return true; |
139 } | 147 } |
140 | 148 |
141 } // namespace | 149 } // namespace |
142 | 150 |
143 void ProxySettingsFunction::ApplyPreference(const char* pref_path, | 151 void ProxySettingsFunction::ApplyPreference(const char* pref_path, |
144 Value* pref_value, | 152 Value* pref_value, |
145 bool incognito) { | 153 bool incognito) { |
146 profile()->GetExtensionService()->extension_prefs()-> | 154 Profile* use_profile = profile(); |
| 155 if (use_profile->IsOffTheRecord()) |
| 156 use_profile = use_profile->GetOriginalProfile(); |
| 157 |
| 158 use_profile->GetExtensionService()->extension_prefs()-> |
147 SetExtensionControlledPref(extension_id(), pref_path, incognito, | 159 SetExtensionControlledPref(extension_id(), pref_path, incognito, |
148 pref_value); | 160 pref_value); |
149 } | 161 } |
150 | 162 |
151 void ProxySettingsFunction::RemovePreference(const char* pref_path, | 163 void ProxySettingsFunction::RemovePreference(const char* pref_path, |
152 bool incognito) { | 164 bool incognito) { |
153 profile()->GetExtensionService()->extension_prefs()-> | 165 Profile* use_profile = profile(); |
| 166 if (use_profile->IsOffTheRecord()) |
| 167 use_profile = use_profile->GetOriginalProfile(); |
| 168 |
| 169 use_profile->GetExtensionService()->extension_prefs()-> |
154 RemoveExtensionControlledPref(extension_id(), pref_path, incognito); | 170 RemoveExtensionControlledPref(extension_id(), pref_path, incognito); |
155 } | 171 } |
156 | 172 |
157 bool UseCustomProxySettingsFunction::RunImpl() { | 173 bool UseCustomProxySettingsFunction::RunImpl() { |
158 DictionaryValue* proxy_config; | 174 DictionaryValue* proxy_config; |
159 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &proxy_config)); | 175 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &proxy_config)); |
160 | 176 |
161 bool incognito = false; // Optional argument, defaults to false. | 177 bool incognito = false; // Optional argument, defaults to false. |
162 if (HasOptionalArgument(1)) { | 178 if (HasOptionalArgument(1)) { |
163 EXTENSION_FUNCTION_VALIDATE(args_->GetBoolean(1, &incognito)); | 179 EXTENSION_FUNCTION_VALIDATE(args_->GetBoolean(1, &incognito)); |
164 } | 180 } |
165 | 181 |
166 std::string proxy_mode; | 182 std::string proxy_mode; |
167 proxy_config->GetString("mode", &proxy_mode); | 183 proxy_config->GetString(kProxyCfgMode, &proxy_mode); |
168 ProxyPrefs::ProxyMode mode_enum; | 184 ProxyPrefs::ProxyMode mode_enum; |
169 if (!ProxyPrefs::StringToProxyMode(proxy_mode, &mode_enum)) { | 185 if (!ProxyPrefs::StringToProxyMode(proxy_mode, &mode_enum)) { |
170 LOG(ERROR) << "Invalid mode for proxy settings: " << proxy_mode << ". " | 186 LOG(ERROR) << "Invalid mode for proxy settings: " << proxy_mode << ". " |
171 << "Setting custom proxy settings failed."; | 187 << "Setting custom proxy settings failed."; |
172 return false; | 188 return false; |
173 } | 189 } |
174 | 190 |
175 DictionaryValue* pac_dict = NULL; | 191 DictionaryValue* pac_dict = NULL; |
176 proxy_config->GetDictionary("pacScript", &pac_dict); | 192 proxy_config->GetDictionary(kProxyCfgPacScript, &pac_dict); |
177 std::string pac_url; | 193 std::string pac_url; |
178 if (pac_dict && !pac_dict->GetString("url", &pac_url)) { | 194 if (pac_dict && !pac_dict->GetString(kProxyCfgPacScriptUrl, &pac_url)) { |
179 LOG(ERROR) << "'pacScript' requires a 'url' field. " | 195 LOG(ERROR) << "'pacScript' requires a 'url' field. " |
180 << "Setting custom proxy settings failed."; | 196 << "Setting custom proxy settings failed."; |
181 return false; | 197 return false; |
182 } | 198 } |
183 | 199 |
184 DictionaryValue* proxy_rules = NULL; | 200 DictionaryValue* proxy_rules = NULL; |
185 proxy_config->GetDictionary("rules", &proxy_rules); | 201 proxy_config->GetDictionary(kProxyCfgRules, &proxy_rules); |
186 std::string proxy_rules_string; | 202 std::string proxy_rules_string; |
187 if (proxy_rules && !GetProxyRules(proxy_rules, &proxy_rules_string)) { | 203 if (proxy_rules && !GetProxyRules(proxy_rules, &proxy_rules_string)) { |
188 LOG(ERROR) << "Invalid 'rules' specified. " | 204 LOG(ERROR) << "Invalid 'rules' specified. " |
189 << "Setting custom proxy settings failed."; | 205 << "Setting custom proxy settings failed."; |
190 return false; | 206 return false; |
191 } | 207 } |
192 | 208 |
193 // not supported, yet. | 209 // not supported, yet. |
194 std::string bypass_list; | 210 std::string bypass_list; |
195 | 211 |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
235 | 251 |
236 bool RemoveCustomProxySettingsFunction::RunImpl() { | 252 bool RemoveCustomProxySettingsFunction::RunImpl() { |
237 bool incognito = false; | 253 bool incognito = false; |
238 if (HasOptionalArgument(0)) { | 254 if (HasOptionalArgument(0)) { |
239 EXTENSION_FUNCTION_VALIDATE(args_->GetBoolean(0, &incognito)); | 255 EXTENSION_FUNCTION_VALIDATE(args_->GetBoolean(0, &incognito)); |
240 } | 256 } |
241 | 257 |
242 RemovePreference(prefs::kProxy, incognito); | 258 RemovePreference(prefs::kProxy, incognito); |
243 return true; | 259 return true; |
244 } | 260 } |
| 261 |
| 262 bool GetCurrentProxySettingsFunction::RunImpl() { |
| 263 bool incognito = false; |
| 264 EXTENSION_FUNCTION_VALIDATE(args_->GetBoolean(0, &incognito)); |
| 265 |
| 266 // This is how it is stored in the PrefStores: |
| 267 const DictionaryValue* proxy_prefs; |
| 268 |
| 269 Profile* use_profile = profile(); |
| 270 if (use_profile->IsOffTheRecord()) |
| 271 use_profile = use_profile->GetOriginalProfile(); |
| 272 |
| 273 PrefService* prefs = incognito ? use_profile->GetOffTheRecordPrefs() |
| 274 : use_profile->GetPrefs(); |
| 275 proxy_prefs = prefs->GetDictionary(prefs::kProxy); |
| 276 |
| 277 // This is how it is presented to the API caller: |
| 278 scoped_ptr<DictionaryValue> out(new DictionaryValue); |
| 279 |
| 280 if (!ConvertToApiFormat(proxy_prefs, out.get())) |
| 281 return false; |
| 282 |
| 283 result_.reset(out.release()); |
| 284 return true; |
| 285 } |
| 286 |
| 287 bool GetCurrentProxySettingsFunction::ConvertToApiFormat( |
| 288 const DictionaryValue* proxy_prefs, |
| 289 DictionaryValue* api_proxy_config) const { |
| 290 ProxyConfigDictionary dict(proxy_prefs); |
| 291 |
| 292 ProxyPrefs::ProxyMode mode; |
| 293 if (!dict.GetMode(&mode)) { |
| 294 LOG(ERROR) << "Cannot determine proxy mode."; |
| 295 return false; |
| 296 } |
| 297 api_proxy_config->SetString(kProxyCfgMode, |
| 298 ProxyPrefs::ProxyModeToString(mode)); |
| 299 |
| 300 switch (mode) { |
| 301 case ProxyPrefs::MODE_DIRECT: |
| 302 case ProxyPrefs::MODE_AUTO_DETECT: |
| 303 case ProxyPrefs::MODE_SYSTEM: |
| 304 // These modes have no further parameters. |
| 305 break; |
| 306 case ProxyPrefs::MODE_PAC_SCRIPT: { |
| 307 std::string pac_url; |
| 308 if (!dict.GetPacUrl(&pac_url)) { |
| 309 LOG(ERROR) << "Missing pac url"; |
| 310 return false; |
| 311 } |
| 312 DictionaryValue* pac_dict = new DictionaryValue; |
| 313 pac_dict->SetString(kProxyCfgPacScriptUrl, pac_url); |
| 314 api_proxy_config->Set(kProxyCfgPacScript, pac_dict); |
| 315 break; |
| 316 } |
| 317 case ProxyPrefs::MODE_FIXED_SERVERS: { |
| 318 // TODO(battre): Handle bypass list. |
| 319 std::string proxy_servers; |
| 320 if (!dict.GetProxyServer(&proxy_servers)) { |
| 321 LOG(ERROR) << "Missing proxy servers"; |
| 322 return false; |
| 323 } |
| 324 DictionaryValue* rules_dict = new DictionaryValue; |
| 325 if (!ParseRules(proxy_servers, rules_dict)) { |
| 326 LOG(ERROR) << "Could not parse proxy rules"; |
| 327 return false; |
| 328 } |
| 329 api_proxy_config->Set(kProxyCfgRules, rules_dict); |
| 330 break; |
| 331 } |
| 332 case ProxyPrefs::kModeCount: |
| 333 NOTREACHED(); |
| 334 } |
| 335 return true; |
| 336 } |
| 337 |
| 338 bool GetCurrentProxySettingsFunction::ParseRules(const std::string& rules, |
| 339 DictionaryValue* out) const { |
| 340 net::ProxyConfig::ProxyRules config; |
| 341 config.ParseFromString(rules); |
| 342 switch (config.type) { |
| 343 case net::ProxyConfig::ProxyRules::TYPE_NO_RULES: |
| 344 return false; |
| 345 case net::ProxyConfig::ProxyRules::TYPE_SINGLE_PROXY: |
| 346 if (config.single_proxy.is_valid()) { |
| 347 out->Set(field_name[SCHEME_ALL], |
| 348 ConvertToDictionary(config.single_proxy)); |
| 349 } |
| 350 break; |
| 351 case net::ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME: |
| 352 if (config.proxy_for_http.is_valid()) { |
| 353 out->Set(field_name[SCHEME_HTTP], |
| 354 ConvertToDictionary(config.proxy_for_http)); |
| 355 } |
| 356 if (config.proxy_for_https.is_valid()) { |
| 357 out->Set(field_name[SCHEME_HTTPS], |
| 358 ConvertToDictionary(config.proxy_for_https)); |
| 359 } |
| 360 if (config.proxy_for_ftp.is_valid()) { |
| 361 out->Set(field_name[SCHEME_FTP], |
| 362 ConvertToDictionary(config.proxy_for_ftp)); |
| 363 } |
| 364 if (config.fallback_proxy.is_valid()) { |
| 365 out->Set(field_name[SCHEME_SOCKS], |
| 366 ConvertToDictionary(config.fallback_proxy)); |
| 367 } |
| 368 COMPILE_ASSERT(SCHEME_MAX == 4, SCHEME_FORGOTTEN); |
| 369 break; |
| 370 } |
| 371 return true; |
| 372 } |
| 373 |
| 374 DictionaryValue* GetCurrentProxySettingsFunction::ConvertToDictionary( |
| 375 const net::ProxyServer& proxy) const { |
| 376 DictionaryValue* out = new DictionaryValue; |
| 377 switch (proxy.scheme()) { |
| 378 case net::ProxyServer::SCHEME_HTTP: |
| 379 out->SetString(kProxyCfgScheme, "http"); |
| 380 break; |
| 381 case net::ProxyServer::SCHEME_HTTPS: |
| 382 out->SetString(kProxyCfgScheme, "https"); |
| 383 break; |
| 384 case net::ProxyServer::SCHEME_SOCKS4: |
| 385 out->SetString(kProxyCfgScheme, "socks4"); |
| 386 break; |
| 387 case net::ProxyServer::SCHEME_SOCKS5: |
| 388 out->SetString(kProxyCfgScheme, "socks5"); |
| 389 break; |
| 390 case net::ProxyServer::SCHEME_DIRECT: |
| 391 case net::ProxyServer::SCHEME_INVALID: |
| 392 NOTREACHED(); |
| 393 return out; |
| 394 } |
| 395 out->SetString(kProxyCfgRuleHost, proxy.host_port_pair().host()); |
| 396 out->SetInteger(kProxyCfgRulePort, proxy.host_port_pair().port()); |
| 397 return out; |
| 398 } |
OLD | NEW |