1 /* -*- Mode: C; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
3 * GIO - GLib Input, Output and Streaming Library
5 * Copyright 2010 Collabora, Ltd.
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General
18 * Public License along with this library; if not, see
19 * <http://www.gnu.org/licenses/>.
21 * Author: Nicolas Dufresne <nicolas.dufresne@collabora.co.uk>
30 #include "glibproxyresolver.h"
33 #include <glib/gi18n-lib.h>
35 struct _GLibproxyResolver {
36 GObject parent_instance;
37 pxProxyFactory *factory;
40 static void g_libproxy_resolver_iface_init (GProxyResolverInterface *iface);
42 #ifdef GLIBPROXY_MODULE
44 g_libproxy_resolver_class_finalize (GLibproxyResolverClass *klass)
48 G_DEFINE_DYNAMIC_TYPE_EXTENDED (GLibproxyResolver,
51 G_IMPLEMENT_INTERFACE_DYNAMIC (G_TYPE_PROXY_RESOLVER,
52 g_libproxy_resolver_iface_init))
54 G_DEFINE_TYPE_EXTENDED (GLibproxyResolver,
57 G_IMPLEMENT_INTERFACE (G_TYPE_PROXY_RESOLVER,
58 g_libproxy_resolver_iface_init))
62 g_libproxy_resolver_finalize (GObject *object)
64 GLibproxyResolver *resolver = G_LIBPROXY_RESOLVER (object);
66 if (resolver->factory)
68 px_proxy_factory_free (resolver->factory);
69 resolver->factory = NULL;
73 G_OBJECT_CLASS (g_libproxy_resolver_parent_class)->finalize (object);
77 is_running_environment_proxy_test (void)
79 return g_strcmp0 (g_getenv ("GIO_PROXY_TEST_NAME"), "environment") == 0;
83 g_libproxy_resolver_init (GLibproxyResolver *resolver)
85 if (!is_running_environment_proxy_test ())
86 resolver->factory = px_proxy_factory_new ();
90 g_libproxy_resolver_is_supported (GProxyResolver *object)
92 GLibproxyResolver *resolver = G_LIBPROXY_RESOLVER (object);
93 return resolver->factory != NULL;
97 copy_proxies (gchar **proxies)
102 GError *error = NULL;
104 for (i = 0; proxies[i]; i++)
106 if (!strncmp ("socks://", proxies[i], 8))
112 copy = g_new (gchar *, len + 1);
113 for (i = j = 0; proxies[i]; i++, j++)
115 if (!g_uri_is_valid (proxies[i], G_URI_FLAGS_NONE, &error))
117 g_warning ("Received invalid URI %s from libproxy: %s", proxies[i], error->message);
118 g_clear_error (&error);
123 if (!strncmp ("socks://", proxies[i], 8))
125 copy[j++] = g_strdup_printf ("socks5://%s", proxies[i] + 8);
126 copy[j++] = g_strdup_printf ("socks4a://%s", proxies[i] + 8);
127 copy[j] = g_strdup_printf ("socks4://%s", proxies[i] + 8);
131 copy[j] = g_strdup (proxies[i]);
140 get_libproxy_proxies (GTask *task,
141 gpointer source_object,
143 GCancellable *cancellable)
145 GLibproxyResolver *resolver = source_object;
146 const gchar *uri = task_data;
147 GError *error = NULL;
150 if (g_task_return_error_if_cancelled (task))
153 proxies = px_proxy_factory_get_proxies (resolver->factory, uri);
156 /* We always copy to be able to translate "socks" entry into
157 * three entries ("socks5", "socks4a", "socks4").
159 g_task_return_pointer (task, copy_proxies (proxies), (GDestroyNotify) g_strfreev);
160 px_proxy_factory_free_proxies (proxies);
164 g_set_error_literal (&error, G_IO_ERROR, G_IO_ERROR_FAILED,
165 _("Proxy resolver internal error."));
166 g_task_return_error (task, error);
171 g_libproxy_resolver_lookup (GProxyResolver *iresolver,
173 GCancellable *cancellable,
176 GLibproxyResolver *resolver = G_LIBPROXY_RESOLVER (iresolver);
180 task = g_task_new (resolver, cancellable, NULL, NULL);
181 g_task_set_name (task, "[glib-networking] g_libproxy_resolver_lookup");
182 g_task_set_task_data (task, g_strdup (uri), g_free);
183 g_task_set_return_on_cancel (task, TRUE);
185 g_task_run_in_thread_sync (task, get_libproxy_proxies);
186 proxies = g_task_propagate_pointer (task, error);
187 g_object_unref (task);
193 g_libproxy_resolver_lookup_async (GProxyResolver *resolver,
195 GCancellable *cancellable,
196 GAsyncReadyCallback callback,
201 task = g_task_new (resolver, cancellable, callback, user_data);
202 g_task_set_source_tag (task, g_libproxy_resolver_lookup_async);
203 g_task_set_name (task, "[glib-networking] g_libproxy_resolver_lookup_async");
204 g_task_set_task_data (task, g_strdup (uri), g_free);
205 g_task_set_return_on_cancel (task, TRUE);
206 g_task_run_in_thread (task, get_libproxy_proxies);
207 g_object_unref (task);
211 g_libproxy_resolver_lookup_finish (GProxyResolver *resolver,
212 GAsyncResult *result,
215 g_return_val_if_fail (g_task_is_valid (result, resolver), NULL);
216 g_return_val_if_fail (g_task_get_source_tag (G_TASK (result)) == g_libproxy_resolver_lookup_async, NULL);
218 return g_task_propagate_pointer (G_TASK (result), error);
222 g_libproxy_resolver_class_init (GLibproxyResolverClass *resolver_class)
224 GObjectClass *object_class;
226 object_class = G_OBJECT_CLASS (resolver_class);
227 object_class->finalize = g_libproxy_resolver_finalize;
231 g_libproxy_resolver_iface_init (GProxyResolverInterface *iface)
233 iface->is_supported = g_libproxy_resolver_is_supported;
234 iface->lookup = g_libproxy_resolver_lookup;
235 iface->lookup_async = g_libproxy_resolver_lookup_async;
236 iface->lookup_finish = g_libproxy_resolver_lookup_finish;
239 #ifdef GLIBPROXY_MODULE
241 g_libproxy_resolver_register (GIOModule *module)
243 g_libproxy_resolver_register_type (G_TYPE_MODULE (module));
245 g_io_extension_point_register (G_PROXY_RESOLVER_EXTENSION_POINT_NAME);
246 g_io_extension_point_implement (G_PROXY_RESOLVER_EXTENSION_POINT_NAME,
247 g_libproxy_resolver_get_type(),