diff options
author | Gustavo Noronha Silva <gustavo.noronha@collabora.co.uk> | 2011-02-21 20:04:35 -0300 |
---|---|---|
committer | Dan Winship <danw@gnome.org> | 2011-03-21 12:43:13 -0400 |
commit | 0d6fa497de2b5defe6be96f755bc007c942dea56 (patch) | |
tree | f42dcc011b29fefeedba7adbe65bbfb30f8a2a25 | |
parent | 608b14e7fef529151e1a23963189f5a0ea22fade (diff) | |
download | libsoup-0d6fa497de2b5defe6be96f755bc007c942dea56.tar.gz |
soup-proxy-resolver-default.c: new proxy resolver based on GProxyResolver
This adds a new session feature that makes it easy to take advantage
of the new GProxyResolver object available in GIO.
https://bugzilla.gnome.org/show_bug.cgi?id=642928
-rw-r--r-- | libsoup/Makefile.am | 2 | ||||
-rw-r--r-- | libsoup/soup-proxy-resolver-default.c | 167 | ||||
-rw-r--r-- | libsoup/soup-proxy-resolver-default.h | 30 | ||||
-rw-r--r-- | libsoup/soup.h | 1 |
4 files changed, 200 insertions, 0 deletions
diff --git a/libsoup/Makefile.am b/libsoup/Makefile.am index a26d8202..de9c9b69 100644 --- a/libsoup/Makefile.am +++ b/libsoup/Makefile.am @@ -73,6 +73,7 @@ soup_headers = \ soup-password-manager.h \ soup-portability.h \ soup-proxy-resolver.h \ + soup-proxy-resolver-default.h \ soup-proxy-uri-resolver.h \ soup-request.h \ soup-request-data.h \ @@ -156,6 +157,7 @@ libsoup_2_4_la_SOURCES = \ soup-path-map.h \ soup-path-map.c \ soup-proxy-resolver.c \ + soup-proxy-resolver-default.c \ soup-proxy-resolver-static.h \ soup-proxy-resolver-static.c \ soup-proxy-uri-resolver.c \ diff --git a/libsoup/soup-proxy-resolver-default.c b/libsoup/soup-proxy-resolver-default.c new file mode 100644 index 00000000..962d0c12 --- /dev/null +++ b/libsoup/soup-proxy-resolver-default.c @@ -0,0 +1,167 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * soup-proxy-resolver-default.c: proxy resolution based on GIO's GProxyResolver + * + * Copyright (C) 2011 Collabora Ltd. + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <string.h> +#include <stdlib.h> + +#include "soup-proxy-resolver-default.h" +#include "soup-proxy-uri-resolver.h" +#include "soup-session-feature.h" +#include "soup-uri.h" + +static void soup_proxy_resolver_default_interface_init (SoupProxyURIResolverInterface *proxy_resolver_interface); + +G_DEFINE_TYPE_EXTENDED (SoupProxyResolverDefault, soup_proxy_resolver_default, G_TYPE_OBJECT, 0, + G_IMPLEMENT_INTERFACE (SOUP_TYPE_SESSION_FEATURE, NULL) + G_IMPLEMENT_INTERFACE (SOUP_TYPE_PROXY_URI_RESOLVER, soup_proxy_resolver_default_interface_init)) + + +static void +soup_proxy_resolver_default_init (SoupProxyResolverDefault *resolver) +{ +} + +static void +soup_proxy_resolver_default_class_init (SoupProxyResolverDefaultClass *klass) +{ +} + +typedef struct { + SoupProxyURIResolver *resolver; + GCancellable *cancellable; + SoupProxyURIResolverCallback callback; + gpointer user_data; +} SoupAsyncData; + +static void +resolved_proxy (GObject *object, GAsyncResult *result, gpointer data) +{ + GProxyResolver *proxy_resolver = G_PROXY_RESOLVER (object); + SoupAsyncData *async_data = data; + GError *error = NULL; + char **proxy_uris = NULL; + SoupURI *proxy_uri = NULL; + guint status = SOUP_STATUS_OK; + + proxy_uris = g_proxy_resolver_lookup_finish (proxy_resolver, + result, + &error); + + if (error || proxy_uris == NULL || proxy_uris[0] == NULL) { + status = SOUP_STATUS_CANT_RESOLVE_PROXY; + goto finish; + } + + /* We need to handle direct:// specially, otherwise + * SoupSession will try to resolve it as the proxy address. + */ + if (!g_strcmp0 (proxy_uris[0], "direct://")) + goto finish; + + proxy_uri = soup_uri_new (proxy_uris[0]); + if (proxy_uri == NULL) + status = SOUP_STATUS_CANT_RESOLVE_PROXY; + +finish: + async_data->callback (async_data->resolver, + status, + proxy_uri, + async_data->user_data); + + if (async_data->cancellable) + g_object_unref (async_data->cancellable); + + g_strfreev (proxy_uris); + + if (proxy_uri) + soup_uri_free (proxy_uri); + + g_object_unref (async_data->resolver); + g_slice_free (SoupAsyncData, async_data); +} + +static void +get_proxy_uri_async (SoupProxyURIResolver *resolver, + SoupURI *uri, + GMainContext *async_context, + GCancellable *cancellable, + SoupProxyURIResolverCallback callback, + gpointer user_data) +{ + SoupAsyncData *async_data; + char *uri_string; + + async_data = g_slice_new0 (SoupAsyncData); + async_data->resolver = (SoupProxyURIResolver*) g_object_ref (resolver); + async_data->cancellable = cancellable; + async_data->callback = callback; + async_data->user_data = user_data; + + uri_string = soup_uri_to_string (uri, FALSE); + + g_proxy_resolver_lookup_async (g_proxy_resolver_get_default (), + uri_string, + cancellable ? g_object_ref (cancellable) : NULL, + resolved_proxy, + async_data); + + g_free (uri_string); +} + +static guint +get_proxy_uri_sync (SoupProxyURIResolver *resolver, + SoupURI *uri, + GCancellable *cancellable, + SoupURI **proxy_uri) +{ + GError *error = NULL; + char** proxy_uris = NULL; + char *uri_string; + guint status = SOUP_STATUS_OK; + + uri_string = soup_uri_to_string (uri, FALSE); + + proxy_uris = g_proxy_resolver_lookup (g_proxy_resolver_get_default (), + uri_string, + cancellable, + &error); + + g_free (uri_string); + + if (error || proxy_uris == NULL || proxy_uris[0] == NULL) { + status = SOUP_STATUS_CANT_RESOLVE_PROXY; + goto cleanup; + } + + /* We need to handle direct:// specially, otherwise + * SoupSession will try to resolve it as the proxy address. + */ + if (!g_strcmp0 (proxy_uris[0], "direct://")) + goto cleanup; + + *proxy_uri = soup_uri_new (proxy_uris[0]); + + if (!*proxy_uri) + status = SOUP_STATUS_CANT_RESOLVE_PROXY; + +cleanup: + g_strfreev (proxy_uris); + if (error) + g_clear_error (&error); + return status; +} + +static void +soup_proxy_resolver_default_interface_init (SoupProxyURIResolverInterface *iface) +{ + iface->get_proxy_uri_async = get_proxy_uri_async; + iface->get_proxy_uri_sync = get_proxy_uri_sync; +} diff --git a/libsoup/soup-proxy-resolver-default.h b/libsoup/soup-proxy-resolver-default.h new file mode 100644 index 00000000..6c9715cf --- /dev/null +++ b/libsoup/soup-proxy-resolver-default.h @@ -0,0 +1,30 @@ +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */ +/* + * Copyright (C) 2011 Collabora Ltd. + */ + +#ifndef SOUP_PROXY_RESOLVER_DEFAULT_H +#define SOUP_PROXY_RESOLVER_DEFAULT_H 1 + +#include <glib-object.h> + +#define SOUP_PROXY_RESOLVER_DEFAULT(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), SOUP_TYPE_PROXY_RESOLVER_DEFAULT, SoupProxyResolverDefault)) +#define SOUP_PROXY_RESOLVER_DEFAULT_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SOUP_TYPE_PROXY_RESOLVER_DEFAULT, SoupProxyResolverDefaultClass)) +#define SOUP_IS_PROXY_RESOLVER_DEFAULT(object) (G_TYPE_CHECK_INSTANCE_TYPE ((object), SOUP_TYPE_PROXY_RESOLVER_DEFAULT)) +#define SOUP_IS_PROXY_RESOLVER_DEFAULT_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SOUP_TYPE_PROXY_RESOLVER_DEFAULT)) +#define SOUP_PROXY_RESOLVER_DEFAULT_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SOUP_TYPE_PROXY_RESOLVER_DEFAULT, SoupProxyResolverDefaultClass)) + +typedef struct { + GObject parent; + +} SoupProxyResolverDefault; + +typedef struct { + GObjectClass parent_class; + +} SoupProxyResolverDefaultClass; + +GType soup_proxy_resolver_default_get_type (void); +#define SOUP_TYPE_PROXY_RESOLVER_DEFAULT (soup_proxy_resolver_default_get_type ()) + +#endif /*SOUP_PROXY_RESOLVER_DEFAULT_H*/ diff --git a/libsoup/soup.h b/libsoup/soup.h index e7273614..97170a8d 100644 --- a/libsoup/soup.h +++ b/libsoup/soup.h @@ -31,6 +31,7 @@ extern "C" { #include <libsoup/soup-multipart.h> #include <libsoup/soup-password-manager.h> #include <libsoup/soup-proxy-resolver.h> +#include <libsoup/soup-proxy-resolver-default.h> #include <libsoup/soup-proxy-uri-resolver.h> #include <libsoup/soup-server.h> #include <libsoup/soup-session-async.h> |