nexmon – Blame information for rev 1
?pathlinks?
Rev | Author | Line No. | Line |
---|---|---|---|
1 | office | 1 | /* GIO - GLib Input, Output and Streaming Library |
2 | * |
||
3 | * Copyright 2010, 2013 Red Hat, Inc. |
||
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, see |
||
17 | * <http://www.gnu.org/licenses/>. |
||
18 | */ |
||
19 | |||
20 | #include "config.h" |
||
21 | |||
22 | #include <stdlib.h> |
||
23 | #include <string.h> |
||
24 | |||
25 | #include "gsimpleproxyresolver.h" |
||
26 | #include "ginetaddress.h" |
||
27 | #include "ginetaddressmask.h" |
||
28 | #include "gnetworkingprivate.h" |
||
29 | #include "gtask.h" |
||
30 | |||
31 | #include "glibintl.h" |
||
32 | |||
33 | /** |
||
34 | * SECTION:gsimpleproxyresolver |
||
35 | * @short_description: Simple proxy resolver implementation |
||
36 | * @include: gio/gio.h |
||
37 | * @see_also: g_socket_client_set_proxy_resolver() |
||
38 | * |
||
39 | * #GSimpleProxyResolver is a simple #GProxyResolver implementation |
||
40 | * that handles a single default proxy, multiple URI-scheme-specific |
||
41 | * proxies, and a list of hosts that proxies should not be used for. |
||
42 | * |
||
43 | * #GSimpleProxyResolver is never the default proxy resolver, but it |
||
44 | * can be used as the base class for another proxy resolver |
||
45 | * implementation, or it can be created and used manually, such as |
||
46 | * with g_socket_client_set_proxy_resolver(). |
||
47 | * |
||
48 | * Since: 2.36 |
||
49 | */ |
||
50 | |||
51 | typedef struct { |
||
52 | gchar *name; |
||
53 | gint length; |
||
54 | gushort port; |
||
55 | } GSimpleProxyResolverDomain; |
||
56 | |||
57 | struct _GSimpleProxyResolverPrivate { |
||
58 | gchar *default_proxy, **ignore_hosts; |
||
59 | GHashTable *uri_proxies; |
||
60 | |||
61 | GPtrArray *ignore_ips; |
||
62 | GSimpleProxyResolverDomain *ignore_domains; |
||
63 | }; |
||
64 | |||
65 | static void g_simple_proxy_resolver_iface_init (GProxyResolverInterface *iface); |
||
66 | |||
67 | G_DEFINE_TYPE_WITH_CODE (GSimpleProxyResolver, g_simple_proxy_resolver, G_TYPE_OBJECT, |
||
68 | G_ADD_PRIVATE (GSimpleProxyResolver) |
||
69 | G_IMPLEMENT_INTERFACE (G_TYPE_PROXY_RESOLVER, |
||
70 | g_simple_proxy_resolver_iface_init)) |
||
71 | |||
72 | enum |
||
73 | { |
||
74 | PROP_0, |
||
75 | PROP_DEFAULT_PROXY, |
||
76 | PROP_IGNORE_HOSTS |
||
77 | }; |
||
78 | |||
79 | static void reparse_ignore_hosts (GSimpleProxyResolver *resolver); |
||
80 | |||
81 | static void |
||
82 | g_simple_proxy_resolver_finalize (GObject *object) |
||
83 | { |
||
84 | GSimpleProxyResolver *resolver = G_SIMPLE_PROXY_RESOLVER (object); |
||
85 | GSimpleProxyResolverPrivate *priv = resolver->priv; |
||
86 | |||
87 | g_free (priv->default_proxy); |
||
88 | g_hash_table_destroy (priv->uri_proxies); |
||
89 | |||
90 | g_clear_pointer (&priv->ignore_hosts, g_strfreev); |
||
91 | /* This will free ignore_ips and ignore_domains */ |
||
92 | reparse_ignore_hosts (resolver); |
||
93 | |||
94 | G_OBJECT_CLASS (g_simple_proxy_resolver_parent_class)->finalize (object); |
||
95 | } |
||
96 | |||
97 | static void |
||
98 | g_simple_proxy_resolver_init (GSimpleProxyResolver *resolver) |
||
99 | { |
||
100 | resolver->priv = g_simple_proxy_resolver_get_instance_private (resolver); |
||
101 | resolver->priv->uri_proxies = g_hash_table_new_full (g_str_hash, g_str_equal, |
||
102 | g_free, g_free); |
||
103 | } |
||
104 | |||
105 | static void |
||
106 | g_simple_proxy_resolver_set_property (GObject *object, |
||
107 | guint prop_id, |
||
108 | const GValue *value, |
||
109 | GParamSpec *pspec) |
||
110 | { |
||
111 | GSimpleProxyResolver *resolver = G_SIMPLE_PROXY_RESOLVER (object); |
||
112 | |||
113 | switch (prop_id) |
||
114 | { |
||
115 | case PROP_DEFAULT_PROXY: |
||
116 | g_simple_proxy_resolver_set_default_proxy (resolver, g_value_get_string (value)); |
||
117 | break; |
||
118 | |||
119 | case PROP_IGNORE_HOSTS: |
||
120 | g_simple_proxy_resolver_set_ignore_hosts (resolver, g_value_get_boxed (value)); |
||
121 | break; |
||
122 | |||
123 | default: |
||
124 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); |
||
125 | } |
||
126 | } |
||
127 | |||
128 | static void |
||
129 | g_simple_proxy_resolver_get_property (GObject *object, |
||
130 | guint prop_id, |
||
131 | GValue *value, |
||
132 | GParamSpec *pspec) |
||
133 | { |
||
134 | GSimpleProxyResolver *resolver = G_SIMPLE_PROXY_RESOLVER (object); |
||
135 | |||
136 | switch (prop_id) |
||
137 | { |
||
138 | case PROP_DEFAULT_PROXY: |
||
139 | g_value_set_string (value, resolver->priv->default_proxy); |
||
140 | break; |
||
141 | |||
142 | case PROP_IGNORE_HOSTS: |
||
143 | g_value_set_boxed (value, resolver->priv->ignore_hosts); |
||
144 | break; |
||
145 | |||
146 | default: |
||
147 | G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); |
||
148 | } |
||
149 | } |
||
150 | |||
151 | static void |
||
152 | reparse_ignore_hosts (GSimpleProxyResolver *resolver) |
||
153 | { |
||
154 | GSimpleProxyResolverPrivate *priv = resolver->priv; |
||
155 | GPtrArray *ignore_ips; |
||
156 | GArray *ignore_domains; |
||
157 | gchar *host, *tmp, *colon, *bracket; |
||
158 | GInetAddress *iaddr; |
||
159 | GInetAddressMask *mask; |
||
160 | GSimpleProxyResolverDomain domain; |
||
161 | gushort port; |
||
162 | int i; |
||
163 | |||
164 | if (priv->ignore_ips) |
||
165 | g_ptr_array_free (priv->ignore_ips, TRUE); |
||
166 | if (priv->ignore_domains) |
||
167 | { |
||
168 | for (i = 0; priv->ignore_domains[i].name; i++) |
||
169 | g_free (priv->ignore_domains[i].name); |
||
170 | g_free (priv->ignore_domains); |
||
171 | } |
||
172 | priv->ignore_ips = NULL; |
||
173 | priv->ignore_domains = NULL; |
||
174 | |||
175 | if (!priv->ignore_hosts || !priv->ignore_hosts[0]) |
||
176 | return; |
||
177 | |||
178 | ignore_ips = g_ptr_array_new_with_free_func (g_object_unref); |
||
179 | ignore_domains = g_array_new (TRUE, FALSE, sizeof (GSimpleProxyResolverDomain)); |
||
180 | |||
181 | for (i = 0; priv->ignore_hosts[i]; i++) |
||
182 | { |
||
183 | host = g_strchomp (priv->ignore_hosts[i]); |
||
184 | |||
185 | /* See if it's an IP address or IP/length mask */ |
||
186 | mask = g_inet_address_mask_new_from_string (host, NULL); |
||
187 | if (mask) |
||
188 | { |
||
189 | g_ptr_array_add (ignore_ips, mask); |
||
190 | continue; |
||
191 | } |
||
192 | |||
193 | port = 0; |
||
194 | |||
195 | if (*host == '[') |
||
196 | { |
||
197 | /* [IPv6]:port */ |
||
198 | host++; |
||
199 | bracket = strchr (host, ']'); |
||
200 | if (!bracket || !bracket[1] || bracket[1] != ':') |
||
201 | goto bad; |
||
202 | |||
203 | port = strtoul (bracket + 2, &tmp, 10); |
||
204 | if (*tmp) |
||
205 | goto bad; |
||
206 | |||
207 | *bracket = '\0'; |
||
208 | } |
||
209 | else |
||
210 | { |
||
211 | colon = strchr (host, ':'); |
||
212 | if (colon && !strchr (colon + 1, ':')) |
||
213 | { |
||
214 | /* hostname:port or IPv4:port */ |
||
215 | port = strtoul (colon + 1, &tmp, 10); |
||
216 | if (*tmp) |
||
217 | goto bad; |
||
218 | *colon = '\0'; |
||
219 | } |
||
220 | } |
||
221 | |||
222 | iaddr = g_inet_address_new_from_string (host); |
||
223 | if (iaddr) |
||
224 | g_object_unref (iaddr); |
||
225 | else |
||
226 | { |
||
227 | if (g_str_has_prefix (host, "*.")) |
||
228 | host += 2; |
||
229 | else if (*host == '.') |
||
230 | host++; |
||
231 | } |
||
232 | |||
233 | memset (&domain, 0, sizeof (domain)); |
||
234 | domain.name = g_strdup (host); |
||
235 | domain.length = strlen (domain.name); |
||
236 | domain.port = port; |
||
237 | g_array_append_val (ignore_domains, domain); |
||
238 | continue; |
||
239 | |||
240 | bad: |
||
241 | g_warning ("Ignoring invalid ignore_hosts value '%s'", host); |
||
242 | } |
||
243 | |||
244 | if (ignore_ips->len) |
||
245 | priv->ignore_ips = ignore_ips; |
||
246 | else |
||
247 | g_ptr_array_free (ignore_ips, TRUE); |
||
248 | |||
249 | if (ignore_domains->len) |
||
250 | priv->ignore_domains = (GSimpleProxyResolverDomain *)ignore_domains->data; |
||
251 | g_array_free (ignore_domains, ignore_domains->len == 0); |
||
252 | } |
||
253 | |||
254 | static gboolean |
||
255 | ignore_host (GSimpleProxyResolver *resolver, |
||
256 | const gchar *host, |
||
257 | gushort port) |
||
258 | { |
||
259 | GSimpleProxyResolverPrivate *priv = resolver->priv; |
||
260 | gchar *ascii_host = NULL; |
||
261 | gboolean ignore = FALSE; |
||
262 | gint i, length, offset; |
||
263 | |||
264 | if (priv->ignore_ips) |
||
265 | { |
||
266 | GInetAddress *iaddr; |
||
267 | |||
268 | iaddr = g_inet_address_new_from_string (host); |
||
269 | if (iaddr) |
||
270 | { |
||
271 | for (i = 0; i < priv->ignore_ips->len; i++) |
||
272 | { |
||
273 | GInetAddressMask *mask = priv->ignore_ips->pdata[i]; |
||
274 | |||
275 | if (g_inet_address_mask_matches (mask, iaddr)) |
||
276 | { |
||
277 | ignore = TRUE; |
||
278 | break; |
||
279 | } |
||
280 | } |
||
281 | |||
282 | g_object_unref (iaddr); |
||
283 | if (ignore) |
||
284 | return TRUE; |
||
285 | } |
||
286 | } |
||
287 | |||
288 | if (priv->ignore_domains) |
||
289 | { |
||
290 | if (g_hostname_is_non_ascii (host)) |
||
291 | host = ascii_host = g_hostname_to_ascii (host); |
||
292 | length = strlen (host); |
||
293 | |||
294 | for (i = 0; priv->ignore_domains[i].length; i++) |
||
295 | { |
||
296 | GSimpleProxyResolverDomain *domain = &priv->ignore_domains[i]; |
||
297 | |||
298 | offset = length - domain->length; |
||
299 | if ((domain->port == 0 || domain->port == port) && |
||
300 | (offset == 0 || (offset > 0 && host[offset - 1] == '.')) && |
||
301 | (g_ascii_strcasecmp (domain->name, host + offset) == 0)) |
||
302 | { |
||
303 | ignore = TRUE; |
||
304 | break; |
||
305 | } |
||
306 | } |
||
307 | |||
308 | g_free (ascii_host); |
||
309 | } |
||
310 | |||
311 | return ignore; |
||
312 | } |
||
313 | |||
314 | static gchar ** |
||
315 | g_simple_proxy_resolver_lookup (GProxyResolver *proxy_resolver, |
||
316 | const gchar *uri, |
||
317 | GCancellable *cancellable, |
||
318 | GError **error) |
||
319 | { |
||
320 | GSimpleProxyResolver *resolver = G_SIMPLE_PROXY_RESOLVER (proxy_resolver); |
||
321 | GSimpleProxyResolverPrivate *priv = resolver->priv; |
||
322 | const gchar *proxy = NULL; |
||
323 | gchar **proxies; |
||
324 | |||
325 | if (priv->ignore_ips || priv->ignore_domains) |
||
326 | { |
||
327 | gchar *host = NULL; |
||
328 | gushort port; |
||
329 | |||
330 | if (_g_uri_parse_authority (uri, &host, &port, NULL) && |
||
331 | ignore_host (resolver, host, port)) |
||
332 | proxy = "direct://"; |
||
333 | |||
334 | g_free (host); |
||
335 | } |
||
336 | |||
337 | if (!proxy && g_hash_table_size (priv->uri_proxies)) |
||
338 | { |
||
339 | gchar *scheme = g_ascii_strdown (uri, strcspn (uri, ":")); |
||
340 | |||
341 | proxy = g_hash_table_lookup (priv->uri_proxies, scheme); |
||
342 | g_free (scheme); |
||
343 | } |
||
344 | |||
345 | if (!proxy) |
||
346 | proxy = priv->default_proxy; |
||
347 | if (!proxy) |
||
348 | proxy = "direct://"; |
||
349 | |||
350 | if (!strncmp (proxy, "socks://", 8)) |
||
351 | { |
||
352 | proxies = g_new0 (gchar *, 4); |
||
353 | proxies[0] = g_strdup_printf ("socks5://%s", proxy + 8); |
||
354 | proxies[1] = g_strdup_printf ("socks4a://%s", proxy + 8); |
||
355 | proxies[2] = g_strdup_printf ("socks4://%s", proxy + 8); |
||
356 | proxies[3] = NULL; |
||
357 | } |
||
358 | else |
||
359 | { |
||
360 | proxies = g_new0 (gchar *, 2); |
||
361 | proxies[0] = g_strdup (proxy); |
||
362 | } |
||
363 | |||
364 | return proxies; |
||
365 | } |
||
366 | |||
367 | static void |
||
368 | g_simple_proxy_resolver_lookup_async (GProxyResolver *proxy_resolver, |
||
369 | const gchar *uri, |
||
370 | GCancellable *cancellable, |
||
371 | GAsyncReadyCallback callback, |
||
372 | gpointer user_data) |
||
373 | { |
||
374 | GSimpleProxyResolver *resolver = G_SIMPLE_PROXY_RESOLVER (proxy_resolver); |
||
375 | GTask *task; |
||
376 | GError *error = NULL; |
||
377 | char **proxies; |
||
378 | |||
379 | task = g_task_new (resolver, cancellable, callback, user_data); |
||
380 | |||
381 | proxies = g_simple_proxy_resolver_lookup (proxy_resolver, uri, |
||
382 | cancellable, &error); |
||
383 | if (proxies) |
||
384 | g_task_return_pointer (task, proxies, (GDestroyNotify)g_strfreev); |
||
385 | else |
||
386 | g_task_return_error (task, error); |
||
387 | g_object_unref (task); |
||
388 | } |
||
389 | |||
390 | static gchar ** |
||
391 | g_simple_proxy_resolver_lookup_finish (GProxyResolver *resolver, |
||
392 | GAsyncResult *result, |
||
393 | GError **error) |
||
394 | { |
||
395 | g_return_val_if_fail (g_task_is_valid (result, resolver), NULL); |
||
396 | |||
397 | return g_task_propagate_pointer (G_TASK (result), error); |
||
398 | } |
||
399 | |||
400 | static void |
||
401 | g_simple_proxy_resolver_class_init (GSimpleProxyResolverClass *resolver_class) |
||
402 | { |
||
403 | GObjectClass *object_class = G_OBJECT_CLASS (resolver_class); |
||
404 | |||
405 | object_class->get_property = g_simple_proxy_resolver_get_property; |
||
406 | object_class->set_property = g_simple_proxy_resolver_set_property; |
||
407 | object_class->finalize = g_simple_proxy_resolver_finalize; |
||
408 | |||
409 | /** |
||
410 | * GSimpleProxyResolver:default-proxy: |
||
411 | * |
||
412 | * The default proxy URI that will be used for any URI that doesn't |
||
413 | * match #GSimpleProxyResolver:ignore-hosts, and doesn't match any |
||
414 | * of the schemes set with g_simple_proxy_resolver_set_uri_proxy(). |
||
415 | * |
||
416 | * Note that as a special case, if this URI starts with |
||
417 | * "socks://", #GSimpleProxyResolver will treat it as referring |
||
418 | * to all three of the socks5, socks4a, and socks4 proxy types. |
||
419 | */ |
||
420 | g_object_class_install_property (object_class, PROP_DEFAULT_PROXY, |
||
421 | g_param_spec_string ("default-proxy", |
||
422 | P_("Default proxy"), |
||
423 | P_("The default proxy URI"), |
||
424 | NULL, |
||
425 | G_PARAM_READWRITE | |
||
426 | G_PARAM_STATIC_STRINGS)); |
||
427 | |||
428 | /** |
||
429 | * GSimpleProxyResolver:ignore-hosts: |
||
430 | * |
||
431 | * A list of hostnames and IP addresses that the resolver should |
||
432 | * allow direct connections to. |
||
433 | * |
||
434 | * Entries can be in one of 4 formats: |
||
435 | * |
||
436 | * - A hostname, such as "example.com", ".example.com", or |
||
437 | * "*.example.com", any of which match "example.com" or |
||
438 | * any subdomain of it. |
||
439 | * |
||
440 | * - An IPv4 or IPv6 address, such as "192.168.1.1", |
||
441 | * which matches only that address. |
||
442 | * |
||
443 | * - A hostname or IP address followed by a port, such as |
||
444 | * "example.com:80", which matches whatever the hostname or IP |
||
445 | * address would match, but only for URLs with the (explicitly) |
||
446 | * indicated port. In the case of an IPv6 address, the address |
||
447 | * part must appear in brackets: "[::1]:443" |
||
448 | * |
||
449 | * - An IP address range, given by a base address and prefix length, |
||
450 | * such as "fe80::/10", which matches any address in that range. |
||
451 | * |
||
452 | * Note that when dealing with Unicode hostnames, the matching is |
||
453 | * done against the ASCII form of the name. |
||
454 | * |
||
455 | * Also note that hostname exclusions apply only to connections made |
||
456 | * to hosts identified by name, and IP address exclusions apply only |
||
457 | * to connections made to hosts identified by address. That is, if |
||
458 | * example.com has an address of 192.168.1.1, and the :ignore-hosts list |
||
459 | * contains only "192.168.1.1", then a connection to "example.com" |
||
460 | * (eg, via a #GNetworkAddress) will use the proxy, and a connection to |
||
461 | * "192.168.1.1" (eg, via a #GInetSocketAddress) will not. |
||
462 | * |
||
463 | * These rules match the "ignore-hosts"/"noproxy" rules most |
||
464 | * commonly used by other applications. |
||
465 | */ |
||
466 | g_object_class_install_property (object_class, PROP_IGNORE_HOSTS, |
||
467 | g_param_spec_boxed ("ignore-hosts", |
||
468 | P_("Ignore hosts"), |
||
469 | P_("Hosts that will not use the proxy"), |
||
470 | G_TYPE_STRV, |
||
471 | G_PARAM_READWRITE | |
||
472 | G_PARAM_STATIC_STRINGS)); |
||
473 | |||
474 | } |
||
475 | |||
476 | static void |
||
477 | g_simple_proxy_resolver_iface_init (GProxyResolverInterface *iface) |
||
478 | { |
||
479 | iface->lookup = g_simple_proxy_resolver_lookup; |
||
480 | iface->lookup_async = g_simple_proxy_resolver_lookup_async; |
||
481 | iface->lookup_finish = g_simple_proxy_resolver_lookup_finish; |
||
482 | } |
||
483 | |||
484 | /** |
||
485 | * g_simple_proxy_resolver_new: |
||
486 | * @default_proxy: (allow-none): the default proxy to use, eg |
||
487 | * "socks://192.168.1.1" |
||
488 | * @ignore_hosts: (allow-none): an optional list of hosts/IP addresses |
||
489 | * to not use a proxy for. |
||
490 | * |
||
491 | * Creates a new #GSimpleProxyResolver. See |
||
492 | * #GSimpleProxyResolver:default-proxy and |
||
493 | * #GSimpleProxyResolver:ignore-hosts for more details on how the |
||
494 | * arguments are interpreted. |
||
495 | * |
||
496 | * Returns: (transfer full) a new #GSimpleProxyResolver |
||
497 | * |
||
498 | * Since: 2.36 |
||
499 | */ |
||
500 | GProxyResolver * |
||
501 | g_simple_proxy_resolver_new (const gchar *default_proxy, |
||
502 | gchar **ignore_hosts) |
||
503 | { |
||
504 | return g_object_new (G_TYPE_SIMPLE_PROXY_RESOLVER, |
||
505 | "default-proxy", default_proxy, |
||
506 | "ignore-hosts", ignore_hosts, |
||
507 | NULL); |
||
508 | } |
||
509 | |||
510 | /** |
||
511 | * g_simple_proxy_resolver_set_default_proxy: |
||
512 | * @resolver: a #GSimpleProxyResolver |
||
513 | * @default_proxy: the default proxy to use |
||
514 | * |
||
515 | * Sets the default proxy on @resolver, to be used for any URIs that |
||
516 | * don't match #GSimpleProxyResolver:ignore-hosts or a proxy set |
||
517 | * via g_simple_proxy_resolver_set_uri_proxy(). |
||
518 | * |
||
519 | * If @default_proxy starts with "socks://", |
||
520 | * #GSimpleProxyResolver will treat it as referring to all three of |
||
521 | * the socks5, socks4a, and socks4 proxy types. |
||
522 | * |
||
523 | * Since: 2.36 |
||
524 | */ |
||
525 | void |
||
526 | g_simple_proxy_resolver_set_default_proxy (GSimpleProxyResolver *resolver, |
||
527 | const gchar *default_proxy) |
||
528 | { |
||
529 | g_return_if_fail (G_IS_SIMPLE_PROXY_RESOLVER (resolver)); |
||
530 | |||
531 | g_free (resolver->priv->default_proxy); |
||
532 | resolver->priv->default_proxy = g_strdup (default_proxy); |
||
533 | g_object_notify (G_OBJECT (resolver), "default-proxy"); |
||
534 | } |
||
535 | |||
536 | /** |
||
537 | * g_simple_proxy_resolver_set_ignore_hosts: |
||
538 | * @resolver: a #GSimpleProxyResolver |
||
539 | * @ignore_hosts: %NULL-terminated list of hosts/IP addresses |
||
540 | * to not use a proxy for |
||
541 | * |
||
542 | * Sets the list of ignored hosts. |
||
543 | * |
||
544 | * See #GSimpleProxyResolver:ignore-hosts for more details on how the |
||
545 | * @ignore_hosts argument is interpreted. |
||
546 | * |
||
547 | * Since: 2.36 |
||
548 | */ |
||
549 | void |
||
550 | g_simple_proxy_resolver_set_ignore_hosts (GSimpleProxyResolver *resolver, |
||
551 | gchar **ignore_hosts) |
||
552 | { |
||
553 | g_return_if_fail (G_IS_SIMPLE_PROXY_RESOLVER (resolver)); |
||
554 | |||
555 | g_strfreev (resolver->priv->ignore_hosts); |
||
556 | resolver->priv->ignore_hosts = g_strdupv (ignore_hosts); |
||
557 | reparse_ignore_hosts (resolver); |
||
558 | g_object_notify (G_OBJECT (resolver), "ignore-hosts"); |
||
559 | } |
||
560 | |||
561 | /** |
||
562 | * g_simple_proxy_resolver_set_uri_proxy: |
||
563 | * @resolver: a #GSimpleProxyResolver |
||
564 | * @uri_scheme: the URI scheme to add a proxy for |
||
565 | * @proxy: the proxy to use for @uri_scheme |
||
566 | * |
||
567 | * Adds a URI-scheme-specific proxy to @resolver; URIs whose scheme |
||
568 | * matches @uri_scheme (and which don't match |
||
569 | * #GSimpleProxyResolver:ignore-hosts) will be proxied via @proxy. |
||
570 | * |
||
571 | * As with #GSimpleProxyResolver:default-proxy, if @proxy starts with |
||
572 | * "socks://", #GSimpleProxyResolver will treat it |
||
573 | * as referring to all three of the socks5, socks4a, and socks4 proxy |
||
574 | * types. |
||
575 | * |
||
576 | * Since: 2.36 |
||
577 | */ |
||
578 | void |
||
579 | g_simple_proxy_resolver_set_uri_proxy (GSimpleProxyResolver *resolver, |
||
580 | const gchar *uri_scheme, |
||
581 | const gchar *proxy) |
||
582 | { |
||
583 | g_return_if_fail (G_IS_SIMPLE_PROXY_RESOLVER (resolver)); |
||
584 | |||
585 | g_hash_table_replace (resolver->priv->uri_proxies, |
||
586 | g_ascii_strdown (uri_scheme, -1), |
||
587 | g_strdup (proxy)); |
||
588 | } |