62f41cfeccc25f59e202ce1a9f0135f50b44295f
[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 #GClientSocket 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: 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: 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: A NULL-terminated array of proxy URIs. Must be freed with
164  *               g_strfreev().
165  *
166  * Since: 2.26
167  */
168 gchar **
169 g_proxy_resolver_lookup (GProxyResolver  *resolver,
170                          const gchar     *uri,
171                          GCancellable    *cancellable,
172                          GError         **error)
173 {
174   GProxyResolverInterface *iface;
175
176   g_return_val_if_fail (G_IS_PROXY_RESOLVER (resolver), NULL);
177   g_return_val_if_fail (uri != NULL, NULL);
178
179   iface = G_PROXY_RESOLVER_GET_IFACE (resolver);
180
181   return (* iface->lookup) (resolver, uri, cancellable, error);
182 }
183
184 /**
185  * g_proxy_resolver_lookup_async:
186  * @resolver: a #GProxyResolver
187  * @uri: a URI representing the destination to connect to
188  * @cancellable: a #GCancellable, or %NULL
189  * @callback: callback to call after resolution completes
190  * @user_data: data for @callback
191  *
192  * Asynchronous lookup of proxy. See g_proxy_resolver_lookup() for more
193  * details.
194  *
195  * Since: 2.26
196  */
197 void
198 g_proxy_resolver_lookup_async (GProxyResolver      *resolver,
199                                const gchar         *uri,
200                                GCancellable        *cancellable,
201                                GAsyncReadyCallback  callback,
202                                gpointer             user_data)
203 {
204   GProxyResolverInterface *iface;
205
206   g_return_if_fail (G_IS_PROXY_RESOLVER (resolver));
207   g_return_if_fail (uri != NULL);
208
209   iface = G_PROXY_RESOLVER_GET_IFACE (resolver);
210
211   (* iface->lookup_async) (resolver, uri, cancellable, callback, user_data);
212 }
213
214 /**
215  * g_proxy_resolver_lookup_finish:
216  * @resolver: a #GProxyResolver
217  * @result: the result passed to your #GAsyncReadyCallback
218  * @error: return location for a #GError, or %NULL
219  *
220  * Call this function to obtain the array of proxy URIs when
221  * g_proxy_resolver_lookup_async() is complete. See
222  * g_proxy_resolver_lookup() for more details.
223  *
224  * Return value: A NULL-terminated array of proxy URIs. Must be freed with
225  *               g_strfreev().
226  *
227  * Since: 2.26
228  */
229 gchar **
230 g_proxy_resolver_lookup_finish (GProxyResolver     *resolver,
231                                 GAsyncResult       *result,
232                                 GError            **error)
233 {
234   GProxyResolverInterface *iface;
235
236   g_return_val_if_fail (G_IS_PROXY_RESOLVER (resolver), NULL);
237
238   iface = G_PROXY_RESOLVER_GET_IFACE (resolver);
239
240   return (* iface->lookup_finish) (resolver, result, error);
241 }