libsoup r1192 - in trunk: . libsoup
- From: danw svn gnome org
- To: svn-commits-list gnome org
- Subject: libsoup r1192 - in trunk: . libsoup
- Date: Fri, 31 Oct 2008 13:05:15 +0000 (UTC)
Author: danw
Date: Fri Oct 31 13:05:14 2008
New Revision: 1192
URL: http://svn.gnome.org/viewvc/libsoup?rev=1192&view=rev
Log:
* libsoup/soup-proxy-resolver.c: new abstract base class for a
SoupSessionFeature that determines what proxy to use for a given
URI.
* libsoup/soup-proxy-resolver-static.c: a SoupProxyResolver that
always returns the same value.
* libsoup/soup-session.c (set_property, get_property): implement
the SOUP_SESSION_PROXY_URI property by creating/destroying a
SoupProxyResolverStatic as needed.
(soup_session_get_connection): Use the proxy address passed by the
caller rather than priv->proxy_uri.
* libsoup/soup-session-async.c (run_queue): if the session has a
proxy resolver, use it, and pass the resolved proxy to
soup_session_get_connection().
(request_restarted): clear the previously-resolved proxy address
when restarting the message
* libsoup/soup-session-sync.c (wait_for_connection): if the
session has a proxy resolver, use it, and pass the resolved proxy
to soup_session_get_connection().
* libsoup/soup-message-queue.h (SoupMessageQueueItem): add
proxy-address-resolving fields
* libsoup/soup-status.c (soup_status_proxify): moved from
soup-connection; turn SOUP_STATUS_CANT_RESOLVE into
SOUP_STATUS_CANT_RESOLVE_PROXY, and SOUP_STATUS_CANT_CONNECT into
SOUP_STATUS_CANT_CONNECT_PROXY (and pass all other statuses
through unchanged)
Added:
trunk/libsoup/soup-proxy-resolver-static.c
trunk/libsoup/soup-proxy-resolver-static.h
trunk/libsoup/soup-proxy-resolver.c
trunk/libsoup/soup-proxy-resolver.h
Modified:
trunk/ChangeLog
trunk/libsoup/Makefile.am
trunk/libsoup/soup-connection.c
trunk/libsoup/soup-message-queue.c
trunk/libsoup/soup-message-queue.h
trunk/libsoup/soup-session-async.c
trunk/libsoup/soup-session-private.h
trunk/libsoup/soup-session-sync.c
trunk/libsoup/soup-session.c
trunk/libsoup/soup-status.c
trunk/libsoup/soup-status.h
Modified: trunk/libsoup/Makefile.am
==============================================================================
--- trunk/libsoup/Makefile.am (original)
+++ trunk/libsoup/Makefile.am Fri Oct 31 13:05:14 2008
@@ -65,6 +65,7 @@
soup-misc.h \
soup-multipart.h \
soup-portability.h \
+ soup-proxy-resolver.h \
soup-server.h \
soup-session.h \
soup-session-async.h \
@@ -137,6 +138,9 @@
soup-nossl.c \
soup-path-map.h \
soup-path-map.c \
+ soup-proxy-resolver.c \
+ soup-proxy-resolver-static.h \
+ soup-proxy-resolver-static.c \
soup-server.c \
soup-session.c \
soup-session-async.c \
@@ -153,4 +157,4 @@
EXTRA_DIST= \
soup-marshal.list \
soup-enum-types.h.tmpl \
- soup-enum-types.c.tmpl
+ soup-enum-types.c.tmpl
\ No newline at end of file
Modified: trunk/libsoup/soup-connection.c
==============================================================================
--- trunk/libsoup/soup-connection.c (original)
+++ trunk/libsoup/soup-connection.c Fri Oct 31 13:05:14 2008
@@ -408,20 +408,6 @@
soup_connection_disconnect (conn);
}
-static inline guint
-proxified_status (SoupConnectionPrivate *priv, guint status)
-{
- if (!priv->proxy_addr)
- return status;
-
- if (status == SOUP_STATUS_CANT_RESOLVE)
- return SOUP_STATUS_CANT_RESOLVE_PROXY;
- else if (status == SOUP_STATUS_CANT_CONNECT)
- return SOUP_STATUS_CANT_CONNECT_PROXY;
- else
- return status;
-}
-
static SoupMessage *
connect_message (SoupConnectionPrivate *priv)
{
@@ -460,8 +446,9 @@
status = SOUP_STATUS_PROXY_AUTHENTICATION_REQUIRED;
}
- g_signal_emit (conn, signals[CONNECT_RESULT], 0,
- proxified_status (priv, status));
+ if (priv->proxy_addr)
+ status = soup_status_proxify (status);
+ g_signal_emit (conn, signals[CONNECT_RESULT], 0, status);
g_object_unref (msg);
}
@@ -528,8 +515,9 @@
start_idle_timer (conn);
done:
- g_signal_emit (conn, signals[CONNECT_RESULT], 0,
- proxified_status (priv, status));
+ if (priv->proxy_addr)
+ status = soup_status_proxify (status);
+ g_signal_emit (conn, signals[CONNECT_RESULT], 0, status);
}
/* from soup-misc.c... will eventually go away */
@@ -669,7 +657,8 @@
}
}
- status = proxified_status (priv, status);
+ if (priv->proxy_addr)
+ status = soup_status_proxify (status);
g_signal_emit (conn, signals[CONNECT_RESULT], 0, status);
return status;
}
Modified: trunk/libsoup/soup-message-queue.c
==============================================================================
--- trunk/libsoup/soup-message-queue.c (original)
+++ trunk/libsoup/soup-message-queue.c Fri Oct 31 13:05:14 2008
@@ -149,6 +149,8 @@
g_object_unref (item->cancellable);
if (item->msg_addr)
g_object_unref (item->msg_addr);
+ if (item->proxy_addr)
+ g_object_unref (item->proxy_addr);
g_slice_free (SoupMessageQueueItem, item);
}
Modified: trunk/libsoup/soup-message-queue.h
==============================================================================
--- trunk/libsoup/soup-message-queue.h (original)
+++ trunk/libsoup/soup-message-queue.h Fri Oct 31 13:05:14 2008
@@ -26,13 +26,14 @@
gpointer callback_data;
GCancellable *cancellable;
- SoupAddress *msg_addr;
+ SoupAddress *msg_addr, *proxy_addr;
guint resolving_msg_addr : 1;
+ guint resolving_proxy_addr : 1;
/*< private >*/
guint removed : 1;
- guint ref_count : 30;
+ guint ref_count : 29;
SoupMessageQueueItem *prev, *next;
};
Added: trunk/libsoup/soup-proxy-resolver-static.c
==============================================================================
--- (empty file)
+++ trunk/libsoup/soup-proxy-resolver-static.c Fri Oct 31 13:05:14 2008
@@ -0,0 +1,208 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * soup-proxy-resolver-static.c: Static proxy "resolution"
+ *
+ * Copyright (C) 2008 Red Hat, Inc.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+
+#include "soup-proxy-resolver-static.h"
+#include "soup-address.h"
+#include "soup-dns.h"
+#include "soup-message.h"
+#include "soup-misc.h"
+#include "soup-session-feature.h"
+
+typedef struct {
+ SoupURI *proxy_uri;
+
+} SoupProxyResolverStaticPrivate;
+#define SOUP_PROXY_RESOLVER_STATIC_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SOUP_TYPE_PROXY_RESOLVER_STATIC, SoupProxyResolverStaticPrivate))
+
+static void soup_proxy_resolver_static_interface_init (SoupProxyResolverInterface *proxy_resolver_interface);
+
+G_DEFINE_TYPE_EXTENDED (SoupProxyResolverStatic, soup_proxy_resolver_static, G_TYPE_OBJECT, 0,
+ G_IMPLEMENT_INTERFACE (SOUP_TYPE_SESSION_FEATURE, NULL)
+ G_IMPLEMENT_INTERFACE (SOUP_TYPE_PROXY_RESOLVER, soup_proxy_resolver_static_interface_init))
+
+enum {
+ PROP_0,
+
+ PROP_PROXY_URI,
+
+ LAST_PROP
+};
+
+static void set_property (GObject *object, guint prop_id,
+ const GValue *value, GParamSpec *pspec);
+static void get_property (GObject *object, guint prop_id,
+ GValue *value, GParamSpec *pspec);
+
+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_static_init (SoupProxyResolverStatic *resolver_static)
+{
+}
+
+static void
+finalize (GObject *object)
+{
+ SoupProxyResolverStaticPrivate *priv =
+ SOUP_PROXY_RESOLVER_STATIC_GET_PRIVATE (object);
+
+ if (priv->proxy_uri)
+ soup_uri_free (priv->proxy_uri);
+
+ G_OBJECT_CLASS (soup_proxy_resolver_static_parent_class)->finalize (object);
+}
+
+static void
+soup_proxy_resolver_static_class_init (SoupProxyResolverStaticClass *static_class)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (static_class);
+
+ g_type_class_add_private (static_class, sizeof (SoupProxyResolverStaticPrivate));
+
+ object_class->set_property = set_property;
+ object_class->get_property = get_property;
+ object_class->finalize = finalize;
+
+ g_object_class_install_property (
+ object_class, PROP_PROXY_URI,
+ g_param_spec_boxed (SOUP_PROXY_RESOLVER_STATIC_PROXY_URI,
+ "Proxy URI",
+ "The HTTP Proxy to use",
+ SOUP_TYPE_URI,
+ G_PARAM_READWRITE));
+}
+
+static void
+set_property (GObject *object, guint prop_id,
+ const GValue *value, GParamSpec *pspec)
+{
+ SoupProxyResolverStaticPrivate *priv =
+ SOUP_PROXY_RESOLVER_STATIC_GET_PRIVATE (object);
+ SoupURI *uri;
+
+ switch (prop_id) {
+ case PROP_PROXY_URI:
+ uri = g_value_get_boxed (value);
+ if (priv->proxy_uri)
+ soup_uri_free (priv->proxy_uri);
+
+ priv->proxy_uri = uri ? soup_uri_copy (uri) : NULL;
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+get_property (GObject *object, guint prop_id,
+ GValue *value, GParamSpec *pspec)
+{
+ SoupProxyResolverStaticPrivate *priv =
+ SOUP_PROXY_RESOLVER_STATIC_GET_PRIVATE (object);
+
+ switch (prop_id) {
+ case PROP_PROXY_URI:
+ g_value_set_boxed (value, priv->proxy_uri);
+ break;
+ default:
+ G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+ break;
+ }
+}
+
+static void
+soup_proxy_resolver_static_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_static_new (SoupURI *proxy_uri)
+{
+ return g_object_new (SOUP_TYPE_PROXY_RESOLVER_STATIC,
+ SOUP_PROXY_RESOLVER_STATIC_PROXY_URI, proxy_uri,
+ NULL);
+}
+
+typedef struct {
+ SoupProxyResolver *proxy_resolver;
+ SoupMessage *msg;
+ SoupAddress *addr;
+ SoupProxyResolverCallback callback;
+ gpointer user_data;
+} SoupStaticAsyncData;
+
+static void
+resolved_address (SoupAddress *addr, guint status, gpointer data)
+{
+ SoupStaticAsyncData *ssad = data;
+
+ ssad->callback (ssad->proxy_resolver, ssad->msg,
+ soup_status_proxify (status), addr,
+ ssad->user_data);
+ g_object_unref (ssad->proxy_resolver);
+ g_object_unref (ssad->msg);
+ if (addr)
+ g_object_unref (addr);
+ g_slice_free (SoupStaticAsyncData, ssad);
+}
+
+static void
+get_proxy_async (SoupProxyResolver *proxy_resolver,
+ SoupMessage *msg,
+ GMainContext *async_context,
+ GCancellable *cancellable,
+ SoupProxyResolverCallback callback,
+ gpointer user_data)
+{
+ SoupProxyResolverStaticPrivate *priv =
+ SOUP_PROXY_RESOLVER_STATIC_GET_PRIVATE (proxy_resolver);
+ SoupStaticAsyncData *ssad;
+
+ ssad = g_slice_new0 (SoupStaticAsyncData);
+ ssad->proxy_resolver = g_object_ref (proxy_resolver);
+ ssad->msg = g_object_ref (msg);
+ ssad->callback = callback;
+ ssad->user_data = user_data;
+ ssad->addr = soup_address_new (priv->proxy_uri->host,
+ priv->proxy_uri->port);
+
+ soup_address_resolve_async (ssad->addr, async_context,
+ cancellable, resolved_address,
+ ssad);
+}
+
+static guint
+get_proxy_sync (SoupProxyResolver *proxy_resolver,
+ SoupMessage *msg,
+ GCancellable *cancellable,
+ SoupAddress **addr)
+{
+ SoupProxyResolverStaticPrivate *priv =
+ SOUP_PROXY_RESOLVER_STATIC_GET_PRIVATE (proxy_resolver);
+
+ *addr = soup_address_new (priv->proxy_uri->host,
+ priv->proxy_uri->port);
+ return soup_status_proxify (soup_address_resolve_sync (*addr, cancellable));
+}
Added: trunk/libsoup/soup-proxy-resolver-static.h
==============================================================================
--- (empty file)
+++ trunk/libsoup/soup-proxy-resolver-static.h Fri Oct 31 13:05:14 2008
@@ -0,0 +1,35 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2008 Red Hat, Inc.
+ */
+
+#ifndef SOUP_PROXY_RESOLVER_STATIC_H
+#define SOUP_PROXY_RESOLVER_STATIC_H 1
+
+#include "soup-proxy-resolver.h"
+#include "soup-uri.h"
+
+#define SOUP_TYPE_PROXY_RESOLVER_STATIC (soup_proxy_resolver_static_get_type ())
+#define SOUP_PROXY_RESOLVER_STATIC(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), SOUP_TYPE_PROXY_RESOLVER_STATIC, SoupProxyResolverStatic))
+#define SOUP_PROXY_RESOLVER_STATIC_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SOUP_TYPE_PROXY_RESOLVER_STATIC, SoupProxyResolverStaticClass))
+#define SOUP_IS_PROXY_RESOLVER_STATIC(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), SOUP_TYPE_PROXY_RESOLVER_STATIC))
+#define SOUP_IS_PROXY_RESOLVER_STATIC_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SOUP_TYPE_PROXY_RESOLVER_STATIC))
+#define SOUP_PROXY_RESOLVER_STATIC_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SOUP_TYPE_PROXY_RESOLVER_STATIC, SoupProxyResolverStaticClass))
+
+typedef struct {
+ GObject parent;
+
+} SoupProxyResolverStatic;
+
+typedef struct {
+ GObjectClass parent_class;
+
+} SoupProxyResolverStaticClass;
+
+GType soup_proxy_resolver_static_get_type (void);
+
+#define SOUP_PROXY_RESOLVER_STATIC_PROXY_URI "proxy-uri"
+
+SoupProxyResolver *soup_proxy_resolver_static_new (SoupURI *proxy_uri);
+
+#endif /* SOUP_PROXY_RESOLVER_STATIC_H */
Added: trunk/libsoup/soup-proxy-resolver.c
==============================================================================
--- (empty file)
+++ trunk/libsoup/soup-proxy-resolver.c Fri Oct 31 13:05:14 2008
@@ -0,0 +1,84 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * soup-proxy-resolver.c: HTTP proxy resolver interface
+ *
+ * Copyright (C) 2008 Red Hat, Inc.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "soup-proxy-resolver.h"
+#include "soup-session-feature.h"
+
+GType
+soup_proxy_resolver_get_type (void)
+{
+ static volatile gsize g_define_type_id__volatile = 0;
+ if (g_once_init_enter (&g_define_type_id__volatile))
+ {
+ GType g_define_type_id =
+ g_type_register_static_simple (G_TYPE_INTERFACE,
+ g_intern_static_string ("SoupProxyResolver"),
+ sizeof (SoupProxyResolverInterface),
+ (GClassInitFunc)NULL,
+ 0,
+ (GInstanceInitFunc)NULL,
+ (GTypeFlags) 0);
+ g_type_interface_add_prerequisite (g_define_type_id, G_TYPE_OBJECT);
+ g_type_interface_add_prerequisite (g_define_type_id, SOUP_TYPE_SESSION_FEATURE);
+ g_once_init_leave (&g_define_type_id__volatile, g_define_type_id);
+ }
+ return g_define_type_id__volatile;
+}
+
+/**
+ * soup_proxy_resovler_get_proxy_async:
+ * @proxy_resolver: the #SoupProxyResolver
+ * @msg: the #SoupMessage you want a proxy for
+ * @async_context: the #GMainContext to invoke @callback in
+ * @cancellable: a #GCancellable, or %NULL
+ * @callback: callback to invoke with the proxy address
+ * @user_data: data for @callback
+ *
+ * Asynchronously determines a proxy server address to use for @msg
+ * and calls @callback.
+ **/
+void
+soup_proxy_resolver_get_proxy_async (SoupProxyResolver *proxy_resolver,
+ SoupMessage *msg,
+ GMainContext *async_context,
+ GCancellable *cancellable,
+ SoupProxyResolverCallback callback,
+ gpointer user_data)
+{
+ SOUP_PROXY_RESOLVER_GET_CLASS (proxy_resolver)->
+ get_proxy_async (proxy_resolver, msg,
+ async_context, cancellable,
+ callback, user_data);
+}
+
+/**
+ * soup_proxy_resovler_get_proxy_sync:
+ * @proxy_resolver: the #SoupProxyResolver
+ * @msg: the #SoupMessage you want a proxy for
+ * @cancellable: a #GCancellable, or %NULL
+ * @addr: on return, will contain the proxy address
+ *
+ * Synchronously determines a proxy server address to use for @msg. If
+ * @msg should be sent via proxy, * addr will be set to the address of
+ * the proxy, else it will be set to %NULL.
+ *
+ * Return value: SOUP_STATUS_OK if successful, or a transport-level
+ * error.
+ **/
+guint
+soup_proxy_resolver_get_proxy_sync (SoupProxyResolver *proxy_resolver,
+ SoupMessage *msg,
+ GCancellable *cancellable,
+ SoupAddress **addr)
+{
+ return SOUP_PROXY_RESOLVER_GET_CLASS (proxy_resolver)->
+ get_proxy_sync (proxy_resolver, msg, cancellable, addr);
+}
Added: trunk/libsoup/soup-proxy-resolver.h
==============================================================================
--- (empty file)
+++ trunk/libsoup/soup-proxy-resolver.h Fri Oct 31 13:05:14 2008
@@ -0,0 +1,49 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2008 Red Hat, Inc.
+ */
+
+#ifndef SOUP_PROXY_RESOLVER_H
+#define SOUP_PROXY_RESOLVER_H 1
+
+#include <libsoup/soup-types.h>
+#include <gio/gio.h>
+
+#define SOUP_TYPE_PROXY_RESOLVER (soup_proxy_resolver_get_type ())
+#define SOUP_PROXY_RESOLVER(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), SOUP_TYPE_PROXY_RESOLVER, SoupProxyResolver))
+#define SOUP_PROXY_RESOLVER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SOUP_TYPE_PROXY_RESOLVER, SoupProxyResolverInterface))
+#define SOUP_IS_PROXY_RESOLVER(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), SOUP_TYPE_PROXY_RESOLVER))
+#define SOUP_IS_PROXY_RESOLVER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SOUP_TYPE_PROXY_RESOLVER))
+#define SOUP_PROXY_RESOLVER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), SOUP_TYPE_PROXY_RESOLVER, SoupProxyResolverInterface))
+
+typedef struct _SoupProxyResolver SoupProxyResolver;
+
+typedef void (*SoupProxyResolverCallback) (SoupProxyResolver *, SoupMessage *,
+ guint, SoupAddress *, gpointer);
+
+typedef struct {
+ GTypeInterface base;
+
+ /* virtual methods */
+ void (*get_proxy_async) (SoupProxyResolver *, SoupMessage *,
+ GMainContext *, GCancellable *,
+ SoupProxyResolverCallback, gpointer);
+ guint (*get_proxy_sync) (SoupProxyResolver *, SoupMessage *,
+ GCancellable *, SoupAddress **);
+
+} SoupProxyResolverInterface;
+
+GType soup_proxy_resolver_get_type (void);
+
+void soup_proxy_resolver_get_proxy_async (SoupProxyResolver *proxy_resolver,
+ SoupMessage *msg,
+ GMainContext *async_context,
+ GCancellable *cancellable,
+ SoupProxyResolverCallback callback,
+ gpointer user_data);
+guint soup_proxy_resolver_get_proxy_sync (SoupProxyResolver *proxy_resolver,
+ SoupMessage *msg,
+ GCancellable *cancellable,
+ SoupAddress **addr);
+
+#endif /*SOUP_PROXY_RESOLVER_H*/
Modified: trunk/libsoup/soup-session-async.c
==============================================================================
--- trunk/libsoup/soup-session-async.c (original)
+++ trunk/libsoup/soup-session-async.c Fri Oct 31 13:05:14 2008
@@ -9,6 +9,7 @@
#include <config.h>
#endif
+#include "soup-address.h"
#include "soup-session-async.h"
#include "soup-session-private.h"
#include "soup-address.h"
@@ -150,6 +151,49 @@
}
static void
+resolved_proxy_addr (SoupProxyResolver *proxy_resolver, SoupMessage *msg,
+ guint status, SoupAddress *proxy_addr, gpointer user_data)
+{
+ SoupMessageQueueItem *item = user_data;
+ SoupSession *session = item->session;
+
+ if (item->removed) {
+ /* Message was cancelled before its proxy addr resolved */
+ soup_message_queue_item_unref (item);
+ return;
+ }
+
+ if (!SOUP_STATUS_IS_SUCCESSFUL (status)) {
+ soup_session_cancel_message (session, item->msg, status);
+ soup_message_queue_item_unref (item);
+ return;
+ }
+
+ item->resolving_proxy_addr = FALSE;
+ item->proxy_addr = proxy_addr ? g_object_ref (proxy_addr) : NULL;
+
+ soup_message_queue_item_unref (item);
+
+ /* If we got here we know session still exists */
+ run_queue ((SoupSessionAsync *)session);
+}
+
+static void
+resolve_proxy_addr (SoupMessageQueueItem *item,
+ SoupProxyResolver *proxy_resolver)
+{
+ if (item->resolving_proxy_addr)
+ return;
+ item->resolving_proxy_addr = TRUE;
+
+ soup_message_queue_item_ref (item);
+ soup_proxy_resolver_get_proxy_async (proxy_resolver, item->msg,
+ soup_session_get_async_context (item->session),
+ item->cancellable,
+ resolved_proxy_addr, item);
+}
+
+static void
connection_closed (SoupConnection *conn, gpointer session)
{
/* Run the queue in case anyone was waiting for a connection
@@ -194,6 +238,8 @@
SoupSession *session = SOUP_SESSION (sa);
SoupMessageQueue *queue = soup_session_get_queue (session);
SoupMessageQueueItem *item;
+ SoupProxyResolver *proxy_resolver =
+ soup_session_get_proxy_resolver (session);
SoupMessage *msg;
SoupConnection *conn;
gboolean try_pruning = TRUE, should_prune = FALSE;
@@ -215,8 +261,13 @@
resolve_msg_addr (item);
continue;
}
+ if (proxy_resolver && !item->proxy_addr) {
+ resolve_proxy_addr (item, proxy_resolver);
+ continue;
+ }
conn = soup_session_get_connection (session, msg,
+ item->proxy_addr,
&should_prune, &is_new);
if (!conn)
continue;
@@ -254,6 +305,10 @@
g_object_unref (item->msg_addr);
item->msg_addr = NULL;
}
+ if (item->proxy_addr) {
+ g_object_unref (item->proxy_addr);
+ item->proxy_addr = NULL;
+ }
run_queue ((SoupSessionAsync *)item->session);
}
Modified: trunk/libsoup/soup-session-private.h
==============================================================================
--- trunk/libsoup/soup-session-private.h (original)
+++ trunk/libsoup/soup-session-private.h Fri Oct 31 13:05:14 2008
@@ -9,6 +9,7 @@
#include "soup-session.h"
#include "soup-connection.h"
#include "soup-message-queue.h"
+#include "soup-proxy-resolver.h"
G_BEGIN_DECLS
@@ -17,10 +18,13 @@
SoupConnection *soup_session_get_connection (SoupSession *session,
SoupMessage *msg,
+ SoupAddress *proxy,
gboolean *try_pruning,
gboolean *is_new);
gboolean soup_session_try_prune_connection (SoupSession *session);
+SoupProxyResolver *soup_session_get_proxy_resolver (SoupSession *session);
+
G_END_DECLS
#endif /* SOUP_SESSION_PRIVATE_H */
Modified: trunk/libsoup/soup-session-sync.c
==============================================================================
--- trunk/libsoup/soup-session-sync.c (original)
+++ trunk/libsoup/soup-session-sync.c Fri Oct 31 13:05:14 2008
@@ -9,6 +9,7 @@
#include <config.h>
#endif
+#include "soup-address.h"
#include "soup-session-sync.h"
#include "soup-session-private.h"
#include "soup-address.h"
@@ -130,14 +131,30 @@
wait_for_connection (SoupSession *session, SoupMessage *msg)
{
SoupSessionSyncPrivate *priv = SOUP_SESSION_SYNC_GET_PRIVATE (session);
- SoupConnection *conn;
gboolean try_pruning = FALSE, is_new = FALSE;
+ SoupProxyResolver *proxy_resolver;
+ SoupAddress *proxy_addr = NULL;
+ SoupConnection *conn;
guint status;
+ proxy_resolver = soup_session_get_proxy_resolver (session);
g_mutex_lock (priv->lock);
try_again:
- conn = soup_session_get_connection (session, msg,
+ if (proxy_addr) {
+ g_object_unref (proxy_addr);
+ proxy_addr = NULL;
+ }
+ if (proxy_resolver) {
+ status = soup_proxy_resolver_get_proxy_sync (proxy_resolver, msg, NULL, &proxy_addr);
+ if (!SOUP_STATUS_IS_SUCCESSFUL (status)) {
+ soup_session_cancel_message (session, msg, status);
+ return NULL;
+ }
+ }
+
+
+ conn = soup_session_get_connection (session, msg, proxy_addr,
&try_pruning, &is_new);
if (conn) {
if (is_new) {
Modified: trunk/libsoup/soup-session.c
==============================================================================
--- trunk/libsoup/soup-session.c (original)
+++ trunk/libsoup/soup-session.c Fri Oct 31 13:05:14 2008
@@ -22,6 +22,7 @@
#include "soup-marshal.h"
#include "soup-message-private.h"
#include "soup-message-queue.h"
+#include "soup-proxy-resolver-static.h"
#include "soup-session.h"
#include "soup-session-feature.h"
#include "soup-session-private.h"
@@ -63,9 +64,7 @@
} SoupSessionHost;
typedef struct {
- SoupURI *proxy_uri;
- SoupAddress *proxy_addr;
- SoupAuth *proxy_auth;
+ SoupProxyResolver *proxy_resolver;
char *ssl_ca_file;
SoupSSLCredentials *ssl_creds;
@@ -225,11 +224,6 @@
if (priv->auth_manager)
g_object_unref (priv->auth_manager);
- if (priv->proxy_uri)
- soup_uri_free (priv->proxy_uri);
- if (priv->proxy_addr)
- g_object_unref (priv->proxy_addr);
-
if (priv->ssl_creds)
soup_ssl_free_client_credentials (priv->ssl_creds);
@@ -506,18 +500,6 @@
}
static gboolean
-safe_uri_equal (SoupURI *a, SoupURI *b)
-{
- if (!a && !b)
- return TRUE;
-
- if ((a && !b) || (b && !a))
- return FALSE;
-
- return soup_uri_equal (a, b);
-}
-
-static gboolean
safe_str_equal (const char *a, const char *b)
{
if (!a && !b)
@@ -536,7 +518,6 @@
SoupSession *session = SOUP_SESSION (object);
SoupSessionPrivate *priv = SOUP_SESSION_GET_PRIVATE (session);
SoupURI *uri;
- gboolean need_abort = FALSE;
gboolean ca_file_changed = FALSE;
const char *new_ca_file, *user_agent;
@@ -544,24 +525,16 @@
case PROP_PROXY_URI:
uri = g_value_get_boxed (value);
- if (!safe_uri_equal (priv->proxy_uri, uri))
- need_abort = TRUE;
-
- if (priv->proxy_uri)
- soup_uri_free (priv->proxy_uri);
- if (priv->proxy_addr)
- g_object_unref (priv->proxy_addr);
-
- priv->proxy_uri = uri ? soup_uri_copy (uri) : NULL;
- priv->proxy_addr = uri ?
- soup_address_new (uri->host, uri->port) :
- NULL;
-
- if (need_abort) {
- soup_session_abort (session);
- cleanup_hosts (priv);
- }
+ if (uri) {
+ soup_session_remove_feature_by_type (session, SOUP_TYPE_PROXY_RESOLVER);
+ priv->proxy_resolver = soup_proxy_resolver_static_new (uri);
+ soup_session_add_feature (session, SOUP_SESSION_FEATURE (priv->proxy_resolver));
+ g_object_unref (priv->proxy_resolver);
+ } else if (priv->proxy_resolver && SOUP_IS_PROXY_RESOLVER_STATIC (priv->proxy_resolver))
+ soup_session_remove_feature_by_type (session, SOUP_TYPE_PROXY_RESOLVER);
+ soup_session_abort (session);
+ cleanup_hosts (priv);
break;
case PROP_MAX_CONNS:
priv->max_conns = g_value_get_int (value);
@@ -643,7 +616,12 @@
switch (prop_id) {
case PROP_PROXY_URI:
- g_value_set_boxed (value, priv->proxy_uri);
+ if (priv->proxy_resolver && SOUP_IS_PROXY_RESOLVER_STATIC (priv->proxy_resolver)) {
+ g_object_get_property (G_OBJECT (priv->proxy_resolver),
+ SOUP_PROXY_RESOLVER_STATIC_PROXY_URI,
+ value);
+ } else
+ g_value_set_boxed (value, NULL);
break;
case PROP_MAX_CONNS:
g_value_set_int (value, priv->max_conns);
@@ -1008,6 +986,7 @@
**/
SoupConnection *
soup_session_get_connection (SoupSession *session, SoupMessage *msg,
+ SoupAddress *proxy_addr,
gboolean *try_pruning, gboolean *is_new)
{
SoupSessionPrivate *priv = SOUP_SESSION_GET_PRIVATE (session);
@@ -1058,7 +1037,7 @@
conn = soup_connection_new (
SOUP_CONNECTION_SERVER_ADDRESS, host->addr,
- SOUP_CONNECTION_PROXY_ADDRESS, priv->proxy_addr,
+ SOUP_CONNECTION_PROXY_ADDRESS, proxy_addr,
SOUP_CONNECTION_SSL_CREDENTIALS, ssl_creds,
SOUP_CONNECTION_ASYNC_CONTEXT, priv->async_context,
SOUP_CONNECTION_TIMEOUT, priv->io_timeout,
@@ -1371,6 +1350,9 @@
priv = SOUP_SESSION_GET_PRIVATE (session);
priv->features = g_slist_prepend (priv->features, g_object_ref (feature));
soup_session_feature_attach (feature, session);
+
+ if (SOUP_IS_PROXY_RESOLVER (feature))
+ priv->proxy_resolver = SOUP_PROXY_RESOLVER (feature);
}
/**
@@ -1416,6 +1398,9 @@
priv->features = g_slist_remove (priv->features, feature);
soup_session_feature_detach (feature, session);
g_object_unref (feature);
+
+ if (feature == (SoupSessionFeature *)priv->proxy_resolver)
+ priv->proxy_resolver = NULL;
}
}
@@ -1446,3 +1431,11 @@
}
}
}
+
+SoupProxyResolver *
+soup_session_get_proxy_resolver (SoupSession *session)
+{
+ SoupSessionPrivate *priv = SOUP_SESSION_GET_PRIVATE (session);
+
+ return priv->proxy_resolver;
+}
Modified: trunk/libsoup/soup-status.c
==============================================================================
--- trunk/libsoup/soup-status.c (original)
+++ trunk/libsoup/soup-status.c Fri Oct 31 13:05:14 2008
@@ -248,6 +248,26 @@
return "Unknown Error";
}
+/**
+ * soup_status_proxify:
+ * @status: a status code
+ *
+ * Turns SOUP_STATUS_CANT_RESOLVE into SOUP_STATUS_CANT_RESOLVE_PROXY
+ * and SOUP_STATUS_CANT_CONNECT into SOUP_STATUS_CANT_CONNECT_PROXY.
+ * Other status codes are passed through unchanged.
+ *
+ * Return value: the "proxified" equivalent of @status.
+ **/
+guint
+soup_status_proxify (guint status_code)
+{
+ if (status_code == SOUP_STATUS_CANT_RESOLVE)
+ return SOUP_STATUS_CANT_RESOLVE_PROXY;
+ else if (status_code == SOUP_STATUS_CANT_CONNECT)
+ return SOUP_STATUS_CANT_CONNECT_PROXY;
+ else
+ return status_code;
+}
GQuark
soup_http_error_quark (void)
Modified: trunk/libsoup/soup-status.h
==============================================================================
--- trunk/libsoup/soup-status.h (original)
+++ trunk/libsoup/soup-status.h Fri Oct 31 13:05:14 2008
@@ -92,6 +92,7 @@
} SoupKnownStatusCode;
const char *soup_status_get_phrase (guint status_code);
+guint soup_status_proxify (guint status_code);
#define SOUP_HTTP_ERROR soup_http_error_quark()
GQuark soup_http_error_quark (void);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]