gio: GCancellable can be used concurrently
[platform/upstream/glib.git] / gio / gproxyresolver.c
1 /* GIO - GLib Input, Output and Streaming Library
2  *
3  * Copyright (C) 2010 Collabora, Ltd.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General
16  * Public License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18  * Boston, MA 02111-1307, USA.
19  *
20  * Author: Nicolas Dufresne <nicolas.dufresne@collabora.co.uk>
21  */
22
23 #include "config.h"
24
25 #include "gproxyresolver.h"
26
27 #include <glib.h>
28 #include "glibintl.h"
29
30 #include "gasyncresult.h"
31 #include "gcancellable.h"
32 #include "giomodule.h"
33 #include "giomodule-priv.h"
34 #include "gsimpleasyncresult.h"
35
36 /**
37  * SECTION:gproxyresolver
38  * @short_description: Asynchronous and cancellable network proxy resolver
39  * @include: gio/gio.h
40  *
41  * #GProxyResolver provides synchronous and asynchronous network proxy
42  * resolution. #GProxyResolver is used within #GSocketClient through
43  * the method g_socket_connectable_proxy_enumerate().
44  */
45
46 G_DEFINE_INTERFACE (GProxyResolver, g_proxy_resolver, G_TYPE_OBJECT)
47
48 static void
49 g_proxy_resolver_default_init (GProxyResolverInterface *iface)
50 {
51 }
52
53 static gpointer
54 get_default_proxy_resolver (gpointer arg)
55 {
56   const gchar *use_this;
57   GProxyResolver *resolver;
58   GList *l;
59   GIOExtensionPoint *ep;
60   GIOExtension *extension;
61   
62
63   use_this = g_getenv ("GIO_USE_PROXY_RESOLVER");
64   
65   /* Ensure proxy-resolver modules loaded */
66   _g_io_modules_ensure_loaded ();
67
68   ep = g_io_extension_point_lookup (G_PROXY_RESOLVER_EXTENSION_POINT_NAME);
69
70   if (use_this)
71     {
72       extension = g_io_extension_point_get_extension_by_name (ep, use_this);
73       if (extension)
74         {
75            resolver = g_object_new (g_io_extension_get_type (extension), NULL);
76           
77            if (g_proxy_resolver_is_supported (resolver))
78              return resolver;
79           
80           g_object_unref (resolver);
81         }
82     }
83
84   for (l = g_io_extension_point_get_extensions (ep); l != NULL; l = l->next)
85     {
86       extension = l->data;
87
88       resolver = g_object_new (g_io_extension_get_type (extension), NULL);
89
90       if (g_proxy_resolver_is_supported (resolver))
91         return resolver;
92
93       g_object_unref (resolver);
94     }
95   
96   return NULL;
97 }
98
99 /**
100  * g_proxy_resolver_get_default:
101  *
102  * Gets the default #GProxyResolver for the system.
103  *
104  * Return value: (transfer none): the default #GProxyResolver.
105  *
106  * Since: 2.26
107  */
108 GProxyResolver *
109 g_proxy_resolver_get_default (void)
110 {
111   static GOnce once_init = G_ONCE_INIT;
112
113   return g_once (&once_init, get_default_proxy_resolver, NULL);
114 }
115
116 /**
117  * g_proxy_resolver_is_supported:
118  * @resolver: a #GProxyResolver
119  *
120  * Checks if @resolver can be used on this system. (This is used
121  * internally; g_proxy_resolver_get_default() will only return a proxy
122  * resolver that returns %TRUE for this method.)
123  *
124  * Return value: %TRUE if @resolver is supported.
125  *
126  * Since: 2.26
127  */
128 gboolean
129 g_proxy_resolver_is_supported (GProxyResolver *resolver)
130 {
131   GProxyResolverInterface *iface;
132
133   g_return_val_if_fail (G_IS_PROXY_RESOLVER (resolver), FALSE);
134
135   iface = G_PROXY_RESOLVER_GET_IFACE (resolver);
136
137   return (* iface->is_supported) (resolver);
138 }
139
140 /**
141  * g_proxy_resolver_lookup:
142  * @resolver: a #GProxyResolver
143  * @uri: a URI representing the destination to connect to
144  * @cancellable: (allow-none): a #GCancellable, or %NULL
145  * @error: return location for a #GError, or %NULL
146  *
147  * Looks into the system proxy configuration to determine what proxy,
148  * if any, to use to connect to @uri. The returned proxy URIs are of the
149  * form <literal>&lt;protocol&gt;://[user[:password]@]host:port</literal>
150  * or <literal>direct://</literal>, where &lt;protocol&gt; could be
151  * http, rtsp, socks or other proxying protocol.
152  *
153  * If you don't know what network protocol is being used on the
154  * socket, you should use <literal>none</literal> as the URI protocol.
155  * In this case, the resolver might still return a generic proxy type
156  * (such as SOCKS), but would not return protocol-specific proxy types
157  * (such as http).
158  *
159  * <literal>direct://</literal> is used when no proxy is needed.
160  * Direct connection should not be attempted unless it is part of the
161  * returned array of proxies.
162  *
163  * Return value: (transfer full) (array zero-terminated=1): A
164  *               NULL-terminated array of proxy URIs. Must be freed
165  *               with g_strfreev().
166  *
167  * Since: 2.26
168  */
169 gchar **
170 g_proxy_resolver_lookup (GProxyResolver  *resolver,
171                          const gchar     *uri,
172                          GCancellable    *cancellable,
173                          GError         **error)
174 {
175   GProxyResolverInterface *iface;
176
177   g_return_val_if_fail (G_IS_PROXY_RESOLVER (resolver), NULL);
178   g_return_val_if_fail (uri != NULL, NULL);
179
180   iface = G_PROXY_RESOLVER_GET_IFACE (resolver);
181
182   return (* iface->lookup) (resolver, uri, cancellable, error);
183 }
184
185 /**
186  * g_proxy_resolver_lookup_async:
187  * @resolver: a #GProxyResolver
188  * @uri: a URI representing the destination to connect to
189  * @cancellable: (allow-none): a #GCancellable, or %NULL
190  * @callback: (scope async): callback to call after resolution completes
191  * @user_data: (closure): data for @callback
192  *
193  * Asynchronous lookup of proxy. See g_proxy_resolver_lookup() for more
194  * details.
195  *
196  * Since: 2.26
197  */
198 void
199 g_proxy_resolver_lookup_async (GProxyResolver      *resolver,
200                                const gchar         *uri,
201                                GCancellable        *cancellable,
202                                GAsyncReadyCallback  callback,
203                                gpointer             user_data)
204 {
205   GProxyResolverInterface *iface;
206
207   g_return_if_fail (G_IS_PROXY_RESOLVER (resolver));
208   g_return_if_fail (uri != NULL);
209
210   iface = G_PROXY_RESOLVER_GET_IFACE (resolver);
211
212   (* iface->lookup_async) (resolver, uri, cancellable, callback, user_data);
213 }
214
215 /**
216  * g_proxy_resolver_lookup_finish:
217  * @resolver: a #GProxyResolver
218  * @result: the result passed to your #GAsyncReadyCallback
219  * @error: return location for a #GError, or %NULL
220  *
221  * Call this function to obtain the array of proxy URIs when
222  * g_proxy_resolver_lookup_async() is complete. See
223  * g_proxy_resolver_lookup() for more details.
224  *
225  * Return value: (transfer full) (array zero-terminated=1): A
226  *               NULL-terminated array of proxy URIs. Must be freed
227  *               with g_strfreev().
228  *
229  * Since: 2.26
230  */
231 gchar **
232 g_proxy_resolver_lookup_finish (GProxyResolver     *resolver,
233                                 GAsyncResult       *result,
234                                 GError            **error)
235 {
236   GProxyResolverInterface *iface;
237
238   g_return_val_if_fail (G_IS_PROXY_RESOLVER (resolver), NULL);
239
240   iface = G_PROXY_RESOLVER_GET_IFACE (resolver);
241
242   return (* iface->lookup_finish) (resolver, result, error);
243 }