Chromium Code Reviews| 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 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 157 bool UseCustomProxySettingsFunction::RunImpl() { | 165 bool UseCustomProxySettingsFunction::RunImpl() { |
| 158 DictionaryValue* proxy_config; | 166 DictionaryValue* proxy_config; |
| 159 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &proxy_config)); | 167 EXTENSION_FUNCTION_VALIDATE(args_->GetDictionary(0, &proxy_config)); |
| 160 | 168 |
| 161 bool incognito = false; // Optional argument, defaults to false. | 169 bool incognito = false; // Optional argument, defaults to false. |
| 162 if (HasOptionalArgument(1)) { | 170 if (HasOptionalArgument(1)) { |
| 163 EXTENSION_FUNCTION_VALIDATE(args_->GetBoolean(1, &incognito)); | 171 EXTENSION_FUNCTION_VALIDATE(args_->GetBoolean(1, &incognito)); |
| 164 } | 172 } |
| 165 | 173 |
| 166 std::string proxy_mode; | 174 std::string proxy_mode; |
| 167 proxy_config->GetString("mode", &proxy_mode); | 175 proxy_config->GetString(kProxyCfgMode, &proxy_mode); |
| 168 ProxyPrefs::ProxyMode mode_enum; | 176 ProxyPrefs::ProxyMode mode_enum; |
| 169 if (!ProxyPrefs::StringToProxyMode(proxy_mode, &mode_enum)) { | 177 if (!ProxyPrefs::StringToProxyMode(proxy_mode, &mode_enum)) { |
| 170 LOG(ERROR) << "Invalid mode for proxy settings: " << proxy_mode << ". " | 178 LOG(ERROR) << "Invalid mode for proxy settings: " << proxy_mode << ". " |
| 171 << "Setting custom proxy settings failed."; | 179 << "Setting custom proxy settings failed."; |
| 172 return false; | 180 return false; |
| 173 } | 181 } |
| 174 | 182 |
| 175 DictionaryValue* pac_dict = NULL; | 183 DictionaryValue* pac_dict = NULL; |
| 176 proxy_config->GetDictionary("pacScript", &pac_dict); | 184 proxy_config->GetDictionary(kProxyCfgPacScript, &pac_dict); |
| 177 std::string pac_url; | 185 std::string pac_url; |
| 178 if (pac_dict && !pac_dict->GetString("url", &pac_url)) { | 186 if (pac_dict && !pac_dict->GetString(kProxyCfgPacScriptUrl, &pac_url)) { |
| 179 LOG(ERROR) << "'pacScript' requires a 'url' field. " | 187 LOG(ERROR) << "'pacScript' requires a 'url' field. " |
| 180 << "Setting custom proxy settings failed."; | 188 << "Setting custom proxy settings failed."; |
| 181 return false; | 189 return false; |
| 182 } | 190 } |
| 183 | 191 |
| 184 DictionaryValue* proxy_rules = NULL; | 192 DictionaryValue* proxy_rules = NULL; |
| 185 proxy_config->GetDictionary("rules", &proxy_rules); | 193 proxy_config->GetDictionary(kProxyCfgRules, &proxy_rules); |
| 186 std::string proxy_rules_string; | 194 std::string proxy_rules_string; |
| 187 if (proxy_rules && !GetProxyRules(proxy_rules, &proxy_rules_string)) { | 195 if (proxy_rules && !GetProxyRules(proxy_rules, &proxy_rules_string)) { |
| 188 LOG(ERROR) << "Invalid 'rules' specified. " | 196 LOG(ERROR) << "Invalid 'rules' specified. " |
| 189 << "Setting custom proxy settings failed."; | 197 << "Setting custom proxy settings failed."; |
| 190 return false; | 198 return false; |
| 191 } | 199 } |
| 192 | 200 |
| 193 // not supported, yet. | 201 // not supported, yet. |
| 194 std::string bypass_list; | 202 std::string bypass_list; |
| 195 | 203 |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 235 | 243 |
| 236 bool RemoveCustomProxySettingsFunction::RunImpl() { | 244 bool RemoveCustomProxySettingsFunction::RunImpl() { |
| 237 bool incognito = false; | 245 bool incognito = false; |
| 238 if (HasOptionalArgument(0)) { | 246 if (HasOptionalArgument(0)) { |
| 239 EXTENSION_FUNCTION_VALIDATE(args_->GetBoolean(0, &incognito)); | 247 EXTENSION_FUNCTION_VALIDATE(args_->GetBoolean(0, &incognito)); |
| 240 } | 248 } |
| 241 | 249 |
| 242 RemovePreference(prefs::kProxy, incognito); | 250 RemovePreference(prefs::kProxy, incognito); |
| 243 return true; | 251 return true; |
| 244 } | 252 } |
| 253 | |
| 254 bool GetCurrentProxySettingsFunction::RunImpl() { | |
| 255 bool incognito = false; | |
| 256 EXTENSION_FUNCTION_VALIDATE(args_->GetBoolean(0, &incognito)); | |
| 257 | |
| 258 // This is how it is stored in the PrefStores: | |
| 259 const DictionaryValue* proxy_prefs; | |
| 260 | |
| 261 if (profile_->IsOffTheRecord() && !incognito) { | |
|
Bernhard Bauer
2011/02/10 12:38:01
Does this really happen? I thought |profile_| is a
battre
2011/02/10 13:42:36
I have added all access to profile_ as follows
| |
| 262 LOG(ERROR) << "Incognito profile cannot access the regular profile"; | |
| 263 } | |
| 264 PrefService* prefs = incognito ? profile_->GetOffTheRecordPrefs() | |
| 265 : profile_->GetPrefs(); | |
| 266 proxy_prefs = prefs->GetDictionary(prefs::kProxy); | |
| 267 | |
| 268 // This is how it is presented to the API caller: | |
| 269 scoped_ptr<DictionaryValue> out(new DictionaryValue); | |
| 270 | |
| 271 if (!ConvertToApiFormat(proxy_prefs, out.get())) | |
| 272 return false; | |
| 273 | |
| 274 result_.reset(out.release()); | |
| 275 return true; | |
| 276 } | |
| 277 | |
| 278 bool GetCurrentProxySettingsFunction::ConvertToApiFormat( | |
| 279 const DictionaryValue* proxy_prefs, | |
| 280 DictionaryValue* api_proxy_config) const { | |
| 281 ProxyConfigDictionary dict(proxy_prefs); | |
| 282 | |
| 283 ProxyPrefs::ProxyMode mode; | |
| 284 if (!dict.GetMode(&mode)) { | |
| 285 LOG(ERROR) << "Cannot determine proxy mode."; | |
| 286 return false; | |
| 287 } | |
| 288 api_proxy_config->SetString(kProxyCfgMode, | |
| 289 ProxyPrefs::ProxyModeToString(mode)); | |
| 290 | |
| 291 switch (mode) { | |
| 292 case ProxyPrefs::MODE_DIRECT: | |
| 293 case ProxyPrefs::MODE_AUTO_DETECT: | |
| 294 case ProxyPrefs::MODE_SYSTEM: | |
| 295 // These modes have no further parameters. | |
| 296 break; | |
| 297 case ProxyPrefs::MODE_PAC_SCRIPT: { | |
| 298 std::string pac_url; | |
| 299 if (!dict.GetPacUrl(&pac_url)) { | |
| 300 LOG(ERROR) << "Missing pac url"; | |
| 301 return false; | |
| 302 } | |
| 303 DictionaryValue* pac_dict = new DictionaryValue; | |
| 304 pac_dict->SetString(kProxyCfgPacScriptUrl, pac_url); | |
| 305 api_proxy_config->Set(kProxyCfgPacScript, pac_dict); | |
| 306 break; | |
| 307 } | |
| 308 case ProxyPrefs::MODE_FIXED_SERVERS: { | |
| 309 // TODO(battre): Handle bypass list. | |
| 310 std::string proxy_servers; | |
| 311 if (!dict.GetProxyServer(&proxy_servers)) { | |
| 312 LOG(ERROR) << "Missing proxy servers"; | |
| 313 return false; | |
| 314 } | |
| 315 DictionaryValue* rules_dict = new DictionaryValue; | |
| 316 if (!ParseRules(proxy_servers, &rules_dict)) { | |
| 317 LOG(ERROR) << "Could not parse proxy rules"; | |
| 318 return false; | |
| 319 } | |
| 320 api_proxy_config->Set(kProxyCfgRules, rules_dict); | |
| 321 break; | |
| 322 } | |
| 323 case ProxyPrefs::kModeCount: | |
| 324 NOTREACHED(); | |
| 325 } | |
| 326 return true; | |
| 327 } | |
| 328 | |
| 329 bool GetCurrentProxySettingsFunction::ParseRules(const std::string& rules, | |
| 330 DictionaryValue** out) const { | |
| 331 net::ProxyConfig::ProxyRules config; | |
| 332 config.ParseFromString(rules); | |
| 333 switch (config.type) { | |
| 334 case net::ProxyConfig::ProxyRules::TYPE_NO_RULES: | |
| 335 return false; | |
| 336 case net::ProxyConfig::ProxyRules::TYPE_SINGLE_PROXY: | |
| 337 if (config.single_proxy.is_valid()) { | |
| 338 (*out)->Set(field_name[SCHEME_ALL], | |
| 339 ConvertToDictionary(config.single_proxy)); | |
| 340 } | |
| 341 break; | |
| 342 case net::ProxyConfig::ProxyRules::TYPE_PROXY_PER_SCHEME: | |
| 343 if (config.proxy_for_http.is_valid()) { | |
| 344 (*out)->Set(field_name[SCHEME_HTTP], | |
| 345 ConvertToDictionary(config.proxy_for_http)); | |
| 346 } | |
| 347 if (config.proxy_for_https.is_valid()) { | |
| 348 (*out)->Set(field_name[SCHEME_HTTPS], | |
| 349 ConvertToDictionary(config.proxy_for_https)); | |
| 350 } | |
| 351 if (config.proxy_for_ftp.is_valid()) { | |
| 352 (*out)->Set(field_name[SCHEME_FTP], | |
| 353 ConvertToDictionary(config.proxy_for_ftp)); | |
| 354 } | |
| 355 if (config.fallback_proxy.is_valid()) { | |
| 356 (*out)->Set(field_name[SCHEME_SOCKS], | |
| 357 ConvertToDictionary(config.fallback_proxy)); | |
| 358 } | |
| 359 COMPILE_ASSERT(SCHEME_MAX == 4, SCHEME_FORGOTTEN); | |
| 360 break; | |
| 361 } | |
| 362 return true; | |
| 363 } | |
| 364 | |
| 365 DictionaryValue* GetCurrentProxySettingsFunction::ConvertToDictionary( | |
| 366 const net::ProxyServer& proxy) const { | |
| 367 // Creates a | |
| 368 // { | |
| 369 // scheme ( optional enumerated string | |
| 370 // ["http", "https", "socks", "socks4", "socks5"] ), | |
| 371 // host ( string ), | |
| 372 // port ( optional integer ) | |
| 373 // } | |
| 374 // dictionary. | |
|
Bernhard Bauer
2011/02/10 12:38:01
You could just refer to the ProxyServer type in |e
battre
2011/02/10 13:42:36
Deleted the comment and added the reference in the
| |
| 375 | |
| 376 DictionaryValue* out = new DictionaryValue; | |
| 377 | |
| 378 switch (proxy.scheme()) { | |
| 379 case net::ProxyServer::SCHEME_HTTP: | |
| 380 out->SetString(kProxyCfgScheme, "http"); | |
| 381 break; | |
| 382 case net::ProxyServer::SCHEME_HTTPS: | |
| 383 out->SetString(kProxyCfgScheme, "https"); | |
| 384 break; | |
| 385 case net::ProxyServer::SCHEME_SOCKS4: | |
| 386 out->SetString(kProxyCfgScheme, "socks4"); | |
| 387 break; | |
| 388 case net::ProxyServer::SCHEME_SOCKS5: | |
| 389 out->SetString(kProxyCfgScheme, "socks5"); | |
| 390 break; | |
| 391 case net::ProxyServer::SCHEME_DIRECT: | |
| 392 case net::ProxyServer::SCHEME_INVALID: | |
| 393 NOTREACHED(); | |
| 394 return out; | |
| 395 } | |
| 396 out->SetString(kProxyCfgRuleHost, proxy.host_port_pair().host()); | |
| 397 out->SetInteger(kProxyCfgRulePort, proxy.host_port_pair().port()); | |
| 398 return out; | |
| 399 } | |
| OLD | NEW |