[libsoup] Implement SoupProxyURIResolver, to replace SoupProxyResolver
- From: Dan Winship <danw src gnome org>
- To: svn-commits-list gnome org
- Subject: [libsoup] Implement SoupProxyURIResolver, to replace SoupProxyResolver
- Date: Sat, 6 Jun 2009 23:09:15 -0400 (EDT)
commit e636754a29691d96e89297c2d7c31d829d1de878
Author: Dan Winship <danw gnome org>
Date: Sat Jun 6 18:57:51 2009 -0400
Implement SoupProxyURIResolver, to replace SoupProxyResolver
Simplifies implementations, allows for non-http proxy resolution, and
allows authentication information to be passed.
http://bugzilla.gnome.org/show_bug.cgi?id=580051
---
libsoup/Makefile.am | 2 +
libsoup/soup-auth-manager.c | 21 +++--
libsoup/soup-connection.c | 41 +++++---
libsoup/soup-connection.h | 3 +-
libsoup/soup-message-queue.c | 3 +
libsoup/soup-message-queue.h | 1 +
libsoup/soup-proxy-resolver-gnome.c | 184 +++++++++++++++++------------------
libsoup/soup-proxy-resolver-gnome.h | 1 -
libsoup/soup-proxy-resolver.c | 164 +++++++++++++++++++++++++------
libsoup/soup-proxy-resolver.h | 4 +
libsoup/soup-proxy-uri-resolver.c | 97 ++++++++++++++++++
libsoup/soup-proxy-uri-resolver.h | 57 +++++++++++
libsoup/soup-session-async.c | 75 +++++++++++---
libsoup/soup-session-private.h | 4 +-
libsoup/soup-session-sync.c | 25 ++++-
libsoup/soup-session.c | 40 +++++---
16 files changed, 537 insertions(+), 185 deletions(-)
diff --git a/libsoup/Makefile.am b/libsoup/Makefile.am
index dc9ff55..949f243 100644
--- a/libsoup/Makefile.am
+++ b/libsoup/Makefile.am
@@ -70,6 +70,7 @@ soup_headers = \
soup-multipart.h \
soup-portability.h \
soup-proxy-resolver.h \
+ soup-proxy-uri-resolver.h \
soup-server.h \
soup-session.h \
soup-session-async.h \
@@ -146,6 +147,7 @@ libsoup_2_4_la_SOURCES = \
soup-proxy-resolver.c \
soup-proxy-resolver-static.h \
soup-proxy-resolver-static.c \
+ soup-proxy-uri-resolver.c \
soup-server.c \
soup-session.c \
soup-session-async.c \
diff --git a/libsoup/soup-auth-manager.c b/libsoup/soup-auth-manager.c
index c49cf3b..5d1d1bc 100644
--- a/libsoup/soup-auth-manager.c
+++ b/libsoup/soup-auth-manager.c
@@ -16,9 +16,11 @@
#include "soup-headers.h"
#include "soup-marshal.h"
#include "soup-message-private.h"
+#include "soup-message-queue.h"
#include "soup-path-map.h"
#include "soup-session.h"
#include "soup-session-feature.h"
+#include "soup-session-private.h"
#include "soup-uri.h"
static void soup_auth_manager_session_feature_init (SoupSessionFeatureInterface *feature_interface, gpointer interface_data);
@@ -363,21 +365,26 @@ authenticate_auth (SoupAuthManager *manager, SoupAuth *auth,
return TRUE;
if (proxy) {
- g_object_get (G_OBJECT (priv->session),
- SOUP_SESSION_PROXY_URI, &uri,
- NULL);
- /* FIXME: temporary workaround for proxy auth brokenness */
+ SoupMessageQueue *queue;
+ SoupMessageQueueItem *item;
+
+ queue = soup_session_get_queue (priv->session);
+ item = soup_message_queue_lookup (queue, msg);
+ if (item) {
+ uri = soup_connection_get_proxy_uri (item->conn);
+ soup_message_queue_item_unref (item);
+ } else
+ uri = NULL;
+
if (!uri)
return FALSE;
} else
- uri = soup_uri_copy (soup_message_get_uri (msg));
+ uri = soup_message_get_uri (msg);
if (uri->password && !prior_auth_failed) {
soup_auth_authenticate (auth, uri->user, uri->password);
- soup_uri_free (uri);
return TRUE;
}
- soup_uri_free (uri);
if (can_interact) {
soup_auth_manager_emit_authenticate (manager, msg, auth,
diff --git a/libsoup/soup-connection.c b/libsoup/soup-connection.c
index a6d8670..0d731c0 100644
--- a/libsoup/soup-connection.c
+++ b/libsoup/soup-connection.c
@@ -31,7 +31,7 @@ typedef struct {
SoupSocket *socket;
SoupAddress *remote_addr, *tunnel_addr;
- gboolean is_proxy;
+ SoupURI *proxy_uri;
gpointer ssl_creds;
GMainContext *async_context;
@@ -58,7 +58,7 @@ enum {
PROP_REMOTE_ADDRESS,
PROP_TUNNEL_ADDRESS,
- PROP_IS_PROXY,
+ PROP_PROXY_URI,
PROP_SSL_CREDS,
PROP_ASYNC_CONTEXT,
PROP_TIMEOUT,
@@ -152,12 +152,12 @@ soup_connection_class_init (SoupConnectionClass *connection_class)
SOUP_TYPE_ADDRESS,
G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
g_object_class_install_property (
- object_class, PROP_IS_PROXY,
- g_param_spec_boolean (SOUP_CONNECTION_IS_PROXY,
- "Is proxy",
- "Whether or not this is a connection to an HTTP Proxy",
- FALSE,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
+ object_class, PROP_PROXY_URI,
+ g_param_spec_boxed (SOUP_CONNECTION_PROXY_URI,
+ "Proxy URI",
+ "URI of the HTTP proxy this connection connects to",
+ SOUP_TYPE_URI,
+ G_PARAM_READWRITE));
g_object_class_install_property (
object_class, PROP_SSL_CREDS,
g_param_spec_pointer (SOUP_CONNECTION_SSL_CREDENTIALS,
@@ -214,8 +214,10 @@ set_property (GObject *object, guint prop_id,
case PROP_TUNNEL_ADDRESS:
priv->tunnel_addr = g_value_dup_object (value);
break;
- case PROP_IS_PROXY:
- priv->is_proxy = g_value_get_boolean (value);
+ case PROP_PROXY_URI:
+ if (priv->proxy_uri)
+ soup_uri_free (priv->proxy_uri);
+ priv->proxy_uri = g_value_dup_boxed (value);
break;
case PROP_SSL_CREDS:
priv->ssl_creds = g_value_get_pointer (value);
@@ -250,8 +252,8 @@ get_property (GObject *object, guint prop_id,
case PROP_TUNNEL_ADDRESS:
g_value_set_object (value, priv->tunnel_addr);
break;
- case PROP_IS_PROXY:
- g_value_set_boolean (value, priv->is_proxy);
+ case PROP_PROXY_URI:
+ g_value_set_boxed (value, priv->proxy_uri);
break;
case PROP_SSL_CREDS:
g_value_set_pointer (value, priv->ssl_creds);
@@ -375,7 +377,7 @@ socket_connect_result (SoupSocket *sock, guint status, gpointer user_data)
done:
if (data->callback) {
- if (priv->is_proxy)
+ if (priv->proxy_uri != NULL)
status = soup_status_proxify (status);
data->callback (data->conn, status, data->callback_data);
}
@@ -472,7 +474,7 @@ soup_connection_connect_sync (SoupConnection *conn)
}
}
- if (priv->is_proxy)
+ if (priv->proxy_uri != NULL)
status = soup_status_proxify (status);
return status;
}
@@ -585,6 +587,14 @@ soup_connection_get_socket (SoupConnection *conn)
return SOUP_CONNECTION_GET_PRIVATE (conn)->socket;
}
+SoupURI *
+soup_connection_get_proxy_uri (SoupConnection *conn)
+{
+ g_return_val_if_fail (SOUP_IS_CONNECTION (conn), NULL);
+
+ return SOUP_CONNECTION_GET_PRIVATE (conn)->proxy_uri;
+}
+
SoupConnectionState
soup_connection_get_state (SoupConnection *conn)
{
@@ -643,5 +653,6 @@ soup_connection_send_request (SoupConnection *conn, SoupMessage *req)
if (req != priv->cur_req)
set_current_request (priv, req);
- soup_message_send_request (req, priv->socket, conn, priv->is_proxy);
+ soup_message_send_request (req, priv->socket, conn,
+ priv->proxy_uri != NULL);
}
diff --git a/libsoup/soup-connection.h b/libsoup/soup-connection.h
index d4fe465..68a36ab 100644
--- a/libsoup/soup-connection.h
+++ b/libsoup/soup-connection.h
@@ -49,7 +49,7 @@ typedef enum {
#define SOUP_CONNECTION_REMOTE_ADDRESS "remote-address"
#define SOUP_CONNECTION_TUNNEL_ADDRESS "tunnel-address"
-#define SOUP_CONNECTION_IS_PROXY "is-proxy"
+#define SOUP_CONNECTION_PROXY_URI "proxy-uri"
#define SOUP_CONNECTION_SSL_CREDENTIALS "ssl-creds"
#define SOUP_CONNECTION_ASYNC_CONTEXT "async-context"
#define SOUP_CONNECTION_TIMEOUT "timeout"
@@ -68,6 +68,7 @@ gboolean soup_connection_start_ssl (SoupConnection *conn);
void soup_connection_disconnect (SoupConnection *conn);
SoupSocket *soup_connection_get_socket (SoupConnection *conn);
+SoupURI *soup_connection_get_proxy_uri (SoupConnection *conn);
SoupConnectionState soup_connection_get_state (SoupConnection *conn);
void soup_connection_set_state (SoupConnection *conn,
diff --git a/libsoup/soup-message-queue.c b/libsoup/soup-message-queue.c
index 7a7c363..bce5a16 100644
--- a/libsoup/soup-message-queue.c
+++ b/libsoup/soup-message-queue.c
@@ -11,6 +11,7 @@
#endif
#include "soup-message-queue.h"
+#include "soup-uri.h"
/**
* SECTION:soup-message-queue
@@ -166,6 +167,8 @@ soup_message_queue_item_unref (SoupMessageQueueItem *item)
g_object_unref (item->cancellable);
if (item->proxy_addr)
g_object_unref (item->proxy_addr);
+ if (item->proxy_uri)
+ soup_uri_free (item->proxy_uri);
if (item->conn)
g_object_unref (item->conn);
g_slice_free (SoupMessageQueueItem, item);
diff --git a/libsoup/soup-message-queue.h b/libsoup/soup-message-queue.h
index 8487498..b7bc5d1 100644
--- a/libsoup/soup-message-queue.h
+++ b/libsoup/soup-message-queue.h
@@ -28,6 +28,7 @@ struct SoupMessageQueueItem {
GCancellable *cancellable;
SoupAddress *proxy_addr;
+ SoupURI *proxy_uri;
SoupConnection *conn;
guint resolving_proxy_addr : 1;
diff --git a/libsoup/soup-proxy-resolver-gnome.c b/libsoup/soup-proxy-resolver-gnome.c
index 4371d5a..1873fbb 100644
--- a/libsoup/soup-proxy-resolver-gnome.c
+++ b/libsoup/soup-proxy-resolver-gnome.c
@@ -13,8 +13,7 @@
#include <stdlib.h>
#include "soup-proxy-resolver-gnome.h"
-#include "soup-address.h"
-#include "soup-dns.h"
+#include "soup-proxy-uri-resolver.h"
#include "soup-message.h"
#include "soup-misc.h"
#include "soup-session-feature.h"
@@ -37,15 +36,16 @@ typedef enum {
G_LOCK_DEFINE_STATIC (resolver_gnome);
static SoupProxyResolverGNOMEMode proxy_mode;
static GConfClient *gconf_client;
+static char *proxy_user, *proxy_password;
static pxProxyFactory *libproxy_factory;
static GThreadPool *libproxy_threadpool;
-static void soup_proxy_resolver_gnome_interface_init (SoupProxyResolverInterface *proxy_resolver_interface);
+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_RESOLVER, soup_proxy_resolver_gnome_interface_init))
+ 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);
@@ -53,16 +53,16 @@ static void update_proxy_settings (void);
static void libproxy_threadpool_func (gpointer thread_data, gpointer user_data);
-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 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;
@@ -149,16 +149,19 @@ soup_proxy_resolver_gnome_class_init (SoupProxyResolverGNOMEClass *gconf_class)
}
static void
-soup_proxy_resolver_gnome_interface_init (SoupProxyResolverInterface *proxy_resolver_interface)
+soup_proxy_resolver_gnome_interface_init (SoupProxyURIResolverInterface *proxy_uri_resolver_interface)
{
- proxy_resolver_interface->get_proxy_async = get_proxy_async;
- proxy_resolver_interface->get_proxy_sync = get_proxy_sync;
+ 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"
@@ -179,6 +182,16 @@ update_proxy_settings (void)
/* resolver_gnome is locked */
+ 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;
+ }
+
/* Get new settings */
mode = gconf_client_get_string (
gconf_client, SOUP_GCONF_PROXY_MODE, NULL);
@@ -244,6 +257,13 @@ update_proxy_settings (void)
}
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);
+ }
}
ignore = gconf_client_get_list (
@@ -304,33 +324,31 @@ gconf_value_changed (GConfClient *client, const char *key,
}
static guint
-get_proxy_for_message (SoupMessage *msg, SoupAddress **addr)
+get_proxy_for_uri (SoupURI *uri, SoupURI **proxy_uri)
{
- char *msg_uri, **proxies;
- SoupURI *proxy_uri;
+ char *uristr, **proxies;
gboolean got_proxy;
int i;
+ *proxy_uri = NULL;
+
/* resolver_gnome is locked */
- msg_uri = soup_uri_to_string (soup_message_get_uri (msg), FALSE);
- proxies = px_proxy_factory_get_proxies (libproxy_factory, msg_uri);
- g_free (msg_uri);
+ uristr = soup_uri_to_string (uri, FALSE);
+ proxies = px_proxy_factory_get_proxies (libproxy_factory, uristr);
+ g_free (uristr);
- if (!proxies) {
- *addr = NULL;
+ if (!proxies)
return SOUP_STATUS_OK;
- }
got_proxy = FALSE;
for (i = 0; proxies[i]; i++) {
if (!strcmp (proxies[i], "direct://")) {
- proxy_uri = NULL;
got_proxy = TRUE;
break;
}
if (strncmp (proxies[i], "http://", 7) == 0) {
- proxy_uri = soup_uri_new (proxies[i]);
+ *proxy_uri = soup_uri_new (proxies[i]);
got_proxy = TRUE;
break;
}
@@ -339,55 +357,45 @@ get_proxy_for_message (SoupMessage *msg, SoupAddress **addr)
free (proxies[i]);
free (proxies);
- if (!got_proxy) {
- *addr = NULL;
- return SOUP_STATUS_CANT_RESOLVE_PROXY;
- }
+ if (got_proxy) {
+ if (*proxy_uri && proxy_user) {
+ soup_uri_set_user (*proxy_uri, proxy_user);
+ soup_uri_set_password (*proxy_uri, proxy_password);
+ }
- if (proxy_uri) {
- *addr = soup_address_new (proxy_uri->host, proxy_uri->port);
- soup_uri_free (proxy_uri);
+ return SOUP_STATUS_OK;
} else
- *addr = NULL;
- return SOUP_STATUS_OK;
+ return SOUP_STATUS_CANT_RESOLVE_PROXY;
}
typedef struct {
- SoupProxyResolver *proxy_resolver;
- SoupMessage *msg;
- SoupAddress *addr;
+ SoupProxyURIResolver *proxy_uri_resolver;
+ SoupURI *uri, *proxy_uri;
GMainContext *async_context;
GCancellable *cancellable;
guint status;
- SoupProxyResolverCallback callback;
+ SoupProxyURIResolverCallback callback;
gpointer user_data;
} SoupGNOMEAsyncData;
-static void
-resolved_address (SoupAddress *addr, guint status, gpointer data)
+static gboolean
+resolved_proxy (gpointer data)
{
SoupGNOMEAsyncData *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);
+ 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 (addr)
- g_object_unref (addr);
+ if (sgad->proxy_uri)
+ soup_uri_free (sgad->proxy_uri);
g_slice_free (SoupGNOMEAsyncData, sgad);
-}
-static gboolean
-idle_resolved_address (gpointer data)
-{
- SoupGNOMEAsyncData *sgad = data;
-
- resolved_address (sgad->addr, sgad->status, data);
return FALSE;
}
@@ -396,36 +404,35 @@ libproxy_threadpool_func (gpointer user_data, gpointer thread_data)
{
SoupGNOMEAsyncData *sgad = user_data;
- /* We don't just call get_libproxy_proxy_for_message here,
- * since it's possible that the proxy mode has changed...
+ /* We don't just call get_proxy_for_uri here, since it's
+ * possible that the proxy mode has changed...
*/
- sgad->status = get_proxy_sync (NULL, sgad->msg, sgad->cancellable,
- &sgad->addr);
- soup_add_completion (sgad->async_context, idle_resolved_address, sgad);
+ 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);
}
static void
-get_proxy_async (SoupProxyResolver *proxy_resolver,
- SoupMessage *msg,
- GMainContext *async_context,
- GCancellable *cancellable,
- SoupProxyResolverCallback callback,
- gpointer user_data)
+get_proxy_uri_async (SoupProxyURIResolver *proxy_uri_resolver,
+ SoupURI *uri,
+ GMainContext *async_context,
+ GCancellable *cancellable,
+ SoupProxyURIResolverCallback callback,
+ gpointer user_data)
{
SoupGNOMEAsyncData *sgad;
sgad = g_slice_new0 (SoupGNOMEAsyncData);
- sgad->proxy_resolver = g_object_ref (proxy_resolver);
- sgad->msg = g_object_ref (msg);
+ sgad->proxy_uri_resolver = g_object_ref (proxy_uri_resolver);
sgad->cancellable = cancellable ? g_object_ref (cancellable) : NULL;
- sgad->async_context = async_context ? g_main_context_ref (async_context) : NULL;
sgad->callback = callback;
sgad->user_data = user_data;
G_LOCK (resolver_gnome);
switch (proxy_mode) {
case SOUP_PROXY_RESOLVER_GNOME_MODE_NONE:
- sgad->addr = NULL;
+ sgad->proxy_uri = NULL;
sgad->status = SOUP_STATUS_OK;
break;
@@ -433,48 +440,37 @@ get_proxy_async (SoupProxyResolver *proxy_resolver,
/* We know libproxy won't do PAC or WPAD in this case,
* so we can make a "blocking" call to it.
*/
- sgad->status = get_proxy_for_message (msg, &sgad->addr);
+ sgad->status = get_proxy_for_uri (uri, &sgad->proxy_uri);
break;
case SOUP_PROXY_RESOLVER_GNOME_MODE_AUTO:
/* 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);
G_UNLOCK (resolver_gnome);
return;
}
G_UNLOCK (resolver_gnome);
- if (sgad->addr) {
- soup_address_resolve_async (sgad->addr, async_context,
- cancellable, resolved_address,
- sgad);
- } else
- soup_add_idle (async_context, idle_resolved_address, sgad);
+ soup_add_completion (async_context, resolved_proxy, sgad);
}
static guint
-get_proxy_sync (SoupProxyResolver *proxy_resolver,
- SoupMessage *msg,
- GCancellable *cancellable,
- SoupAddress **addr)
+get_proxy_uri_sync (SoupProxyURIResolver *proxy_uri_resolver,
+ SoupURI *uri,
+ GCancellable *cancellable,
+ SoupURI **proxy_uri)
{
guint status;
G_LOCK (resolver_gnome);
if (proxy_mode == SOUP_PROXY_RESOLVER_GNOME_MODE_NONE) {
- *addr = NULL;
+ *proxy_uri = NULL;
status = SOUP_STATUS_OK;
} else
- status = get_proxy_for_message (msg, addr);
+ status = get_proxy_for_uri (uri, proxy_uri);
G_UNLOCK (resolver_gnome);
- if (!*addr || status != SOUP_STATUS_OK)
- return status;
-
- status = soup_address_resolve_sync (*addr, cancellable);
- if (!SOUP_STATUS_IS_SUCCESSFUL (status)) {
- g_object_unref (*addr);
- *addr = NULL;
- }
- return soup_status_proxify (status);
+ return status;
}
diff --git a/libsoup/soup-proxy-resolver-gnome.h b/libsoup/soup-proxy-resolver-gnome.h
index 9f29842..2f87921 100644
--- a/libsoup/soup-proxy-resolver-gnome.h
+++ b/libsoup/soup-proxy-resolver-gnome.h
@@ -6,7 +6,6 @@
#ifndef SOUP_PROXY_RESOLVER_GNOME_H
#define SOUP_PROXY_RESOLVER_GNOME_H 1
-#include "soup-proxy-resolver.h"
#include "soup-gnome-features.h"
/* SOUP_TYPE_PROXY_RESOLVER_GNOME and soup_proxy_resolver_gnome_get_type()
diff --git a/libsoup/soup-proxy-resolver.c b/libsoup/soup-proxy-resolver.c
index 630c10c..33a908c 100644
--- a/libsoup/soup-proxy-resolver.c
+++ b/libsoup/soup-proxy-resolver.c
@@ -10,7 +10,14 @@
#endif
#include "soup-proxy-resolver.h"
+#include "soup-proxy-uri-resolver.h"
+#include "soup-address.h"
+#include "soup-message.h"
#include "soup-session-feature.h"
+#include "soup-uri.h"
+
+static void soup_proxy_resolver_interface_init (GTypeInterface *interface);
+static void soup_proxy_resolver_uri_resolver_interface_init (SoupProxyURIResolverInterface *uri_resolver_interface);
GType
soup_proxy_resolver_get_type (void)
@@ -22,7 +29,7 @@ soup_proxy_resolver_get_type (void)
g_type_register_static_simple (G_TYPE_INTERFACE,
g_intern_static_string ("SoupProxyResolver"),
sizeof (SoupProxyResolverInterface),
- (GClassInitFunc)NULL,
+ (GClassInitFunc)soup_proxy_resolver_interface_init,
0,
(GInstanceInitFunc)NULL,
(GTypeFlags) 0);
@@ -33,20 +40,44 @@ soup_proxy_resolver_get_type (void)
return g_define_type_id__volatile;
}
-/**
- * soup_proxy_resolver_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.
- *
- * Since: 2.26
- **/
+static void
+proxy_resolver_interface_check (gpointer func_data, gpointer g_iface)
+{
+ GTypeInterface *interface = g_iface;
+ GTypeClass *klass;
+
+ if (interface->g_type != SOUP_TYPE_PROXY_RESOLVER)
+ return;
+
+ klass = g_type_class_peek (interface->g_instance_type);
+ /* If the class hasn't already declared that it implements
+ * SoupProxyURIResolver, add our own compat implementation.
+ */
+ if (!g_type_interface_peek (klass, SOUP_TYPE_PROXY_URI_RESOLVER)) {
+ const GInterfaceInfo uri_resolver_interface_info = {
+ (GInterfaceInitFunc) soup_proxy_resolver_uri_resolver_interface_init, NULL, NULL
+ };
+ g_type_add_interface_static (interface->g_instance_type,
+ SOUP_TYPE_PROXY_URI_RESOLVER,
+ &uri_resolver_interface_info);
+ }
+}
+
+
+static void
+soup_proxy_resolver_interface_init (GTypeInterface *interface)
+{
+ /* Add an interface_check where we can kludgily add the
+ * SoupProxyURIResolver interface to all SoupProxyResolvers.
+ * (SoupProxyResolver can't just implement
+ * SoupProxyURIResolver itself because interface types can't
+ * implement other interfaces.) This is an ugly hack, but it
+ * only gets used if someone actually creates a
+ * SoupProxyResolver...
+ */
+ g_type_add_interface_check (NULL, proxy_resolver_interface_check);
+}
+
void
soup_proxy_resolver_get_proxy_async (SoupProxyResolver *proxy_resolver,
SoupMessage *msg,
@@ -61,22 +92,6 @@ soup_proxy_resolver_get_proxy_async (SoupProxyResolver *proxy_resolver,
callback, user_data);
}
-/**
- * soup_proxy_resolver_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.
- *
- * Since: 2.26
- **/
guint
soup_proxy_resolver_get_proxy_sync (SoupProxyResolver *proxy_resolver,
SoupMessage *msg,
@@ -86,3 +101,90 @@ soup_proxy_resolver_get_proxy_sync (SoupProxyResolver *proxy_resolver,
return SOUP_PROXY_RESOLVER_GET_CLASS (proxy_resolver)->
get_proxy_sync (proxy_resolver, msg, cancellable, addr);
}
+
+/* SoupProxyURIResolver implementation */
+
+static SoupURI *
+uri_from_address (SoupAddress *addr)
+{
+ SoupURI *proxy_uri;
+
+ proxy_uri = soup_uri_new (NULL);
+ soup_uri_set_scheme (proxy_uri, SOUP_URI_SCHEME_HTTP);
+ soup_uri_set_host (proxy_uri, soup_address_get_name (addr));
+ soup_uri_set_port (proxy_uri, soup_address_get_port (addr));
+ return proxy_uri;
+}
+
+typedef struct {
+ SoupProxyURIResolverCallback callback;
+ gpointer user_data;
+} ProxyURIResolverAsyncData;
+
+static void
+compat_got_proxy (SoupProxyResolver *proxy_resolver,
+ SoupMessage *msg, guint status, SoupAddress *proxy_addr,
+ gpointer user_data)
+{
+ ProxyURIResolverAsyncData *purad = user_data;
+ SoupURI *proxy_uri;
+
+ proxy_uri = proxy_addr ? uri_from_address (proxy_addr) : NULL;
+ purad->callback (SOUP_PROXY_URI_RESOLVER (proxy_resolver),
+ status, proxy_uri, purad->user_data);
+ g_object_unref (msg);
+ if (proxy_uri)
+ soup_uri_free (proxy_uri);
+ g_slice_free (ProxyURIResolverAsyncData, purad);
+}
+
+static void
+compat_get_proxy_uri_async (SoupProxyURIResolver *proxy_uri_resolver,
+ SoupURI *uri, GMainContext *async_context,
+ GCancellable *cancellable,
+ SoupProxyURIResolverCallback callback,
+ gpointer user_data)
+{
+ SoupMessage *dummy_msg;
+ ProxyURIResolverAsyncData *purad;
+
+ dummy_msg = soup_message_new_from_uri (SOUP_METHOD_GET, uri);
+
+ purad = g_slice_new (ProxyURIResolverAsyncData);
+ purad->callback = callback;
+ purad->user_data = user_data;
+
+ soup_proxy_resolver_get_proxy_async (
+ SOUP_PROXY_RESOLVER (proxy_uri_resolver), dummy_msg,
+ async_context, cancellable,
+ compat_got_proxy, purad);
+}
+
+static guint
+compat_get_proxy_uri_sync (SoupProxyURIResolver *proxy_uri_resolver,
+ SoupURI *uri, GCancellable *cancellable,
+ SoupURI **proxy_uri)
+{
+ SoupMessage *dummy_msg;
+ SoupAddress *proxy_addr = NULL;
+ guint status;
+
+ dummy_msg = soup_message_new_from_uri (SOUP_METHOD_GET, uri);
+ status = soup_proxy_resolver_get_proxy_sync (
+ SOUP_PROXY_RESOLVER (proxy_uri_resolver), dummy_msg,
+ cancellable, &proxy_addr);
+ g_object_unref (dummy_msg);
+ if (!proxy_addr)
+ return status;
+
+ *proxy_uri = uri_from_address (proxy_addr);
+ g_object_unref (proxy_addr);
+ return status;
+}
+
+static void
+soup_proxy_resolver_uri_resolver_interface_init (SoupProxyURIResolverInterface *uri_resolver_interface)
+{
+ uri_resolver_interface->get_proxy_uri_async = compat_get_proxy_uri_async;
+ uri_resolver_interface->get_proxy_uri_sync = compat_get_proxy_uri_sync;
+}
diff --git a/libsoup/soup-proxy-resolver.h b/libsoup/soup-proxy-resolver.h
index f91f3e1..161ae76 100644
--- a/libsoup/soup-proxy-resolver.h
+++ b/libsoup/soup-proxy-resolver.h
@@ -11,6 +11,8 @@
G_BEGIN_DECLS
+#ifndef LIBSOUP_DISABLE_DEPRECATED
+
#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))
@@ -48,6 +50,8 @@ guint soup_proxy_resolver_get_proxy_sync (SoupProxyResolver *proxy_resolver,
GCancellable *cancellable,
SoupAddress **addr);
+#endif
+
G_END_DECLS
#endif /*SOUP_PROXY_RESOLVER_H*/
diff --git a/libsoup/soup-proxy-uri-resolver.c b/libsoup/soup-proxy-uri-resolver.c
new file mode 100644
index 0000000..bb86f18
--- /dev/null
+++ b/libsoup/soup-proxy-uri-resolver.c
@@ -0,0 +1,97 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * soup-proxy-uri-resolver.c: HTTP proxy resolver interface, take 2
+ *
+ * Copyright (C) 2009 Red Hat, Inc.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "soup-proxy-uri-resolver.h"
+#include "soup-session-feature.h"
+
+GType
+soup_proxy_uri_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 ("SoupProxyURIResolver"),
+ sizeof (SoupProxyURIResolverInterface),
+ (GClassInitFunc)NULL,
+ 0,
+ (GInstanceInitFunc)NULL,
+ (GTypeFlags) 0);
+ g_type_interface_add_prerequisite (g_define_type_id, G_TYPE_OBJECT);
+ g_once_init_leave (&g_define_type_id__volatile, g_define_type_id);
+ }
+ return g_define_type_id__volatile;
+}
+
+/**
+ * SoupProxyURIResolverCallback:
+ * @resolver: the #SoupProxyURIResolver
+ * @status: a #SoupKnownStatusCode
+ * @proxy_uri: the resolved proxy URI, or %NULL
+ * @user_data: data passed to soup_proxy_uri_resolver_get_proxy_uri_async()
+ *
+ * Callback for soup_proxy_uri_resolver_get_proxy_uri_async()
+ **/
+
+/**
+ * soup_proxy_uri_resolver_get_proxy_uri_async:
+ * @proxy_uri_resolver: the #SoupProxyURIResolver
+ * @uri: the #SoupURI 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 URI to use for @msg and calls
+ * @callback.
+ *
+ * Since: 2.26.3
+ **/
+void
+soup_proxy_uri_resolver_get_proxy_uri_async (SoupProxyURIResolver *proxy_uri_resolver,
+ SoupURI *uri,
+ GMainContext *async_context,
+ GCancellable *cancellable,
+ SoupProxyURIResolverCallback callback,
+ gpointer user_data)
+{
+ SOUP_PROXY_URI_RESOLVER_GET_CLASS (proxy_uri_resolver)->
+ get_proxy_uri_async (proxy_uri_resolver, uri,
+ async_context, cancellable,
+ callback, user_data);
+}
+
+/**
+ * soup_proxy_uri_resolver_get_proxy_uri_sync:
+ * @proxy_uri_resolver: the #SoupProxyURIResolver
+ * @uri: the #SoupURI you want a proxy for
+ * @cancellable: a #GCancellable, or %NULL
+ * @proxy_uri: on return, will contain the proxy URI
+ *
+ * Synchronously determines a proxy URI to use for @uri. If @uri
+ * should be sent via proxy, * proxy_uri will be set to the URI of the
+ * proxy, else it will be set to %NULL.
+ *
+ * Return value: %SOUP_STATUS_OK if successful, or a transport-level
+ * error.
+ *
+ * Since: 2.26.3
+ **/
+guint
+soup_proxy_uri_resolver_get_proxy_uri_sync (SoupProxyURIResolver *proxy_uri_resolver,
+ SoupURI *uri,
+ GCancellable *cancellable,
+ SoupURI **proxy_uri)
+{
+ return SOUP_PROXY_URI_RESOLVER_GET_CLASS (proxy_uri_resolver)->
+ get_proxy_uri_sync (proxy_uri_resolver, uri, cancellable, proxy_uri);
+}
diff --git a/libsoup/soup-proxy-uri-resolver.h b/libsoup/soup-proxy-uri-resolver.h
new file mode 100644
index 0000000..97476cb
--- /dev/null
+++ b/libsoup/soup-proxy-uri-resolver.h
@@ -0,0 +1,57 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2009 Red Hat, Inc.
+ */
+
+#ifndef SOUP_PROXY_URI_RESOLVER_H
+#define SOUP_PROXY_URI_RESOLVER_H 1
+
+#include <libsoup/soup-proxy-resolver.h>
+
+G_BEGIN_DECLS
+
+#define SOUP_TYPE_PROXY_URI_RESOLVER (soup_proxy_uri_resolver_get_type ())
+#define SOUP_PROXY_URI_RESOLVER(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), SOUP_TYPE_PROXY_URI_RESOLVER, SoupProxyURIResolver))
+#define SOUP_PROXY_URI_RESOLVER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SOUP_TYPE_PROXY_URI_RESOLVER, SoupProxyURIResolverInterface))
+#define SOUP_IS_PROXY_URI_RESOLVER(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), SOUP_TYPE_PROXY_URI_RESOLVER))
+#define SOUP_IS_PROXY_URI_RESOLVER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SOUP_TYPE_PROXY_URI_RESOLVER))
+#define SOUP_PROXY_URI_RESOLVER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_INTERFACE ((obj), SOUP_TYPE_PROXY_URI_RESOLVER, SoupProxyURIResolverInterface))
+
+typedef struct _SoupProxyURIResolver SoupProxyURIResolver;
+
+typedef void (*SoupProxyURIResolverCallback) (SoupProxyURIResolver *,
+ guint, SoupURI *, gpointer);
+
+typedef struct {
+ GTypeInterface base;
+
+ /* virtual methods */
+ void (*get_proxy_uri_async) (SoupProxyURIResolver *, SoupURI *,
+ GMainContext *, GCancellable *,
+ SoupProxyURIResolverCallback, gpointer);
+ guint (*get_proxy_uri_sync) (SoupProxyURIResolver *, SoupURI *,
+ GCancellable *, SoupURI **);
+
+ /* Padding for future expansion */
+ void (*_libsoup_reserved1) (void);
+ void (*_libsoup_reserved2) (void);
+ void (*_libsoup_reserved3) (void);
+ void (*_libsoup_reserved4) (void);
+} SoupProxyURIResolverInterface;
+
+GType soup_proxy_uri_resolver_get_type (void);
+
+void soup_proxy_uri_resolver_get_proxy_uri_async (SoupProxyURIResolver *proxy_uri_resolver,
+ SoupURI *uri,
+ GMainContext *async_context,
+ GCancellable *cancellable,
+ SoupProxyURIResolverCallback callback,
+ gpointer user_data);
+guint soup_proxy_uri_resolver_get_proxy_uri_sync (SoupProxyURIResolver *proxy_uri_resolver,
+ SoupURI *uri,
+ GCancellable *cancellable,
+ SoupURI **proxy_uri);
+
+G_END_DECLS
+
+#endif /*SOUP_PROXY_URI_RESOLVER_H*/
diff --git a/libsoup/soup-session-async.c b/libsoup/soup-session-async.c
index 29422a9..f505710 100644
--- a/libsoup/soup-session-async.c
+++ b/libsoup/soup-session-async.c
@@ -15,6 +15,8 @@
#include "soup-address.h"
#include "soup-message-private.h"
#include "soup-misc.h"
+#include "soup-proxy-uri-resolver.h"
+#include "soup-uri.h"
/**
* SECTION:soup-session-async
@@ -108,30 +110,69 @@ soup_session_async_new_with_options (const char *optname1, ...)
return session;
}
+static gboolean
+item_failed (SoupMessageQueueItem *item, guint status)
+{
+ if (item->removed) {
+ soup_message_queue_item_unref (item);
+ return TRUE;
+ }
+
+ if (!SOUP_STATUS_IS_SUCCESSFUL (status)) {
+ if (status != SOUP_STATUS_CANCELLED)
+ soup_session_cancel_message (item->session, item->msg, status);
+ soup_message_queue_item_unref (item);
+ return TRUE;
+ }
+
+ return FALSE;
+}
static void
-resolved_proxy_addr (SoupProxyResolver *proxy_resolver, SoupMessage *msg,
- guint status, SoupAddress *proxy_addr, gpointer user_data)
+resolved_proxy_addr (SoupAddress *addr, guint status, 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);
+ if (item_failed (item, status))
return;
- }
- if (!SOUP_STATUS_IS_SUCCESSFUL (status)) {
- soup_session_cancel_message (session, item->msg, status);
- soup_message_queue_item_unref (item);
+ item->proxy_addr = g_object_ref (addr);
+ item->resolving_proxy_addr = FALSE;
+ item->resolved_proxy_addr = TRUE;
+
+ soup_message_queue_item_unref (item);
+
+ /* If we got here we know session still exists */
+ run_queue ((SoupSessionAsync *)session);
+}
+
+static void
+resolved_proxy_uri (SoupProxyURIResolver *proxy_resolver,
+ guint status, SoupURI *proxy_uri, gpointer user_data)
+{
+ SoupMessageQueueItem *item = user_data;
+ SoupSession *session = item->session;
+
+ if (item_failed (item, status))
+ return;
+
+ if (proxy_uri) {
+ SoupAddress *proxy_addr;
+
+ item->proxy_uri = soup_uri_copy (proxy_uri);
+ proxy_addr = soup_address_new (proxy_uri->host,
+ proxy_uri->port);
+ soup_address_resolve_async (proxy_addr,
+ soup_session_get_async_context (session),
+ item->cancellable,
+ resolved_proxy_addr, item);
+ g_object_unref (proxy_addr);
return;
}
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);
/* If we got here we know session still exists */
@@ -140,17 +181,17 @@ resolved_proxy_addr (SoupProxyResolver *proxy_resolver, SoupMessage *msg,
static void
resolve_proxy_addr (SoupMessageQueueItem *item,
- SoupProxyResolver *proxy_resolver)
+ SoupProxyURIResolver *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);
+ soup_proxy_uri_resolver_get_proxy_uri_async (
+ proxy_resolver, soup_message_get_uri (item->msg),
+ soup_session_get_async_context (item->session),
+ item->cancellable, resolved_proxy_uri, item);
}
static void
@@ -255,7 +296,7 @@ run_queue (SoupSessionAsync *sa)
SoupSession *session = SOUP_SESSION (sa);
SoupMessageQueue *queue = soup_session_get_queue (session);
SoupMessageQueueItem *item;
- SoupProxyResolver *proxy_resolver =
+ SoupProxyURIResolver *proxy_resolver =
soup_session_get_proxy_resolver (session);
SoupMessage *msg;
SoupMessageIOStatus cur_io_status = SOUP_MESSAGE_IO_STATUS_CONNECTING;
diff --git a/libsoup/soup-session-private.h b/libsoup/soup-session-private.h
index 324e42b..765ea06 100644
--- a/libsoup/soup-session-private.h
+++ b/libsoup/soup-session-private.h
@@ -9,7 +9,7 @@
#include "soup-session.h"
#include "soup-connection.h"
#include "soup-message-queue.h"
-#include "soup-proxy-resolver.h"
+#include "soup-proxy-uri-resolver.h"
G_BEGIN_DECLS
@@ -26,7 +26,7 @@ void soup_session_connection_failed (SoupSession *s
SoupConnection *conn,
guint status);
-SoupProxyResolver *soup_session_get_proxy_resolver (SoupSession *session);
+SoupProxyURIResolver *soup_session_get_proxy_resolver (SoupSession *session);
void soup_session_send_queue_item (SoupSession *session,
SoupMessageQueueItem *item,
diff --git a/libsoup/soup-session-sync.c b/libsoup/soup-session-sync.c
index d084b00..8c2e56b 100644
--- a/libsoup/soup-session-sync.c
+++ b/libsoup/soup-session-sync.c
@@ -14,7 +14,9 @@
#include "soup-session-private.h"
#include "soup-address.h"
#include "soup-message-private.h"
+#include "soup-proxy-uri-resolver.h"
#include "soup-misc.h"
+#include "soup-uri.h"
/**
* SECTION:soup-session-sync
@@ -162,19 +164,34 @@ wait_for_connection (SoupMessageQueueItem *item)
SoupMessage *msg = item->msg;
SoupSessionSyncPrivate *priv = SOUP_SESSION_SYNC_GET_PRIVATE (session);
gboolean try_pruning = FALSE;
- SoupProxyResolver *proxy_resolver;
+ SoupProxyURIResolver *proxy_resolver;
SoupAddress *tunnel_addr;
SoupConnection *conn;
guint status;
proxy_resolver = soup_session_get_proxy_resolver (session);
if (proxy_resolver && !item->resolved_proxy_addr) {
- status = soup_proxy_resolver_get_proxy_sync (
- proxy_resolver, msg, NULL, &item->proxy_addr);
+ status = soup_proxy_uri_resolver_get_proxy_uri_sync (
+ proxy_resolver, soup_message_get_uri (msg),
+ item->cancellable, &item->proxy_uri);
if (!SOUP_STATUS_IS_SUCCESSFUL (status)) {
- soup_session_cancel_message (session, msg, status);
+ if (status != SOUP_STATUS_CANCELLED)
+ soup_session_cancel_message (session, msg, status);
return NULL;
}
+
+ if (item->proxy_uri) {
+ item->proxy_addr = soup_address_new (
+ item->proxy_uri->host, item->proxy_uri->port);
+ status = soup_address_resolve_sync (item->proxy_addr,
+ item->cancellable);
+ if (!SOUP_STATUS_IS_SUCCESSFUL (status)) {
+ if (status != SOUP_STATUS_CANCELLED)
+ soup_session_cancel_message (session, msg, status);
+ return NULL;
+ }
+ }
+
item->resolved_proxy_addr = TRUE;
}
diff --git a/libsoup/soup-session.c b/libsoup/soup-session.c
index 14f10e9..b9b74f7 100644
--- a/libsoup/soup-session.c
+++ b/libsoup/soup-session.c
@@ -24,6 +24,7 @@
#include "soup-message-queue.h"
#include "soup-misc.h"
#include "soup-proxy-resolver-static.h"
+#include "soup-proxy-uri-resolver.h"
#include "soup-session.h"
#include "soup-session-feature.h"
#include "soup-session-private.h"
@@ -66,7 +67,7 @@ typedef struct {
} SoupSessionHost;
typedef struct {
- SoupProxyResolver *proxy_resolver;
+ SoupProxyURIResolver *proxy_resolver;
char *ssl_ca_file;
SoupSSLCredentials *ssl_creds;
@@ -623,7 +624,7 @@ set_property (GObject *object, guint prop_id,
if (uri) {
soup_session_remove_feature_by_type (session, SOUP_TYPE_PROXY_RESOLVER);
- priv->proxy_resolver = soup_proxy_resolver_static_new (uri);
+ priv->proxy_resolver = SOUP_PROXY_URI_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))
@@ -1021,6 +1022,23 @@ soup_session_connection_failed (SoupSession *session,
g_object_unref (session);
}
+static void
+tunnel_connected (SoupSession *session, SoupMessage *msg, gpointer user_data)
+{
+ if (SOUP_STATUS_IS_SUCCESSFUL (msg->status_code)) {
+ SoupSessionPrivate *priv = SOUP_SESSION_GET_PRIVATE (session);
+ SoupMessageQueueItem *item =
+ soup_message_queue_lookup (priv->queue, msg);
+
+ /* Clear the connection's proxy_uri, since it is now
+ * (effectively) directly connected.
+ */
+ g_object_set (item->conn,
+ SOUP_CONNECTION_PROXY_URI, NULL,
+ NULL);
+ }
+}
+
SoupMessageQueueItem *
soup_session_make_connect_message (SoupSession *session,
SoupAddress *server_addr)
@@ -1042,7 +1060,7 @@ soup_session_make_connect_message (SoupSession *session,
* directly, to add msg to the SoupMessageQueue and cause all
* the right signals to be emitted.
*/
- queue_message (session, msg, NULL, NULL);
+ queue_message (session, msg, tunnel_connected, NULL);
return soup_message_queue_lookup (priv->queue, msg);
}
@@ -1092,7 +1110,7 @@ soup_session_get_connection (SoupSession *session,
SoupAddress *remote_addr, *tunnel_addr;
SoupSSLCredentials *ssl_creds;
GSList *conns;
- gboolean has_pending = FALSE, is_proxy;
+ gboolean has_pending = FALSE;
SoupURI *uri;
g_mutex_lock (priv->host_lock);
@@ -1130,11 +1148,9 @@ soup_session_get_connection (SoupSession *session,
if (item->proxy_addr) {
remote_addr = item->proxy_addr;
tunnel_addr = NULL;
- is_proxy = TRUE;
} else {
remote_addr = host->addr;
tunnel_addr = NULL;
- is_proxy = FALSE;
}
uri = soup_message_get_uri (item->msg);
@@ -1143,17 +1159,15 @@ soup_session_get_connection (SoupSession *session,
priv->ssl_creds = soup_ssl_get_client_credentials (priv->ssl_ca_file);
ssl_creds = priv->ssl_creds;
- if (is_proxy) {
- is_proxy = FALSE;
+ if (item->proxy_addr)
tunnel_addr = host->addr;
- }
} else
ssl_creds = NULL;
conn = soup_connection_new (
SOUP_CONNECTION_REMOTE_ADDRESS, remote_addr,
SOUP_CONNECTION_TUNNEL_ADDRESS, tunnel_addr,
- SOUP_CONNECTION_IS_PROXY, is_proxy,
+ SOUP_CONNECTION_PROXY_URI, item->proxy_uri,
SOUP_CONNECTION_SSL_CREDENTIALS, ssl_creds,
SOUP_CONNECTION_ASYNC_CONTEXT, priv->async_context,
SOUP_CONNECTION_TIMEOUT, priv->io_timeout,
@@ -1482,8 +1496,8 @@ soup_session_add_feature (SoupSession *session, SoupSessionFeature *feature)
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);
+ if (SOUP_IS_PROXY_URI_RESOLVER (feature))
+ priv->proxy_resolver = SOUP_PROXY_URI_RESOLVER (feature);
}
/**
@@ -1629,7 +1643,7 @@ soup_session_get_feature (SoupSession *session, GType feature_type)
return NULL;
}
-SoupProxyResolver *
+SoupProxyURIResolver *
soup_session_get_proxy_resolver (SoupSession *session)
{
SoupSessionPrivate *priv = SOUP_SESSION_GET_PRIVATE (session);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]