libsoup r1194 - in trunk: . libsoup tests



Author: danw
Date: Fri Oct 31 18:12:18 2008
New Revision: 1194
URL: http://svn.gnome.org/viewvc/libsoup?rev=1194&view=rev

Log:
	Add libsoup-gnome, for new features that depend on GNOME
	libraries.

	* configure.in: Check for libproxy and/or gconf, accept
	--without-gnome option, output libsoup-gnome-2.4.pc

	* libsoup-gnome-2.4.pc: pc file for libsoup with GNOME support

	* libsoup/Makefile.am: build libsoup-gnome.la if so configured

	* libsoup/soup-gnome.h: base header for libsoup-gnome

	* libsoup/soup-proxy-resolver-libproxy.c: An implementation of
	SoupProxyResolver that uses libproxy.

	* libsoup/soup-proxy-resolver-gconf.c: An implementation of
	SoupProxyResolver that uses the proxy keys in GConf. Does not
	completely handle ignore_hosts; this is currently just used as a
	fallback if libproxy is not available.

	* libsoup/soup-gnome-features.c: provides
	SOUP_TYPE_PROXY_RESOLVER_GNOME (abstracting over
	SoupProxyResolverGConf and SoupProxyResolverLibproxy) and
	SOUP_TYPE_GNOME_FEATURES_2_26, which adds "all GNOME-specific
	features in libsoup 2.26", which is currently just the proxy
	resolver.

	* libsoup/soup-session-async.c (resolved_proxy_addr): set
	item->resolved_proxy_addr
	(run_queue): resolve the proxy if !item->resolved_proxy_addr, not
	if !item->proxy_addr, since the proxy addr might resolve to NULL.

	* tests/Makefile.am (get_LDADD):
	* tests/get.c: If we built libsoup-gnome, use it in "get" for
	automatic proxy support


Added:
   trunk/libsoup-gnome-2.4.pc.in
   trunk/libsoup/soup-gnome-features.c
   trunk/libsoup/soup-gnome-features.h
   trunk/libsoup/soup-gnome.h
   trunk/libsoup/soup-proxy-resolver-gconf.c
   trunk/libsoup/soup-proxy-resolver-gconf.h
   trunk/libsoup/soup-proxy-resolver-libproxy.c
   trunk/libsoup/soup-proxy-resolver-libproxy.h
Modified:
   trunk/   (props changed)
   trunk/Makefile.am
   trunk/configure.in
   trunk/libsoup/Makefile.am
   trunk/libsoup/soup-session-async.c
   trunk/libsoup/soup-session-sync.c
   trunk/tests/Makefile.am
   trunk/tests/get.c

Modified: trunk/Makefile.am
==============================================================================
--- trunk/Makefile.am	(original)
+++ trunk/Makefile.am	Fri Oct 31 18:12:18 2008
@@ -5,6 +5,7 @@
 
 EXTRA_DIST =			\
 	libsoup-2.4.pc.in	\
+	libsoup-gnome-2.4.pc.in	\
 	gtk-doc.make		\
 	libsoup-zip.in
 
@@ -14,3 +15,6 @@
 
 pkgconfig_DATA = libsoup-2.4.pc
 
+if BUILD_LIBSOUP_GNOME
+pkgconfig_DATA += libsoup-gnome-2.4.pc
+endif

Modified: trunk/configure.in
==============================================================================
--- trunk/configure.in	(original)
+++ trunk/configure.in	Fri Oct 31 18:12:18 2008
@@ -169,6 +169,46 @@
 dnl This is not supposed to be conditional, but...
 AM_CONDITIONAL(HAVE_SSL, test $enable_ssl != no)
 
+
+dnl *********************
+dnl *** GNOME support ***
+dnl *********************
+AC_MSG_CHECKING(whether to build libsoup-gnome)
+AC_ARG_WITH(gnome,
+	    AS_HELP_STRING([--without-gnome], [Do not build libsoup-gnome]),
+	    :, [if test $os_win32 = yes; then with_gnome=no; else with_gnome=yes; fi])
+AC_MSG_RESULT($with_gnome)
+
+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,
+			  have_libproxy=yes, have_libproxy=no)
+	if test $have_libproxy = yes; then
+		AC_DEFINE(HAVE_LIBPROXY, 1, [Defined if libproxy support is enabled])
+	else
+		PKG_CHECK_MODULES(GCONF, gconf-2.0, , [AC_MSG_ERROR(dnl
+[Could not find libproxy or GConf:
+
+$LIBPROXY_PKG_ERRORS
+
+$GCONF_PKG_ERRORS
+
+One or the other is required for GNOME proxy support.
+Pass "--without-gnome" to configure if you want to build without GNOME support.])])
+	fi
+fi
+AC_SUBST(HAVE_GNOME)
+AC_SUBST(GCONF_CFLAGS)
+AC_SUBST(GCONF_LIBS)
+AC_SUBST(HAVE_LIBPROXY)
+AC_SUBST(LIBPROXY_CFLAGS)
+AC_SUBST(LIBPROXY_LIBS)
+AM_CONDITIONAL(WITH_LIBPROXY, [test -n "$LIBPROXY_LIBS"])
+
+
 dnl ***************
 dnl *** gtk-doc ***
 dnl ***************
@@ -318,6 +358,7 @@
 
 AC_OUTPUT([
 	libsoup-2.4.pc
+	libsoup-gnome-2.4.pc
 	Makefile
 	libsoup-zip
 	libsoup/Makefile

Added: trunk/libsoup-gnome-2.4.pc.in
==============================================================================
--- (empty file)
+++ trunk/libsoup-gnome-2.4.pc.in	Fri Oct 31 18:12:18 2008
@@ -0,0 +1,11 @@
+prefix= prefix@
+exec_prefix= exec_prefix@
+libdir= libdir@
+includedir= includedir@
+
+Name: libsoup
+Description: a glib-based HTTP library
+Version: @VERSION@
+Requires: libsoup-2.4
+Libs: -L${libdir} -lsoup-gnome-2.4
+Cflags: -I${includedir}/libsoup-gnome-2.4

Modified: trunk/libsoup/Makefile.am
==============================================================================
--- trunk/libsoup/Makefile.am	(original)
+++ trunk/libsoup/Makefile.am	Fri Oct 31 18:12:18 2008
@@ -11,6 +11,8 @@
 	$(SOUP_MAINTAINER_FLAGS)	\
 	$(GLIB_CFLAGS)			\
 	$(XML_CFLAGS)			\
+	$(GCONF_CFLAGS)			\
+	$(LIBPROXY_CFLAGS)		\
 	$(LIBGCRYPT_CFLAGS)		\
 	$(LIBGNUTLS_CFLAGS)
 
@@ -154,6 +156,42 @@
 	soup-value-utils.c		\
 	soup-xmlrpc.c
 
+if BUILD_LIBSOUP_GNOME
+
+libsoupgnomeincludedir = $(libsoupincludedir)
+
+libsoupgnomeinclude_HEADERS =	\
+	soup-gnome.h		\
+	soup-gnome-features.h
+
+lib_LTLIBRARIES += libsoup-gnome-2.4.la
+
+libsoup_gnome_2_4_la_LDFLAGS = $(libsoup_2_4_la_LDFLAGS)
+
+libsoup_gnome_2_4_la_LIBADD = libsoup-2.4.la
+
+libsoup_gnome_2_4_la_SOURCES =		\
+	soup-gnome-features.c
+
+if WITH_LIBPROXY
+libsoup_gnome_2_4_la_SOURCES +=		\
+	soup-proxy-resolver-libproxy.h	\
+	soup-proxy-resolver-libproxy.c
+
+libsoup_gnome_2_4_la_LIBADD +=		\
+	$(LIBPROXY_LIBS)
+else
+libsoup_gnome_2_4_la_SOURCES +=		\
+	soup-proxy-resolver-gconf.h	\
+	soup-proxy-resolver-gconf.c
+
+libsoup_gnome_2_4_la_LIBADD +=		\
+	$(GCONF_LIBS)
+endif
+
+endif
+
+
 EXTRA_DIST=				\
 	soup-marshal.list		\
 	soup-enum-types.h.tmpl		\

Added: trunk/libsoup/soup-gnome-features.c
==============================================================================
--- (empty file)
+++ trunk/libsoup/soup-gnome-features.c	Fri Oct 31 18:12:18 2008
@@ -0,0 +1,62 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * soup-gnome-features.c: GNOME-specific features
+ *
+ * Copyright (C) 2008 Red Hat, Inc.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "soup-gnome-features.h"
+
+#ifdef HAVE_LIBPROXY
+#include "soup-proxy-resolver-libproxy.h"
+#else
+#include "soup-proxy-resolver-gconf.h"
+#endif
+
+/**
+ * SOUP_TYPE_PROXY_RESOLVER_GNOME:
+ *
+ * This returns the #GType of a #SoupProxyResolver that can be used to
+ * resolve HTTP proxies for GNOME applications. You can add this to
+ * a session using soup_session_add_feature_by_type() or by using the
+ * %SOUP_SESSION_ADD_FEATURE_BY_TIME construct-time property.
+ *
+ * This feature is included in %SOUP_TYPE_GNOME_FEATURES_2_26, so if
+ * you are using that feature, you do not need to include this feature
+ * separately.
+ **/
+GType
+soup_proxy_resolver_gnome_get_type (void)
+{
+#ifdef HAVE_LIBPROXY
+	return SOUP_TYPE_PROXY_RESOLVER_LIBPROXY;
+#else
+	return SOUP_TYPE_PROXY_RESOLVER_GCONF;
+#endif
+}
+
+/**
+ * SOUP_TYPE_GNOME_FEATURES_2_26:
+ *
+ * This returns the #GType of a #SoupSessionFeature that automatically
+ * adds all of the GNOME features defined for libsoup 2.26. At the
+ * moment, this is just %SOUP_TYPE_PROXY_RESOLVER_GNOME.
+ *
+ * You can add this to a session using
+ * soup_session_add_feature_by_type() or by using the
+ * %SOUP_SESSION_ADD_FEATURE_BY_TIME construct-time property.
+ **/
+GType
+soup_gnome_features_2_26_get_type (void)
+{
+	/* Eventually this needs to be a special SoupSessionFeature
+	 * class that registers other features. But for now we can
+	 * just do this:
+	 */
+	return SOUP_TYPE_PROXY_RESOLVER_GNOME;
+}
+

Added: trunk/libsoup/soup-gnome-features.h
==============================================================================
--- (empty file)
+++ trunk/libsoup/soup-gnome-features.h	Fri Oct 31 18:12:18 2008
@@ -0,0 +1,21 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2008 Red Hat, Inc.
+ */
+
+#ifndef SOUP_GNOME_FEATURES_H
+#define SOUP_GNOME_FEATURES_H 1
+
+#include <libsoup/soup-types.h>
+
+G_BEGIN_DECLS
+
+GType soup_proxy_resolver_gnome_get_type (void);
+#define SOUP_TYPE_PROXY_RESOLVER_GNOME (soup_proxy_resolver_gnome_get_type ())
+
+GType soup_gnome_features_2_26_get_type (void);
+#define SOUP_TYPE_GNOME_FEATURES_2_26 (soup_gnome_features_2_26_get_type ())
+
+G_END_DECLS
+
+#endif /* SOUP_GNOME_FEATURES_H */

Added: trunk/libsoup/soup-gnome.h
==============================================================================
--- (empty file)
+++ trunk/libsoup/soup-gnome.h	Fri Oct 31 18:12:18 2008
@@ -0,0 +1,13 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2008 Red Hat, Inc.
+ */
+
+#ifndef SOUP_GNOME_H
+#define SOUP_GNOME_H 1
+
+#include <libsoup/soup.h>
+
+#include <libsoup/soup-gnome-features.h>
+
+#endif /* SOUP_GNOME_H */

Added: trunk/libsoup/soup-proxy-resolver-gconf.c
==============================================================================
--- (empty file)
+++ trunk/libsoup/soup-proxy-resolver-gconf.c	Fri Oct 31 18:12:18 2008
@@ -0,0 +1,314 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * soup-proxy-resolver-gconf.c: GConf-based proxy resolution
+ *
+ * Copyright (C) 2008 Red Hat, Inc.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+
+#include "soup-proxy-resolver-gconf.h"
+#include "soup-address.h"
+#include "soup-dns.h"
+#include "soup-message.h"
+#include "soup-misc.h"
+#include "soup-session-feature.h"
+
+#include <gconf/gconf-client.h>
+
+typedef struct {
+	GMutex *lock;
+	GConfClient *gconf;
+
+	SoupAddress *proxy_addr;
+	char *user, *password;
+
+	GSList *ignore_hosts;
+} SoupProxyResolverGConfPrivate;
+#define SOUP_PROXY_RESOLVER_GCONF_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SOUP_TYPE_PROXY_RESOLVER_GCONF, SoupProxyResolverGConfPrivate))
+
+static void soup_proxy_resolver_gconf_interface_init (SoupProxyResolverInterface *proxy_resolver_interface);
+
+G_DEFINE_TYPE_EXTENDED (SoupProxyResolverGConf, soup_proxy_resolver_gconf, G_TYPE_OBJECT, 0,
+			G_IMPLEMENT_INTERFACE (SOUP_TYPE_SESSION_FEATURE, NULL)
+			G_IMPLEMENT_INTERFACE (SOUP_TYPE_PROXY_RESOLVER, soup_proxy_resolver_gconf_interface_init))
+
+static void gconf_value_changed (GConfClient *client, const char *key,
+				 GConfValue *value, gpointer user_data);
+static void update_proxy_settings (SoupProxyResolverGConfPrivate *priv);
+static void free_proxy_settings (SoupProxyResolverGConfPrivate *priv);
+
+static void get_proxy_async (SoupProxyResolver  *proxy_resolver,
+			     SoupMessage        *msg,
+			     GMainContext       *async_context,
+			     GCancellable       *cancellable,
+			     SoupProxyResolverCallback callback,
+			     gpointer            user_data);
+static guint get_proxy_sync (SoupProxyResolver  *proxy_resolver,
+			     SoupMessage        *msg,
+			     GCancellable       *cancellable,
+			     SoupAddress       **addr);
+
+static void
+soup_proxy_resolver_gconf_init (SoupProxyResolverGConf *resolver_gconf)
+{
+	SoupProxyResolverGConfPrivate *priv =
+		SOUP_PROXY_RESOLVER_GCONF_GET_PRIVATE (resolver_gconf);
+
+	priv->lock = g_mutex_new ();
+	priv->gconf = gconf_client_get_default ();
+
+	gconf_client_add_dir (priv->gconf, "/system/http_proxy",
+			      GCONF_CLIENT_PRELOAD_RECURSIVE, NULL);
+	g_signal_connect (priv->gconf, "value_changed",
+			  G_CALLBACK (gconf_value_changed),
+			  resolver_gconf);
+	update_proxy_settings (priv);
+}
+
+static void
+finalize (GObject *object)
+{
+	SoupProxyResolverGConfPrivate *priv =
+		SOUP_PROXY_RESOLVER_GCONF_GET_PRIVATE (object);
+
+	free_proxy_settings (priv);
+	g_object_unref (priv->gconf);
+	g_mutex_free (priv->lock);
+
+	G_OBJECT_CLASS (soup_proxy_resolver_gconf_parent_class)->finalize (object);
+}
+
+static void
+soup_proxy_resolver_gconf_class_init (SoupProxyResolverGConfClass *gconf_class)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (gconf_class);
+
+	g_type_class_add_private (gconf_class, sizeof (SoupProxyResolverGConfPrivate));
+
+	object_class->finalize = finalize;
+}
+
+static void
+soup_proxy_resolver_gconf_interface_init (SoupProxyResolverInterface *proxy_resolver_interface)
+{
+	proxy_resolver_interface->get_proxy_async = get_proxy_async;
+	proxy_resolver_interface->get_proxy_sync = get_proxy_sync;
+}
+
+SoupProxyResolver *
+soup_proxy_resolver_gconf_new (void)
+{
+	return g_object_new (SOUP_TYPE_PROXY_RESOLVER_GCONF, NULL);
+}
+
+static void
+free_proxy_settings (SoupProxyResolverGConfPrivate *priv)
+{
+	GSList *l;
+
+	if (priv->proxy_addr) {
+		g_object_unref (priv->proxy_addr);
+		priv->proxy_addr = NULL;
+	}
+	g_free (priv->user);
+	priv->user = NULL;
+	g_free (priv->password);
+	priv->password = NULL;
+
+	for (l = priv->ignore_hosts; l; l = l->next)
+		g_free (l->data);
+	g_slist_free (priv->ignore_hosts);
+	priv->ignore_hosts = NULL;
+}
+
+#define SOUP_GCONF_PROXY_ENABLED      "/system/http_proxy/use_http_proxy"
+#define SOUP_GCONF_PROXY_USE_AUTH     "/system/http_proxy/use_authentication"
+#define SOUP_GCONF_PROXY_HOST         "/system/http_proxy/host"
+#define SOUP_GCONF_PROXY_PORT         "/system/http_proxy/port"
+#define SOUP_GCONF_PROXY_USER         "/system/http_proxy/authentication_user"
+#define SOUP_GCONF_PROXY_PASSWORD     "/system/http_proxy/authentication_password"
+#define SOUP_GCONF_PROXY_IGNORE_HOSTS "/system/http_proxy/ignore_hosts"
+
+static void
+update_proxy_settings (SoupProxyResolverGConfPrivate *priv)
+{
+	GSList *ignore_hosts, *i;
+	char *host;
+	guint port;
+
+	if (!gconf_client_get_bool (priv->gconf, SOUP_GCONF_PROXY_ENABLED, NULL))
+		return;
+
+	host = gconf_client_get_string (
+		priv->gconf, SOUP_GCONF_PROXY_HOST, NULL);
+	if (!host)
+		return;
+	port = gconf_client_get_int (
+		priv->gconf, SOUP_GCONF_PROXY_PORT, NULL);
+	priv->proxy_addr = soup_address_new (host, port);
+	g_free (host);
+
+	if (gconf_client_get_bool (priv->gconf, SOUP_GCONF_PROXY_USE_AUTH, NULL)) {
+		priv->user = gconf_client_get_string (
+			priv->gconf, SOUP_GCONF_PROXY_USER, NULL);
+		priv->password = gconf_client_get_string (
+			priv->gconf, SOUP_GCONF_PROXY_PASSWORD, NULL);
+	}
+
+	ignore_hosts = gconf_client_get_list (
+		priv->gconf, SOUP_GCONF_PROXY_IGNORE_HOSTS,
+		GCONF_VALUE_STRING, NULL);
+	for (i = ignore_hosts; i; i = i->next) {
+		host = i->data;
+
+		/* FIXME: not right. Need to handle addresses, masks */
+		priv->ignore_hosts = g_slist_prepend (
+			priv->ignore_hosts,
+			g_ascii_strdown (host, -1));
+		g_free (host);
+	}
+	g_slist_free (ignore_hosts);
+}
+
+static void
+gconf_value_changed (GConfClient *client, const char *key,
+		     GConfValue *value, gpointer user_data)
+{
+	SoupProxyResolverGConf *resolver_gconf = user_data;
+	SoupProxyResolverGConfPrivate *priv =
+		SOUP_PROXY_RESOLVER_GCONF_GET_PRIVATE (resolver_gconf);
+
+	free_proxy_settings (priv);
+	update_proxy_settings (priv);
+}
+
+static gboolean
+message_has_ignored_address (SoupProxyResolverGConfPrivate *priv,
+			     SoupMessage *msg)
+{
+	SoupAddress *addr;
+	struct sockaddr *sockaddr;
+	const char *name, *ignore_name;
+	char *hostname;
+	GSList *l;
+	int len;
+
+	if (!priv->ignore_hosts)
+		return FALSE;
+
+	addr = soup_message_get_address (msg);
+	name = soup_address_get_name (addr);
+	sockaddr = soup_address_get_sockaddr (addr, &len);
+	g_return_val_if_fail (name != NULL && sockaddr != NULL, FALSE);
+
+	hostname = g_ascii_strdown (name, -1);
+	for (l = priv->ignore_hosts; l; l = l->next) {
+		ignore_name = l->data;
+
+		if (*ignore_name == '*') {
+			if (g_str_has_suffix (hostname, ignore_name + 1)) {
+				g_free (hostname);
+				return TRUE;
+			}
+		} else if (strcmp (hostname, ignore_name) == 0) {
+			g_free (hostname);
+			return TRUE;
+		}
+	}
+	g_free (hostname);
+
+	return FALSE;
+}
+
+static SoupAddress *
+get_proxy_for_message (SoupProxyResolver  *proxy_resolver,
+		       SoupMessage        *msg)
+{
+	SoupProxyResolverGConfPrivate *priv =
+		SOUP_PROXY_RESOLVER_GCONF_GET_PRIVATE (proxy_resolver);
+	SoupAddress *addr;
+
+	g_mutex_lock (priv->lock);
+
+	if (!priv->proxy_addr || message_has_ignored_address (priv, msg)) {
+		g_mutex_unlock (priv->lock);
+		return NULL;
+	}
+
+	addr = g_object_ref (priv->proxy_addr);
+	g_mutex_unlock (priv->lock);
+	return addr;
+}
+
+typedef struct {
+	SoupProxyResolver *proxy_resolver;
+	SoupMessage *msg;
+	SoupAddress *addr;
+	SoupProxyResolverCallback callback;
+	gpointer user_data;
+} SoupGConfAsyncData;
+
+static void
+resolved_address (SoupAddress *addr, guint status, gpointer data)
+{
+	SoupGConfAsyncData *sgad = data;
+
+	sgad->callback (sgad->proxy_resolver, sgad->msg,
+			soup_status_proxify (status), addr,
+			sgad->user_data);
+	g_object_unref (sgad->proxy_resolver);
+	g_object_unref (sgad->msg);
+	if (addr)
+		g_object_unref (addr);
+	g_slice_free (SoupGConfAsyncData, sgad);
+}
+
+static gboolean
+resolved_no_address (gpointer data)
+{
+	resolved_address (NULL, SOUP_STATUS_OK, data);
+	return FALSE;
+}
+
+static void
+get_proxy_async (SoupProxyResolver  *proxy_resolver,
+		 SoupMessage        *msg,
+		 GMainContext       *async_context,
+		 GCancellable       *cancellable,
+		 SoupProxyResolverCallback callback,
+		 gpointer            user_data)
+{
+	SoupGConfAsyncData *sgad;
+
+	sgad = g_slice_new0 (SoupGConfAsyncData);
+	sgad->proxy_resolver = g_object_ref (proxy_resolver);
+	sgad->msg = g_object_ref (msg);
+	sgad->callback = callback;
+	sgad->user_data = user_data;
+	sgad->addr = get_proxy_for_message (proxy_resolver, msg);
+
+	if (sgad->addr) {
+		soup_address_resolve_async (sgad->addr, async_context,
+					    cancellable, resolved_address,
+					    sgad);
+	} else
+		soup_add_idle (async_context, resolved_no_address, sgad);
+}
+
+static guint
+get_proxy_sync (SoupProxyResolver  *proxy_resolver,
+		SoupMessage        *msg,
+		GCancellable       *cancellable,
+		SoupAddress       **addr)
+{
+	*addr = get_proxy_for_message (proxy_resolver, msg);
+	if (*addr)
+		return soup_status_proxify (soup_address_resolve_sync (*addr, cancellable));
+	else
+		return SOUP_STATUS_OK;
+}

Added: trunk/libsoup/soup-proxy-resolver-gconf.h
==============================================================================
--- (empty file)
+++ trunk/libsoup/soup-proxy-resolver-gconf.h	Fri Oct 31 18:12:18 2008
@@ -0,0 +1,32 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2008 Red Hat, Inc.
+ */
+
+#ifndef SOUP_PROXY_RESOLVER_GCONF_H
+#define SOUP_PROXY_RESOLVER_GCONF_H 1
+
+#include <libsoup/soup-proxy-resolver.h>
+
+#define SOUP_TYPE_PROXY_RESOLVER_GCONF            (soup_proxy_resolver_gconf_get_type ())
+#define SOUP_PROXY_RESOLVER_GCONF(object)         (G_TYPE_CHECK_INSTANCE_CAST ((object), SOUP_TYPE_PROXY_RESOLVER_GCONF, SoupProxyResolverGConf))
+#define SOUP_PROXY_RESOLVER_GCONF_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), SOUP_TYPE_PROXY_RESOLVER_GCONF, SoupProxyResolverGConfClass))
+#define SOUP_IS_PROXY_RESOLVER_GCONF(object)      (G_TYPE_CHECK_INSTANCE_TYPE ((object), SOUP_TYPE_PROXY_RESOLVER_GCONF))
+#define SOUP_IS_PROXY_RESOLVER_GCONF_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SOUP_TYPE_PROXY_RESOLVER_GCONF))
+#define SOUP_PROXY_RESOLVER_GCONF_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), SOUP_TYPE_PROXY_RESOLVER_GCONF, SoupProxyResolverGConfClass))
+
+typedef struct {
+	GObject parent;
+
+} SoupProxyResolverGConf;
+
+typedef struct {
+	GObjectClass parent_class;
+
+} SoupProxyResolverGConfClass;
+
+GType soup_proxy_resolver_gconf_get_type (void);
+
+SoupProxyResolver *soup_proxy_resolver_gconf_new (void);
+
+#endif /*SOUP_PROXY_RESOLVER_GCONF_H*/

Added: trunk/libsoup/soup-proxy-resolver-libproxy.c
==============================================================================
--- (empty file)
+++ trunk/libsoup/soup-proxy-resolver-libproxy.c	Fri Oct 31 18:12:18 2008
@@ -0,0 +1,208 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * soup-proxy-resolver-libproxy.c: libproxy-based proxy resolution
+ *
+ * Copyright (C) 2008 Red Hat, Inc.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+
+#include "soup-proxy-resolver-libproxy.h"
+#include "soup-address.h"
+#include "soup-message.h"
+#include "soup-misc.h"
+#include "soup-session-feature.h"
+#include "soup-uri.h"
+
+#include <proxy.h>
+
+typedef struct {
+	pxProxyFactory *factory;
+} SoupProxyResolverLibproxyPrivate;
+	
+#define SOUP_PROXY_RESOLVER_LIBPROXY_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SOUP_TYPE_PROXY_RESOLVER_LIBPROXY, SoupProxyResolverLibproxyPrivate))
+
+static void soup_proxy_resolver_libproxy_interface_init (SoupProxyResolverInterface *proxy_resolver_interface);
+
+G_DEFINE_TYPE_EXTENDED (SoupProxyResolverLibproxy, soup_proxy_resolver_libproxy, G_TYPE_OBJECT, 0,
+			G_IMPLEMENT_INTERFACE (SOUP_TYPE_SESSION_FEATURE, NULL)
+			G_IMPLEMENT_INTERFACE (SOUP_TYPE_PROXY_RESOLVER, soup_proxy_resolver_libproxy_interface_init))
+
+static void get_proxy_async (SoupProxyResolver  *proxy_resolver,
+			     SoupMessage        *msg,
+			     GMainContext       *async_context,
+			     GCancellable       *cancellable,
+			     SoupProxyResolverCallback callback,
+			     gpointer            user_data);
+static guint get_proxy_sync (SoupProxyResolver  *proxy_resolver,
+			     SoupMessage        *msg,
+			     GCancellable       *cancellable,
+			     SoupAddress       **addr);
+
+static void
+soup_proxy_resolver_libproxy_init (SoupProxyResolverLibproxy *libproxy)
+{
+	SoupProxyResolverLibproxyPrivate *priv =
+		SOUP_PROXY_RESOLVER_LIBPROXY_GET_PRIVATE (libproxy);
+
+	priv->factory = px_proxy_factory_new ();
+}
+
+static void
+finalize (GObject *object)
+{
+	SoupProxyResolverLibproxyPrivate *priv =
+		SOUP_PROXY_RESOLVER_LIBPROXY_GET_PRIVATE (object);
+
+	px_proxy_factory_free (priv->factory);
+
+	G_OBJECT_CLASS (soup_proxy_resolver_libproxy_parent_class)->finalize (object);
+}
+
+static void
+soup_proxy_resolver_libproxy_class_init (SoupProxyResolverLibproxyClass *libproxy_class)
+{
+	GObjectClass *object_class = G_OBJECT_CLASS (libproxy_class);
+
+	g_type_class_add_private (libproxy_class, sizeof (SoupProxyResolverLibproxyPrivate));
+
+	object_class->finalize = finalize;
+}
+
+static void
+soup_proxy_resolver_libproxy_interface_init (SoupProxyResolverInterface *proxy_resolver_interface)
+{
+	proxy_resolver_interface->get_proxy_async = get_proxy_async;
+	proxy_resolver_interface->get_proxy_sync = get_proxy_sync;
+}
+
+SoupProxyResolver *
+soup_proxy_resolver_libproxy_new (void)
+{
+	return g_object_new (SOUP_TYPE_PROXY_RESOLVER_LIBPROXY, NULL);
+}
+
+typedef struct {
+	SoupProxyResolver *proxy_resolver;
+	SoupMessage *msg;
+	GMainContext *async_context;
+	GCancellable *cancellable;
+	guint status;
+	SoupAddress *addr;
+	SoupProxyResolverCallback callback;
+	gpointer user_data;
+} SoupLibproxyAsyncData;
+
+static gboolean
+resolve_callback (gpointer data)
+{
+	SoupLibproxyAsyncData *slad = data;
+
+	slad->callback (slad->proxy_resolver, slad->msg,
+			slad->status, slad->addr, slad->user_data);
+	g_object_unref (slad->proxy_resolver);
+	g_object_unref (slad->msg);
+	if (slad->addr)
+		g_object_unref (slad->addr);
+	g_slice_free (SoupLibproxyAsyncData, slad);
+
+	return FALSE;
+}
+
+static gpointer
+resolve_thread (gpointer data)
+{
+	SoupLibproxyAsyncData *slad = data;
+
+	slad->status = get_proxy_sync (slad->proxy_resolver,
+				       slad->msg,
+				       slad->cancellable,
+				       &slad->addr);
+	soup_add_idle (slad->async_context, resolve_callback, slad);
+	return NULL;
+}
+
+static void
+get_proxy_async (SoupProxyResolver  *proxy_resolver,
+		 SoupMessage        *msg,
+		 GMainContext       *async_context,
+		 GCancellable       *cancellable,
+		 SoupProxyResolverCallback callback,
+		 gpointer            user_data)
+{
+	SoupLibproxyAsyncData *slad;
+
+	slad = g_slice_new0 (SoupLibproxyAsyncData);
+	slad->proxy_resolver = g_object_ref (proxy_resolver);
+	slad->msg = g_object_ref (msg);
+	slad->async_context = async_context;
+	slad->cancellable = cancellable;
+	slad->callback = callback;
+	slad->user_data = user_data;
+
+	g_thread_create (resolve_thread, slad, FALSE, NULL);
+}
+
+static void
+free_proxies (char **proxies)
+{
+	int i;
+
+	for (i = 0; proxies[i]; i++)
+		free (proxies[i]);
+	free (proxies);
+}
+
+static guint
+get_proxy_sync (SoupProxyResolver  *proxy_resolver,
+		SoupMessage        *msg,
+		GCancellable       *cancellable,
+		SoupAddress       **addr)
+{
+	SoupProxyResolverLibproxyPrivate *priv =
+		SOUP_PROXY_RESOLVER_LIBPROXY_GET_PRIVATE (proxy_resolver);
+	char *msg_uri, **proxies;
+	SoupURI *proxy_uri;
+	int i;
+
+	msg_uri = soup_uri_to_string (soup_message_get_uri (msg), FALSE);
+	proxies = px_proxy_factory_get_proxies (priv->factory, msg_uri);
+	g_free (msg_uri);
+
+	if (!proxies) {
+		*addr = NULL;
+		return SOUP_STATUS_OK;
+	}
+
+	if (proxies[0] && !strcmp (proxies[0], "direct://")) {
+		free_proxies (proxies);
+		*addr = NULL;
+		return SOUP_STATUS_OK;
+	}
+
+	for (i = 0; proxies[i]; i++) {
+		if (strncmp (proxies[i], "http://";, 7) == 0)
+			break;
+	}
+	if (!proxies[i]) {
+		free_proxies (proxies);
+		*addr = NULL;
+		return SOUP_STATUS_CANT_RESOLVE_PROXY;
+	}
+
+	proxy_uri = soup_uri_new (proxies[i]);
+	free_proxies (proxies);
+	if (!proxy_uri) {
+		*addr = NULL;
+		return SOUP_STATUS_CANT_RESOLVE_PROXY;
+	}
+
+	*addr = soup_address_new (proxy_uri->host, proxy_uri->port);
+	soup_uri_free (proxy_uri);
+	return soup_status_proxify (soup_address_resolve_sync (*addr, cancellable));
+}

Added: trunk/libsoup/soup-proxy-resolver-libproxy.h
==============================================================================
--- (empty file)
+++ trunk/libsoup/soup-proxy-resolver-libproxy.h	Fri Oct 31 18:12:18 2008
@@ -0,0 +1,32 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2008 Red Hat, Inc.
+ */
+
+#ifndef SOUP_PROXY_RESOLVER_LIBPROXY_H
+#define SOUP_PROXY_RESOLVER_LIBPROXY_H 1
+
+#include <libsoup/soup-proxy-resolver.h>
+
+#define SOUP_TYPE_PROXY_RESOLVER_LIBPROXY            (soup_proxy_resolver_libproxy_get_type ())
+#define SOUP_PROXY_RESOLVER_LIBPROXY(object)         (G_TYPE_CHECK_INSTANCE_CAST ((object), SOUP_TYPE_PROXY_RESOLVER_LIBPROXY, SoupProxyResolverLibproxy))
+#define SOUP_PROXY_RESOLVER_LIBPROXY_CLASS(klass)    (G_TYPE_CHECK_CLASS_CAST ((klass), SOUP_TYPE_PROXY_RESOLVER_LIBPROXY, SoupProxyResolverLibproxyClass))
+#define SOUP_IS_PROXY_RESOLVER_LIBPROXY(object)      (G_TYPE_CHECK_INSTANCE_TYPE ((object), SOUP_TYPE_PROXY_RESOLVER_LIBPROXY))
+#define SOUP_IS_PROXY_RESOLVER_LIBPROXY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SOUP_TYPE_PROXY_RESOLVER_LIBPROXY))
+#define SOUP_PROXY_RESOLVER_LIBPROXY_GET_CLASS(obj)  (G_TYPE_INSTANCE_GET_CLASS ((obj), SOUP_TYPE_PROXY_RESOLVER_LIBPROXY, SoupProxyResolverLibproxyClass))
+
+typedef struct {
+	GObject parent;
+
+} SoupProxyResolverLibproxy;
+
+typedef struct {
+	GObjectClass parent_class;
+
+} SoupProxyResolverLibproxyClass;
+
+GType soup_proxy_resolver_libproxy_get_type (void);
+
+SoupProxyResolver *soup_proxy_resolver_libproxy_new (void);
+
+#endif /*SOUP_PROXY_RESOLVER_LIBPROXY_H*/

Modified: trunk/libsoup/soup-session-async.c
==============================================================================
--- trunk/libsoup/soup-session-async.c	(original)
+++ trunk/libsoup/soup-session-async.c	Fri Oct 31 18:12:18 2008
@@ -170,6 +170,7 @@
 	}
 
 	item->resolving_proxy_addr = FALSE;
+	item->resolved_proxy_addr = TRUE;
 	item->proxy_addr = proxy_addr ? g_object_ref (proxy_addr) : NULL;
 
 	soup_message_queue_item_unref (item);
@@ -261,7 +262,7 @@
 			resolve_msg_addr (item);
 			continue;
 		}
-		if (proxy_resolver && !item->proxy_addr) {
+		if (proxy_resolver && !item->resolved_proxy_addr) {
 			resolve_proxy_addr (item, proxy_resolver);
 			continue;
 		}
@@ -309,6 +310,7 @@
 		g_object_unref (item->proxy_addr);
 		item->proxy_addr = NULL;
 	}
+	item->resolved_proxy_addr = FALSE;
 
 	run_queue ((SoupSessionAsync *)item->session);
 }

Modified: trunk/libsoup/soup-session-sync.c
==============================================================================
--- trunk/libsoup/soup-session-sync.c	(original)
+++ trunk/libsoup/soup-session-sync.c	Fri Oct 31 18:12:18 2008
@@ -153,7 +153,6 @@
 		}
 	}
 
-
 	conn = soup_session_get_connection (session, msg, proxy_addr,
 					    &try_pruning, &is_new);
 	if (conn) {

Modified: trunk/tests/Makefile.am
==============================================================================
--- trunk/tests/Makefile.am	(original)
+++ trunk/tests/Makefile.am	Fri Oct 31 18:12:18 2008
@@ -42,6 +42,9 @@
 dns_SOURCES = dns.c
 forms_test_SOURCES = forms-test.c $(TEST_SRCS)
 get_SOURCES = get.c
+if BUILD_LIBSOUP_GNOME
+get_LDADD = $(top_srcdir)/libsoup/libsoup-gnome-2.4.la
+endif
 getbug_SOURCES = getbug.c
 header_parsing_SOURCES = header-parsing.c $(TEST_SRCS)
 misc_test_SOURCES = misc-test.c $(TEST_SRCS)

Modified: trunk/tests/get.c
==============================================================================
--- trunk/tests/get.c	(original)
+++ trunk/tests/get.c	Fri Oct 31 18:12:18 2008
@@ -3,6 +3,10 @@
  * Copyright (C) 2001-2003, Ximian, Inc.
  */
 
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
 #include <ctype.h>
 #include <errno.h>
 #include <fcntl.h>
@@ -12,7 +16,11 @@
 #include <sys/stat.h>
 #include <unistd.h>
 
+#ifdef HAVE_GNOME
+#include <libsoup/soup-gnome.h>
+#else
 #include <libsoup/soup.h>
+#endif
 
 #ifdef G_OS_WIN32
 #include <io.h>
@@ -285,12 +293,18 @@
 		session = soup_session_sync_new_with_options (
 			SOUP_SESSION_SSL_CA_FILE, cafile,
 			SOUP_SESSION_PROXY_URI, proxy,
+#ifdef HAVE_GNOME
+			SOUP_SESSION_ADD_FEATURE_BY_TYPE, SOUP_TYPE_GNOME_FEATURES_2_26,
+#endif
 			SOUP_SESSION_USER_AGENT, "get ",
 			NULL);
 	} else {
 		session = soup_session_async_new_with_options (
 			SOUP_SESSION_SSL_CA_FILE, cafile,
 			SOUP_SESSION_PROXY_URI, proxy,
+#ifdef HAVE_GNOME
+			SOUP_SESSION_ADD_FEATURE_BY_TYPE, SOUP_TYPE_GNOME_FEATURES_2_26,
+#endif
 			SOUP_SESSION_USER_AGENT, "get ",
 			NULL);
 	}



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