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.1 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, see <http://www.gnu.org/licenses/>.
17 *
18 * Author: Nicolas Dufresne <nicolas.dufresne@collabora.co.uk>
19 */
20
21 #include "config.h"
22
23 #include "gproxy.h"
24
25 #include "giomodule.h"
26 #include "giomodule-priv.h"
27 #include "glibintl.h"
28
29 /**
30 * SECTION:gproxy
31 * @short_description: Interface for proxy handling
32 * @include: gio/gio.h
33 *
34 * A #GProxy handles connecting to a remote host via a given type of
35 * proxy server. It is implemented by the 'gio-proxy' extension point.
36 * The extensions are named after their proxy protocol name. As an
37 * example, a SOCKS5 proxy implementation can be retrieved with the
38 * name 'socks5' using the function
39 * g_io_extension_point_get_extension_by_name().
40 *
41 * Since: 2.26
42 **/
43
G_DEFINE_INTERFACE(GProxy,g_proxy,G_TYPE_OBJECT)44 G_DEFINE_INTERFACE (GProxy, g_proxy, G_TYPE_OBJECT)
45
46 static void
47 g_proxy_default_init (GProxyInterface *iface)
48 {
49 }
50
51 /**
52 * g_proxy_get_default_for_protocol:
53 * @protocol: the proxy protocol name (e.g. http, socks, etc)
54 *
55 * Find the `gio-proxy` extension point for a proxy implementation that supports
56 * the specified protocol.
57 *
58 * Returns: (nullable) (transfer full): return a #GProxy or NULL if protocol
59 * is not supported.
60 *
61 * Since: 2.26
62 **/
63 GProxy *
g_proxy_get_default_for_protocol(const gchar * protocol)64 g_proxy_get_default_for_protocol (const gchar *protocol)
65 {
66 GIOExtensionPoint *ep;
67 GIOExtension *extension;
68
69 /* Ensure proxy modules loaded */
70 _g_io_modules_ensure_loaded ();
71
72 ep = g_io_extension_point_lookup (G_PROXY_EXTENSION_POINT_NAME);
73
74 extension = g_io_extension_point_get_extension_by_name (ep, protocol);
75
76 if (extension)
77 return g_object_new (g_io_extension_get_type (extension), NULL);
78
79 return NULL;
80 }
81
82 /**
83 * g_proxy_connect:
84 * @proxy: a #GProxy
85 * @connection: a #GIOStream
86 * @proxy_address: a #GProxyAddress
87 * @cancellable: (nullable): a #GCancellable
88 * @error: return #GError
89 *
90 * Given @connection to communicate with a proxy (eg, a
91 * #GSocketConnection that is connected to the proxy server), this
92 * does the necessary handshake to connect to @proxy_address, and if
93 * required, wraps the #GIOStream to handle proxy payload.
94 *
95 * Returns: (transfer full): a #GIOStream that will replace @connection. This might
96 * be the same as @connection, in which case a reference
97 * will be added.
98 *
99 * Since: 2.26
100 */
101 GIOStream *
g_proxy_connect(GProxy * proxy,GIOStream * connection,GProxyAddress * proxy_address,GCancellable * cancellable,GError ** error)102 g_proxy_connect (GProxy *proxy,
103 GIOStream *connection,
104 GProxyAddress *proxy_address,
105 GCancellable *cancellable,
106 GError **error)
107 {
108 GProxyInterface *iface;
109
110 g_return_val_if_fail (G_IS_PROXY (proxy), NULL);
111
112 iface = G_PROXY_GET_IFACE (proxy);
113
114 return (* iface->connect) (proxy,
115 connection,
116 proxy_address,
117 cancellable,
118 error);
119 }
120
121 /**
122 * g_proxy_connect_async:
123 * @proxy: a #GProxy
124 * @connection: a #GIOStream
125 * @proxy_address: a #GProxyAddress
126 * @cancellable: (nullable): a #GCancellable
127 * @callback: (scope async): a #GAsyncReadyCallback
128 * @user_data: (closure): callback data
129 *
130 * Asynchronous version of g_proxy_connect().
131 *
132 * Since: 2.26
133 */
134 void
g_proxy_connect_async(GProxy * proxy,GIOStream * connection,GProxyAddress * proxy_address,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)135 g_proxy_connect_async (GProxy *proxy,
136 GIOStream *connection,
137 GProxyAddress *proxy_address,
138 GCancellable *cancellable,
139 GAsyncReadyCallback callback,
140 gpointer user_data)
141 {
142 GProxyInterface *iface;
143
144 g_return_if_fail (G_IS_PROXY (proxy));
145
146 iface = G_PROXY_GET_IFACE (proxy);
147
148 (* iface->connect_async) (proxy,
149 connection,
150 proxy_address,
151 cancellable,
152 callback,
153 user_data);
154 }
155
156 /**
157 * g_proxy_connect_finish:
158 * @proxy: a #GProxy
159 * @result: a #GAsyncResult
160 * @error: return #GError
161 *
162 * See g_proxy_connect().
163 *
164 * Returns: (transfer full): a #GIOStream.
165 *
166 * Since: 2.26
167 */
168 GIOStream *
g_proxy_connect_finish(GProxy * proxy,GAsyncResult * result,GError ** error)169 g_proxy_connect_finish (GProxy *proxy,
170 GAsyncResult *result,
171 GError **error)
172 {
173 GProxyInterface *iface;
174
175 g_return_val_if_fail (G_IS_PROXY (proxy), NULL);
176
177 iface = G_PROXY_GET_IFACE (proxy);
178
179 return (* iface->connect_finish) (proxy, result, error);
180 }
181
182 /**
183 * g_proxy_supports_hostname:
184 * @proxy: a #GProxy
185 *
186 * Some proxy protocols expect to be passed a hostname, which they
187 * will resolve to an IP address themselves. Others, like SOCKS4, do
188 * not allow this. This function will return %FALSE if @proxy is
189 * implementing such a protocol. When %FALSE is returned, the caller
190 * should resolve the destination hostname first, and then pass a
191 * #GProxyAddress containing the stringified IP address to
192 * g_proxy_connect() or g_proxy_connect_async().
193 *
194 * Returns: %TRUE if hostname resolution is supported.
195 *
196 * Since: 2.26
197 */
198 gboolean
g_proxy_supports_hostname(GProxy * proxy)199 g_proxy_supports_hostname (GProxy *proxy)
200 {
201 GProxyInterface *iface;
202
203 g_return_val_if_fail (G_IS_PROXY (proxy), FALSE);
204
205 iface = G_PROXY_GET_IFACE (proxy);
206
207 return (* iface->supports_hostname) (proxy);
208 }
209