[glib-networking] Implement a GNOME proxy backend using GSettings
- From: Dan Winship <danw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [glib-networking] Implement a GNOME proxy backend using GSettings
- Date: Wed, 16 Mar 2011 14:10:31 +0000 (UTC)
commit 00c639ccb953a36ae5be3dc2bcfe87a14b9592d1
Author: Dan Winship <danw gnome org>
Date: Sat Dec 11 15:23:51 2010 +0100
Implement a GNOME proxy backend using GSettings
Use the network proxy settings from gsettings-desktop-schemas and
return proxies based on that.
For Automatic proxy configuration, we use the D-Bus service provided
by the libproxy plugin.
https://bugzilla.gnome.org/show_bug.cgi?id=644211
Makefile.am | 4 +
configure.ac | 24 ++-
proxy/gnome/Makefile.am | 26 ++
proxy/gnome/gnome-proxy-module.c | 45 +++
proxy/gnome/gproxyresolvergnome.c | 641 +++++++++++++++++++++++++++++++++++++
proxy/gnome/gproxyresolvergnome.h | 48 +++
6 files changed, 783 insertions(+), 5 deletions(-)
---
diff --git a/Makefile.am b/Makefile.am
index 6e030c1..2c34280 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -9,6 +9,10 @@ if HAVE_LIBPROXY
SUBDIRS += proxy/libproxy
endif
+if HAVE_GNOME_PROXY
+SUBDIRS += proxy/gnome
+endif
+
if HAVE_GNUTLS
SUBDIRS += tls/gnutls
endif
diff --git a/configure.ac b/configure.ac
index 0218196..dac8721 100644
--- a/configure.ac
+++ b/configure.ac
@@ -43,9 +43,6 @@ AC_SUBST(GIO_MODULE_DIR)
AC_PATH_PROG(GIO_QUERYMODULES, gio-querymodules)
AC_SUBST(GIO_QUERYMODULES)
-proxy_support=no
-tls_support=no
-
dnl *****************************
dnl *** Checks for LibProxy ***
dnl *****************************
@@ -64,6 +61,22 @@ AM_CONDITIONAL(HAVE_LIBPROXY, [test "x$with_libproxy" = "xyes"])
AC_SUBST(LIBPROXY_CFLAGS)
AC_SUBST(LIBPROXY_LIBS)
+dnl **************************************
+dnl *** Checks for GNOME proxy backend ***
+dnl **************************************
+AC_ARG_WITH(gnome-proxy,
+ [AC_HELP_STRING([--with-gnome-proxy],
+ [support for GNOME proxy configuration @<:@default=check@:>@])]
+ [],
+ [with_gnome_proxy=check])
+AS_IF([test "x$with_gnome_proxy" != "xno"],
+ [PKG_CHECK_MODULES(GSETTINGS_DESKTOP_SCHEMAS, [gsettings-desktop-schemas],
+ [with_gnome_proxy=yes; proxy_support="gnome $proxy_support"],
+ [AS_IF([test "x$with_gnome_proxy" = "xyes"],
+ [AC_MSG_FAILURE("$GSETTINGS_DESKTOP_SCHEMAS_PKG_ERRORS")])])])
+AM_CONDITIONAL(HAVE_GNOME_PROXY, [test "x$with_gnome_proxy" = "xyes"])
+AC_SUBST(GSETTINGS_DESKTOP_SCHEMAS_CFLAGS)
+
dnl *****************************
dnl *** Checks for GNUTLS ***
dnl *****************************
@@ -143,13 +156,14 @@ dnl *****************************
AC_CONFIG_FILES([Makefile
po/Makefile.in po/Makefile
proxy/libproxy/Makefile
+ proxy/gnome/Makefile
tls/gnutls/Makefile
])
AC_OUTPUT
echo ""
-echo " Proxy support: $proxy_support"
-echo " TLS support: $tls_support"
+echo " Proxy support: ${proxy_support:-no}"
+echo " TLS support: ${tls_support:-no}"
if test "$tls_support" != "no"; then
echo " TLS CA file: ${with_ca_certificates:-(none)}"
if test -n "$with_ca_certificates"; then
diff --git a/proxy/gnome/Makefile.am b/proxy/gnome/Makefile.am
new file mode 100644
index 0000000..a59b436
--- /dev/null
+++ b/proxy/gnome/Makefile.am
@@ -0,0 +1,26 @@
+include $(top_srcdir)/Makefile.decl
+
+NULL =
+
+module_flags = -export_dynamic -avoid-version -module -no-undefined -export-symbols-regex '^g_io_module_(load|unload|query)'
+
+giomodule_LTLIBRARIES = libgiognomeproxy.la
+giomoduledir = $(GIO_MODULE_DIR)
+
+libgiognomeproxy_la_SOURCES = \
+ gproxyresolvergnome.c \
+ gproxyresolvergnome.h \
+ gnome-proxy-module.c \
+ $(NULL)
+
+libgiognomeproxy_la_CFLAGS = \
+ -DG_LOG_DOMAIN=\"GLib-Net\" \
+ $(GLIB_CFLAGS) \
+ $(GSETTINGS_DESKTOP_SCHEMAS_CFLAGS) \
+ -DGIO_MODULE_DIR=\"$(GIO_MODULE_DIR)\" \
+ -DG_DISABLE_DEPRECATED
+
+libgiognomeproxy_la_LDFLAGS = $(module_flags)
+libgiognomeproxy_la_LIBADD = \
+ $(GLIB_LIBS) \
+ $(NULL)
diff --git a/proxy/gnome/gnome-proxy-module.c b/proxy/gnome/gnome-proxy-module.c
new file mode 100644
index 0000000..03495ca
--- /dev/null
+++ b/proxy/gnome/gnome-proxy-module.c
@@ -0,0 +1,45 @@
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright (C) 2010 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include "gproxyresolvergnome.h"
+
+
+void
+g_io_module_load (GIOModule *module)
+{
+ g_proxy_resolver_gnome_register (module);
+}
+
+void
+g_io_module_unload (GIOModule *module)
+{
+}
+
+gchar **
+g_io_module_query (void)
+{
+ gchar *eps[] = {
+ G_PROXY_RESOLVER_EXTENSION_POINT_NAME,
+ NULL
+ };
+ return g_strdupv (eps);
+}
diff --git a/proxy/gnome/gproxyresolvergnome.c b/proxy/gnome/gproxyresolvergnome.c
new file mode 100644
index 0000000..80fc806
--- /dev/null
+++ b/proxy/gnome/gproxyresolvergnome.c
@@ -0,0 +1,641 @@
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright (C) 2010 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+
+#include "gproxyresolvergnome.h"
+
+#include <glib/gi18n-lib.h>
+#include <gdesktop-enums.h>
+
+#define GNOME_PROXY_SETTINGS_SCHEMA "org.gnome.system.proxy"
+#define GNOME_PROXY_MODE_KEY "mode"
+#define GNOME_PROXY_AUTOCONFIG_URL_KEY "autoconfig-url"
+#define GNOME_PROXY_IGNORE_HOSTS_KEY "ignore-hosts"
+#define GNOME_PROXY_USE_SAME_PROXY_KEY "use-same-proxy"
+
+#define GNOME_PROXY_HTTP_SETTINGS_SCHEMA "org.gnome.system.proxy.http"
+#define GNOME_PROXY_HTTP_ENABLED_KEY "enabled"
+#define GNOME_PROXY_HTTP_HOST_KEY "host"
+#define GNOME_PROXY_HTTP_PORT_KEY "port"
+#define GNOME_PROXY_HTTP_USE_AUTH_KEY "use-authentication"
+#define GNOME_PROXY_HTTP_USER_KEY "authentication-user"
+#define GNOME_PROXY_HTTP_PASSWORD_KEY "authentication-password"
+
+#define GNOME_PROXY_HTTPS_SETTINGS_SCHEMA "org.gnome.system.proxy.https"
+#define GNOME_PROXY_HTTPS_HOST_KEY "host"
+#define GNOME_PROXY_HTTPS_PORT_KEY "port"
+
+#define GNOME_PROXY_FTP_SETTINGS_SCHEMA "org.gnome.system.proxy.ftp"
+#define GNOME_PROXY_FTP_HOST_KEY "host"
+#define GNOME_PROXY_FTP_PORT_KEY "port"
+
+#define GNOME_PROXY_SOCKS_SETTINGS_SCHEMA "org.gnome.system.proxy.socks"
+#define GNOME_PROXY_SOCKS_HOST_KEY "host"
+#define GNOME_PROXY_SOCKS_PORT_KEY "port"
+
+typedef struct {
+ GSocketFamily family;
+ guint8 mask[16];
+ gint length;
+} GProxyResolverGnomeIPMask;
+
+struct _GProxyResolverGnome {
+ GObject parent_instance;
+
+ GSettings *proxy_settings;
+ GSettings *http_settings;
+ GSettings *https_settings;
+ GSettings *ftp_settings;
+ GSettings *socks_settings;
+ gboolean need_update;
+
+ GDesktopProxyMode mode;
+ gchar *autoconfig_url;
+ gboolean use_same_proxy;
+ gchar **ignore_hosts;
+ GProxyResolverGnomeIPMask *ignore_ips;
+
+ gchar *http_proxy, *https_proxy;
+ gchar *ftp_proxy, *socks_authority;
+
+ GDBusProxy *pacrunner;
+};
+
+static void g_proxy_resolver_gnome_iface_init (GProxyResolverInterface *iface);
+
+G_DEFINE_DYNAMIC_TYPE_EXTENDED (GProxyResolverGnome,
+ g_proxy_resolver_gnome,
+ G_TYPE_OBJECT, 0,
+ G_IMPLEMENT_INTERFACE_DYNAMIC (G_TYPE_PROXY_RESOLVER,
+ g_proxy_resolver_gnome_iface_init))
+
+static void
+g_proxy_resolver_gnome_class_finalize (GProxyResolverGnomeClass *klass)
+{
+}
+
+static void
+free_settings (GProxyResolverGnome *resolver)
+{
+ g_free (resolver->autoconfig_url);
+ g_strfreev (resolver->ignore_hosts);
+ g_free (resolver->ignore_ips);
+
+ g_free (resolver->http_proxy);
+ g_free (resolver->https_proxy);
+ g_free (resolver->ftp_proxy);
+ g_free (resolver->socks_authority);
+}
+
+static void
+gsettings_changed (GSettings *settings,
+ const gchar *key,
+ gpointer user_data)
+{
+ GProxyResolverGnome *resolver = user_data;
+
+ resolver->need_update = TRUE;
+}
+
+static void
+g_proxy_resolver_gnome_finalize (GObject *object)
+{
+ GProxyResolverGnome *resolver = G_PROXY_RESOLVER_GNOME (object);
+
+ if (resolver->proxy_settings)
+ {
+ g_signal_handlers_disconnect_by_func (resolver->proxy_settings,
+ (gpointer)gsettings_changed,
+ resolver);
+ g_object_unref (resolver->proxy_settings);
+
+ g_signal_handlers_disconnect_by_func (resolver->http_settings,
+ (gpointer)gsettings_changed,
+ resolver);
+ g_object_unref (resolver->http_settings);
+
+ g_signal_handlers_disconnect_by_func (resolver->https_settings,
+ (gpointer)gsettings_changed,
+ resolver);
+ g_object_unref (resolver->https_settings);
+
+ g_signal_handlers_disconnect_by_func (resolver->ftp_settings,
+ (gpointer)gsettings_changed,
+ resolver);
+ g_object_unref (resolver->ftp_settings);
+
+ g_signal_handlers_disconnect_by_func (resolver->socks_settings,
+ (gpointer)gsettings_changed,
+ resolver);
+ g_object_unref (resolver->socks_settings);
+
+ free_settings (resolver);
+ }
+
+ if (resolver->pacrunner)
+ g_object_unref (resolver->pacrunner);
+
+ G_OBJECT_CLASS (g_proxy_resolver_gnome_parent_class)->finalize (object);
+}
+
+static void
+g_proxy_resolver_gnome_init (GProxyResolverGnome *resolver)
+{
+ resolver->proxy_settings = g_settings_new (GNOME_PROXY_SETTINGS_SCHEMA);
+ g_signal_connect (resolver->proxy_settings, "changed",
+ G_CALLBACK (gsettings_changed), resolver);
+ resolver->http_settings = g_settings_new (GNOME_PROXY_HTTP_SETTINGS_SCHEMA);
+ g_signal_connect (resolver->http_settings, "changed",
+ G_CALLBACK (gsettings_changed), resolver);
+ resolver->https_settings = g_settings_new (GNOME_PROXY_HTTPS_SETTINGS_SCHEMA);
+ g_signal_connect (resolver->https_settings, "changed",
+ G_CALLBACK (gsettings_changed), resolver);
+ resolver->ftp_settings = g_settings_new (GNOME_PROXY_FTP_SETTINGS_SCHEMA);
+ g_signal_connect (resolver->ftp_settings, "changed",
+ G_CALLBACK (gsettings_changed), resolver);
+ resolver->socks_settings = g_settings_new (GNOME_PROXY_SOCKS_SETTINGS_SCHEMA);
+ g_signal_connect (resolver->socks_settings, "changed",
+ G_CALLBACK (gsettings_changed), resolver);
+
+ resolver->need_update = TRUE;
+}
+
+static void
+update_settings (GProxyResolverGnome *resolver)
+{
+ gchar *host;
+ guint port;
+ int i;
+
+ resolver->need_update = FALSE;
+
+ free_settings (resolver);
+
+ resolver->mode =
+ g_settings_get_enum (resolver->proxy_settings, GNOME_PROXY_MODE_KEY);
+ resolver->autoconfig_url =
+ g_settings_get_string (resolver->proxy_settings, GNOME_PROXY_AUTOCONFIG_URL_KEY);
+ resolver->use_same_proxy =
+ g_settings_get_boolean (resolver->proxy_settings, GNOME_PROXY_USE_SAME_PROXY_KEY);
+
+ resolver->ignore_hosts =
+ g_settings_get_strv (resolver->proxy_settings, GNOME_PROXY_IGNORE_HOSTS_KEY);
+
+ if (resolver->ignore_hosts && resolver->ignore_hosts[0])
+ {
+ GArray *ignore_ips;
+ gchar *slash;
+ GInetAddress *iaddr;
+ GProxyResolverGnomeIPMask mask;
+
+ ignore_ips = g_array_new (TRUE, FALSE, sizeof (GProxyResolverGnomeIPMask));
+ for (i = 0; resolver->ignore_hosts[i]; i++)
+ {
+ host = resolver->ignore_hosts[i];
+ slash = strchr (host, '/');
+ if (slash)
+ host = g_strndup (host, slash - host);
+ iaddr = g_inet_address_new_from_string (host);
+ if (iaddr)
+ {
+ int addrlen = g_inet_address_get_native_size (iaddr);
+
+ memset (&mask, 0, sizeof (mask));
+ mask.family = g_inet_address_get_family (iaddr);
+ memcpy (mask.mask, g_inet_address_to_bytes (iaddr), addrlen);
+ if (slash)
+ {
+ mask.length = atoi (slash + 1);
+ if (mask.length > addrlen * 8)
+ {
+ g_warning("ignore_host '%s' has invalid mask length",
+ resolver->ignore_hosts[i]);
+ mask.length = addrlen;
+ }
+ }
+ else
+ mask.length = 0;
+
+ g_array_append_val (ignore_ips, mask);
+
+ g_object_unref (iaddr);
+ }
+ if (slash)
+ g_free (host);
+ }
+
+ if (ignore_ips->len)
+ resolver->ignore_ips = (GProxyResolverGnomeIPMask *)g_array_free (ignore_ips, FALSE);
+ else
+ {
+ g_array_free (ignore_ips, TRUE);
+ resolver->ignore_ips = NULL;
+ }
+ }
+ else
+ resolver->ignore_ips = NULL;
+
+ host = g_settings_get_string (resolver->http_settings, GNOME_PROXY_HTTP_HOST_KEY);
+ port = g_settings_get_int (resolver->http_settings, GNOME_PROXY_HTTP_PORT_KEY);
+
+ if (g_settings_get_boolean (resolver->http_settings, GNOME_PROXY_HTTP_USE_AUTH_KEY))
+ {
+ gchar *user, *password;
+ gchar *enc_user, *enc_password;
+
+ user = g_settings_get_string (resolver->http_settings, GNOME_PROXY_HTTP_USER_KEY);
+ enc_user = g_uri_escape_string (user, NULL, TRUE);
+ g_free (user);
+ password = g_settings_get_string (resolver->http_settings, GNOME_PROXY_HTTP_PASSWORD_KEY);
+ enc_password = g_uri_escape_string (password, NULL, TRUE);
+ g_free (password);
+
+ resolver->http_proxy = g_strdup_printf ("http://%s:%s %s:%u",
+ enc_user, enc_password,
+ host, port);
+ g_free (enc_user);
+ g_free (enc_password);
+ }
+ else
+ resolver->http_proxy = g_strdup_printf ("http://%s:%u", host, port);
+ g_free (host);
+
+ host = g_settings_get_string (resolver->https_settings, GNOME_PROXY_HTTPS_HOST_KEY);
+ port = g_settings_get_int (resolver->https_settings, GNOME_PROXY_HTTPS_PORT_KEY);
+ if (host && *host)
+ resolver->https_proxy = g_strdup_printf ("http://%s:%u", host, port);
+ g_free (host);
+
+ host = g_settings_get_string (resolver->ftp_settings, GNOME_PROXY_FTP_HOST_KEY);
+ port = g_settings_get_int (resolver->ftp_settings, GNOME_PROXY_FTP_PORT_KEY);
+ if (host && *host)
+ resolver->ftp_proxy = g_strdup_printf ("ftp://%s:%u", host, port);
+ g_free (host);
+
+ host = g_settings_get_string (resolver->socks_settings, GNOME_PROXY_SOCKS_HOST_KEY);
+ port = g_settings_get_int (resolver->socks_settings, GNOME_PROXY_SOCKS_PORT_KEY);
+ if (host && *host)
+ resolver->socks_authority = g_strdup_printf ("%s:%u", host, port);
+ g_free (host);
+
+ if (resolver->mode == G_DESKTOP_PROXY_MODE_AUTO && !resolver->pacrunner)
+ {
+ GError *error = NULL;
+ resolver->pacrunner =
+ g_dbus_proxy_new_for_bus_sync (G_BUS_TYPE_SESSION,
+ G_DBUS_PROXY_FLAGS_NONE,
+ NULL,
+ "org.gtk.GLib.PACRunner",
+ "/org/gtk/GLib/PACRunner",
+ "org.gtk.GLib.PACRunner",
+ NULL, &error);
+ if (error)
+ {
+ g_warning ("Could not start proxy autoconfiguration helper:"
+ "\n %s\nProxy autoconfiguration will not work",
+ error->message);
+ }
+ }
+ else if (resolver->mode != G_DESKTOP_PROXY_MODE_AUTO && resolver->pacrunner)
+ {
+ g_object_unref (resolver->pacrunner);
+ resolver->pacrunner = NULL;
+ }
+}
+
+static gboolean
+g_proxy_resolver_gnome_is_supported (GProxyResolver *object)
+{
+ GProxyResolverGnome *resolver = G_PROXY_RESOLVER_GNOME (object);
+
+ return resolver->proxy_settings != NULL;
+}
+
+static gboolean
+parse_uri (const gchar *uri,
+ gchar **scheme,
+ gchar **host)
+{
+ const gchar *authority, *hoststart, *hostend, *at, *colon, *slash;
+
+ colon = strchr (uri, ':');
+ if (!colon || strncmp (colon, "://", 3) != 0)
+ return FALSE;
+
+ *scheme = g_strndup (uri, colon - uri);
+
+ authority = colon + 3;
+ colon = strchr (authority, ':');
+ slash = strchr (authority, '/');
+ if (colon && (!slash || colon < slash))
+ hostend = colon;
+ else if (slash)
+ hostend = slash;
+ else
+ hostend = authority + strlen (authority);
+
+ at = strchr (authority, '@');
+ if (at && at < hostend)
+ hoststart = at + 1;
+ else
+ hoststart = authority;
+ *host = g_strndup (hoststart, hostend - hoststart);
+
+ return TRUE;
+}
+
+static gboolean
+masked_compare (const guint8 *mask,
+ const guint8 *addr,
+ int maskbits)
+{
+ int bytes, bits;
+
+ if (maskbits == 0)
+ return TRUE;
+
+ bytes = maskbits / 8;
+ if (bytes != 0 && memcmp (mask, addr, bytes) != 0)
+ return FALSE;
+
+ bits = maskbits % 8;
+ return mask[bytes] == (addr[bytes] & (0xFF << (8 - bits)));
+}
+
+static gboolean
+ignore_host (GProxyResolverGnome *resolver,
+ const gchar *host)
+{
+ gboolean ignore = FALSE;
+ gint i;
+
+ if (resolver->ignore_ips)
+ {
+ GInetAddress *iaddr;
+
+ iaddr = g_inet_address_new_from_string (host);
+ if (iaddr)
+ {
+ GSocketFamily family = g_inet_address_get_family (iaddr);
+ const guint8 *addr = g_inet_address_to_bytes (iaddr);
+
+ for (i = 0; resolver->ignore_ips[i].length; i++)
+ {
+ if (resolver->ignore_ips[i].family == family &&
+ masked_compare (resolver->ignore_ips[i].mask, addr,
+ resolver->ignore_ips[i].length))
+ {
+ ignore = TRUE;
+ break;
+ }
+ }
+
+ g_object_unref (iaddr);
+ return ignore;
+ }
+ }
+
+ if (resolver->ignore_hosts && resolver->ignore_hosts[0])
+ {
+ gchar *ascii_host = NULL;
+
+ if (g_hostname_is_non_ascii (host))
+ host = ascii_host = g_hostname_to_ascii (host);
+
+ for (i = 0; resolver->ignore_hosts[i]; i++)
+ {
+ if (!g_ascii_strcasecmp (host, resolver->ignore_hosts[i]))
+ {
+ ignore = TRUE;
+ break;
+ }
+ }
+
+ g_free (ascii_host);
+ }
+
+ return ignore;
+}
+
+static gchar **
+g_proxy_resolver_gnome_lookup (GProxyResolver *proxy_resolver,
+ const gchar *uri,
+ GCancellable *cancellable,
+ GError **error)
+{
+ GProxyResolverGnome *resolver = G_PROXY_RESOLVER_GNOME (proxy_resolver);
+ gchar *scheme = NULL, *host = NULL;
+ const gchar *proxy = "direct://";
+ gchar **proxies = NULL;
+
+ if (resolver->need_update)
+ update_settings (resolver);
+
+ if (resolver->mode == G_DESKTOP_PROXY_MODE_NONE)
+ goto done;
+
+ /* FIXME: use guri when it lands... */
+ if (!parse_uri (uri, &scheme, &host))
+ goto done;
+ if (ignore_host (resolver, host))
+ goto done;
+
+ if (resolver->pacrunner)
+ {
+ GVariant *vproxies;
+
+ vproxies = g_dbus_proxy_call_sync (resolver->pacrunner,
+ "Lookup",
+ g_variant_new ("(ss)",
+ resolver->autoconfig_url,
+ uri),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ cancellable, error);
+ if (vproxies)
+ {
+ g_variant_get (vproxies, "(^as)", &proxies);
+ g_variant_unref (vproxies);
+ }
+ }
+ else if (resolver->ftp_proxy &&
+ (!strcmp (scheme, "ftp") || !strcmp (scheme, "ftps")))
+ {
+ proxy = resolver->ftp_proxy;
+ }
+ else if (resolver->https_proxy && !strcmp (scheme, "https"))
+ {
+ proxy = resolver->https_proxy;
+ }
+ else if (resolver->http_proxy &&
+ (!strcmp (scheme, "http") || !strcmp (scheme, "https")))
+ {
+ proxy = resolver->http_proxy;
+ }
+ else if (resolver->socks_authority)
+ {
+ proxies = g_new0 (gchar *, 4);
+ proxies[0] = g_strdup_printf ("socks5://%s", resolver->socks_authority);
+ proxies[1] = g_strdup_printf ("socks4a://%s", resolver->socks_authority);
+ proxies[2] = g_strdup_printf ("socks4://%s", resolver->socks_authority);
+ }
+ else if (resolver->use_same_proxy && resolver->http_proxy)
+ {
+ proxy = resolver->http_proxy;
+ }
+
+done:
+ g_free (scheme);
+ g_free (host);
+
+ if (!proxies)
+ {
+ proxies = g_new0 (gchar *, 2);
+ proxies[0] = g_strdup (proxy);
+ }
+ return proxies;
+}
+
+static void
+got_autoconfig_proxies (GObject *source,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ GSimpleAsyncResult *simple = user_data;
+ GVariant *vproxies;
+ char **proxies;
+ GError *error = NULL;
+
+ vproxies = g_dbus_proxy_call_finish (G_DBUS_PROXY (source),
+ result, &error);
+ if (vproxies)
+ {
+ g_variant_get (vproxies, "(^as)", &proxies);
+ g_simple_async_result_set_op_res_gpointer (simple, proxies,
+ (GDestroyNotify)g_strfreev);
+ g_variant_unref (vproxies);
+ }
+ else
+ {
+ g_simple_async_result_set_from_error (simple, error);
+ g_error_free (error);
+ }
+ g_simple_async_result_complete (simple);
+ g_object_unref (simple);
+}
+
+static void
+g_proxy_resolver_gnome_lookup_async (GProxyResolver *proxy_resolver,
+ const gchar *uri,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
+{
+ GProxyResolverGnome *resolver = G_PROXY_RESOLVER_GNOME (proxy_resolver);
+ GSimpleAsyncResult *simple;
+
+ simple = g_simple_async_result_new (G_OBJECT (resolver),
+ callback, user_data,
+ g_proxy_resolver_gnome_lookup_async);
+
+ if (resolver->pacrunner)
+ {
+ g_dbus_proxy_call (resolver->pacrunner,
+ "Lookup",
+ g_variant_new ("(ss)",
+ resolver->autoconfig_url,
+ uri),
+ G_DBUS_CALL_FLAGS_NONE,
+ -1,
+ cancellable,
+ got_autoconfig_proxies,
+ simple);
+ }
+ else
+ {
+ GError *error = NULL;
+ char **proxies;
+
+ proxies = g_proxy_resolver_gnome_lookup (proxy_resolver, uri,
+ cancellable, &error);
+ if (proxies)
+ {
+ g_simple_async_result_set_op_res_gpointer (simple, proxies,
+ (GDestroyNotify)g_strfreev);
+ }
+ else
+ {
+ g_simple_async_result_set_from_error (simple, error);
+ g_error_free (error);
+ }
+ g_simple_async_result_complete_in_idle (simple);
+ g_object_unref (simple);
+ }
+}
+
+static gchar **
+g_proxy_resolver_gnome_lookup_finish (GProxyResolver *resolver,
+ GAsyncResult *result,
+ GError **error)
+{
+ GSimpleAsyncResult *simple;
+ gchar **proxies;
+
+ g_return_val_if_fail (g_simple_async_result_is_valid (result, G_OBJECT (resolver), g_proxy_resolver_gnome_lookup_async), NULL);
+
+ simple = G_SIMPLE_ASYNC_RESULT (result);
+
+ if (g_simple_async_result_propagate_error (simple, error))
+ return NULL;
+
+ proxies = g_simple_async_result_get_op_res_gpointer (simple);
+ return g_strdupv (proxies);
+}
+
+static void
+g_proxy_resolver_gnome_class_init (GProxyResolverGnomeClass *resolver_class)
+{
+ GObjectClass *object_class;
+
+ object_class = G_OBJECT_CLASS (resolver_class);
+ object_class->finalize = g_proxy_resolver_gnome_finalize;
+}
+
+static void
+g_proxy_resolver_gnome_iface_init (GProxyResolverInterface *iface)
+{
+ iface->is_supported = g_proxy_resolver_gnome_is_supported;
+ iface->lookup = g_proxy_resolver_gnome_lookup;
+ iface->lookup_async = g_proxy_resolver_gnome_lookup_async;
+ iface->lookup_finish = g_proxy_resolver_gnome_lookup_finish;
+}
+
+void
+g_proxy_resolver_gnome_register (GIOModule *module)
+{
+ g_proxy_resolver_gnome_register_type (G_TYPE_MODULE (module));
+ g_io_extension_point_implement (G_PROXY_RESOLVER_EXTENSION_POINT_NAME,
+ g_proxy_resolver_gnome_get_type(),
+ "gnome",
+ 80);
+}
diff --git a/proxy/gnome/gproxyresolvergnome.h b/proxy/gnome/gproxyresolvergnome.h
new file mode 100644
index 0000000..be173a4
--- /dev/null
+++ b/proxy/gnome/gproxyresolvergnome.h
@@ -0,0 +1,48 @@
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright (C) 2010 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General
+ * Public License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __G_PROXY_RESOLVER_GNOME_H__
+#define __G_PROXY_RESOLVER_GNOME_H__
+
+#include <glib-object.h>
+#include <gio/gio.h>
+
+G_BEGIN_DECLS
+
+#define G_TYPE_PROXY_RESOLVER_GNOME (g_proxy_resolver_gnome_get_type ())
+#define G_PROXY_RESOLVER_GNOME(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), G_TYPE_PROXY_RESOLVER_GNOME, GProxyResolverGnome))
+#define G_PROXY_RESOLVER_GNOME_CLASS(k) (G_TYPE_CHECK_CLASS_CAST((k), G_TYPE_PROXY_RESOLVER_GNOME, GProxyResolverGnomeClass))
+#define G_IS_PROXY_RESOLVER_GNOME(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), G_TYPE_PROXY_RESOLVER_GNOME))
+#define G_IS_PROXY_RESOLVER_GNOME_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), G_TYPE_PROXY_RESOLVER_GNOME))
+#define G_PROXY_RESOLVER_GNOME_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), G_TYPE_PROXY_RESOLVER_GNOME, GProxyResolverGnomeClass))
+
+typedef struct _GProxyResolverGnome GProxyResolverGnome;
+typedef struct _GProxyResolverGnomeClass GProxyResolverGnomeClass;
+
+struct _GProxyResolverGnomeClass {
+ GObjectClass parent_class;
+};
+
+GType g_proxy_resolver_gnome_get_type (void);
+void g_proxy_resolver_gnome_register (GIOModule *module);
+
+G_END_DECLS
+
+#endif /* __G_PROXY_RESOLVER_GNOME_H__ */
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]