summaryrefslogtreecommitdiff
path: root/libsoup/soup-proxy-resolver.c
diff options
context:
space:
mode:
authorDan Winship <danw@gnome.org>2009-06-06 18:57:51 -0400
committerDan Winship <danw@gnome.org>2009-06-06 22:58:53 -0400
commite636754a29691d96e89297c2d7c31d829d1de878 (patch)
tree4a32640e9251f4e44521abe6786362dc39a26e34 /libsoup/soup-proxy-resolver.c
parent83da293b3f2038d969e83c4227db817046092d2d (diff)
downloadlibsoup-e636754a29691d96e89297c2d7c31d829d1de878.tar.gz
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
Diffstat (limited to 'libsoup/soup-proxy-resolver.c')
-rw-r--r--libsoup/soup-proxy-resolver.c164
1 files changed, 133 insertions, 31 deletions
diff --git a/libsoup/soup-proxy-resolver.c b/libsoup/soup-proxy-resolver.c
index 630c10c1..33a908c0 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;
+}