Merge branch '976-disable-assert-checks' into 'master'
[glib.git] / gio / tests / proxy.c
blob50a20622ef02e1e041abee78aa222179a8baf91b
1 /* GLib testing framework examples and tests
3 * Copyright (C) 2010 Collabora, Ltd.
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.
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.
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/>.
18 * Authors: Nicolas Dufresne <nicolas.dufresne@collabora.co.uk>
21 #include "config.h"
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
27 #include <gio/gio.h>
28 #include <glib.h>
30 #include "glibintl.h"
32 #ifdef G_OS_UNIX
33 #include "gio/gunixsocketaddress.h"
34 #endif
36 static const gchar *info = NULL;
37 static GCancellable *cancellable = NULL;
38 static gint return_value = 0;
40 static void G_GNUC_NORETURN
41 usage (void)
43 fprintf (stderr, "Usage: proxy [-s] (uri|host:port|ip:port|path|srv/protocol/domain)\n");
44 fprintf (stderr, " Use -t to enable threading.\n");
45 fprintf (stderr, " Use -s to do synchronous lookups.\n");
46 fprintf (stderr, " Use -c to cancel operation.\n");
47 fprintf (stderr, " Use -e to use enumerator.\n");
48 fprintf (stderr, " Use -inet to use GInetSocketAddress enumerator (ip:port).\n");
49 #ifdef G_OS_UNIX
50 fprintf (stderr, " Use -unix to use GUnixSocketAddress enumerator (path).\n");
51 #endif
52 fprintf (stderr, " Use -proxyaddr tp use GProxyAddress enumerator "
53 "(ip:port:protocol:dest_host:dest_port[:username[:password]]).\n");
54 fprintf (stderr, " Use -netaddr to use GNetworkAddress enumerator (host:port).\n");
55 fprintf (stderr, " Use -neturi to use GNetworkAddress enumerator (uri).\n");
56 fprintf (stderr, " Use -netsrv to use GNetworkService enumerator (srv/protocol/domain).\n");
57 fprintf (stderr, " Use -connect to create a connection using GSocketClient object (uri).\n");
58 exit (1);
61 static void
62 print_and_free_error (GError *error)
64 fprintf (stderr, "Failed to obtain proxies: %s\n", error->message);
65 g_error_free (error);
66 return_value = 1;
69 static void
70 print_proxies (const gchar *info, gchar **proxies)
72 printf ("Proxies for URI '%s' are:\n", info);
74 if (proxies == NULL || proxies[0] == NULL)
75 printf ("\tnone\n");
76 else
77 for (; proxies[0]; proxies++)
78 printf ("\t%s\n", proxies[0]);
81 static void
82 _proxy_lookup_cb (GObject *source_object,
83 GAsyncResult *result,
84 gpointer user_data)
86 GError *error = NULL;
87 gchar **proxies;
88 GMainLoop *loop = user_data;
90 proxies = g_proxy_resolver_lookup_finish (G_PROXY_RESOLVER (source_object),
91 result,
92 &error);
93 if (error)
95 print_and_free_error (error);
97 else
99 print_proxies (info, proxies);
100 g_strfreev (proxies);
103 g_main_loop_quit (loop);
106 static void
107 use_resolver (gboolean synchronous)
109 GProxyResolver *resolver;
111 resolver = g_proxy_resolver_get_default ();
113 if (synchronous)
115 GError *error = NULL;
116 gchar **proxies;
118 proxies = g_proxy_resolver_lookup (resolver, info, cancellable, &error);
120 if (error)
121 print_and_free_error (error);
122 else
123 print_proxies (info, proxies);
125 g_strfreev (proxies);
127 else
129 GMainLoop *loop = g_main_loop_new (NULL, FALSE);
131 g_proxy_resolver_lookup_async (resolver,
132 info,
133 cancellable,
134 _proxy_lookup_cb,
135 loop);
137 g_main_loop_run (loop);
138 g_main_loop_unref (loop);
142 static void
143 print_proxy_address (GSocketAddress *sockaddr)
145 GProxyAddress *proxy = NULL;
147 if (sockaddr == NULL)
149 printf ("\tdirect://\n");
150 return;
153 if (G_IS_PROXY_ADDRESS (sockaddr))
155 proxy = G_PROXY_ADDRESS (sockaddr);
156 printf ("\t%s://", g_proxy_address_get_protocol(proxy));
158 else
160 printf ("\tdirect://");
163 if (G_IS_INET_SOCKET_ADDRESS (sockaddr))
165 GInetAddress *inetaddr;
166 guint port;
167 gchar *addr;
169 g_object_get (sockaddr,
170 "address", &inetaddr,
171 "port", &port,
172 NULL);
174 addr = g_inet_address_to_string (inetaddr);
176 printf ("%s:%u", addr, port);
178 g_free (addr);
181 if (proxy)
183 if (g_proxy_address_get_username(proxy))
184 printf (" (Username: %s Password: %s)",
185 g_proxy_address_get_username(proxy),
186 g_proxy_address_get_password(proxy));
187 printf (" (Hostname: %s, Port: %i)",
188 g_proxy_address_get_destination_hostname (proxy),
189 g_proxy_address_get_destination_port (proxy));
192 printf ("\n");
195 static void
196 _proxy_enumerate_cb (GObject *object,
197 GAsyncResult *result,
198 gpointer user_data)
200 GError *error = NULL;
201 GMainLoop *loop = user_data;
202 GSocketAddressEnumerator *enumerator = G_SOCKET_ADDRESS_ENUMERATOR (object);
203 GSocketAddress *sockaddr;
205 sockaddr = g_socket_address_enumerator_next_finish (enumerator,
206 result,
207 &error);
208 if (sockaddr)
210 print_proxy_address (sockaddr);
211 g_socket_address_enumerator_next_async (enumerator,
212 cancellable,
213 _proxy_enumerate_cb,
214 loop);
215 g_object_unref (sockaddr);
217 else
219 if (error)
220 print_and_free_error (error);
222 g_main_loop_quit (loop);
226 static void
227 run_with_enumerator (gboolean synchronous, GSocketAddressEnumerator *enumerator)
229 GError *error = NULL;
231 if (synchronous)
233 GSocketAddress *sockaddr;
235 while ((sockaddr = g_socket_address_enumerator_next (enumerator,
236 cancellable,
237 &error)))
239 print_proxy_address (sockaddr);
240 g_object_unref (sockaddr);
243 if (error)
244 print_and_free_error (error);
246 else
248 GMainLoop *loop = g_main_loop_new (NULL, FALSE);
250 g_socket_address_enumerator_next_async (enumerator,
251 cancellable,
252 _proxy_enumerate_cb,
253 loop);
254 g_main_loop_run (loop);
255 g_main_loop_unref (loop);
259 static void
260 use_enumerator (gboolean synchronous)
262 GSocketAddressEnumerator *enumerator;
264 enumerator = g_object_new (G_TYPE_PROXY_ADDRESS_ENUMERATOR,
265 "uri", info,
266 NULL);
268 printf ("Proxies for URI '%s' are:\n", info);
269 run_with_enumerator (synchronous, enumerator);
271 g_object_unref (enumerator);
274 static void
275 use_inet_address (gboolean synchronous)
277 GSocketAddressEnumerator *enumerator;
278 GSocketAddress *sockaddr;
279 GInetAddress *addr = NULL;
280 guint port = 0;
281 gchar **ip_and_port;
283 ip_and_port = g_strsplit (info, ":", 2);
285 if (ip_and_port[0])
287 addr = g_inet_address_new_from_string (ip_and_port[0]);
288 if (ip_and_port [1])
289 port = strtoul (ip_and_port [1], NULL, 10);
292 g_strfreev (ip_and_port);
294 if (addr == NULL || port <= 0 || port >= 65535)
296 fprintf (stderr, "Bad 'ip:port' parameter '%s'\n", info);
297 if (addr)
298 g_object_unref (addr);
299 return_value = 1;
300 return;
303 sockaddr = g_inet_socket_address_new (addr, port);
304 g_object_unref (addr);
306 enumerator =
307 g_socket_connectable_proxy_enumerate (G_SOCKET_CONNECTABLE (sockaddr));
308 g_object_unref (sockaddr);
310 printf ("Proxies for ip and port '%s' are:\n", info);
311 run_with_enumerator (synchronous, enumerator);
313 g_object_unref (enumerator);
316 #ifdef G_OS_UNIX
317 static void
318 use_unix_address (gboolean synchronous)
320 GSocketAddressEnumerator *enumerator;
321 GSocketAddress *sockaddr;
323 sockaddr = g_unix_socket_address_new_with_type (info, -1, G_UNIX_SOCKET_ADDRESS_ABSTRACT);
325 if (sockaddr == NULL)
327 fprintf (stderr, "Failed to create unix socket with name '%s'\n", info);
328 return_value = 1;
329 return;
332 enumerator =
333 g_socket_connectable_proxy_enumerate (G_SOCKET_CONNECTABLE (sockaddr));
334 g_object_unref (sockaddr);
336 printf ("Proxies for path '%s' are:\n", info);
337 run_with_enumerator (synchronous, enumerator);
339 g_object_unref (enumerator);
341 #endif
343 static void
344 use_proxy_address (gboolean synchronous)
346 GSocketAddressEnumerator *enumerator;
347 GSocketAddress *sockaddr;
348 GInetAddress *addr;
349 guint port = 0;
350 gchar *protocol;
351 gchar *dest_host;
352 guint dest_port;
353 gchar *username = NULL;
354 gchar *password = NULL;
355 gchar **split_info;
357 split_info = g_strsplit (info, ":", 7);
359 if (!split_info[0]
360 || !split_info[1]
361 || !split_info[2]
362 || !split_info[3]
363 || !split_info[4])
365 fprintf (stderr, "Bad 'ip:port:protocol:dest_host:dest_port' parameter '%s'\n", info);
366 return_value = 1;
367 return;
370 addr = g_inet_address_new_from_string (split_info[0]);
371 port = strtoul (split_info [1], NULL, 10);
372 protocol = g_strdup (split_info[2]);
373 dest_host = g_strdup (split_info[3]);
374 dest_port = strtoul (split_info[4], NULL, 10);
376 if (split_info[5])
378 username = g_strdup (split_info[5]);
379 if (split_info[6])
380 password = g_strdup (split_info[6]);
383 g_strfreev (split_info);
385 sockaddr = g_proxy_address_new (addr, port,
386 protocol, dest_host, dest_port,
387 username, password);
389 g_object_unref (addr);
390 g_free (protocol);
391 g_free (dest_host);
392 g_free (username);
393 g_free (password);
395 enumerator =
396 g_socket_connectable_proxy_enumerate (G_SOCKET_CONNECTABLE (sockaddr));
397 g_object_unref (sockaddr);
399 printf ("Proxies for ip and port '%s' are:\n", info);
400 run_with_enumerator (synchronous, enumerator);
402 g_object_unref (enumerator);
405 static void
406 use_network_address (gboolean synchronous)
408 GError *error = NULL;
409 GSocketAddressEnumerator *enumerator;
410 GSocketConnectable *connectable;
412 connectable = g_network_address_parse (info, -1, &error);
414 if (error)
416 print_and_free_error (error);
417 return;
420 enumerator = g_socket_connectable_proxy_enumerate (connectable);
421 g_object_unref (connectable);
423 printf ("Proxies for hostname and port '%s' are:\n", info);
424 run_with_enumerator (synchronous, enumerator);
426 g_object_unref (enumerator);
429 static void
430 use_network_uri (gboolean synchronous)
432 GError *error = NULL;
433 GSocketAddressEnumerator *enumerator;
434 GSocketConnectable *connectable;
436 connectable = g_network_address_parse_uri (info, 0, &error);
438 if (error)
440 print_and_free_error (error);
441 return;
444 enumerator = g_socket_connectable_proxy_enumerate (connectable);
445 g_object_unref (connectable);
447 printf ("Proxies for URI '%s' are:\n", info);
448 run_with_enumerator (synchronous, enumerator);
450 g_object_unref (enumerator);
453 static void
454 use_network_service (gboolean synchronous)
456 GSocketAddressEnumerator *enumerator;
457 GSocketConnectable *connectable = NULL;
458 gchar **split;
460 split = g_strsplit (info, "/", 3);
462 if (split[0] && split[1] && split[2])
463 connectable = g_network_service_new (split[0], split[1], split[2]);
465 g_strfreev (split);
467 if (connectable == NULL)
469 fprintf (stderr, "Bad 'srv/protocol/domain' parameter '%s'\n", info);
470 return_value = 1;
471 return;
474 enumerator = g_socket_connectable_proxy_enumerate (connectable);
475 g_object_unref (connectable);
477 printf ("Proxies for hostname and port '%s' are:\n", info);
478 run_with_enumerator (synchronous, enumerator);
480 g_object_unref (enumerator);
483 static void
484 _socket_connect_cb (GObject *object,
485 GAsyncResult *result,
486 gpointer user_data)
488 GError *error = NULL;
489 GMainLoop *loop = user_data;
490 GSocketClient *client = G_SOCKET_CLIENT (object);
491 GSocketConnection *connection;
493 connection = g_socket_client_connect_to_uri_finish (client,
494 result,
495 &error);
496 if (connection)
498 GSocketAddress *proxy_addr;
499 proxy_addr = g_socket_connection_get_remote_address (connection, NULL);
500 print_proxy_address (proxy_addr);
502 else
504 print_and_free_error (error);
507 g_main_loop_quit (loop);
510 static void
511 use_socket_client (gboolean synchronous)
513 GError *error = NULL;
514 GSocketClient *client;
516 client = g_socket_client_new ();
518 printf ("Proxies for URI '%s' are:\n", info);
520 if (synchronous)
522 GSocketConnection *connection;
523 GSocketAddress *proxy_addr;
525 connection = g_socket_client_connect_to_uri (client,
526 info,
528 cancellable,
529 &error);
531 if (connection)
533 proxy_addr = g_socket_connection_get_remote_address (connection, NULL);
534 print_proxy_address (proxy_addr);
536 else
538 print_and_free_error (error);
541 else
543 GMainLoop *loop = g_main_loop_new (NULL, FALSE);
545 g_socket_client_connect_to_uri_async (client,
546 info,
548 cancellable,
549 _socket_connect_cb,
550 loop);
552 g_main_loop_run (loop);
553 g_main_loop_unref (loop);
556 g_object_unref (client);
559 typedef enum
561 USE_RESOLVER,
562 USE_ENUMERATOR,
563 #ifdef G_OS_UNIX
564 USE_UNIX_SOCKET_ADDRESS,
565 #endif
566 USE_INET_SOCKET_ADDRESS,
567 USE_PROXY_ADDRESS,
568 USE_NETWORK_ADDRESS,
569 USE_NETWORK_URI,
570 USE_NETWORK_SERVICE,
571 USE_SOCKET_CLIENT,
572 } ProxyTestType;
574 gint
575 main (gint argc, gchar **argv)
577 gboolean synchronous = FALSE;
578 gboolean cancel = FALSE;
579 ProxyTestType type = USE_RESOLVER;
581 while (argc >= 2 && argv[1][0] == '-')
583 if (!strcmp (argv[1], "-s"))
584 synchronous = TRUE;
585 else if (!strcmp (argv[1], "-c"))
586 cancel = TRUE;
587 else if (!strcmp (argv[1], "-e"))
588 type = USE_ENUMERATOR;
589 else if (!strcmp (argv[1], "-inet"))
590 type = USE_INET_SOCKET_ADDRESS;
591 #ifdef G_OS_UNIX
592 else if (!strcmp (argv[1], "-unix"))
593 type = USE_UNIX_SOCKET_ADDRESS;
594 #endif
595 else if (!strcmp (argv[1], "-proxyaddr"))
596 type = USE_PROXY_ADDRESS;
597 else if (!strcmp (argv[1], "-netaddr"))
598 type = USE_NETWORK_ADDRESS;
599 else if (!strcmp (argv[1], "-neturi"))
600 type = USE_NETWORK_URI;
601 else if (!strcmp (argv[1], "-netsrv"))
602 type = USE_NETWORK_SERVICE;
603 else if (!strcmp (argv[1], "-connect"))
604 type = USE_SOCKET_CLIENT;
605 else
606 usage ();
608 argv++;
609 argc--;
612 if (argc != 2)
613 usage ();
615 /* Save URI for asynchronous callback */
616 info = argv[1];
618 if (cancel)
620 cancellable = g_cancellable_new ();
621 g_cancellable_cancel (cancellable);
624 switch (type)
626 case USE_RESOLVER:
627 use_resolver (synchronous);
628 break;
629 case USE_ENUMERATOR:
630 use_enumerator (synchronous);
631 break;
632 case USE_INET_SOCKET_ADDRESS:
633 use_inet_address (synchronous);
634 break;
635 #ifdef G_OS_UNIX
636 case USE_UNIX_SOCKET_ADDRESS:
637 use_unix_address (synchronous);
638 break;
639 #endif
640 case USE_PROXY_ADDRESS:
641 use_proxy_address (synchronous);
642 break;
643 case USE_NETWORK_ADDRESS:
644 use_network_address (synchronous);
645 break;
646 case USE_NETWORK_URI:
647 use_network_uri (synchronous);
648 break;
649 case USE_NETWORK_SERVICE:
650 use_network_service (synchronous);
651 break;
652 case USE_SOCKET_CLIENT:
653 use_socket_client (synchronous);
654 break;
657 return return_value;