Index: chrome_proxy_resolver.cc |
diff --git a/chrome_proxy_resolver.cc b/chrome_proxy_resolver.cc |
new file mode 100644 |
index 0000000000000000000000000000000000000000..0aeb290f20c2afd1e441efd1c5efccaed9922ff5 |
--- /dev/null |
+++ b/chrome_proxy_resolver.cc |
@@ -0,0 +1,193 @@ |
+// Copyright (c) 2010 The Chromium Authors. All rights reserved. |
petkov
2010/11/18 23:26:46
Chromium OS
adlr
2010/11/19 00:41:06
Done.
|
+// 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 <string> |
petkov
2010/11/18 23:26:46
no need to include it again
adlr
2010/11/19 00:41:06
Done.
|
+ |
+#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 { |
+ |
+extern const char kNoProxy[]; |
petkov
2010/11/18 23:26:46
declared in proxy_resolver.h already? remove
adlr
2010/11/19 00:41:06
Done.
|
+ |
+const char kSessionManagerService[] = "org.chromium.SessionManager"; |
+const char kSessionManagerPath[] = "/org/chromium/SessionManager"; |
+const char kSessionManagerInterface[] = "org.chromium.SessionManagerInterface"; |
+const char kSessionManagerRetreivePropertyMethod[] = |
petkov
2010/11/18 23:26:46
Retrieve
adlr
2010/11/19 00:41:06
Done.
|
+ "RetrieveProperty"; |
+const char kSessionManagerProxySettingsKey[] = "cros.proxy.everywhere"; |
+ |
+bool ChromeProxyResolver::ProxyForUrl(const std::string& url, |
+ std::vector<std::string>* out_proxies) { |
+ // First, query dbus for the currently stored settings |
+ DBusGProxy* proxy = NULL; |
+ TEST_AND_RETURN_FALSE(DbusProxy(&proxy)); |
+ string json_settings; |
+ TEST_AND_RETURN_FALSE(JsonProxySettings(proxy, &json_settings)); |
+ LOG(INFO) << "got settings:" << json_settings; |
+ TEST_AND_RETURN_FALSE( |
+ ProxyForUrlWithSettings(url, json_settings, out_proxies)); |
+ return true; |
+} |
+bool ChromeProxyResolver::JsonProxySettings(DBusGProxy* proxy, |
petkov
2010/11/18 23:26:46
add empty line before
adlr
2010/11/19 00:41:06
Done.
|
+ std::string* out_json) { |
+ gchar* value = NULL; |
+ GArray* sig = NULL; |
+ GError* error = NULL; |
+ TEST_AND_RETURN_FALSE( |
+ dbus_->ProxyCall(proxy, |
+ kSessionManagerRetreivePropertyMethod, |
+ &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; |
+} |
+ |
+bool ChromeProxyResolver::DbusProxy(DBusGProxy** out_proxy) { |
+ GError* error = NULL; |
+ DBusGConnection* bus = dbus_->BusGet(DBUS_BUS_SYSTEM, &error); |
+ if (!bus) { |
petkov
2010/11/18 23:26:46
You may as well TEST_AND_RETURN_FALSE(bus) here un
adlr
2010/11/19 00:41:06
Done.
|
+ LOG(ERROR) << "Failed to get system bus"; |
+ return false; |
+ } |
+ DBusGProxy* proxy = dbus_->ProxyNewForNameOwner(bus, |
+ kSessionManagerService, |
+ kSessionManagerPath, |
+ kSessionManagerInterface, |
+ &error); |
+ if (!proxy) { |
+ LOG(ERROR) << "Error getting FlimFlam proxy: " |
+ << utils::GetGErrorMessage(error); |
+ return false; |
+ } |
+ *out_proxy = proxy; |
+ return true; |
+} |
+ |
+namespace { |
+enum ProxyMode { |
+ kProxyModeDirect = 0, |
+ kProxyModeAutoDetect, |
+ kProxyModePACScript, |
+ kProxyModeSingle, |
+ kProxyModeProxyPerScheme |
+}; |
+} // namespace {} |
+ |
+bool ChromeProxyResolver::ProxyForUrlWithSettings( |
+ 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; |
+} |
+ |
petkov
2010/11/18 23:26:46
remove extra blank line
adlr
2010/11/19 00:41:06
Done.
|
+ |
+bool ChromeProxyResolver::ProxyTypeForProxy(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 |