• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* GLib testing framework examples and tests
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  * Authors: Nicolas Dufresne <nicolas.dufresne@collabora.co.uk>
19  */
20 
21 #include "config.h"
22 
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <string.h>
26 
27 #include <gio/gio.h>
28 #include <glib.h>
29 
30 #include "glibintl.h"
31 
32 #ifdef G_OS_UNIX
33 #include "gio/gunixsocketaddress.h"
34 #endif
35 
36 static const gchar *info = NULL;
37 static GCancellable *cancellable = NULL;
38 static gint return_value = 0;
39 
40 static G_NORETURN void
usage(void)41 usage (void)
42 {
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);
59 }
60 
61 static void
print_and_free_error(GError * error)62 print_and_free_error (GError *error)
63 {
64   fprintf (stderr, "Failed to obtain proxies: %s\n", error->message);
65   g_error_free (error);
66   return_value = 1;
67 }
68 
69 static void
print_proxies(const gchar * info,gchar ** proxies)70 print_proxies (const gchar *info, gchar **proxies)
71 {
72   printf ("Proxies for URI '%s' are:\n", info);
73 
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]);
79 }
80 
81 static void
_proxy_lookup_cb(GObject * source_object,GAsyncResult * result,gpointer user_data)82 _proxy_lookup_cb (GObject *source_object,
83 		  GAsyncResult *result,
84 		  gpointer user_data)
85 {
86   GError *error = NULL;
87   gchar **proxies;
88   GMainLoop *loop = user_data;
89 
90   proxies = g_proxy_resolver_lookup_finish (G_PROXY_RESOLVER (source_object),
91 					    result,
92 					    &error);
93   if (error)
94     {
95       print_and_free_error (error);
96     }
97   else
98     {
99       print_proxies (info, proxies);
100       g_strfreev (proxies);
101     }
102 
103   g_main_loop_quit (loop);
104 }
105 
106 static void
use_resolver(gboolean synchronous)107 use_resolver (gboolean synchronous)
108 {
109   GProxyResolver *resolver;
110 
111   resolver = g_proxy_resolver_get_default ();
112 
113   if (synchronous)
114     {
115       GError *error = NULL;
116       gchar **proxies;
117 
118       proxies = g_proxy_resolver_lookup (resolver, info, cancellable, &error);
119 
120       if (error)
121 	  print_and_free_error (error);
122       else
123 	  print_proxies (info, proxies);
124 
125       g_strfreev (proxies);
126     }
127   else
128     {
129       GMainLoop *loop = g_main_loop_new (NULL, FALSE);
130 
131       g_proxy_resolver_lookup_async (resolver,
132 				     info,
133 				     cancellable,
134 				     _proxy_lookup_cb,
135 				     loop);
136 
137       g_main_loop_run (loop);
138       g_main_loop_unref (loop);
139     }
140 }
141 
142 static void
print_proxy_address(GSocketAddress * sockaddr)143 print_proxy_address (GSocketAddress *sockaddr)
144 {
145   GProxyAddress *proxy = NULL;
146 
147   if (sockaddr == NULL)
148     {
149       printf ("\tdirect://\n");
150       return;
151     }
152 
153   if (G_IS_PROXY_ADDRESS (sockaddr))
154     {
155       proxy = G_PROXY_ADDRESS (sockaddr);
156       printf ("\t%s://", g_proxy_address_get_protocol(proxy));
157     }
158   else
159     {
160       printf ("\tdirect://");
161     }
162 
163   if (G_IS_INET_SOCKET_ADDRESS (sockaddr))
164     {
165       GInetAddress *inetaddr;
166       guint port;
167       gchar *addr;
168 
169       g_object_get (sockaddr,
170 		    "address", &inetaddr,
171 		    "port", &port,
172 		    NULL);
173 
174       addr = g_inet_address_to_string (inetaddr);
175 
176       printf ("%s:%u", addr, port);
177 
178       g_free (addr);
179     }
180 
181   if (proxy)
182     {
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));
190     }
191 
192   printf ("\n");
193 }
194 
195 static void
_proxy_enumerate_cb(GObject * object,GAsyncResult * result,gpointer user_data)196 _proxy_enumerate_cb (GObject *object,
197 		     GAsyncResult *result,
198 		     gpointer user_data)
199 {
200   GError *error = NULL;
201   GMainLoop *loop = user_data;
202   GSocketAddressEnumerator *enumerator = G_SOCKET_ADDRESS_ENUMERATOR (object);
203   GSocketAddress *sockaddr;
204 
205   sockaddr = g_socket_address_enumerator_next_finish (enumerator,
206 						      result,
207 						      &error);
208   if (sockaddr)
209     {
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);
216     }
217   else
218     {
219       if (error)
220 	print_and_free_error (error);
221 
222       g_main_loop_quit (loop);
223     }
224 }
225 
226 static void
run_with_enumerator(gboolean synchronous,GSocketAddressEnumerator * enumerator)227 run_with_enumerator (gboolean synchronous, GSocketAddressEnumerator *enumerator)
228 {
229   GError *error = NULL;
230 
231   if (synchronous)
232     {
233       GSocketAddress *sockaddr;
234 
235       while ((sockaddr = g_socket_address_enumerator_next (enumerator,
236 							   cancellable,
237 							   &error)))
238 	{
239 	  print_proxy_address (sockaddr);
240 	  g_object_unref (sockaddr);
241 	}
242 
243       if (error)
244 	print_and_free_error (error);
245     }
246   else
247     {
248       GMainLoop *loop = g_main_loop_new (NULL, FALSE);
249 
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);
256     }
257 }
258 
259 static void
use_enumerator(gboolean synchronous)260 use_enumerator (gboolean synchronous)
261 {
262   GSocketAddressEnumerator *enumerator;
263 
264   enumerator = g_object_new (G_TYPE_PROXY_ADDRESS_ENUMERATOR,
265 			     "uri", info,
266 			     NULL);
267 
268   printf ("Proxies for URI '%s' are:\n", info);
269   run_with_enumerator (synchronous, enumerator);
270 
271   g_object_unref (enumerator);
272 }
273 
274 static void
use_inet_address(gboolean synchronous)275 use_inet_address (gboolean synchronous)
276 {
277   GSocketAddressEnumerator *enumerator;
278   GSocketAddress *sockaddr;
279   GInetAddress *addr = NULL;
280   guint port = 0;
281   gchar **ip_and_port;
282 
283   ip_and_port = g_strsplit (info, ":", 2);
284 
285   if (ip_and_port[0])
286     {
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);
290     }
291 
292   g_strfreev (ip_and_port);
293 
294   if (addr == NULL || port <= 0 || port >= 65535)
295     {
296       fprintf (stderr, "Bad 'ip:port' parameter '%s'\n", info);
297       if (addr)
298 	g_object_unref (addr);
299       return_value = 1;
300       return;
301     }
302 
303   sockaddr = g_inet_socket_address_new (addr, port);
304   g_object_unref (addr);
305 
306   enumerator =
307     g_socket_connectable_proxy_enumerate (G_SOCKET_CONNECTABLE (sockaddr));
308   g_object_unref (sockaddr);
309 
310   printf ("Proxies for ip and port '%s' are:\n", info);
311   run_with_enumerator (synchronous, enumerator);
312 
313   g_object_unref (enumerator);
314 }
315 
316 #ifdef G_OS_UNIX
317 static void
use_unix_address(gboolean synchronous)318 use_unix_address (gboolean synchronous)
319 {
320   GSocketAddressEnumerator *enumerator;
321   GSocketAddress *sockaddr;
322 
323   sockaddr = g_unix_socket_address_new_with_type (info, -1, G_UNIX_SOCKET_ADDRESS_ABSTRACT);
324 
325   if (sockaddr == NULL)
326     {
327       fprintf (stderr, "Failed to create unix socket with name '%s'\n", info);
328       return_value = 1;
329       return;
330     }
331 
332   enumerator =
333     g_socket_connectable_proxy_enumerate (G_SOCKET_CONNECTABLE (sockaddr));
334   g_object_unref (sockaddr);
335 
336   printf ("Proxies for path '%s' are:\n", info);
337   run_with_enumerator (synchronous, enumerator);
338 
339   g_object_unref (enumerator);
340 }
341 #endif
342 
343 static void
use_proxy_address(gboolean synchronous)344 use_proxy_address (gboolean synchronous)
345 {
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;
356 
357   split_info = g_strsplit (info, ":", 7);
358 
359   if (!split_info[0]
360       || !split_info[1]
361       || !split_info[2]
362       || !split_info[3]
363       || !split_info[4])
364     {
365       fprintf (stderr, "Bad 'ip:port:protocol:dest_host:dest_port' parameter '%s'\n", info);
366       return_value = 1;
367       return;
368     }
369 
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);
375 
376   if (split_info[5])
377     {
378       username = g_strdup (split_info[5]);
379       if (split_info[6])
380         password = g_strdup (split_info[6]);
381     }
382 
383   g_strfreev (split_info);
384 
385   sockaddr = g_proxy_address_new (addr, port,
386                                   protocol, dest_host, dest_port,
387                                   username, password);
388 
389   g_object_unref (addr);
390   g_free (protocol);
391   g_free (dest_host);
392   g_free (username);
393   g_free (password);
394 
395   enumerator =
396     g_socket_connectable_proxy_enumerate (G_SOCKET_CONNECTABLE (sockaddr));
397   g_object_unref (sockaddr);
398 
399   printf ("Proxies for ip and port '%s' are:\n", info);
400   run_with_enumerator (synchronous, enumerator);
401 
402   g_object_unref (enumerator);
403 }
404 
405 static void
use_network_address(gboolean synchronous)406 use_network_address (gboolean synchronous)
407 {
408   GError *error = NULL;
409   GSocketAddressEnumerator *enumerator;
410   GSocketConnectable *connectable;
411 
412   connectable = g_network_address_parse (info, -1, &error);
413 
414   if (error)
415     {
416       print_and_free_error (error);
417       return;
418     }
419 
420   enumerator = g_socket_connectable_proxy_enumerate (connectable);
421   g_object_unref (connectable);
422 
423   printf ("Proxies for hostname and port '%s' are:\n", info);
424   run_with_enumerator (synchronous, enumerator);
425 
426   g_object_unref (enumerator);
427 }
428 
429 static void
use_network_uri(gboolean synchronous)430 use_network_uri (gboolean synchronous)
431 {
432   GError *error = NULL;
433   GSocketAddressEnumerator *enumerator;
434   GSocketConnectable *connectable;
435 
436   connectable = g_network_address_parse_uri (info, 0, &error);
437 
438   if (error)
439     {
440       print_and_free_error (error);
441       return;
442     }
443 
444   enumerator = g_socket_connectable_proxy_enumerate (connectable);
445   g_object_unref (connectable);
446 
447   printf ("Proxies for URI '%s' are:\n", info);
448   run_with_enumerator (synchronous, enumerator);
449 
450   g_object_unref (enumerator);
451 }
452 
453 static void
use_network_service(gboolean synchronous)454 use_network_service (gboolean synchronous)
455 {
456   GSocketAddressEnumerator *enumerator;
457   GSocketConnectable *connectable = NULL;
458   gchar **split;
459 
460   split = g_strsplit (info, "/", 3);
461 
462   if (split[0] && split[1] && split[2])
463     connectable = g_network_service_new (split[0], split[1], split[2]);
464 
465   g_strfreev (split);
466 
467   if (connectable == NULL)
468     {
469        fprintf (stderr, "Bad 'srv/protocol/domain' parameter '%s'\n", info);
470        return_value = 1;
471        return;
472     }
473 
474   enumerator = g_socket_connectable_proxy_enumerate (connectable);
475   g_object_unref (connectable);
476 
477   printf ("Proxies for hostname and port '%s' are:\n", info);
478   run_with_enumerator (synchronous, enumerator);
479 
480   g_object_unref (enumerator);
481 }
482 
483 static void
_socket_connect_cb(GObject * object,GAsyncResult * result,gpointer user_data)484 _socket_connect_cb (GObject *object,
485 		    GAsyncResult *result,
486 		    gpointer user_data)
487 {
488   GError *error = NULL;
489   GMainLoop *loop = user_data;
490   GSocketClient *client = G_SOCKET_CLIENT (object);
491   GSocketConnection *connection;
492 
493   connection = g_socket_client_connect_to_uri_finish (client,
494 						      result,
495 						      &error);
496   if (connection)
497     {
498       GSocketAddress *proxy_addr;
499       proxy_addr = g_socket_connection_get_remote_address (connection, NULL);
500       print_proxy_address (proxy_addr);
501     }
502   else
503     {
504       print_and_free_error (error);
505     }
506 
507   g_main_loop_quit (loop);
508 }
509 
510 static void
use_socket_client(gboolean synchronous)511 use_socket_client (gboolean synchronous)
512 {
513   GError *error = NULL;
514   GSocketClient *client;
515 
516   client = g_socket_client_new ();
517 
518   printf ("Proxies for URI '%s' are:\n", info);
519 
520   if (synchronous)
521     {
522       GSocketConnection *connection;
523       GSocketAddress *proxy_addr;
524 
525       connection = g_socket_client_connect_to_uri (client,
526 						   info,
527 						   0,
528       						   cancellable,
529 						   &error);
530 
531       if (connection)
532 	{
533 	  proxy_addr = g_socket_connection_get_remote_address (connection, NULL);
534 	  print_proxy_address (proxy_addr);
535 	}
536       else
537 	{
538 	  print_and_free_error (error);
539 	}
540     }
541   else
542     {
543       GMainLoop *loop = g_main_loop_new (NULL, FALSE);
544 
545       g_socket_client_connect_to_uri_async (client,
546 					    info,
547 					    0,
548 					    cancellable,
549 					    _socket_connect_cb,
550 					    loop);
551 
552       g_main_loop_run (loop);
553       g_main_loop_unref (loop);
554     }
555 
556   g_object_unref (client);
557 }
558 
559 typedef enum
560 {
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;
573 
574 gint
main(gint argc,gchar ** argv)575 main (gint argc, gchar **argv)
576 {
577   gboolean synchronous = FALSE;
578   gboolean cancel = FALSE;
579   ProxyTestType type = USE_RESOLVER;
580 
581   while (argc >= 2 && argv[1][0] == '-')
582     {
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 ();
607 
608       argv++;
609       argc--;
610     }
611 
612   if (argc != 2)
613     usage ();
614 
615   /* Save URI for asynchronous callback */
616   info = argv[1];
617 
618   if (cancel)
619     {
620       cancellable = g_cancellable_new ();
621       g_cancellable_cancel (cancellable);
622     }
623 
624   switch (type)
625     {
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;
655     }
656 
657   return return_value;
658 }
659