Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(123)

Unified Diff: net/proxy/proxy_config_service_linux.cc

Issue 49009: Proxy config for Linux (ProxyConfigServiceLinux)... (Closed) Base URL: http://src.chromium.org/svn/trunk/src/
Patch Set: '' Created 11 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: net/proxy/proxy_config_service_linux.cc
===================================================================
--- net/proxy/proxy_config_service_linux.cc (revision 0)
+++ net/proxy/proxy_config_service_linux.cc (revision 0)
@@ -0,0 +1,306 @@
+// Copyright (c) 2009 The Chromium 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 "net/proxy/proxy_config_service_linux.h"
+
+#include <ctype.h>
+#include <string.h>
+#include <gdk/gdk.h>
+#include <gconf/gconf-client.h>
+
+#include <string>
+#include <sstream>
+#include <vector>
+
+#include "base/string_tokenizer.h"
+#include "base/sys_string_conversions.h"
+#include "net/base/net_errors.h"
+#include "net/proxy/proxy_config.h"
+#include "net/proxy/proxy_info.h"
+#include "net/proxy/proxy_server.h"
+
+#define GCONF_MODE_KEY "/system/proxy/mode"
+#define GCONF_USE_HTTP_PROXY_KEY "/system/http_proxy/use_http_proxy"
+#define GCONF_AUTOCONFIG_KEY "/system/proxy/autoconfig_url"
+#define GCONF_SAME_PROXY_KEY "/system/http_proxy/use_same_proxy"
+#define GCONF_HTTP_PROXY_KEY "/system/http_proxy/host"
+#define GCONF_HTTP_PROXY_PORT_KEY "/system/http_proxy/port"
+#define GCONF_SHTTP_PROXY_KEY "/system/proxy/secure_host"
+#define GCONF_SHTTP_PROXY_PORT_KEY "/system/proxy/secure_port"
+#define GCONF_FTP_PROXY_KEY "/system/proxy/ftp_host"
+#define GCONF_FTP_PROXY_PORT_KEY "/system/proxy/ftp_port"
+#define GCONF_PROXY_BYPASS_LIST_KEY "/system/http_proxy/ignore_hosts"
+#define GCONF_SOCKS_PROXY_KEY "/system/proxy/socks_host"
+#define GCONF_SOCKS_PROXY_PORT_KEY "/system/proxy/socks_port"
+
+const struct SchemeInGCONF {
+ const gchar* scheme;
+ const gchar* host_key;
+ const gchar* port_key;
+} kSchemeInGCONF[] = {
+ {"http", GCONF_HTTP_PROXY_KEY, GCONF_HTTP_PROXY_PORT_KEY},
+ {"https", GCONF_SHTTP_PROXY_KEY, GCONF_SHTTP_PROXY_PORT_KEY},
+ {"ftp", GCONF_FTP_PROXY_KEY, GCONF_FTP_PROXY_PORT_KEY},
+};
+
+namespace net {
+
+// Simple test input data
+bool IsValidDomain(const std::string& str) {
eroman 2009/03/30 21:25:08 nit: make this "static".
+ if (str.size () < 3)
+ return false;
+ for (size_t i = 0; i < str.size(); i++) {
+ if ( !(isalnum(str[i]) || str[i] == '.' || str[i] == '-' ||
eroman 2009/03/30 21:25:08 nit: remove the space here "( !"
+ str[i] == ':' || str[i] == '[' || str [i] == ']'))
+ return false;
+ }
+ return true;
+}
+
+ProxyServer GetProxyServerFromGconf(
eroman 2009/03/30 21:25:08 nit: make this "static".
+ GConfClient* client,
+ ProxyServer::Scheme scheme,
+ const char* host_key,
+ const char* port_key) {
+ gchar* proxy_host = gconf_client_get_string(client, host_key, NULL);
+ gint proxy_port = gconf_client_get_int(client, port_key, NULL);
+
+ ProxyServer result; // Initialized to invalid.
eroman 2009/03/30 21:25:08 nit: two spaces between ";" and "/"
+
+ if (proxy_host != NULL && IsValidDomain(proxy_host)) {
+ if (proxy_port == 0)
+ proxy_port = ProxyServer::GetDefaultPortForScheme (scheme);
eroman 2009/03/30 21:25:08 nit: no space between "GetDefaultPortForScheme" an
+ result = ProxyServer(scheme, proxy_host, proxy_port);
+ }
+
+ g_free(proxy_host);
+ return result;
+}
+
+bool GetProxyConfigGCONF(ProxyConfig* config) {
eroman 2009/03/30 21:25:08 nit: make this "static".
+ bool res = true;
eroman 2009/03/30 21:25:08 nit: I would suggest a more descriptive name like
+ GConfClient* client = GCONF_CLIENT(gconf_client_get_default());
+ gchar* mode;
+
+ mode = gconf_client_get_string(client, GCONF_MODE_KEY, NULL);
+ if (mode) {
+ if (strcmp(mode, "auto") == 0) {
+ gchar* url = gconf_client_get_string(client, GCONF_AUTOCONFIG_KEY, NULL);
+ if (url) {
+ if (strlen (url))
+ config->pac_url = GURL(url);
+ else
+ config->auto_detect = true;
+ } else {
+ res = false;
+ }
+ g_free(url);
+ }
+
+ if (strcmp(mode, "manual") == 0) {
+ gboolean same_proxy, use_http_proxy;
+
+ use_http_proxy = gconf_client_get_bool(client, GCONF_USE_HTTP_PROXY_KEY,
+ NULL);
+ config->proxy_rules = "";
+
+ if (!use_http_proxy) {
+ ProxyServer proxy_server = GetProxyServerFromGconf(
+ client,
eroman 2009/03/30 21:25:08 nit: indent these parameters by 4 spaces instead o
+ ProxyServer::SCHEME_SOCKS4,
+ GCONF_SOCKS_PROXY_KEY,
+ GCONF_SOCKS_PROXY_PORT_KEY);
+
+ if (proxy_server.is_valid()) {
+ config->proxy_rules += proxy_server.ToURI();
+ } else {
+ res = false;
+ }
+ } else {
+ same_proxy = gconf_client_get_bool(client, GCONF_SAME_PROXY_KEY, NULL);
+
+ if (same_proxy) {
+ ProxyServer proxy_server = GetProxyServerFromGconf(
+ client,
eroman 2009/03/30 21:25:08 nit: indent these parameters by 4 spaces instead o
+ ProxyServer::SCHEME_HTTP,
+ GCONF_HTTP_PROXY_KEY,
+ GCONF_HTTP_PROXY_PORT_KEY);
+
+ if (proxy_server.is_valid()) {
+ config->proxy_rules = proxy_server.ToURI();
+ } else {
+ res = false;
+ }
+ } else {
+ for (size_t i = 0; i < arraysize(kSchemeInGCONF); ++i) {
+ ProxyServer proxy_server = GetProxyServerFromGconf(
+ client,
eroman 2009/03/30 21:25:08 nit: indent these parameters by 4 spaces instead o
+ ProxyServer::SCHEME_HTTP,
+ kSchemeInGCONF[i].host_key,
+ kSchemeInGCONF[i].port_key);
+
+ if (proxy_server.is_valid()) {
+ if (config->proxy_rules.size()) {
+ config->proxy_rules += ";";
+ }
+ config->proxy_rules += kSchemeInGCONF[i].scheme;
+ config->proxy_rules += "=";
+ config->proxy_rules += proxy_server.ToURI();
+ }
+ }
+ if (!config->proxy_rules.size()) {
+ ProxyServer proxy_server = GetProxyServerFromGconf(
+ client,
+ ProxyServer::SCHEME_SOCKS4,
+ GCONF_SOCKS_PROXY_KEY,
+ GCONF_SOCKS_PROXY_PORT_KEY);
+
+ if (proxy_server.is_valid()) {
+ config->proxy_rules += proxy_server.ToURI();
+ }
+ }
+ }
+ }
+ if (res && config->proxy_rules.size()) {
+ GSList* list;
+
+ list = gconf_client_get_list(client, GCONF_PROXY_BYPASS_LIST_KEY,
+ GCONF_VALUE_STRING, NULL);
eroman 2009/03/30 21:25:08 nit: two more spaces to line this up.
+ config->proxy_bypass.clear();
+
+ for (GSList* i = list; i; i = g_slist_next(i)) {
+ if (i->data)
+ config->proxy_bypass.push_back(static_cast<gchar*>(i->data));
+ }
+
+ g_slist_foreach(list, GFunc(g_free), NULL);
+ g_slist_free(list);
+ }
+ }
+ g_free(mode);
+ } else {
+ res = false;
+ }
+
+ g_object_unref(client);
+ return res;
+}
+
+const struct SchemeInEnv {
+ const gchar* scheme;
+ const gchar* env_name;
+} kSchemeInEnv[] = {
eroman 2009/03/30 21:25:08 nit: can you make this "static" ?
+ {"http", "http_proxy"},
+ {"https", "https_proxy"},
+ {"ftp", "ftp_proxy"},
+};
+
+bool GetProxyConfigEnv(ProxyConfig* config) {
+ gchar* no_proxy = g_strdup(g_getenv("no_proxy"));
+ gchar* socks_ver = g_strdup(g_getenv("SOCKS_VERSION"));
+ gchar* socks_server = g_strdup(g_getenv("SOCKS_SERVER"));
+ gchar* auto_proxy = g_strdup(g_getenv("auto_proxy"));
+ bool res = true;
+
+ config->proxy_rules = "";
+
+ if (auto_proxy != NULL) {
eroman 2009/03/30 21:25:08 nit: for consistency, consider "if (auto_proxy)"
+ if (strlen(auto_proxy) == 0)
+ config->auto_detect = true;
+ else
+ config->pac_url = GURL(auto_proxy);
+ }
+
+ if (socks_ver != NULL && socks_server != NULL) {
eroman 2009/03/30 21:25:08 nit: for consistency consider omitting "!= NULL"
+ int ver = 0;
+ ProxyServer server;
+
+ ver = atoi(socks_ver);
+ if (ver != 4 && ver != 5)
+ ver = 4;
+
+ if (strncmp(socks_server, "socks", 5) == 0) {
+ server = ProxyServer::FromURI(socks_server);
+ } else {
+ if (ver == 4)
+ server = ProxyServer::FromURI("socks4://" + std::string(socks_server));
+ else
+ server = ProxyServer::FromURI("socks5://" + std::string(socks_server));
+ }
+ if (!server.is_valid())
+ res = false;
+ else
+ config->proxy_rules += server.ToURI();
+ } else {
+ gchar* all_proxy = g_strdup(g_getenv("all_proxy"));
+ if (all_proxy != NULL) {
eroman 2009/03/30 21:25:08 nit: for consistency consider omitting "!= NULL".
+ ProxyServer server = ProxyServer::FromURI(all_proxy);
+ if (!server.is_valid())
+ res = false;
+ else
+ config->proxy_rules = server.ToURI();
+ } else {
+ for (size_t i = 0; i < arraysize(kSchemeInEnv); ++i) {
+ gchar* proxy = g_strdup(g_getenv(kSchemeInEnv[i].env_name));
+ if (proxy != NULL) {
eroman 2009/03/30 21:25:08 nit: for consistency consider omitting "!= NULL".
+ ProxyServer server = ProxyServer::FromURI(proxy);
+ if (server.is_valid()) {
+ if (config->proxy_rules.size() > 1)
eroman 2009/03/30 21:25:08 I believe you can just test > 0 here (i.e. not emp
+ config->proxy_rules += ";";
+ config->proxy_rules += kSchemeInEnv[i].scheme;
+ config->proxy_rules += "=";
+ config->proxy_rules += server.ToURI();
+ }
+ }
+ g_free(proxy);
+ }
+ }
+ g_free(all_proxy);
+ }
+
+ if (no_proxy) {
+ std::string str;
+ for (size_t i = 0, k = strlen(no_proxy); i < k; i++) {
+ if (no_proxy[i] != ' ')
+ str += no_proxy[i];
eroman 2009/03/30 21:25:08 instead of stripping whitespace here, I would sugg
+ }
+ StringTokenizer proxy_server_bypass_list(str, ",");
+ while (proxy_server_bypass_list.GetNext()) {
+ int i[4];
+ std::string bypass_url_domain = proxy_server_bypass_list.token();
+ if (sscanf(bypass_url_domain.c_str(), "%d.%d.%d.%d",
eroman 2009/03/30 21:25:08 I recommend using GURL to test if it is an IP addr
+ i, i + 1, i + 2, i + 3) == 4) {
+ config->proxy_bypass.push_back(bypass_url_domain);
+ } else {
+ config->proxy_bypass.push_back("*" + bypass_url_domain);
+ }
+ }
+ }
+
+ g_free(no_proxy);
+ g_free(socks_ver);
+ g_free(socks_server);
+ g_free(auto_proxy);
+ return res;
+}
+
+int ProxyConfigServiceLinux::GetProxyConfig(ProxyConfig* config) {
+ if (g_getenv("DESKTOP_SESSION") &&
+ strcmp(g_getenv("DESKTOP_SESSION"), "gnome") == 0 ||
+ g_getenv("GNOME_DESKTOP_SESSION_ID")) {
+ gdk_threads_enter();
+ if (GetProxyConfigGCONF(config)) {
+ gdk_threads_leave();
+ return OK;
+ }
+ gdk_threads_leave();
+ }
+
+ if (GetProxyConfigEnv(config)) {
+ return OK;
+ }
+ return ERR_FAILED;
+}
+
+} // namespace net

Powered by Google App Engine
This is Rietveld 408576698