[kdbus] KDBUS_ITEM_PAYLOAD_OFF items are (once again) relative to msg header
[platform/upstream/glib.git] / gio / tests / proxy.c
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 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 void G_GNUC_NORETURN
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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 }