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.
12 #undef SOUP_VERSION_MIN_REQUIRED
13 #define SOUP_VERSION_MIN_REQUIRED SOUP_VERSION_2_42
15 #include "soup-proxy-resolver-default.h"
19 * SECTION:soup-proxy-resolver-default
20 * @short_description: System proxy configuration integration
22 * #SoupProxyResolverDefault is a <type>SoupProxyURIResolver</type>
23 * implementation that uses the default gio #GProxyResolver to resolve
26 * In libsoup 2.44 and later, you can set the session's
27 * #SoupSession:proxy-resolver property to the resolver returned by
28 * g_proxy_resolver_get_default() to get the same effect. Note that
29 * for "plain" #SoupSessions (ie, not #SoupSessionAsync or
30 * #SoupSessionSync), this is done for you automatically.
34 * Deprecated: Use #SoupSession:proxy-resolver
37 static void soup_proxy_resolver_default_interface_init (SoupProxyURIResolverInterface *proxy_resolver_interface);
39 G_DEFINE_TYPE_EXTENDED (SoupProxyResolverDefault, soup_proxy_resolver_default, G_TYPE_OBJECT, 0,
40 G_IMPLEMENT_INTERFACE (SOUP_TYPE_SESSION_FEATURE, NULL)
41 G_IMPLEMENT_INTERFACE (SOUP_TYPE_PROXY_URI_RESOLVER, soup_proxy_resolver_default_interface_init))
49 GProxyResolver *gproxy_resolver;
50 } SoupProxyResolverDefaultPrivate;
51 #define SOUP_PROXY_RESOLVER_DEFAULT_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SOUP_TYPE_PROXY_RESOLVER_DEFAULT, SoupProxyResolverDefaultPrivate))
54 soup_proxy_resolver_default_init (SoupProxyResolverDefault *resolver)
59 soup_proxy_resolver_default_set_property (GObject *object, guint prop_id,
60 const GValue *value, GParamSpec *pspec)
62 SoupProxyResolverDefaultPrivate *priv = SOUP_PROXY_RESOLVER_DEFAULT_GET_PRIVATE (object);
65 case PROP_GPROXY_RESOLVER:
66 if (priv->gproxy_resolver)
67 g_object_unref (priv->gproxy_resolver);
68 priv->gproxy_resolver = g_value_dup_object (value);
71 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
77 soup_proxy_resolver_default_constructed (GObject *object)
79 SoupProxyResolverDefaultPrivate *priv = SOUP_PROXY_RESOLVER_DEFAULT_GET_PRIVATE (object);
81 if (!priv->gproxy_resolver) {
82 priv->gproxy_resolver = g_proxy_resolver_get_default ();
83 g_object_ref (priv->gproxy_resolver);
86 G_OBJECT_CLASS (soup_proxy_resolver_default_parent_class)->constructed (object);
90 soup_proxy_resolver_default_finalize (GObject *object)
92 SoupProxyResolverDefaultPrivate *priv = SOUP_PROXY_RESOLVER_DEFAULT_GET_PRIVATE (object);
94 g_clear_object (&priv->gproxy_resolver);
96 G_OBJECT_CLASS (soup_proxy_resolver_default_parent_class)->finalize (object);
100 soup_proxy_resolver_default_class_init (SoupProxyResolverDefaultClass *klass)
102 GObjectClass *object_class = G_OBJECT_CLASS (klass);
104 g_type_class_add_private (klass, sizeof (SoupProxyResolverDefaultPrivate));
106 object_class->set_property = soup_proxy_resolver_default_set_property;
107 object_class->constructed = soup_proxy_resolver_default_constructed;
108 object_class->finalize = soup_proxy_resolver_default_finalize;
110 g_object_class_install_property (
111 object_class, PROP_GPROXY_RESOLVER,
112 g_param_spec_object ("gproxy-resolver",
114 "The underlying GProxyResolver",
115 G_TYPE_PROXY_RESOLVER,
120 SoupProxyURIResolver *resolver;
121 GCancellable *cancellable;
122 SoupProxyURIResolverCallback callback;
127 resolved_proxy (GObject *object, GAsyncResult *result, gpointer data)
129 GProxyResolver *proxy_resolver = G_PROXY_RESOLVER (object);
130 SoupAsyncData *async_data = data;
131 GError *error = NULL;
132 char **proxy_uris = NULL;
133 SoupURI *proxy_uri = NULL;
134 guint status = SOUP_STATUS_OK;
136 proxy_uris = g_proxy_resolver_lookup_finish (proxy_resolver,
140 if (error || proxy_uris == NULL || proxy_uris[0] == NULL) {
141 status = SOUP_STATUS_CANT_RESOLVE_PROXY;
145 /* We need to handle direct:// specially, otherwise
146 * SoupSession will try to resolve it as the proxy address.
148 if (!g_strcmp0 (proxy_uris[0], "direct://"))
151 proxy_uri = soup_uri_new (proxy_uris[0]);
152 if (proxy_uri == NULL)
153 status = SOUP_STATUS_CANT_RESOLVE_PROXY;
156 async_data->callback (async_data->resolver,
159 async_data->user_data);
161 if (async_data->cancellable)
162 g_object_unref (async_data->cancellable);
164 g_strfreev (proxy_uris);
167 soup_uri_free (proxy_uri);
169 g_object_unref (async_data->resolver);
170 g_slice_free (SoupAsyncData, async_data);
174 get_proxy_uri_async (SoupProxyURIResolver *resolver,
176 GMainContext *async_context,
177 GCancellable *cancellable,
178 SoupProxyURIResolverCallback callback,
181 SoupProxyResolverDefaultPrivate *priv = SOUP_PROXY_RESOLVER_DEFAULT_GET_PRIVATE (resolver);
182 SoupAsyncData *async_data;
185 async_data = g_slice_new0 (SoupAsyncData);
186 async_data->resolver = (SoupProxyURIResolver*) g_object_ref (resolver);
187 async_data->cancellable = cancellable;
188 async_data->callback = callback;
189 async_data->user_data = user_data;
191 uri_string = soup_uri_to_string (uri, FALSE);
194 g_main_context_push_thread_default (async_context);
196 g_proxy_resolver_lookup_async (priv->gproxy_resolver,
198 cancellable ? g_object_ref (cancellable) : NULL,
203 g_main_context_pop_thread_default (async_context);
209 get_proxy_uri_sync (SoupProxyURIResolver *resolver,
211 GCancellable *cancellable,
214 SoupProxyResolverDefaultPrivate *priv = SOUP_PROXY_RESOLVER_DEFAULT_GET_PRIVATE (resolver);
215 GError *error = NULL;
216 char** proxy_uris = NULL;
218 guint status = SOUP_STATUS_OK;
220 uri_string = soup_uri_to_string (uri, FALSE);
222 proxy_uris = g_proxy_resolver_lookup (priv->gproxy_resolver,
229 if (error || proxy_uris == NULL || proxy_uris[0] == NULL) {
230 status = SOUP_STATUS_CANT_RESOLVE_PROXY;
234 /* We need to handle direct:// specially, otherwise
235 * SoupSession will try to resolve it as the proxy address.
237 if (!g_strcmp0 (proxy_uris[0], "direct://"))
240 *proxy_uri = soup_uri_new (proxy_uris[0]);
243 status = SOUP_STATUS_CANT_RESOLVE_PROXY;
246 g_strfreev (proxy_uris);
248 g_clear_error (&error);
253 soup_proxy_resolver_default_interface_init (SoupProxyURIResolverInterface *iface)
255 iface->get_proxy_uri_async = get_proxy_uri_async;
256 iface->get_proxy_uri_sync = get_proxy_uri_sync;