Install all test data
[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, write to the
17  * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
18  * Boston, MA 02111-1307, USA.
19  *
20  * Authors: Nicolas Dufresne <nicolas.dufresne@collabora.co.uk>
21  */
22
23 #include "config.h"
24
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <string.h>
28
29 #include <gio/gio.h>
30 #include <glib.h>
31
32 #include "glibintl.h"
33
34 #ifdef G_OS_UNIX
35 #include "gio/gunixsocketaddress.h"
36 #endif
37
38 static const gchar *info = NULL;
39 static GCancellable *cancellable = NULL;
40 static gint return_value = 0;
41
42 static void G_GNUC_NORETURN
43 usage (void)
44 {
45   fprintf (stderr, "Usage: proxy [-s] (uri|host:port|ip:port|path|srv/protocol/domain)\n");
46   fprintf (stderr, "       Use -t to enable threading.\n");
47   fprintf (stderr, "       Use -s to do synchronous lookups.\n");
48   fprintf (stderr, "       Use -c to cancel operation.\n");
49   fprintf (stderr, "       Use -e to use enumerator.\n");
50   fprintf (stderr, "       Use -inet to use GInetSocketAddress enumerator (ip:port).\n");
51 #ifdef G_OS_UNIX
52   fprintf (stderr, "       Use -unix to use GUnixSocketAddress enumerator (path).\n");
53 #endif
54   fprintf (stderr, "       Use -proxyaddr tp use GProxyAddress enumerator "
55                    "(ip:port:protocol:dest_host:dest_port[:username[:password]]).\n");
56   fprintf (stderr, "       Use -netaddr to use GNetworkAddress enumerator (host:port).\n");
57   fprintf (stderr, "       Use -neturi to use GNetworkAddress enumerator (uri).\n");
58   fprintf (stderr, "       Use -netsrv to use GNetworkService enumerator (srv/protocol/domain).\n");
59   fprintf (stderr, "       Use -connect to create a connection using GSocketClient object (uri).\n");
60   exit (1);
61 }
62
63 static void
64 print_and_free_error (GError *error)
65 {
66   fprintf (stderr, "Failed to obtain proxies: %s\n", error->message);
67   g_error_free (error);
68   return_value = 1;
69 }
70
71 static void
72 print_proxies (const gchar *info, gchar **proxies)
73 {
74   printf ("Proxies for URI '%s' are:\n", info);
75
76   if (proxies == NULL || proxies[0] == NULL)
77     printf ("\tnone\n");
78   else
79     for (; proxies[0]; proxies++)
80       printf ("\t%s\n", proxies[0]);
81 }
82
83 static void
84 _proxy_lookup_cb (GObject *source_object,
85                   GAsyncResult *result,
86                   gpointer user_data)
87 {
88   GError *error = NULL;
89   gchar **proxies;
90   GMainLoop *loop = user_data;
91
92   proxies = g_proxy_resolver_lookup_finish (G_PROXY_RESOLVER (source_object),
93                                             result,
94                                             &error);
95   if (error)
96     {
97       print_and_free_error (error);
98     }
99   else
100     {
101       print_proxies (info, proxies);
102       g_strfreev (proxies);
103     }
104
105   g_main_loop_quit (loop);
106 }
107
108 static void
109 use_resolver (gboolean synchronous)
110 {
111   GProxyResolver *resolver;
112
113   resolver = g_proxy_resolver_get_default ();
114
115   if (synchronous)
116     {
117       GError *error = NULL;
118       gchar **proxies;
119
120       proxies = g_proxy_resolver_lookup (resolver, info, cancellable, &error);
121
122       if (error)
123           print_and_free_error (error);
124       else
125           print_proxies (info, proxies);
126
127       g_strfreev (proxies);
128     }
129   else
130     {
131       GMainLoop *loop = g_main_loop_new (NULL, FALSE);
132
133       g_proxy_resolver_lookup_async (resolver,
134                                      info,
135                                      cancellable,
136                                      _proxy_lookup_cb,
137                                      loop);
138
139       g_main_loop_run (loop);
140       g_main_loop_unref (loop);
141     }
142 }
143
144 static void
145 print_proxy_address (GSocketAddress *sockaddr)
146 {
147   GProxyAddress *proxy = NULL;
148
149   if (sockaddr == NULL)
150     {
151       printf ("\tdirect://\n");
152       return;
153     }
154
155   if (G_IS_PROXY_ADDRESS (sockaddr))
156     {
157       proxy = G_PROXY_ADDRESS (sockaddr);
158       printf ("\t%s://", g_proxy_address_get_protocol(proxy));
159     }
160   else
161     {
162       printf ("\tdirect://");
163     }
164
165   if (G_IS_INET_SOCKET_ADDRESS (sockaddr))
166     {
167       GInetAddress *inetaddr;
168       guint port;
169       gchar *addr;
170
171       g_object_get (sockaddr,
172                     "address", &inetaddr,
173                     "port", &port,
174                     NULL);
175
176       addr = g_inet_address_to_string (inetaddr);
177
178       printf ("%s:%u", addr, port);
179
180       g_free (addr);
181     }
182
183   if (proxy)
184     {
185       if (g_proxy_address_get_username(proxy))
186         printf (" (Username: %s  Password: %s)",
187                 g_proxy_address_get_username(proxy),
188                 g_proxy_address_get_password(proxy));
189       printf (" (Hostname: %s, Port: %i)",
190               g_proxy_address_get_destination_hostname (proxy),
191               g_proxy_address_get_destination_port (proxy));
192     }
193
194   printf ("\n");
195 }
196
197 static void
198 _proxy_enumerate_cb (GObject *object,
199                      GAsyncResult *result,
200                      gpointer user_data)
201 {
202   GError *error = NULL;
203   GMainLoop *loop = user_data;
204   GSocketAddressEnumerator *enumerator = G_SOCKET_ADDRESS_ENUMERATOR (object);
205   GSocketAddress *sockaddr;
206
207   sockaddr = g_socket_address_enumerator_next_finish (enumerator,
208                                                       result,
209                                                       &error);
210   if (sockaddr)
211     {
212       print_proxy_address (sockaddr);
213       g_socket_address_enumerator_next_async (enumerator,
214                                               cancellable,
215                                               _proxy_enumerate_cb,
216                                               loop);
217       g_object_unref (sockaddr);
218     }
219   else
220     {
221       if (error)
222         print_and_free_error (error);
223
224       g_main_loop_quit (loop);
225     }
226 }
227
228 static void
229 run_with_enumerator (gboolean synchronous, GSocketAddressEnumerator *enumerator)
230 {
231   GError *error = NULL;
232
233   if (synchronous)
234     {
235       GSocketAddress *sockaddr;
236
237       while ((sockaddr = g_socket_address_enumerator_next (enumerator,
238                                                            cancellable,
239                                                            &error)))
240         {
241           print_proxy_address (sockaddr);
242           g_object_unref (sockaddr);
243         }
244
245       if (error)
246         print_and_free_error (error);
247     }
248   else
249     {
250       GMainLoop *loop = g_main_loop_new (NULL, FALSE);
251
252       g_socket_address_enumerator_next_async (enumerator,
253                                               cancellable,
254                                               _proxy_enumerate_cb,
255                                               loop);
256       g_main_loop_run (loop);
257       g_main_loop_unref (loop);
258     }
259 }
260
261 static void
262 use_enumerator (gboolean synchronous)
263 {
264   GSocketAddressEnumerator *enumerator;
265
266   enumerator = g_object_new (G_TYPE_PROXY_ADDRESS_ENUMERATOR,
267                              "uri", info,
268                              NULL);
269
270   printf ("Proxies for URI '%s' are:\n", info);
271   run_with_enumerator (synchronous, enumerator);
272
273   g_object_unref (enumerator);
274 }
275
276 static void
277 use_inet_address (gboolean synchronous)
278 {
279   GSocketAddressEnumerator *enumerator;
280   GSocketAddress *sockaddr;
281   GInetAddress *addr = NULL;
282   guint port = 0;
283   gchar **ip_and_port;
284
285   ip_and_port = g_strsplit (info, ":", 2);
286
287   if (ip_and_port[0])
288     {
289       addr = g_inet_address_new_from_string (ip_and_port[0]);
290       if (ip_and_port [1])
291         port = strtoul (ip_and_port [1], NULL, 10);
292     }
293
294   g_strfreev (ip_and_port);
295
296   if (addr == NULL || port <= 0 || port >= 65535)
297     {
298       fprintf (stderr, "Bad 'ip:port' parameter '%s'\n", info);
299       if (addr)
300         g_object_unref (addr);
301       return_value = 1;
302       return;
303     }
304
305   sockaddr = g_inet_socket_address_new (addr, port);
306   g_object_unref (addr);
307
308   enumerator =
309     g_socket_connectable_proxy_enumerate (G_SOCKET_CONNECTABLE (sockaddr));
310   g_object_unref (sockaddr);
311
312   printf ("Proxies for ip and port '%s' are:\n", info);
313   run_with_enumerator (synchronous, enumerator);
314
315   g_object_unref (enumerator);
316 }
317
318 #ifdef G_OS_UNIX
319 static void
320 use_unix_address (gboolean synchronous)
321 {
322   GSocketAddressEnumerator *enumerator;
323   GSocketAddress *sockaddr;
324
325   sockaddr = g_unix_socket_address_new_with_type (info, -1, G_UNIX_SOCKET_ADDRESS_ABSTRACT);
326
327   if (sockaddr == NULL)
328     {
329       fprintf (stderr, "Failed to create unix socket with name '%s'\n", info);
330       return_value = 1;
331       return;
332     }
333
334   enumerator =
335     g_socket_connectable_proxy_enumerate (G_SOCKET_CONNECTABLE (sockaddr));
336   g_object_unref (sockaddr);
337
338   printf ("Proxies for path '%s' are:\n", info);
339   run_with_enumerator (synchronous, enumerator);
340
341   g_object_unref (enumerator);
342 }
343 #endif
344
345 static void
346 use_proxy_address (gboolean synchronous)
347 {
348   GSocketAddressEnumerator *enumerator;
349   GSocketAddress *sockaddr;
350   GInetAddress *addr;
351   guint port = 0;
352   gchar *protocol;
353   gchar *dest_host;
354   guint dest_port;
355   gchar *username = NULL;
356   gchar *password = NULL;
357   gchar **split_info;
358
359   split_info = g_strsplit (info, ":", 7);
360
361   if (!split_info[0]
362       || !split_info[1]
363       || !split_info[2]
364       || !split_info[3]
365       || !split_info[4])
366     {
367       fprintf (stderr, "Bad 'ip:port:protocol:dest_host:dest_port' parameter '%s'\n", info);
368       return_value = 1;
369       return;
370     }
371
372   addr = g_inet_address_new_from_string (split_info[0]);
373   port = strtoul (split_info [1], NULL, 10);
374   protocol = g_strdup (split_info[2]);
375   dest_host = g_strdup (split_info[3]);
376   dest_port = strtoul (split_info[4], NULL, 10);
377  
378   if (split_info[5])
379     {
380       username = g_strdup (split_info[5]);
381       if (split_info[6])
382         password = g_strdup (split_info[6]);
383     }
384
385   g_strfreev (split_info);
386
387   sockaddr = g_proxy_address_new (addr, port,
388                                   protocol, dest_host, dest_port,
389                                   username, password);
390   
391   g_object_unref (addr);
392   g_free (protocol);
393   g_free (dest_host);
394   g_free (username);
395   g_free (password);
396
397   enumerator =
398     g_socket_connectable_proxy_enumerate (G_SOCKET_CONNECTABLE (sockaddr));
399   g_object_unref (sockaddr);
400
401   printf ("Proxies for ip and port '%s' are:\n", info);
402   run_with_enumerator (synchronous, enumerator);
403
404   g_object_unref (enumerator);
405 }
406
407 static void
408 use_network_address (gboolean synchronous)
409 {
410   GError *error = NULL;
411   GSocketAddressEnumerator *enumerator;
412   GSocketConnectable *connectable;
413
414   connectable = g_network_address_parse (info, -1, &error);
415
416   if (error)
417     {
418       print_and_free_error (error);
419       return;
420     }
421
422   enumerator = g_socket_connectable_proxy_enumerate (connectable);
423   g_object_unref (connectable);
424
425   printf ("Proxies for hostname and port '%s' are:\n", info);
426   run_with_enumerator (synchronous, enumerator);
427
428   g_object_unref (enumerator);
429 }
430
431 static void
432 use_network_uri (gboolean synchronous)
433 {
434   GError *error = NULL;
435   GSocketAddressEnumerator *enumerator;
436   GSocketConnectable *connectable;
437
438   connectable = g_network_address_parse_uri (info, 0, &error);
439
440   if (error)
441     {
442       print_and_free_error (error);
443       return;
444     }
445
446   enumerator = g_socket_connectable_proxy_enumerate (connectable);
447   g_object_unref (connectable);
448
449   printf ("Proxies for URI '%s' are:\n", info);
450   run_with_enumerator (synchronous, enumerator);
451
452   g_object_unref (enumerator);
453 }
454
455 static void
456 use_network_service (gboolean synchronous)
457 {
458   GSocketAddressEnumerator *enumerator;
459   GSocketConnectable *connectable = NULL;
460   gchar **split;
461
462   split = g_strsplit (info, "/", 3);
463
464   if (split[0] && split[1] && split[2])
465     connectable = g_network_service_new (split[0], split[1], split[2]);
466
467   g_strfreev (split);
468
469   if (connectable == NULL)
470     {
471        fprintf (stderr, "Bad 'srv/protocol/domain' parameter '%s'\n", info);
472        return_value = 1;
473        return;
474     }
475
476   enumerator = g_socket_connectable_proxy_enumerate (connectable);
477   g_object_unref (connectable);
478
479   printf ("Proxies for hostname and port '%s' are:\n", info);
480   run_with_enumerator (synchronous, enumerator);
481
482   g_object_unref (enumerator);
483 }
484
485 static void
486 _socket_connect_cb (GObject *object,
487                     GAsyncResult *result,
488                     gpointer user_data)
489 {
490   GError *error = NULL;
491   GMainLoop *loop = user_data;
492   GSocketClient *client = G_SOCKET_CLIENT (object);
493   GSocketConnection *connection;
494
495   connection = g_socket_client_connect_to_uri_finish (client,
496                                                       result,
497                                                       &error);
498   if (connection)
499     {
500       GSocketAddress *proxy_addr;
501       proxy_addr = g_socket_connection_get_remote_address (connection, NULL);
502       print_proxy_address (proxy_addr);
503     }
504   else
505     {
506       print_and_free_error (error);
507     }
508
509   g_main_loop_quit (loop);
510 }
511
512 static void
513 use_socket_client (gboolean synchronous)
514 {
515   GError *error = NULL;
516   GSocketClient *client;
517
518   client = g_socket_client_new ();
519
520   printf ("Proxies for URI '%s' are:\n", info);
521
522   if (synchronous)
523     {
524       GSocketConnection *connection;
525       GSocketAddress *proxy_addr;
526
527       connection = g_socket_client_connect_to_uri (client,
528                                                    info,
529                                                    0,
530                                                    cancellable,
531                                                    &error);
532
533       if (connection)
534         {
535           proxy_addr = g_socket_connection_get_remote_address (connection, NULL);
536           print_proxy_address (proxy_addr);
537         }
538       else
539         {
540           print_and_free_error (error);
541         }
542     }
543   else
544     {
545       GMainLoop *loop = g_main_loop_new (NULL, FALSE);
546
547       g_socket_client_connect_to_uri_async (client,
548                                             info,
549                                             0,
550                                             cancellable,
551                                             _socket_connect_cb,
552                                             loop);
553
554       g_main_loop_run (loop);
555       g_main_loop_unref (loop);
556     }
557
558   g_object_unref (client);
559 }
560
561 typedef enum
562 {
563   USE_RESOLVER,
564   USE_ENUMERATOR,
565 #ifdef G_OS_UNIX
566   USE_UNIX_SOCKET_ADDRESS,
567 #endif
568   USE_INET_SOCKET_ADDRESS,
569   USE_PROXY_ADDRESS,
570   USE_NETWORK_ADDRESS,
571   USE_NETWORK_URI,
572   USE_NETWORK_SERVICE,
573   USE_SOCKET_CLIENT,
574 } ProxyTestType;
575
576 gint
577 main (gint argc, gchar **argv)
578 {
579   gboolean synchronous = FALSE;
580   gboolean cancel = FALSE;
581   ProxyTestType type = USE_RESOLVER;
582
583   while (argc >= 2 && argv[1][0] == '-')
584     {
585       if (!strcmp (argv[1], "-s"))
586         synchronous = TRUE;
587       else if (!strcmp (argv[1], "-c"))
588         cancel = TRUE;
589       else if (!strcmp (argv[1], "-e"))
590         type = USE_ENUMERATOR;
591       else if (!strcmp (argv[1], "-inet"))
592         type = USE_INET_SOCKET_ADDRESS;
593 #ifdef G_OS_UNIX
594       else if (!strcmp (argv[1], "-unix"))
595         type = USE_UNIX_SOCKET_ADDRESS;
596 #endif
597       else if (!strcmp (argv[1], "-proxyaddr"))
598         type = USE_PROXY_ADDRESS;
599       else if (!strcmp (argv[1], "-netaddr"))
600         type = USE_NETWORK_ADDRESS;
601       else if (!strcmp (argv[1], "-neturi"))
602         type = USE_NETWORK_URI;
603       else if (!strcmp (argv[1], "-netsrv"))
604         type = USE_NETWORK_SERVICE;
605       else if (!strcmp (argv[1], "-connect"))
606         type = USE_SOCKET_CLIENT;
607       else
608         usage ();
609
610       argv++;
611       argc--;
612     }
613
614   if (argc != 2)
615     usage ();
616
617   /* Save URI for asynchronous callback */
618   info = argv[1];
619
620   if (cancel)
621     {
622       cancellable = g_cancellable_new ();
623       g_cancellable_cancel (cancellable);
624     }
625
626   switch (type)
627     {
628     case USE_RESOLVER:
629       use_resolver (synchronous);
630       break;
631     case USE_ENUMERATOR:
632       use_enumerator (synchronous);
633       break;
634     case USE_INET_SOCKET_ADDRESS:
635       use_inet_address (synchronous);
636       break;
637 #ifdef G_OS_UNIX
638     case USE_UNIX_SOCKET_ADDRESS:
639       use_unix_address (synchronous);
640       break;
641 #endif
642     case USE_PROXY_ADDRESS:
643       use_proxy_address (synchronous);
644       break;
645     case USE_NETWORK_ADDRESS:
646       use_network_address (synchronous);
647       break;
648     case USE_NETWORK_URI:
649       use_network_uri (synchronous);
650       break;
651     case USE_NETWORK_SERVICE:
652       use_network_service (synchronous);
653       break;
654     case USE_SOCKET_CLIENT:
655       use_socket_client (synchronous);
656       break;
657     }
658
659   return return_value;
660 }