Chromium Code Reviews| Index: chrome_proxy_resolver.cc |
| diff --git a/chrome_proxy_resolver.cc b/chrome_proxy_resolver.cc |
| new file mode 100644 |
| index 0000000000000000000000000000000000000000..2b824797e01d346bcbbac84eb0f50d1dd3c7dc4e |
| --- /dev/null |
| +++ b/chrome_proxy_resolver.cc |
| @@ -0,0 +1,184 @@ |
| +// Copyright (c) 2010 The Chromium OS Authors. All rights reserved. |
| +// Use of this source code is governed by a BSD-style license that can be |
| +// found in the LICENSE file. |
| + |
| +#include "update_engine/chrome_proxy_resolver.h" |
| + |
| +#include <base/json/json_reader.h> |
| +#include <base/scoped_ptr.h> |
| +#include <base/values.h> |
| + |
| +#include "update_engine/utils.h" |
| + |
| +using std::string; |
| +using std::vector; |
| + |
| +namespace chromeos_update_engine { |
| + |
| +const char kSessionManagerService[] = "org.chromium.SessionManager"; |
| +const char kSessionManagerPath[] = "/org/chromium/SessionManager"; |
| +const char kSessionManagerInterface[] = "org.chromium.SessionManagerInterface"; |
| +const char kSessionManagerRetrievePropertyMethod[] = |
| + "RetrieveProperty"; |
| +const char kSessionManagerProxySettingsKey[] = "cros.proxy.everywhere"; |
| + |
| +bool ChromeProxyResolver::GetProxiesForUrl(const std::string& url, |
| + std::vector<std::string>* out_proxies) { |
|
petkov
2010/11/19 01:09:19
indent is off
adlr
2010/11/19 02:00:52
Done.
|
| + // First, query dbus for the currently stored settings |
| + DBusGProxy* proxy = DbusProxy(); |
| + TEST_AND_RETURN_FALSE(proxy); |
| + string json_settings; |
| + TEST_AND_RETURN_FALSE(GetJsonProxySettings(proxy, &json_settings)); |
| + LOG(INFO) << "got settings:" << json_settings; |
| + TEST_AND_RETURN_FALSE( |
| + GetProxiesForUrlWithSettings(url, json_settings, out_proxies)); |
| + return true; |
| +} |
| + |
| +bool ChromeProxyResolver::GetJsonProxySettings(DBusGProxy* proxy, |
| + std::string* out_json) { |
| + gchar* value = NULL; |
| + GArray* sig = NULL; |
| + GError* error = NULL; |
| + TEST_AND_RETURN_FALSE( |
| + dbus_->ProxyCall(proxy, |
| + kSessionManagerRetrievePropertyMethod, |
| + &error, |
| + G_TYPE_STRING, kSessionManagerProxySettingsKey, |
| + G_TYPE_INVALID, |
| + G_TYPE_STRING, &value, |
| + DBUS_TYPE_G_UCHAR_ARRAY, &sig, |
| + G_TYPE_INVALID)); |
| + g_array_free(sig, false); |
| + out_json->assign(value); |
| + g_free(value); |
| + return true; |
| +} |
| + |
| +DBusGProxy* ChromeProxyResolver::DbusProxy() { |
| + GError* error = NULL; |
| + DBusGConnection* bus = dbus_->BusGet(DBUS_BUS_SYSTEM, &error); |
| + TEST_AND_RETURN_FALSE(bus); |
| + DBusGProxy* proxy = dbus_->ProxyNewForNameOwner(bus, |
| + kSessionManagerService, |
| + kSessionManagerPath, |
| + kSessionManagerInterface, |
| + &error); |
| + if (!proxy) { |
| + LOG(ERROR) << "Error getting FlimFlam proxy: " |
| + << utils::GetGErrorMessage(error); |
| + } |
| + return proxy; |
| +} |
| + |
| +namespace { |
| +enum ProxyMode { |
| + kProxyModeDirect = 0, |
| + kProxyModeAutoDetect, |
| + kProxyModePACScript, |
| + kProxyModeSingle, |
| + kProxyModeProxyPerScheme |
| +}; |
| +} // namespace {} |
| + |
| +bool ChromeProxyResolver::GetProxiesForUrlWithSettings( |
| + const string& url, |
| + const string& json_settings, |
| + std::vector<std::string>* out_proxies) { |
| + base::JSONReader parser; |
| + |
| + scoped_ptr<Value> root( |
| + parser.JsonToValue(json_settings, |
| + true, // check root is obj/arr |
| + false)); // false = disallow trailing comma |
| + if (!root.get()) { |
| + LOG(ERROR) << "Unable to parse \"" << json_settings << "\": " |
| + << parser.GetErrorMessage(); |
| + return false; |
| + } |
| + |
| + TEST_AND_RETURN_FALSE(root->IsType(Value::TYPE_DICTIONARY)); |
| + |
| + DictionaryValue* root_dict = dynamic_cast<DictionaryValue*>(root.get()); |
| + TEST_AND_RETURN_FALSE(root_dict); |
| + int mode = -1; |
| + TEST_AND_RETURN_FALSE(root_dict->GetInteger("mode", &mode)); |
| + |
| + LOG(INFO) << "proxy mode: " << mode; |
| + if (mode != kProxyModeSingle && |
| + mode != kProxyModeProxyPerScheme) { |
| + LOG(INFO) << "unsupported proxy scheme"; |
| + out_proxies->clear(); |
| + out_proxies->push_back(kNoProxy); |
| + return true; |
| + } |
| + if (mode == kProxyModeSingle) { |
| + LOG(INFO) << "single proxy mode"; |
| + string proxy_string; |
| + TEST_AND_RETURN_FALSE(root_dict->GetString("single.server", &proxy_string)); |
| + if (proxy_string.find("://") == string::npos) { |
| + // missing protocol, assume http. |
| + proxy_string = string("http://") + proxy_string; |
| + } |
| + out_proxies->clear(); |
| + out_proxies->push_back(proxy_string); |
| + LOG(INFO) << "single proxy: " << (*out_proxies)[0]; |
| + out_proxies->push_back(kNoProxy); |
| + return true; |
| + } |
| + // Proxy per scheme mode. |
| + LOG(INFO) << "proxy per scheme mode"; |
| + |
| + // Find which scheme we are |
| + bool url_is_http = utils::StringHasPrefix(url, "http://"); |
| + if (!url_is_http) |
| + TEST_AND_RETURN_FALSE(utils::StringHasPrefix(url, "https://")); |
| + |
| + // Using "proto_*" variables to refer to http or https |
| + const string proto_path = url_is_http ? "http.server" : "https.server"; |
| + const string socks_path = "socks.server"; |
| + |
| + out_proxies->clear(); |
| + |
| + string proto_server, socks_server; |
| + if (root_dict->GetString(proto_path, &proto_server)) { |
| + if (proto_server.find("://") == string::npos) { |
| + // missing protocol, assume http. |
| + proto_server = string("http://") + proto_server; |
| + } |
| + out_proxies->push_back(proto_server); |
| + LOG(INFO) << "got http/https server: " << proto_server; |
| + } |
| + if (root_dict->GetString(socks_path, &socks_server)) { |
| + out_proxies->push_back(socks_server); |
| + LOG(INFO) << "got socks server: " << proto_server; |
| + } |
| + out_proxies->push_back(kNoProxy); |
| + return true; |
| +} |
| + |
| +bool ChromeProxyResolver::GetTypeForProxy(const std::string& proxy, |
| + curl_proxytype* out_type) { |
| + if (utils::StringHasPrefix(proxy, "socks5://") || |
| + utils::StringHasPrefix(proxy, "socks://")) { |
| + *out_type = CURLPROXY_SOCKS5_HOSTNAME; |
| + return true; |
| + } |
| + if (utils::StringHasPrefix(proxy, "socks4://")) { |
| + *out_type = CURLPROXY_SOCKS4A; |
| + return true; |
| + } |
| + if (utils::StringHasPrefix(proxy, "http://") || |
| + utils::StringHasPrefix(proxy, "https://")) { |
| + *out_type = CURLPROXY_HTTP; |
| + return true; |
| + } |
| + if (utils::StringHasPrefix(proxy, kNoProxy)) { |
| + // known failure case. don't log. |
| + return false; |
| + } |
| + LOG(INFO) << "Unknown proxy type: " << proxy; |
| + return false; |
| +} |
| + |
| +} // namespace chromeos_update_engine |