SoupProxyResolverGNOME: make this a subclass of SoupProxyResolverDefault
authorDan Winship <danw@gnome.org>
Mon, 21 Mar 2011 17:23:15 +0000 (13:23 -0400)
committerDan Winship <danw@gnome.org>
Mon, 21 Mar 2011 17:28:14 +0000 (13:28 -0400)
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
docs/reference/Makefile.am
libsoup/Makefile.am
libsoup/soup-proxy-resolver-default.c
libsoup/soup-proxy-resolver-gnome.c
libsoup/soup-proxy-resolver-gnome.h

index efaac57..dc23fe7 100644 (file)
@@ -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)
 
index 64d3cf8..43b568d 100644 (file)
@@ -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
 
index de9c9b6..308c08f 100644 (file)
@@ -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)
 
index 962d0c1..b0bcbac 100644 (file)
@@ -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);
index 186ca4e..e01dd6a 100644 (file)
 #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;
 }
index 2f87921..809e9dd 100644 (file)
@@ -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.
 #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*/