1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
3 * soup-proxy-resolver-default.c: proxy resolution based on GIO's GProxyResolver
5 * Copyright (C) 2011 Collabora Ltd.
15 #include "soup-proxy-resolver-default.h"
16 #include "soup-proxy-uri-resolver.h"
17 #include "soup-session-feature.h"
21 * SoupProxyResolverDefault:
23 * A #SoupProxyURIResolver implementation that uses the default gio
24 * #GProxyResolver to resolve proxies.
29 static void soup_proxy_resolver_default_interface_init (SoupProxyURIResolverInterface *proxy_resolver_interface);
31 G_DEFINE_TYPE_EXTENDED (SoupProxyResolverDefault, soup_proxy_resolver_default, G_TYPE_OBJECT, 0,
32 G_IMPLEMENT_INTERFACE (SOUP_TYPE_SESSION_FEATURE, NULL)
33 G_IMPLEMENT_INTERFACE (SOUP_TYPE_PROXY_URI_RESOLVER, soup_proxy_resolver_default_interface_init))
41 GProxyResolver *gproxy_resolver;
42 } SoupProxyResolverDefaultPrivate;
43 #define SOUP_PROXY_RESOLVER_DEFAULT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SOUP_TYPE_PROXY_RESOLVER_DEFAULT, SoupProxyResolverDefaultPrivate))
46 soup_proxy_resolver_default_init (SoupProxyResolverDefault *resolver)
51 soup_proxy_resolver_default_set_property (GObject *object, guint prop_id,
52 const GValue *value, GParamSpec *pspec)
54 SoupProxyResolverDefaultPrivate *priv = SOUP_PROXY_RESOLVER_DEFAULT_GET_PRIVATE (object);
57 case PROP_GPROXY_RESOLVER:
58 if (priv->gproxy_resolver)
59 g_object_unref (priv->gproxy_resolver);
60 priv->gproxy_resolver = g_value_dup_object (value);
63 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
69 soup_proxy_resolver_default_constructed (GObject *object)
71 SoupProxyResolverDefaultPrivate *priv = SOUP_PROXY_RESOLVER_DEFAULT_GET_PRIVATE (object);
73 if (!priv->gproxy_resolver) {
74 priv->gproxy_resolver = g_proxy_resolver_get_default ();
75 g_object_ref (priv->gproxy_resolver);
78 G_OBJECT_CLASS (soup_proxy_resolver_default_parent_class)->constructed (object);
82 soup_proxy_resolver_default_finalize (GObject *object)
84 SoupProxyResolverDefaultPrivate *priv = SOUP_PROXY_RESOLVER_DEFAULT_GET_PRIVATE (object);
86 if (priv->gproxy_resolver)
87 g_object_unref (priv->gproxy_resolver);
89 G_OBJECT_CLASS (soup_proxy_resolver_default_parent_class)->finalize (object);
93 soup_proxy_resolver_default_class_init (SoupProxyResolverDefaultClass *klass)
95 GObjectClass *object_class = G_OBJECT_CLASS (klass);
97 g_type_class_add_private (klass, sizeof (SoupProxyResolverDefaultPrivate));
99 object_class->set_property = soup_proxy_resolver_default_set_property;
100 object_class->constructed = soup_proxy_resolver_default_constructed;
101 object_class->finalize = soup_proxy_resolver_default_finalize;
103 g_object_class_install_property (
104 object_class, PROP_GPROXY_RESOLVER,
105 g_param_spec_object ("gproxy-resolver",
107 "The underlying GProxyResolver",
108 G_TYPE_PROXY_RESOLVER,
113 SoupProxyURIResolver *resolver;
114 GCancellable *cancellable;
115 SoupProxyURIResolverCallback callback;
120 resolved_proxy (GObject *object, GAsyncResult *result, gpointer data)
122 GProxyResolver *proxy_resolver = G_PROXY_RESOLVER (object);
123 SoupAsyncData *async_data = data;
124 GError *error = NULL;
125 char **proxy_uris = NULL;
126 SoupURI *proxy_uri = NULL;
127 guint status = SOUP_STATUS_OK;
129 proxy_uris = g_proxy_resolver_lookup_finish (proxy_resolver,
133 if (error || proxy_uris == NULL || proxy_uris[0] == NULL) {
134 status = SOUP_STATUS_CANT_RESOLVE_PROXY;
138 /* We need to handle direct:// specially, otherwise
139 * SoupSession will try to resolve it as the proxy address.
141 if (!g_strcmp0 (proxy_uris[0], "direct://"))
144 proxy_uri = soup_uri_new (proxy_uris[0]);
145 if (proxy_uri == NULL)
146 status = SOUP_STATUS_CANT_RESOLVE_PROXY;
149 async_data->callback (async_data->resolver,
152 async_data->user_data);
154 if (async_data->cancellable)
155 g_object_unref (async_data->cancellable);
157 g_strfreev (proxy_uris);
160 soup_uri_free (proxy_uri);
162 g_object_unref (async_data->resolver);
163 g_slice_free (SoupAsyncData, async_data);
167 get_proxy_uri_async (SoupProxyURIResolver *resolver,
169 GMainContext *async_context,
170 GCancellable *cancellable,
171 SoupProxyURIResolverCallback callback,
174 SoupProxyResolverDefaultPrivate *priv = SOUP_PROXY_RESOLVER_DEFAULT_GET_PRIVATE (resolver);
175 SoupAsyncData *async_data;
178 async_data = g_slice_new0 (SoupAsyncData);
179 async_data->resolver = (SoupProxyURIResolver*) g_object_ref (resolver);
180 async_data->cancellable = cancellable;
181 async_data->callback = callback;
182 async_data->user_data = user_data;
184 uri_string = soup_uri_to_string (uri, FALSE);
187 g_main_context_push_thread_default (async_context);
189 g_proxy_resolver_lookup_async (priv->gproxy_resolver,
191 cancellable ? g_object_ref (cancellable) : NULL,
196 g_main_context_pop_thread_default (async_context);
202 get_proxy_uri_sync (SoupProxyURIResolver *resolver,
204 GCancellable *cancellable,
207 SoupProxyResolverDefaultPrivate *priv = SOUP_PROXY_RESOLVER_DEFAULT_GET_PRIVATE (resolver);
208 GError *error = NULL;
209 char** proxy_uris = NULL;
211 guint status = SOUP_STATUS_OK;
213 uri_string = soup_uri_to_string (uri, FALSE);
215 proxy_uris = g_proxy_resolver_lookup (priv->gproxy_resolver,
222 if (error || proxy_uris == NULL || proxy_uris[0] == NULL) {
223 status = SOUP_STATUS_CANT_RESOLVE_PROXY;
227 /* We need to handle direct:// specially, otherwise
228 * SoupSession will try to resolve it as the proxy address.
230 if (!g_strcmp0 (proxy_uris[0], "direct://"))
233 *proxy_uri = soup_uri_new (proxy_uris[0]);
236 status = SOUP_STATUS_CANT_RESOLVE_PROXY;
239 g_strfreev (proxy_uris);
241 g_clear_error (&error);
246 soup_proxy_resolver_default_interface_init (SoupProxyURIResolverInterface *iface)
248 iface->get_proxy_uri_async = get_proxy_uri_async;
249 iface->get_proxy_uri_sync = get_proxy_uri_sync;