Coverage Report

Created: 2025-07-01 07:09

/src/glib/gio/gproxyresolver.c
Line
Count
Source (jump to first uncovered line)
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 "gproxyresolver.h"
24
25
#include <glib.h>
26
#include "glibintl.h"
27
28
#include "gasyncresult.h"
29
#include "gcancellable.h"
30
#include "gtask.h"
31
#include "giomodule.h"
32
#include "gioerror.h"
33
#include "giomodule-priv.h"
34
#include "gnetworkingprivate.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
 * Implementations of #GProxyResolver based on libproxy and GNOME settings can
46
 * be found in glib-networking. GIO comes with an implementation for use inside
47
 * Flatpak portals.
48
 */
49
50
/**
51
 * GProxyResolverInterface:
52
 * @g_iface: The parent interface.
53
 * @is_supported: the virtual function pointer for g_proxy_resolver_is_supported()
54
 * @lookup: the virtual function pointer for g_proxy_resolver_lookup()
55
 * @lookup_async: the virtual function pointer for
56
 *  g_proxy_resolver_lookup_async()
57
 * @lookup_finish: the virtual function pointer for
58
 *  g_proxy_resolver_lookup_finish()
59
 *
60
 * The virtual function table for #GProxyResolver.
61
 */
62
63
G_DEFINE_INTERFACE (GProxyResolver, g_proxy_resolver, G_TYPE_OBJECT)
64
65
static void
66
g_proxy_resolver_default_init (GProxyResolverInterface *iface)
67
0
{
68
0
}
69
70
static GProxyResolver *proxy_resolver_default_singleton = NULL;  /* (owned) (atomic) */
71
72
/**
73
 * g_proxy_resolver_get_default:
74
 *
75
 * Gets the default #GProxyResolver for the system.
76
 *
77
 * Returns: (not nullable) (transfer none): the default #GProxyResolver, which
78
 *     will be a dummy object if no proxy resolver is available
79
 *
80
 * Since: 2.26
81
 */
82
GProxyResolver *
83
g_proxy_resolver_get_default (void)
84
0
{
85
0
  if (g_once_init_enter (&proxy_resolver_default_singleton))
86
0
    {
87
0
      GProxyResolver *singleton;
88
89
0
      singleton = _g_io_module_get_default (G_PROXY_RESOLVER_EXTENSION_POINT_NAME,
90
0
                                            "GIO_USE_PROXY_RESOLVER",
91
0
                                            (GIOModuleVerifyFunc) g_proxy_resolver_is_supported);
92
93
0
      g_once_init_leave (&proxy_resolver_default_singleton, singleton);
94
0
    }
95
96
0
  return proxy_resolver_default_singleton;
97
0
}
98
99
/**
100
 * g_proxy_resolver_is_supported:
101
 * @resolver: a #GProxyResolver
102
 *
103
 * Checks if @resolver can be used on this system. (This is used
104
 * internally; g_proxy_resolver_get_default() will only return a proxy
105
 * resolver that returns %TRUE for this method.)
106
 *
107
 * Returns: %TRUE if @resolver is supported.
108
 *
109
 * Since: 2.26
110
 */
111
gboolean
112
g_proxy_resolver_is_supported (GProxyResolver *resolver)
113
0
{
114
0
  GProxyResolverInterface *iface;
115
116
0
  g_return_val_if_fail (G_IS_PROXY_RESOLVER (resolver), FALSE);
117
118
0
  iface = G_PROXY_RESOLVER_GET_IFACE (resolver);
119
120
0
  return (* iface->is_supported) (resolver);
121
0
}
122
123
/**
124
 * g_proxy_resolver_lookup:
125
 * @resolver: a #GProxyResolver
126
 * @uri: a URI representing the destination to connect to
127
 * @cancellable: (nullable): a #GCancellable, or %NULL
128
 * @error: return location for a #GError, or %NULL
129
 *
130
 * Looks into the system proxy configuration to determine what proxy,
131
 * if any, to use to connect to @uri. The returned proxy URIs are of
132
 * the form `<protocol>://[user[:password]@]host:port` or
133
 * `direct://`, where <protocol> could be http, rtsp, socks
134
 * or other proxying protocol.
135
 *
136
 * If you don't know what network protocol is being used on the
137
 * socket, you should use `none` as the URI protocol.
138
 * In this case, the resolver might still return a generic proxy type
139
 * (such as SOCKS), but would not return protocol-specific proxy types
140
 * (such as http).
141
 *
142
 * `direct://` is used when no proxy is needed.
143
 * Direct connection should not be attempted unless it is part of the
144
 * returned array of proxies.
145
 *
146
 * Returns: (transfer full) (array zero-terminated=1): A
147
 *               NULL-terminated array of proxy URIs. Must be freed
148
 *               with g_strfreev().
149
 *
150
 * Since: 2.26
151
 */
152
gchar **
153
g_proxy_resolver_lookup (GProxyResolver  *resolver,
154
       const gchar     *uri,
155
       GCancellable    *cancellable,
156
       GError         **error)
157
0
{
158
0
  GProxyResolverInterface *iface;
159
160
0
  g_return_val_if_fail (G_IS_PROXY_RESOLVER (resolver), NULL);
161
0
  g_return_val_if_fail (uri != NULL, NULL);
162
163
0
  if (!g_uri_is_valid (uri, G_URI_FLAGS_NONE, NULL))
164
0
    {
165
0
      g_set_error (error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
166
0
                   "Invalid URI ā€˜%s’", uri);
167
0
      return NULL;
168
0
    }
169
170
0
  iface = G_PROXY_RESOLVER_GET_IFACE (resolver);
171
172
0
  return (* iface->lookup) (resolver, uri, cancellable, error);
173
0
}
174
175
/**
176
 * g_proxy_resolver_lookup_async:
177
 * @resolver: a #GProxyResolver
178
 * @uri: a URI representing the destination to connect to
179
 * @cancellable: (nullable): a #GCancellable, or %NULL
180
 * @callback: (scope async): callback to call after resolution completes
181
 * @user_data: (closure): data for @callback
182
 *
183
 * Asynchronous lookup of proxy. See g_proxy_resolver_lookup() for more
184
 * details.
185
 *
186
 * Since: 2.26
187
 */
188
void
189
g_proxy_resolver_lookup_async (GProxyResolver      *resolver,
190
             const gchar         *uri,
191
             GCancellable        *cancellable,
192
             GAsyncReadyCallback  callback,
193
             gpointer             user_data)
194
0
{
195
0
  GProxyResolverInterface *iface;
196
0
  GError *error = NULL;
197
198
0
  g_return_if_fail (G_IS_PROXY_RESOLVER (resolver));
199
0
  g_return_if_fail (uri != NULL);
200
201
0
  if (!g_uri_is_valid (uri, G_URI_FLAGS_NONE, NULL))
202
0
    {
203
0
      g_set_error (&error, G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT,
204
0
                   "Invalid URI ā€˜%s’", uri);
205
0
      g_task_report_error (resolver, callback, user_data,
206
0
                           g_proxy_resolver_lookup_async,
207
0
                           g_steal_pointer (&error));
208
0
      return;
209
0
    }
210
211
0
  iface = G_PROXY_RESOLVER_GET_IFACE (resolver);
212
213
0
  (* iface->lookup_async) (resolver, uri, cancellable, callback, user_data);
214
0
}
215
216
/**
217
 * g_proxy_resolver_lookup_finish:
218
 * @resolver: a #GProxyResolver
219
 * @result: the result passed to your #GAsyncReadyCallback
220
 * @error: return location for a #GError, or %NULL
221
 *
222
 * Call this function to obtain the array of proxy URIs when
223
 * g_proxy_resolver_lookup_async() is complete. See
224
 * g_proxy_resolver_lookup() for more details.
225
 *
226
 * Returns: (transfer full) (array zero-terminated=1): A
227
 *               NULL-terminated array of proxy URIs. Must be freed
228
 *               with g_strfreev().
229
 *
230
 * Since: 2.26
231
 */
232
gchar **
233
g_proxy_resolver_lookup_finish (GProxyResolver     *resolver,
234
        GAsyncResult       *result,
235
        GError            **error)
236
0
{
237
0
  GProxyResolverInterface *iface;
238
239
0
  g_return_val_if_fail (G_IS_PROXY_RESOLVER (resolver), NULL);
240
241
0
  iface = G_PROXY_RESOLVER_GET_IFACE (resolver);
242
243
0
  return (* iface->lookup_finish) (resolver, result, error);
244
0
}