Blame libsoup/soup-proxy-resolver-default.c

rpm-build 4f3c61
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
rpm-build 4f3c61
/*
rpm-build 4f3c61
 * soup-proxy-resolver-default.c: proxy resolution based on GIO's GProxyResolver
rpm-build 4f3c61
 *
rpm-build 4f3c61
 * Copyright (C) 2011 Collabora Ltd.
rpm-build 4f3c61
 */
rpm-build 4f3c61
rpm-build 4f3c61
#ifdef HAVE_CONFIG_H
rpm-build 4f3c61
#include <config.h>
rpm-build 4f3c61
#endif
rpm-build 4f3c61
rpm-build 4f3c61
#undef SOUP_VERSION_MIN_REQUIRED
rpm-build 4f3c61
#define SOUP_VERSION_MIN_REQUIRED SOUP_VERSION_2_42
rpm-build 4f3c61
rpm-build 4f3c61
#include "soup-proxy-resolver-default.h"
rpm-build 4f3c61
#include "soup.h"
rpm-build 4f3c61
rpm-build 4f3c61
/**
rpm-build 4f3c61
 * SECTION:soup-proxy-resolver-default
rpm-build 4f3c61
 * @short_description: System proxy configuration integration
rpm-build 4f3c61
 *
rpm-build 4f3c61
 * #SoupProxyResolverDefault is a <type>SoupProxyURIResolver</type>
rpm-build 4f3c61
 * implementation that uses the default gio #GProxyResolver to resolve
rpm-build 4f3c61
 * proxies.
rpm-build 4f3c61
 *
rpm-build 4f3c61
 * In libsoup 2.44 and later, you can set the session's
rpm-build 4f3c61
 * #SoupSession:proxy-resolver property to the resolver returned by
rpm-build 4f3c61
 * g_proxy_resolver_get_default() to get the same effect. Note that
rpm-build 4f3c61
 * for "plain" #SoupSessions (ie, not #SoupSessionAsync or
rpm-build 4f3c61
 * #SoupSessionSync), this is done for you automatically.
rpm-build 4f3c61
 *
rpm-build 4f3c61
 * Since: 2.34
rpm-build 4f3c61
 *
rpm-build 4f3c61
 * Deprecated: Use #SoupSession:proxy-resolver
rpm-build 4f3c61
 */
rpm-build 4f3c61
rpm-build 4f3c61
enum {
rpm-build 4f3c61
	PROP_0,
rpm-build 4f3c61
	PROP_GPROXY_RESOLVER
rpm-build 4f3c61
};
rpm-build 4f3c61
rpm-build 4f3c61
typedef struct {
rpm-build 4f3c61
	GProxyResolver *gproxy_resolver;
rpm-build 4f3c61
} SoupProxyResolverDefaultPrivate;
rpm-build 4f3c61
rpm-build 4f3c61
static void soup_proxy_resolver_default_interface_init (SoupProxyURIResolverInterface *proxy_resolver_interface);
rpm-build 4f3c61
rpm-build 4f3c61
G_DEFINE_TYPE_EXTENDED (SoupProxyResolverDefault, soup_proxy_resolver_default, G_TYPE_OBJECT, 0,
rpm-build 4f3c61
                        G_ADD_PRIVATE (SoupProxyResolverDefault)
rpm-build 4f3c61
			G_IMPLEMENT_INTERFACE (SOUP_TYPE_SESSION_FEATURE, NULL)
rpm-build 4f3c61
			G_IMPLEMENT_INTERFACE (SOUP_TYPE_PROXY_URI_RESOLVER, soup_proxy_resolver_default_interface_init))
rpm-build 4f3c61
rpm-build 4f3c61
static void
rpm-build 4f3c61
soup_proxy_resolver_default_init (SoupProxyResolverDefault *resolver)
rpm-build 4f3c61
{
rpm-build 4f3c61
}
rpm-build 4f3c61
rpm-build 4f3c61
static void
rpm-build 4f3c61
soup_proxy_resolver_default_set_property (GObject *object, guint prop_id,
rpm-build 4f3c61
					  const GValue *value, GParamSpec *pspec)
rpm-build 4f3c61
{
rpm-build 4f3c61
	SoupProxyResolverDefault *resolver = SOUP_PROXY_RESOLVER_DEFAULT (object);
rpm-build 4f3c61
	SoupProxyResolverDefaultPrivate *priv = soup_proxy_resolver_default_get_instance_private (resolver);
rpm-build 4f3c61
rpm-build 4f3c61
	switch (prop_id) {
rpm-build 4f3c61
	case PROP_GPROXY_RESOLVER:
rpm-build 4f3c61
		if (priv->gproxy_resolver)
rpm-build 4f3c61
			g_object_unref (priv->gproxy_resolver);
rpm-build 4f3c61
		priv->gproxy_resolver = g_value_dup_object (value);
rpm-build 4f3c61
		break;
rpm-build 4f3c61
	default:
rpm-build 4f3c61
		G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
rpm-build 4f3c61
		break;
rpm-build 4f3c61
	}
rpm-build 4f3c61
}
rpm-build 4f3c61
rpm-build 4f3c61
static void
rpm-build 4f3c61
soup_proxy_resolver_default_constructed (GObject *object)
rpm-build 4f3c61
{
rpm-build 4f3c61
	SoupProxyResolverDefault *resolver = SOUP_PROXY_RESOLVER_DEFAULT (object);
rpm-build 4f3c61
	SoupProxyResolverDefaultPrivate *priv = soup_proxy_resolver_default_get_instance_private (resolver);
rpm-build 4f3c61
rpm-build 4f3c61
	if (!priv->gproxy_resolver) {
rpm-build 4f3c61
		priv->gproxy_resolver = g_proxy_resolver_get_default ();
rpm-build 4f3c61
		g_object_ref (priv->gproxy_resolver);
rpm-build 4f3c61
	}
rpm-build 4f3c61
rpm-build 4f3c61
	G_OBJECT_CLASS (soup_proxy_resolver_default_parent_class)->constructed (object);
rpm-build 4f3c61
}
rpm-build 4f3c61
rpm-build 4f3c61
static void
rpm-build 4f3c61
soup_proxy_resolver_default_finalize (GObject *object)
rpm-build 4f3c61
{
rpm-build 4f3c61
	SoupProxyResolverDefault *resolver = SOUP_PROXY_RESOLVER_DEFAULT (object);
rpm-build 4f3c61
	SoupProxyResolverDefaultPrivate *priv = soup_proxy_resolver_default_get_instance_private (resolver);
rpm-build 4f3c61
rpm-build 4f3c61
	g_clear_object (&priv->gproxy_resolver);
rpm-build 4f3c61
rpm-build 4f3c61
	G_OBJECT_CLASS (soup_proxy_resolver_default_parent_class)->finalize (object);
rpm-build 4f3c61
}
rpm-build 4f3c61
rpm-build 4f3c61
static void
rpm-build 4f3c61
soup_proxy_resolver_default_class_init (SoupProxyResolverDefaultClass *klass)
rpm-build 4f3c61
{
rpm-build 4f3c61
	GObjectClass *object_class = G_OBJECT_CLASS (klass);
rpm-build 4f3c61
rpm-build 4f3c61
	object_class->set_property = soup_proxy_resolver_default_set_property;
rpm-build 4f3c61
	object_class->constructed = soup_proxy_resolver_default_constructed;
rpm-build 4f3c61
	object_class->finalize = soup_proxy_resolver_default_finalize;
rpm-build 4f3c61
rpm-build 4f3c61
	g_object_class_install_property (
rpm-build 4f3c61
		object_class, PROP_GPROXY_RESOLVER,
rpm-build 4f3c61
		g_param_spec_object ("gproxy-resolver",
rpm-build 4f3c61
				     "GProxyResolver",
rpm-build 4f3c61
				     "The underlying GProxyResolver",
rpm-build 4f3c61
				     G_TYPE_PROXY_RESOLVER,
rpm-build 4f3c61
				     G_PARAM_WRITABLE));
rpm-build 4f3c61
}
rpm-build 4f3c61
rpm-build 4f3c61
typedef struct {
rpm-build 4f3c61
	SoupProxyURIResolver *resolver;
rpm-build 4f3c61
	GCancellable *cancellable;
rpm-build 4f3c61
	SoupProxyURIResolverCallback callback;
rpm-build 4f3c61
	gpointer user_data;
rpm-build 4f3c61
} SoupAsyncData;
rpm-build 4f3c61
rpm-build 4f3c61
static void
rpm-build 4f3c61
resolved_proxy (GObject *object, GAsyncResult *result, gpointer data)
rpm-build 4f3c61
{
rpm-build 4f3c61
	GProxyResolver *proxy_resolver = G_PROXY_RESOLVER (object);
rpm-build 4f3c61
	SoupAsyncData *async_data = data;
rpm-build 4f3c61
	GError *error = NULL;
rpm-build 4f3c61
	char **proxy_uris = NULL;
rpm-build 4f3c61
	SoupURI *proxy_uri = NULL;
rpm-build 4f3c61
	guint status = SOUP_STATUS_OK;
rpm-build 4f3c61
rpm-build 4f3c61
	proxy_uris = g_proxy_resolver_lookup_finish (proxy_resolver,
rpm-build 4f3c61
						     result,
rpm-build 4f3c61
						     &error);
rpm-build 4f3c61
rpm-build 4f3c61
	if (error || proxy_uris == NULL || proxy_uris[0] == NULL) {
rpm-build 4f3c61
		status = SOUP_STATUS_CANT_RESOLVE_PROXY;
rpm-build 4f3c61
		goto finish;
rpm-build 4f3c61
	}
rpm-build 4f3c61
rpm-build 4f3c61
	/* We need to handle direct:// specially, otherwise
rpm-build 4f3c61
	 * SoupSession will try to resolve it as the proxy address.
rpm-build 4f3c61
	 */
rpm-build 4f3c61
	if (!g_strcmp0 (proxy_uris[0], "direct://"))
rpm-build 4f3c61
		goto finish;
rpm-build 4f3c61
rpm-build 4f3c61
	proxy_uri = soup_uri_new (proxy_uris[0]);
rpm-build 4f3c61
	if (proxy_uri == NULL)
rpm-build 4f3c61
		status = SOUP_STATUS_CANT_RESOLVE_PROXY;
rpm-build 4f3c61
rpm-build 4f3c61
finish:
rpm-build 4f3c61
	async_data->callback (async_data->resolver,
rpm-build 4f3c61
			      status,
rpm-build 4f3c61
			      proxy_uri,
rpm-build 4f3c61
			      async_data->user_data);
rpm-build 4f3c61
rpm-build 4f3c61
	if (async_data->cancellable)
rpm-build 4f3c61
		g_object_unref (async_data->cancellable);
rpm-build 4f3c61
rpm-build 4f3c61
	g_strfreev (proxy_uris);
rpm-build 4f3c61
rpm-build 4f3c61
	if (proxy_uri)
rpm-build 4f3c61
		soup_uri_free (proxy_uri);
rpm-build 4f3c61
rpm-build 4f3c61
	g_object_unref (async_data->resolver);
rpm-build 4f3c61
	g_slice_free (SoupAsyncData, async_data);
rpm-build 4f3c61
}
rpm-build 4f3c61
rpm-build 4f3c61
static void
rpm-build 4f3c61
get_proxy_uri_async (SoupProxyURIResolver  *resolver,
rpm-build 4f3c61
		     SoupURI		   *uri,
rpm-build 4f3c61
		     GMainContext	   *async_context,
rpm-build 4f3c61
		     GCancellable	   *cancellable,
rpm-build 4f3c61
		     SoupProxyURIResolverCallback callback,
rpm-build 4f3c61
		     gpointer		    user_data)
rpm-build 4f3c61
{
rpm-build 4f3c61
	SoupProxyResolverDefault *resolver_default = SOUP_PROXY_RESOLVER_DEFAULT (resolver);
rpm-build 4f3c61
	SoupProxyResolverDefaultPrivate *priv = soup_proxy_resolver_default_get_instance_private (resolver_default);
rpm-build 4f3c61
	SoupAsyncData *async_data;
rpm-build 4f3c61
	char *uri_string;
rpm-build 4f3c61
rpm-build 4f3c61
	async_data = g_slice_new0 (SoupAsyncData);
rpm-build 4f3c61
	async_data->resolver = (SoupProxyURIResolver*) g_object_ref (resolver);
rpm-build 4f3c61
	async_data->cancellable = cancellable;
rpm-build 4f3c61
	async_data->callback = callback;
rpm-build 4f3c61
	async_data->user_data = user_data;
rpm-build 4f3c61
rpm-build 4f3c61
	uri_string = soup_uri_to_string (uri, FALSE);
rpm-build 4f3c61
rpm-build 4f3c61
	if (async_context)
rpm-build 4f3c61
		g_main_context_push_thread_default (async_context);
rpm-build 4f3c61
rpm-build 4f3c61
	g_proxy_resolver_lookup_async (priv->gproxy_resolver,
rpm-build 4f3c61
				       uri_string,
rpm-build 4f3c61
				       cancellable ? g_object_ref (cancellable) : NULL,
rpm-build 4f3c61
				       resolved_proxy,
rpm-build 4f3c61
				       async_data);
rpm-build 4f3c61
rpm-build 4f3c61
	if (async_context)
rpm-build 4f3c61
		g_main_context_pop_thread_default (async_context);
rpm-build 4f3c61
rpm-build 4f3c61
	g_free (uri_string);
rpm-build 4f3c61
}
rpm-build 4f3c61
rpm-build 4f3c61
static guint
rpm-build 4f3c61
get_proxy_uri_sync (SoupProxyURIResolver  *resolver,
rpm-build 4f3c61
		    SoupURI		  *uri,
rpm-build 4f3c61
		    GCancellable	  *cancellable,
rpm-build 4f3c61
		    SoupURI		 **proxy_uri)
rpm-build 4f3c61
{
rpm-build 4f3c61
	SoupProxyResolverDefault *resolver_default = SOUP_PROXY_RESOLVER_DEFAULT (resolver);
rpm-build 4f3c61
	SoupProxyResolverDefaultPrivate *priv = soup_proxy_resolver_default_get_instance_private (resolver_default);
rpm-build 4f3c61
	GError *error = NULL;
rpm-build 4f3c61
	char** proxy_uris = NULL;
rpm-build 4f3c61
	char *uri_string;
rpm-build 4f3c61
	guint status = SOUP_STATUS_OK;
rpm-build 4f3c61
rpm-build 4f3c61
	uri_string = soup_uri_to_string (uri, FALSE);
rpm-build 4f3c61
rpm-build 4f3c61
	proxy_uris = g_proxy_resolver_lookup (priv->gproxy_resolver,
rpm-build 4f3c61
					      uri_string,
rpm-build 4f3c61
					      cancellable,
rpm-build 4f3c61
					      &error);
rpm-build 4f3c61
rpm-build 4f3c61
	g_free (uri_string);
rpm-build 4f3c61
rpm-build 4f3c61
	if (error || proxy_uris == NULL || proxy_uris[0] == NULL) {
rpm-build 4f3c61
		status = SOUP_STATUS_CANT_RESOLVE_PROXY;
rpm-build 4f3c61
		goto cleanup;
rpm-build 4f3c61
	}
rpm-build 4f3c61
rpm-build 4f3c61
	/* We need to handle direct:// specially, otherwise
rpm-build 4f3c61
	 * SoupSession will try to resolve it as the proxy address.
rpm-build 4f3c61
	 */
rpm-build 4f3c61
	if (!g_strcmp0 (proxy_uris[0], "direct://"))
rpm-build 4f3c61
		goto cleanup;
rpm-build 4f3c61
rpm-build 4f3c61
	*proxy_uri = soup_uri_new (proxy_uris[0]);
rpm-build 4f3c61
rpm-build 4f3c61
	if (!*proxy_uri)
rpm-build 4f3c61
		status = SOUP_STATUS_CANT_RESOLVE_PROXY;
rpm-build 4f3c61
rpm-build 4f3c61
cleanup:
rpm-build 4f3c61
	g_strfreev (proxy_uris);
rpm-build 4f3c61
	if (error)
rpm-build 4f3c61
		g_clear_error (&error);
rpm-build 4f3c61
	return status;
rpm-build 4f3c61
}
rpm-build 4f3c61
rpm-build 4f3c61
static void
rpm-build 4f3c61
soup_proxy_resolver_default_interface_init (SoupProxyURIResolverInterface *iface)
rpm-build 4f3c61
{
rpm-build 4f3c61
	iface->get_proxy_uri_async = get_proxy_uri_async;
rpm-build 4f3c61
	iface->get_proxy_uri_sync = get_proxy_uri_sync;
rpm-build 4f3c61
}