[libsoup] SoupProxyResolverGNOME: make this a subclass of SoupProxyResolverDefault



commit 5a8df74a4705aa2ce958d8024aca0ce71c146047
Author: Dan Winship <danw gnome org>
Date:   Mon Mar 21 13:23:15 2011 -0400

    SoupProxyResolverGNOME: make this a subclass of SoupProxyResolverDefault
    
    modify SoupProxyResolverDefault so it's possible to override the
    choice of g_proxy_resolver_get_default(), and make
    SoupProxyResolverGNOME just be a subclass of SoupProxyResolverDefault
    that specifically requests the "gnome" GProxyResolver.
    
    libsoup-gnome no longer depends on libproxy and GConf. (Perhaps it
    should now depend on gsettings-desktop-schemas, or else a
    glib-networking that includes GProxyResolverGnome. But it will fall
    back to using the libproxy-based proxy resolver in that case anyway,
    so it's all good.)
    
    https://bugzilla.gnome.org/show_bug.cgi?id=625898

 configure.ac                          |   36 --
 docs/reference/Makefile.am            |    3 +-
 libsoup/Makefile.am                   |    4 -
 libsoup/soup-proxy-resolver-default.c |   72 ++++-
 libsoup/soup-proxy-resolver-gnome.c   |  570 ++-------------------------------
 libsoup/soup-proxy-resolver-gnome.h   |   12 +-
 6 files changed, 98 insertions(+), 599 deletions(-)
---
diff --git a/configure.ac b/configure.ac
index efaac57..dc23fe7 100644
--- a/configure.ac
+++ b/configure.ac
@@ -130,38 +130,6 @@ AM_CONDITIONAL(BUILD_LIBSOUP_GNOME, test $with_gnome != no)
 if test $with_gnome != no; then
 	AC_DEFINE(HAVE_GNOME, 1, [Defined if GNOME support is enabled])
 
-	PKG_CHECK_MODULES(LIBPROXY, libproxy-1.0, :, [AC_MSG_ERROR(dnl
-[Could not find libproxy:
-
-$LIBPROXY_PKG_ERRORS
-
-This is required for GNOME proxy support.
-
-Pass "--without-gnome" to configure if you want to build libsoup
-without GNOME support.])])
-
-	AC_MSG_CHECKING(libproxy version)
-	libproxy_version=`$PKG_CONFIG --modversion libproxy-1.0`
-	case $libproxy_version in
-	0.2.*)
-		AC_MSG_RESULT([$libproxy_version, using workarounds...])
-		AC_DEFINE(HAVE_LIBPROXY_WITH_NON_THREAD_SAFE_GNOME_MODULE, 1, [Defined if libproxy is old and has a non-thread-safe gnome module])
-		;;
-	*)
-		AC_MSG_RESULT([$libproxy_version, ok])
-		;;
-	esac
-
-	PKG_CHECK_MODULES(GCONF, gconf-2.0, , [AC_MSG_ERROR(dnl
-[Could not find GConf:
-
-$GCONF_PKG_ERRORS
-
-This is required for GNOME proxy support.
-
-Pass "--without-gnome" to configure if you want to build libsoup
-without GNOME support.])])
-
 	PKG_CHECK_MODULES(SQLITE, sqlite3, :, [AC_MSG_ERROR(dnl
 [Could not find sqlite3 devel files:
 
@@ -171,10 +139,6 @@ Pass "--without-gnome" to configure if you want to build libsoup
 without GNOME support.])])
 fi
 AC_SUBST(HAVE_GNOME)
-AC_SUBST(GCONF_CFLAGS)
-AC_SUBST(GCONF_LIBS)
-AC_SUBST(LIBPROXY_CFLAGS)
-AC_SUBST(LIBPROXY_LIBS)
 AC_SUBST(SQLITE_CFLAGS)
 AC_SUBST(SQLITE_LIBS)
 
diff --git a/docs/reference/Makefile.am b/docs/reference/Makefile.am
index 64d3cf8..43b568d 100644
--- a/docs/reference/Makefile.am
+++ b/docs/reference/Makefile.am
@@ -59,8 +59,7 @@ GTKDOC_CFLAGS =				\
 	-I$(top_builddir)		\
 	$(GLIB_CFLAGS)			\
 	$(XML_CFLAGS)			\
-	$(GNUTLS_CFLAGS)		\
-	$(LIBPROXY_LIBS)
+	$(GNUTLS_CFLAGS)
 
 GTKDOC_LIBS = $(top_builddir)/libsoup/libsoup-gnome-2.4.la
 
diff --git a/libsoup/Makefile.am b/libsoup/Makefile.am
index de9c9b6..308c08f 100644
--- a/libsoup/Makefile.am
+++ b/libsoup/Makefile.am
@@ -11,8 +11,6 @@ INCLUDES = 				\
 	$(SOUP_MAINTAINER_FLAGS)	\
 	$(GLIB_CFLAGS)			\
 	$(XML_CFLAGS)			\
-	$(GCONF_CFLAGS)			\
-	$(LIBPROXY_CFLAGS)		\
 	$(SQLITE_CFLAGS)		\
 	$(GNOME_KEYRING_CFLAGS)
 
@@ -196,8 +194,6 @@ libsoup_gnome_2_4_la_LDFLAGS = $(libsoup_2_4_la_LDFLAGS)
 libsoup_gnome_2_4_la_LIBADD =		\
 	libsoup-2.4.la			\
 	$(GLIB_LIBS)			\
-	$(GCONF_LIBS)			\
-	$(LIBPROXY_LIBS)		\
 	$(SQLITE_LIBS)			\
 	$(GNOME_KEYRING_LIBS)
 
diff --git a/libsoup/soup-proxy-resolver-default.c b/libsoup/soup-proxy-resolver-default.c
index 962d0c1..b0bcbac 100644
--- a/libsoup/soup-proxy-resolver-default.c
+++ b/libsoup/soup-proxy-resolver-default.c
@@ -23,6 +23,15 @@ G_DEFINE_TYPE_EXTENDED (SoupProxyResolverDefault, soup_proxy_resolver_default, G
 			G_IMPLEMENT_INTERFACE (SOUP_TYPE_SESSION_FEATURE, NULL)
 			G_IMPLEMENT_INTERFACE (SOUP_TYPE_PROXY_URI_RESOLVER, soup_proxy_resolver_default_interface_init))
 
+enum {
+	PROP_0,
+	PROP_GPROXY_RESOLVER
+};
+
+typedef struct {
+	GProxyResolver *gproxy_resolver;
+} SoupProxyResolverDefaultPrivate;
+#define SOUP_PROXY_RESOLVER_DEFAULT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SOUP_TYPE_PROXY_RESOLVER_DEFAULT, SoupProxyResolverDefaultPrivate))
 
 static void
 soup_proxy_resolver_default_init (SoupProxyResolverDefault *resolver)
@@ -30,8 +39,65 @@ soup_proxy_resolver_default_init (SoupProxyResolverDefault *resolver)
 }
 
 static void
+soup_proxy_resolver_default_set_property (GObject *object, guint prop_id,
+					  const GValue *value, GParamSpec *pspec)
+{
+	SoupProxyResolverDefaultPrivate *priv = SOUP_PROXY_RESOLVER_DEFAULT_GET_PRIVATE (object);
+
+	switch (prop_id) {
+	case PROP_GPROXY_RESOLVER:
+		if (priv->gproxy_resolver)
+			g_object_unref (priv->gproxy_resolver);
+		priv->gproxy_resolver = g_value_dup_object (value);
+		break;
+	default:
+		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+		break;
+	}
+}
+
+static void
+soup_proxy_resolver_default_constructed (GObject *object)
+{
+	SoupProxyResolverDefaultPrivate *priv = SOUP_PROXY_RESOLVER_DEFAULT_GET_PRIVATE (object);
+
+	if (!priv->gproxy_resolver) {
+		priv->gproxy_resolver = g_proxy_resolver_get_default ();
+		g_object_ref (priv->gproxy_resolver);
+	}
+
+	G_OBJECT_CLASS (soup_proxy_resolver_default_parent_class)->constructed (object);
+}
+
+static void
+soup_proxy_resolver_default_finalize (GObject *object)
+{
+	SoupProxyResolverDefaultPrivate *priv = SOUP_PROXY_RESOLVER_DEFAULT_GET_PRIVATE (object);
+
+	if (priv->gproxy_resolver)
+		g_object_unref (priv->gproxy_resolver);
+
+	G_OBJECT_CLASS (soup_proxy_resolver_default_parent_class)->finalize (object);
+}
+
+static void
 soup_proxy_resolver_default_class_init (SoupProxyResolverDefaultClass *klass)
 {
+	GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+	g_type_class_add_private (klass, sizeof (SoupProxyResolverDefaultPrivate));
+
+	object_class->set_property = soup_proxy_resolver_default_set_property;
+	object_class->constructed = soup_proxy_resolver_default_constructed;
+	object_class->finalize = soup_proxy_resolver_default_finalize;
+
+	g_object_class_install_property (
+		object_class, PROP_GPROXY_RESOLVER,
+		g_param_spec_object ("gproxy-resolver",
+				     "GProxyResolver",
+				     "The underlying GProxyResolver",
+				     G_TYPE_PROXY_RESOLVER,
+				     G_PARAM_WRITABLE));
 }
 
 typedef struct {
@@ -96,6 +162,7 @@ get_proxy_uri_async (SoupProxyURIResolver  *resolver,
 		     SoupProxyURIResolverCallback callback,
 		     gpointer		    user_data)
 {
+	SoupProxyResolverDefaultPrivate *priv = SOUP_PROXY_RESOLVER_DEFAULT_GET_PRIVATE (resolver);
 	SoupAsyncData *async_data;
 	char *uri_string;
 
@@ -107,7 +174,7 @@ get_proxy_uri_async (SoupProxyURIResolver  *resolver,
 
 	uri_string = soup_uri_to_string (uri, FALSE);
 
-	g_proxy_resolver_lookup_async (g_proxy_resolver_get_default (),
+	g_proxy_resolver_lookup_async (priv->gproxy_resolver,
 				       uri_string,
 				       cancellable ? g_object_ref (cancellable) : NULL,
 				       resolved_proxy,
@@ -122,6 +189,7 @@ get_proxy_uri_sync (SoupProxyURIResolver  *resolver,
 		    GCancellable	  *cancellable,
 		    SoupURI		 **proxy_uri)
 {
+	SoupProxyResolverDefaultPrivate *priv = SOUP_PROXY_RESOLVER_DEFAULT_GET_PRIVATE (resolver);
 	GError *error = NULL;
 	char** proxy_uris = NULL;
 	char *uri_string;
@@ -129,7 +197,7 @@ get_proxy_uri_sync (SoupProxyURIResolver  *resolver,
 
 	uri_string = soup_uri_to_string (uri, FALSE);
 
-	proxy_uris = g_proxy_resolver_lookup (g_proxy_resolver_get_default (),
+	proxy_uris = g_proxy_resolver_lookup (priv->gproxy_resolver,
 					      uri_string,
 					      cancellable,
 					      &error);
diff --git a/libsoup/soup-proxy-resolver-gnome.c b/libsoup/soup-proxy-resolver-gnome.c
index 186ca4e..e01dd6a 100644
--- a/libsoup/soup-proxy-resolver-gnome.c
+++ b/libsoup/soup-proxy-resolver-gnome.c
@@ -10,567 +10,45 @@
 #endif
 
 #include <string.h>
-#include <stdlib.h>
 
 #include "soup-proxy-resolver-gnome.h"
-#include "soup-proxy-uri-resolver.h"
-#include "soup-message.h"
-#include "soup-misc.h"
-#include "soup-session-feature.h"
-#include "soup-uri.h"
 
-#include <gconf/gconf-client.h>
-#include <proxy.h>
-
-/* libproxy/GConf-based proxy resolution, working around multiple
- * problems:
- *
- *   1. GConf is not thread-safe, but a SoupProxyResolver may be used
- *      from multiple threads. We need to take steps to ensure that if
- *      there is a thread running the default main loop, then GConf
- *      calls are only made from that thread.
- *
- *   2. libproxy 0.2 was unaware of GConf's non-thread-safety, so it
- *      is unsafe to call into libproxy other than from the main
- *      thread as well, unless we can guarantee that it won't use the
- *      "gnome" plugin.
- *
- *   3. libproxy 0.3 fixes the thread-safety issues by just calling
- *      out to gconftool-2 on every call. That fixes the crashes but
- *      makes things a lot slower, so ideally we still don't want to
- *      call it if it's going to use the "gnome" plugin.
- *
- *   4. libproxy is not cancellable, and may block (eg, doing WPAD or
- *      just DNS, or running a PAC script), so if we want to be able
- *      to cancel calls to it, we need to do them in another thread
- *      even if we're making a sync call.
- *
- * The only good way to ensure that libproxy won't use the gnome
- * plugin is to ensure that it will use environment variables instead.
- * But if we just copy the GConf settings to the environment, then
- * we'll leak them to child processes. For libproxy 0.2, we *can't*
- * let it use the gnome plugin, so if we need to use libproxy (to get
- * PAC/WPAD or ignore_host support) then we just suffer through
- * environment leakage. For libproxy 0.3, the gconftool-calling
- * slowness is less bad than environment variable leakage would be, so
- * we let it use the gnome plugin in that case.
- */
-
-/* We make these variables static rather than per-resolver, since
- * they're awkward to deal with because of GConf's non-thread-safety,
- * and because there's only one GConf database regardless of how many
- * SoupProxyResolverGNOMEs there are anyway.
- */
-G_LOCK_DEFINE_STATIC (resolver_gnome);
-static GConfClient *gconf_client;
-static char *proxy_user, *proxy_password;
-static char *http_proxy, *https_proxy;
-
-static pxProxyFactory *libproxy_factory;
-static GThreadPool *libproxy_threadpool;
-#ifdef HAVE_LIBPROXY_WITH_NON_THREAD_SAFE_GNOME_MODULE
-static gboolean overrode_environment;
-#endif
-
-static void soup_proxy_resolver_gnome_interface_init (SoupProxyURIResolverInterface *proxy_resolver_interface);
-
-G_DEFINE_TYPE_EXTENDED (SoupProxyResolverGNOME, soup_proxy_resolver_gnome, G_TYPE_OBJECT, 0,
-			G_IMPLEMENT_INTERFACE (SOUP_TYPE_SESSION_FEATURE, NULL)
-			G_IMPLEMENT_INTERFACE (SOUP_TYPE_PROXY_URI_RESOLVER, soup_proxy_resolver_gnome_interface_init))
-
-static void gconf_value_changed (GConfClient *client, const char *key,
-				 GConfValue *value, gpointer user_data);
-static void update_proxy_settings (void);
-
-static void libproxy_threadpool_func (gpointer thread_data, gpointer user_data);
-
-static void get_proxy_uri_async (SoupProxyURIResolver  *proxy_uri_resolver,
-				 SoupURI               *uri,
-				 GMainContext          *async_context,
-				 GCancellable          *cancellable,
-				 SoupProxyURIResolverCallback callback,
-				 gpointer               user_data);
-static guint get_proxy_uri_sync (SoupProxyURIResolver  *proxy_uri_resolver,
-				 SoupURI               *uri,
-				 GCancellable          *cancellable,
-				 SoupURI              **proxy_uri);
-
-typedef struct {
-	GMutex *lock;
-	GCond *cond;
-} SoupProxyResolverGNOMEInitData;
-
-static gboolean
-init_gconf (gpointer user_data)
-{
-	SoupProxyResolverGNOMEInitData *id = user_data;
-
-	if (id)
-		g_mutex_lock (id->lock);
-
-	/* resolver_gnome is locked */
-
-	gconf_client = gconf_client_get_default ();
-
-	gconf_client_add_dir (gconf_client, "/system/proxy",
-			      GCONF_CLIENT_PRELOAD_RECURSIVE, NULL);
-	gconf_client_add_dir (gconf_client, "/system/http_proxy",
-			      GCONF_CLIENT_PRELOAD_RECURSIVE, NULL);
-	g_signal_connect (gconf_client, "value_changed",
-			  G_CALLBACK (gconf_value_changed),
-			  NULL);
-	update_proxy_settings ();
-
-	if (id) {
-		g_mutex_unlock (id->lock);
-		g_cond_signal (id->cond);
-	}
-	return FALSE;
-}
+G_DEFINE_TYPE (SoupProxyResolverGNOME, soup_proxy_resolver_gnome, SOUP_TYPE_PROXY_RESOLVER_DEFAULT)
 
 static void
 soup_proxy_resolver_gnome_init (SoupProxyResolverGNOME *resolver_gnome)
 {
-	GMainContext *default_context;
-
-	G_LOCK (resolver_gnome);
-	if (!gconf_client) {
-		/* GConf is not thread-safe, and we might be running
-		 * in some random thread right now while other
-		 * GConf-related activity is going on in the main
-		 * thread. To prevent badness, we try to claim the
-		 * default GMainContext; if we succeed, then either
-		 * we're in the thread of the default GMainContext, or
-		 * else there isn't currently any thread running the
-		 * default GMainContext (meaning either the main loop
-		 * hasn't been started yet, or else there is no main
-		 * loop). Either way, it's safe to use GConf.
-		 *
-		 * If we can't manage to acquire the default
-		 * GMainContext, then that means another thread
-		 * already has it, so we use g_idle_add() to ask that
-		 * thread to do the GConf initialization, and wait
-		 * for that thread to finish.
-		 */
-		default_context = g_main_context_default ();
-		if (g_main_context_acquire (default_context)) {
-			init_gconf (NULL);
-			g_main_context_release (default_context);
-		} else {
-			SoupProxyResolverGNOMEInitData id;
-
-			id.lock = g_mutex_new ();
-			id.cond = g_cond_new ();
-
-			g_mutex_lock (id.lock);
-			g_idle_add (init_gconf, &id);
-			g_cond_wait (id.cond, id.lock);
-			g_mutex_unlock (id.lock);
-
-			g_cond_free (id.cond);
-			g_mutex_free (id.lock);
-		}
-	}
-	G_UNLOCK(resolver_gnome);
-}
-
-static void
-soup_proxy_resolver_gnome_class_init (SoupProxyResolverGNOMEClass *gconf_class)
-{
-}
-
-static void
-soup_proxy_resolver_gnome_interface_init (SoupProxyURIResolverInterface *proxy_uri_resolver_interface)
-{
-	proxy_uri_resolver_interface->get_proxy_uri_async = get_proxy_uri_async;
-	proxy_uri_resolver_interface->get_proxy_uri_sync = get_proxy_uri_sync;
-}
-
-#define SOUP_GCONF_PROXY_MODE           "/system/proxy/mode"
-#define SOUP_GCONF_PROXY_AUTOCONFIG_URL "/system/proxy/autoconfig_url"
-#define SOUP_GCONF_HTTP_PROXY_HOST      "/system/http_proxy/host"
-#define SOUP_GCONF_HTTP_PROXY_PORT      "/system/http_proxy/port"
-#define SOUP_GCONF_HTTP_USE_AUTH        "/system/http_proxy/use_authentication"
-#define SOUP_GCONF_HTTP_PROXY_USER      "/system/http_proxy/authentication_user"
-#define SOUP_GCONF_HTTP_PROXY_PASSWORD  "/system/http_proxy/authentication_password"
-#define SOUP_GCONF_HTTPS_PROXY_HOST     "/system/proxy/secure_host"
-#define SOUP_GCONF_HTTPS_PROXY_PORT     "/system/proxy/secure_port"
-#define SOUP_GCONF_USE_SAME_PROXY       "/system/http_proxy/use_same_proxy"
-#define SOUP_GCONF_PROXY_IGNORE_HOSTS   "/system/http_proxy/ignore_hosts"
-
-typedef enum {
-	SOUP_PROXY_RESOLVER_GNOME_GCONF_MODE_NONE,
-	SOUP_PROXY_RESOLVER_GNOME_GCONF_MODE_MANUAL,
-	SOUP_PROXY_RESOLVER_GNOME_GCONF_MODE_AUTO
-} SoupProxyResolverGNOMEGConfMode;
-
-static GConfEnumStringPair proxy_mode_map [] = {
-	{ SOUP_PROXY_RESOLVER_GNOME_GCONF_MODE_NONE,   "none"   },
-	{ SOUP_PROXY_RESOLVER_GNOME_GCONF_MODE_MANUAL, "manual" },
-	{ SOUP_PROXY_RESOLVER_GNOME_GCONF_MODE_AUTO,   "auto"   },
-	{ 0, NULL }
-};
-
-static void
-update_proxy_settings (void)
-{
-	SoupProxyResolverGNOMEGConfMode proxy_mode;
-	char *mode, *no_proxy = NULL;
-	char *autoconfig_url, *host;
-	guint port;
-	GSList *ignore;
-	gboolean need_libproxy;
-
-	/* resolver_gnome is locked */
-
-	if (http_proxy) {
-		g_free (http_proxy);
-		http_proxy = NULL;
-	}
-	if (https_proxy) {
-		g_free (https_proxy);
-		https_proxy = NULL;
-	}
-	if (proxy_user) {
-		g_free (proxy_user);
-		proxy_user = NULL;
-	}
-	if (proxy_password) {
-		memset (proxy_password, 0, strlen (proxy_password));
-		g_free (proxy_password);
-		proxy_password = NULL;
-	}
-
-#ifdef HAVE_LIBPROXY_WITH_NON_THREAD_SAFE_GNOME_MODULE
-	if (overrode_environment) {
-		g_unsetenv ("PX_CONFIG_ORDER");
-		g_unsetenv ("http_proxy");
-		g_unsetenv ("https_proxy");
-		g_unsetenv ("no_proxy");
-		overrode_environment = FALSE;
-	}
-#endif
-
-	/* Get new settings */
-	mode = gconf_client_get_string (
-		gconf_client, SOUP_GCONF_PROXY_MODE, NULL);
-	if (!mode || !gconf_string_to_enum (proxy_mode_map, mode,
-					    (int *)&proxy_mode))
-		proxy_mode = SOUP_PROXY_RESOLVER_GNOME_GCONF_MODE_NONE;
-	g_free (mode);
-
-	switch (proxy_mode) {
-	case SOUP_PROXY_RESOLVER_GNOME_GCONF_MODE_NONE:
-		/* If GConf says "no", but the environment variables are
-		 * set, then use the environment variables
-		 */
-		http_proxy = g_strdup (g_getenv ("http_proxy"));
-		https_proxy = g_strdup (g_getenv ("https_proxy"));
-		no_proxy = g_strdup (g_getenv ("no_proxy"));
-		break;
-
-	case SOUP_PROXY_RESOLVER_GNOME_GCONF_MODE_AUTO:
-		autoconfig_url = gconf_client_get_string (
-			gconf_client, SOUP_GCONF_PROXY_AUTOCONFIG_URL, NULL);
-		if (autoconfig_url && !strncmp (autoconfig_url, "http", 4))
-			http_proxy = g_strconcat ("pac+", autoconfig_url, NULL);
-		else
-			http_proxy = g_strdup ("wpad://");
-		https_proxy = g_strdup (http_proxy);
-		g_free (autoconfig_url);
-		goto do_ignore_list;
-
-	case SOUP_PROXY_RESOLVER_GNOME_GCONF_MODE_MANUAL:
-		host = gconf_client_get_string (
-			gconf_client, SOUP_GCONF_HTTP_PROXY_HOST, NULL);
-		if (!host || !*host) {
-			g_free (host);
-			proxy_mode = SOUP_PROXY_RESOLVER_GNOME_GCONF_MODE_NONE;
-			return;
-		}
-		port = gconf_client_get_int (
-			gconf_client, SOUP_GCONF_HTTP_PROXY_PORT, NULL);
+	GProxyResolver *gproxyresolver;
+	GIOExtensionPoint *ep;
+	GIOExtension *ext;
+	GType type;
 
-		if (port) {
-			http_proxy = g_strdup_printf ("http://%s:%u";,
-						      host, port);
-		} else
-			http_proxy = g_strdup_printf ("http://%s";, host);
-		g_free (host);
-
-		if (!gconf_client_get_bool (gconf_client, SOUP_GCONF_USE_SAME_PROXY, NULL)) {
-			host = gconf_client_get_string (
-				gconf_client, SOUP_GCONF_HTTPS_PROXY_HOST, NULL);
-			port = gconf_client_get_int (
-				gconf_client, SOUP_GCONF_HTTPS_PROXY_PORT, NULL);
-
-			if (host && *host) {
-				if (port) {
-					https_proxy = g_strdup_printf (
-						"http://%s:%u";, host, port);
-				} else {
-					https_proxy = g_strdup_printf (
-						"http://%s";, host);
-				}
-			}
-			g_free (host);
-		}
-
-		if (gconf_client_get_bool (gconf_client, SOUP_GCONF_HTTP_USE_AUTH, NULL)) {
-			proxy_user = gconf_client_get_string (
-				gconf_client, SOUP_GCONF_HTTP_PROXY_USER, NULL);
-			proxy_password = gconf_client_get_string (
-				gconf_client, SOUP_GCONF_HTTP_PROXY_PASSWORD, NULL);
-		}
-
-		/* fall through */
-
-	do_ignore_list:
-		ignore = gconf_client_get_list (
-			gconf_client, SOUP_GCONF_PROXY_IGNORE_HOSTS,
-			GCONF_VALUE_STRING, NULL);
-		if (ignore) {
-			GString *ignore_list;
-			GSList *i;
-
-			ignore_list = g_string_new (NULL);
-			for (i = ignore; i; i = i->next) {
-				if (ignore_list->len)
-					g_string_append_c (ignore_list, ',');
-				g_string_append (ignore_list, i->data);
-				g_free (i->data);
-			}
-			g_slist_free (ignore);
-			no_proxy = g_string_free (ignore_list, FALSE);
-		}
-		break;
-	}
-
-	/* We need to use libproxy if (a) there is an ignore list, or
-	 * (b) we're using PAC or WPAD.
+	/* FIXME: there is no way to force _g_io_modules_ensure_loaded()
+	 * to be run other than by requesting some extension that we
+	 * don't necessarily want.
 	 */
-	if (no_proxy)
-		need_libproxy = TRUE;
-	else if (http_proxy &&
-		 (g_str_has_prefix (http_proxy, "pac+") ||
-		  g_str_has_prefix (http_proxy, "wpad:")))
-		need_libproxy = TRUE;
-	else if (https_proxy &&
-		 (g_str_has_prefix (https_proxy, "pac+") ||
-		  g_str_has_prefix (https_proxy, "wpad:")))
-		need_libproxy = TRUE;
-	else
-		need_libproxy = FALSE;
-
-	if (!need_libproxy) {
-		if (libproxy_factory) {
-			px_proxy_factory_free (libproxy_factory);
-			libproxy_factory = NULL;
-		}
-		if (libproxy_threadpool) {
-			g_thread_pool_free (libproxy_threadpool, FALSE, FALSE);
-			libproxy_threadpool = NULL;
-		}
+	gproxyresolver = g_proxy_resolver_get_default ();
+	if (strcmp (G_OBJECT_TYPE_NAME (gproxyresolver),
+		    "GProxyResolverGnome") == 0)
 		return;
-	}
-
-	/* If we have a "bad" libproxy, set environment variables
-	 * and force it to use them.
-	 */
-#ifdef HAVE_LIBPROXY_WITH_NON_THREAD_SAFE_GNOME_MODULE
-	g_setenv ("PX_CONFIG_ORDER", "envvar", TRUE);
-	if (http_proxy)
-		g_setenv ("http_proxy", http_proxy, TRUE);
-	else
-		g_unsetenv ("http_proxy");
-	if (https_proxy)
-		g_setenv ("https_proxy", https_proxy, TRUE);
-	else
-		g_unsetenv ("https_proxy");
-	if (no_proxy)
-		g_setenv ("no_proxy", no_proxy, TRUE);
-	else
-		g_unsetenv ("no_proxy");
-	overrode_environment = TRUE;
-#endif
-
-	/* If we haven't created a proxy factory or thread pool yet,
-	 * do so. If we already have one, we don't need to update
-	 * anything, because it rechecks the environment variables, etc
-	 * every time.
-	 */
-	if (!libproxy_factory)
-		libproxy_factory = px_proxy_factory_new ();
-
-	if (!libproxy_threadpool) {
-		libproxy_threadpool =
-			g_thread_pool_new (libproxy_threadpool_func,
-					   NULL, -1, FALSE, NULL);
-	}
-}
-
-static void
-gconf_value_changed (GConfClient *client, const char *key,
-		     GConfValue *value, gpointer user_data)
-{
-	G_LOCK (resolver_gnome);
-	update_proxy_settings ();
-	G_UNLOCK (resolver_gnome);
-}
-
-static guint
-get_proxy_for_uri_direct (SoupURI *uri, SoupURI **proxy_uri)
-{
-	/* resolver_gnome is locked */
-
-	if (uri->scheme == SOUP_URI_SCHEME_HTTP && http_proxy)
-		*proxy_uri = soup_uri_new (http_proxy);
-	else if (uri->scheme == SOUP_URI_SCHEME_HTTPS && https_proxy)
-		*proxy_uri = soup_uri_new (https_proxy);
-	else
-		*proxy_uri = NULL;
-
-	if (*proxy_uri && proxy_user) {
-		soup_uri_set_user (*proxy_uri, proxy_user);
-		soup_uri_set_password (*proxy_uri, proxy_password);
-	}
-
-	return SOUP_STATUS_OK;
-}
-
-static guint
-get_proxy_for_uri_via_libproxy (SoupURI *uri, SoupURI **proxy_uri)
-{
-	char *uristr, **proxies;
-	gboolean got_proxy;
-	int i;
-
-	*proxy_uri = NULL;
-
-	/* resolver_gnome is locked */
-
-	uristr = soup_uri_to_string (uri, FALSE);
-	proxies = px_proxy_factory_get_proxies (libproxy_factory, uristr);
-	g_free (uristr);
-
-	if (!proxies)
-		return SOUP_STATUS_OK;
-
-	got_proxy = FALSE;
-	for (i = 0; proxies[i]; i++) {
-		if (!strcmp (proxies[i], "direct://")) {
-			got_proxy = TRUE;
-			break;
-		}
-		if (strncmp (proxies[i], "http://";, 7) == 0) {
-			*proxy_uri = soup_uri_new (proxies[i]);
-			got_proxy = TRUE;
-			break;
-		}
-	}
-	for (i = 0; proxies[i]; i++)
-		free (proxies[i]);
-	free (proxies);
-
-	if (got_proxy) {
-		if (*proxy_uri && proxy_user) {
-			soup_uri_set_user (*proxy_uri, proxy_user);
-			soup_uri_set_password (*proxy_uri, proxy_password);
-		}
-
-		return SOUP_STATUS_OK;
-	} else
-		return SOUP_STATUS_CANT_RESOLVE_PROXY;
-}
-
-typedef struct {
-	SoupProxyURIResolver *proxy_uri_resolver;
-	SoupURI *uri, *proxy_uri;
-	GMainContext *async_context;
-	GCancellable *cancellable;
-	guint status;
-	SoupProxyURIResolverCallback callback;
-	gpointer user_data;
-} SoupGNOMEAsyncData;
-
-static gboolean
-resolved_proxy (gpointer data)
-{
-	SoupGNOMEAsyncData *sgad = data;
-
-	sgad->callback (sgad->proxy_uri_resolver, sgad->status,
-			sgad->proxy_uri, sgad->user_data);
-	g_object_unref (sgad->proxy_uri_resolver);
-	if (sgad->uri)
-		soup_uri_free (sgad->uri);
-	if (sgad->async_context)
-		g_main_context_unref (sgad->async_context);
-	if (sgad->cancellable)
-		g_object_unref (sgad->cancellable);
-	if (sgad->proxy_uri)
-		soup_uri_free (sgad->proxy_uri);
-	g_slice_free (SoupGNOMEAsyncData, sgad);
 
-	return FALSE;
-}
+	ep = g_io_extension_point_lookup (G_PROXY_RESOLVER_EXTENSION_POINT_NAME);
+	if (!ep)
+		return;
 
-static void
-libproxy_threadpool_func (gpointer user_data, gpointer thread_data)
-{
-	SoupGNOMEAsyncData *sgad = user_data;
+	ext = g_io_extension_point_get_extension_by_name (ep, "gnome");
+	if (!ext)
+		return;
 
-	/* We don't just call get_proxy_for_uri here, since it's
-	 * possible that the proxy mode has changed...
-	 */
-	sgad->status = get_proxy_uri_sync (sgad->proxy_uri_resolver,
-					   sgad->uri, sgad->cancellable,
-					   &sgad->proxy_uri);
-	soup_add_completion (sgad->async_context, resolved_proxy, sgad);
+	type = g_io_extension_get_type (ext);
+	gproxyresolver = g_object_new (type, NULL);
+	g_object_set (G_OBJECT (resolver_gnome),
+		      "gproxy-resolver", gproxyresolver,
+		      NULL);
+	g_object_unref (gproxyresolver);
 }
 
 static void
-get_proxy_uri_async (SoupProxyURIResolver  *proxy_uri_resolver,
-		     SoupURI               *uri,
-		     GMainContext          *async_context,
-		     GCancellable          *cancellable,
-		     SoupProxyURIResolverCallback callback,
-		     gpointer               user_data)
+soup_proxy_resolver_gnome_class_init (SoupProxyResolverGNOMEClass *gnome_class)
 {
-	SoupGNOMEAsyncData *sgad;
-
-	sgad = g_slice_new0 (SoupGNOMEAsyncData);
-	sgad->proxy_uri_resolver = g_object_ref (proxy_uri_resolver);
-	sgad->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
-	sgad->callback = callback;
-	sgad->user_data = user_data;
-
-	G_LOCK (resolver_gnome);
-	if (libproxy_threadpool) {
-		/* FIXME: cancellable */
-		sgad->uri = soup_uri_copy (uri);
-		sgad->async_context = async_context ? g_main_context_ref (async_context) : NULL;
-		g_thread_pool_push (libproxy_threadpool, sgad, NULL);
-	} else {
-		sgad->status = get_proxy_for_uri_direct (uri, &sgad->proxy_uri);
-		soup_add_completion (async_context, resolved_proxy, sgad);
-	}
-	G_UNLOCK (resolver_gnome);
-}
-
-static guint
-get_proxy_uri_sync (SoupProxyURIResolver  *proxy_uri_resolver,
-		    SoupURI               *uri,
-		    GCancellable          *cancellable,
-		    SoupURI              **proxy_uri)
-{
-	guint status;
-
-	G_LOCK (resolver_gnome);
-	if (libproxy_factory)
-		status = get_proxy_for_uri_via_libproxy (uri, proxy_uri);
-	else
-		status = get_proxy_for_uri_direct (uri, proxy_uri);
-	G_UNLOCK (resolver_gnome);
-
-	return status;
 }
diff --git a/libsoup/soup-proxy-resolver-gnome.h b/libsoup/soup-proxy-resolver-gnome.h
index 2f87921..809e9dd 100644
--- a/libsoup/soup-proxy-resolver-gnome.h
+++ b/libsoup/soup-proxy-resolver-gnome.h
@@ -7,6 +7,7 @@
 #define SOUP_PROXY_RESOLVER_GNOME_H 1
 
 #include "soup-gnome-features.h"
+#include "soup-proxy-resolver-default.h"
 
 /* SOUP_TYPE_PROXY_RESOLVER_GNOME and soup_proxy_resolver_gnome_get_type()
  * are declared in soup-gnome-features.h.
@@ -18,14 +19,7 @@
 #define SOUP_IS_PROXY_RESOLVER_GNOME_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SOUP_TYPE_PROXY_RESOLVER_GNOME))
 #define SOUP_PROXY_RESOLVER_GNOME_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), SOUP_TYPE_PROXY_RESOLVER_GNOME, SoupProxyResolverGNOMEClass))
 
-typedef struct {
-	GObject parent;
-
-} SoupProxyResolverGNOME;
-
-typedef struct {
-	GObjectClass parent_class;
-
-} SoupProxyResolverGNOMEClass;
+typedef SoupProxyResolverDefault SoupProxyResolverGNOME;
+typedef SoupProxyResolverDefaultClass SoupProxyResolverGNOMEClass;
 
 #endif /*SOUP_PROXY_RESOLVER_GNOME_H*/



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]