1 /* GLib testing framework examples and tests
2 *
3 * Copyright 2012 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.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
19 #include <string.h>
20
21 #define GLIB_VERSION_MIN_REQUIRED GLIB_VERSION_2_34
22 #include <gio/gio.h>
23
24 /* Overview:
25 *
26 * We have an echo server, two proxy servers, two GProxy
27 * implementations, and two GProxyResolver implementations.
28 *
29 * The echo server runs at @server.server_addr (on
30 * @server.server_port).
31 *
32 * The two proxy servers, A and B, run on @proxy_a.port and
33 * @proxy_b.port, with @proxy_a.uri and @proxy_b.uri pointing to them.
34 * The "negotiation" with the two proxies is just sending the single
35 * letter "a" or "b" and receiving it back in uppercase; the proxy
36 * then connects to @server_addr.
37 *
38 * Proxy A supports "alpha://" URIs, and does not support hostname
39 * resolution, and Proxy B supports "beta://" URIs, and does support
40 * hostname resolution (but it just ignores the hostname and always
41 * connects to @server_addr anyway).
42 *
43 * The default GProxyResolver (GTestProxyResolver) looks at its URI
44 * and returns [ "direct://" ] for "simple://" URIs, and [
45 * proxy_a.uri, proxy_b.uri ] for other URIs. The other GProxyResolver
46 * (GTestAltProxyResolver) always returns [ proxy_a.uri ].
47 */
48
49 typedef struct {
50 gchar *proxy_command;
51 gchar *supported_protocol;
52
53 GSocket *server;
54 GThread *thread;
55 GCancellable *cancellable;
56 gchar *uri;
57 gushort port;
58
59 GSocket *client_sock, *server_sock;
60 GMainLoop *loop;
61
62 GError *last_error;
63 } ProxyData;
64
65 static ProxyData proxy_a, proxy_b;
66
67 typedef struct {
68 GSocket *server;
69 GThread *server_thread;
70 GCancellable *cancellable;
71 GSocketAddress *server_addr;
72 gushort server_port;
73 } ServerData;
74
75 static ServerData server;
76
77 static gchar **last_proxies;
78
79 static GSocketClient *client;
80
81
82 /**************************************/
83 /* Test GProxyResolver implementation */
84 /**************************************/
85
86 typedef struct {
87 GObject parent_instance;
88 } GTestProxyResolver;
89
90 typedef struct {
91 GObjectClass parent_class;
92 } GTestProxyResolverClass;
93
94 static void g_test_proxy_resolver_iface_init (GProxyResolverInterface *iface);
95
96 static GType _g_test_proxy_resolver_get_type (void);
97 #define g_test_proxy_resolver_get_type _g_test_proxy_resolver_get_type
98 G_DEFINE_TYPE_WITH_CODE (GTestProxyResolver, g_test_proxy_resolver, G_TYPE_OBJECT,
99 G_IMPLEMENT_INTERFACE (G_TYPE_PROXY_RESOLVER,
100 g_test_proxy_resolver_iface_init)
101 g_io_extension_point_implement (G_PROXY_RESOLVER_EXTENSION_POINT_NAME,
102 g_define_type_id,
103 "test",
104 0))
105
106 static void
g_test_proxy_resolver_init(GTestProxyResolver * resolver)107 g_test_proxy_resolver_init (GTestProxyResolver *resolver)
108 {
109 }
110
111 static gboolean
g_test_proxy_resolver_is_supported(GProxyResolver * resolver)112 g_test_proxy_resolver_is_supported (GProxyResolver *resolver)
113 {
114 return TRUE;
115 }
116
117 static gchar **
g_test_proxy_resolver_lookup(GProxyResolver * resolver,const gchar * uri,GCancellable * cancellable,GError ** error)118 g_test_proxy_resolver_lookup (GProxyResolver *resolver,
119 const gchar *uri,
120 GCancellable *cancellable,
121 GError **error)
122 {
123 gchar **proxies;
124
125 g_assert (last_proxies == NULL);
126
127 if (g_cancellable_set_error_if_cancelled (cancellable, error))
128 return NULL;
129
130 proxies = g_new (gchar *, 3);
131
132 if (!strncmp (uri, "simple://", 4))
133 {
134 proxies[0] = g_strdup ("direct://");
135 proxies[1] = NULL;
136 }
137 else
138 {
139 /* Proxy A can only deal with "alpha://" URIs, not
140 * "beta://", but we always return both URIs
141 * anyway so we can test error handling when the first
142 * fails.
143 */
144 proxies[0] = g_strdup (proxy_a.uri);
145 proxies[1] = g_strdup (proxy_b.uri);
146 proxies[2] = NULL;
147 }
148
149 last_proxies = g_strdupv (proxies);
150
151 return proxies;
152 }
153
154 static void
g_test_proxy_resolver_lookup_async(GProxyResolver * resolver,const gchar * uri,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)155 g_test_proxy_resolver_lookup_async (GProxyResolver *resolver,
156 const gchar *uri,
157 GCancellable *cancellable,
158 GAsyncReadyCallback callback,
159 gpointer user_data)
160 {
161 GError *error = NULL;
162 GTask *task;
163 gchar **proxies;
164
165 proxies = g_proxy_resolver_lookup (resolver, uri, cancellable, &error);
166
167 task = g_task_new (resolver, NULL, callback, user_data);
168 if (proxies == NULL)
169 g_task_return_error (task, error);
170 else
171 g_task_return_pointer (task, proxies, (GDestroyNotify) g_strfreev);
172
173 g_object_unref (task);
174 }
175
176 static gchar **
g_test_proxy_resolver_lookup_finish(GProxyResolver * resolver,GAsyncResult * result,GError ** error)177 g_test_proxy_resolver_lookup_finish (GProxyResolver *resolver,
178 GAsyncResult *result,
179 GError **error)
180 {
181 return g_task_propagate_pointer (G_TASK (result), error);
182 }
183
184 static void
g_test_proxy_resolver_class_init(GTestProxyResolverClass * resolver_class)185 g_test_proxy_resolver_class_init (GTestProxyResolverClass *resolver_class)
186 {
187 }
188
189 static void
g_test_proxy_resolver_iface_init(GProxyResolverInterface * iface)190 g_test_proxy_resolver_iface_init (GProxyResolverInterface *iface)
191 {
192 iface->is_supported = g_test_proxy_resolver_is_supported;
193 iface->lookup = g_test_proxy_resolver_lookup;
194 iface->lookup_async = g_test_proxy_resolver_lookup_async;
195 iface->lookup_finish = g_test_proxy_resolver_lookup_finish;
196 }
197
198 /****************************/
199 /* Alternate GProxyResolver */
200 /****************************/
201
202 typedef GTestProxyResolver GTestAltProxyResolver;
203 typedef GTestProxyResolverClass GTestAltProxyResolverClass;
204
205 static void g_test_alt_proxy_resolver_iface_init (GProxyResolverInterface *iface);
206
207 static GType _g_test_alt_proxy_resolver_get_type (void);
208 #define g_test_alt_proxy_resolver_get_type _g_test_alt_proxy_resolver_get_type
G_DEFINE_TYPE_WITH_CODE(GTestAltProxyResolver,g_test_alt_proxy_resolver,g_test_proxy_resolver_get_type (),G_IMPLEMENT_INTERFACE (G_TYPE_PROXY_RESOLVER,g_test_alt_proxy_resolver_iface_init);)209 G_DEFINE_TYPE_WITH_CODE (GTestAltProxyResolver, g_test_alt_proxy_resolver, g_test_proxy_resolver_get_type (),
210 G_IMPLEMENT_INTERFACE (G_TYPE_PROXY_RESOLVER,
211 g_test_alt_proxy_resolver_iface_init);
212 )
213
214 static void
215 g_test_alt_proxy_resolver_init (GTestProxyResolver *resolver)
216 {
217 }
218
219 static gchar **
g_test_alt_proxy_resolver_lookup(GProxyResolver * resolver,const gchar * uri,GCancellable * cancellable,GError ** error)220 g_test_alt_proxy_resolver_lookup (GProxyResolver *resolver,
221 const gchar *uri,
222 GCancellable *cancellable,
223 GError **error)
224 {
225 gchar **proxies;
226
227 proxies = g_new (gchar *, 2);
228
229 proxies[0] = g_strdup (proxy_a.uri);
230 proxies[1] = NULL;
231
232 last_proxies = g_strdupv (proxies);
233
234 return proxies;
235 }
236
237 static void
g_test_alt_proxy_resolver_class_init(GTestProxyResolverClass * resolver_class)238 g_test_alt_proxy_resolver_class_init (GTestProxyResolverClass *resolver_class)
239 {
240 }
241
242 static void
g_test_alt_proxy_resolver_iface_init(GProxyResolverInterface * iface)243 g_test_alt_proxy_resolver_iface_init (GProxyResolverInterface *iface)
244 {
245 iface->lookup = g_test_alt_proxy_resolver_lookup;
246 }
247
248
249 /****************************************/
250 /* Test proxy implementation base class */
251 /****************************************/
252
253 typedef struct {
254 GObject parent;
255
256 ProxyData *proxy_data;
257 } GProxyBase;
258
259 typedef struct {
260 GObjectClass parent_class;
261 } GProxyBaseClass;
262
263 static GType _g_proxy_base_get_type (void);
264 #define g_proxy_base_get_type _g_proxy_base_get_type
G_DEFINE_ABSTRACT_TYPE(GProxyBase,g_proxy_base,G_TYPE_OBJECT)265 G_DEFINE_ABSTRACT_TYPE (GProxyBase, g_proxy_base, G_TYPE_OBJECT)
266
267 static void
268 g_proxy_base_init (GProxyBase *proxy)
269 {
270 }
271
272 static GIOStream *
g_proxy_base_connect(GProxy * proxy,GIOStream * io_stream,GProxyAddress * proxy_address,GCancellable * cancellable,GError ** error)273 g_proxy_base_connect (GProxy *proxy,
274 GIOStream *io_stream,
275 GProxyAddress *proxy_address,
276 GCancellable *cancellable,
277 GError **error)
278 {
279 ProxyData *data = ((GProxyBase *) proxy)->proxy_data;
280 const gchar *protocol;
281 GOutputStream *ostream;
282 GInputStream *istream;
283 gchar response;
284
285 g_assert_no_error (data->last_error);
286
287 protocol = g_proxy_address_get_destination_protocol (proxy_address);
288 if (strcmp (protocol, data->supported_protocol) != 0)
289 {
290 g_set_error_literal (&data->last_error,
291 G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
292 "Unsupported protocol");
293 goto fail;
294 }
295
296 ostream = g_io_stream_get_output_stream (io_stream);
297 if (g_output_stream_write (ostream, data->proxy_command, 1, cancellable,
298 &data->last_error) != 1)
299 goto fail;
300
301 istream = g_io_stream_get_input_stream (io_stream);
302 if (g_input_stream_read (istream, &response, 1, cancellable,
303 &data->last_error) != 1)
304 goto fail;
305
306 if (response != g_ascii_toupper (*data->proxy_command))
307 {
308 g_set_error_literal (&data->last_error,
309 G_IO_ERROR, G_IO_ERROR_FAILED,
310 "Failed");
311 goto fail;
312 }
313
314 return g_object_ref (io_stream);
315
316 fail:
317 g_propagate_error (error, g_error_copy (data->last_error));
318 return NULL;
319 }
320
321 static void
g_proxy_base_connect_async(GProxy * proxy,GIOStream * io_stream,GProxyAddress * proxy_address,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)322 g_proxy_base_connect_async (GProxy *proxy,
323 GIOStream *io_stream,
324 GProxyAddress *proxy_address,
325 GCancellable *cancellable,
326 GAsyncReadyCallback callback,
327 gpointer user_data)
328 {
329 GError *error = NULL;
330 GTask *task;
331 GIOStream *proxy_io_stream;
332
333 task = g_task_new (proxy, NULL, callback, user_data);
334
335 proxy_io_stream = g_proxy_connect (proxy, io_stream, proxy_address,
336 cancellable, &error);
337 if (proxy_io_stream)
338 g_task_return_pointer (task, proxy_io_stream, g_object_unref);
339 else
340 g_task_return_error (task, error);
341 g_object_unref (task);
342 }
343
344 static GIOStream *
g_proxy_base_connect_finish(GProxy * proxy,GAsyncResult * result,GError ** error)345 g_proxy_base_connect_finish (GProxy *proxy,
346 GAsyncResult *result,
347 GError **error)
348 {
349 return g_task_propagate_pointer (G_TASK (result), error);
350 }
351
352 static void
g_proxy_base_class_init(GProxyBaseClass * class)353 g_proxy_base_class_init (GProxyBaseClass *class)
354 {
355 }
356
357
358 /********************************************/
359 /* Test proxy implementation #1 ("Proxy A") */
360 /********************************************/
361
362 typedef GProxyBase GProxyA;
363 typedef GProxyBaseClass GProxyAClass;
364
365 static void g_proxy_a_iface_init (GProxyInterface *proxy_iface);
366
367 static GType _g_proxy_a_get_type (void);
368 #define g_proxy_a_get_type _g_proxy_a_get_type
369 G_DEFINE_TYPE_WITH_CODE (GProxyA, g_proxy_a, g_proxy_base_get_type (),
370 G_IMPLEMENT_INTERFACE (G_TYPE_PROXY,
371 g_proxy_a_iface_init)
372 g_io_extension_point_implement (G_PROXY_EXTENSION_POINT_NAME,
373 g_define_type_id,
374 "proxy-a",
375 0))
376
377 static void
g_proxy_a_init(GProxyA * proxy)378 g_proxy_a_init (GProxyA *proxy)
379 {
380 ((GProxyBase *) proxy)->proxy_data = &proxy_a;
381 }
382
383 static gboolean
g_proxy_a_supports_hostname(GProxy * proxy)384 g_proxy_a_supports_hostname (GProxy *proxy)
385 {
386 return FALSE;
387 }
388
389 static void
g_proxy_a_class_init(GProxyAClass * class)390 g_proxy_a_class_init (GProxyAClass *class)
391 {
392 }
393
394 static void
g_proxy_a_iface_init(GProxyInterface * proxy_iface)395 g_proxy_a_iface_init (GProxyInterface *proxy_iface)
396 {
397 proxy_iface->connect = g_proxy_base_connect;
398 proxy_iface->connect_async = g_proxy_base_connect_async;
399 proxy_iface->connect_finish = g_proxy_base_connect_finish;
400 proxy_iface->supports_hostname = g_proxy_a_supports_hostname;
401 }
402
403 /********************************************/
404 /* Test proxy implementation #2 ("Proxy B") */
405 /********************************************/
406
407 typedef GProxyBase GProxyB;
408 typedef GProxyBaseClass GProxyBClass;
409
410 static void g_proxy_b_iface_init (GProxyInterface *proxy_iface);
411
412 static GType _g_proxy_b_get_type (void);
413 #define g_proxy_b_get_type _g_proxy_b_get_type
414 G_DEFINE_TYPE_WITH_CODE (GProxyB, g_proxy_b, g_proxy_base_get_type (),
415 G_IMPLEMENT_INTERFACE (G_TYPE_PROXY,
416 g_proxy_b_iface_init)
417 g_io_extension_point_implement (G_PROXY_EXTENSION_POINT_NAME,
418 g_define_type_id,
419 "proxy-b",
420 0))
421
422 static void
g_proxy_b_init(GProxyB * proxy)423 g_proxy_b_init (GProxyB *proxy)
424 {
425 ((GProxyBase *) proxy)->proxy_data = &proxy_b;
426 }
427
428 static gboolean
g_proxy_b_supports_hostname(GProxy * proxy)429 g_proxy_b_supports_hostname (GProxy *proxy)
430 {
431 return TRUE;
432 }
433
434 static void
g_proxy_b_class_init(GProxyBClass * class)435 g_proxy_b_class_init (GProxyBClass *class)
436 {
437 }
438
439 static void
g_proxy_b_iface_init(GProxyInterface * proxy_iface)440 g_proxy_b_iface_init (GProxyInterface *proxy_iface)
441 {
442 proxy_iface->connect = g_proxy_base_connect;
443 proxy_iface->connect_async = g_proxy_base_connect_async;
444 proxy_iface->connect_finish = g_proxy_base_connect_finish;
445 proxy_iface->supports_hostname = g_proxy_b_supports_hostname;
446 }
447
448
449 /***********************************/
450 /* The proxy server implementation */
451 /***********************************/
452
453 static gboolean
proxy_bytes(GSocket * socket,GIOCondition condition,gpointer user_data)454 proxy_bytes (GSocket *socket,
455 GIOCondition condition,
456 gpointer user_data)
457 {
458 ProxyData *proxy = user_data;
459 gssize nread, nwrote, total;
460 gchar buffer[8];
461 GSocket *out_socket;
462 GError *error = NULL;
463
464 nread = g_socket_receive_with_blocking (socket, buffer, sizeof (buffer),
465 TRUE, NULL, &error);
466 if (nread == -1)
467 {
468 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CLOSED);
469 return FALSE;
470 }
471 else
472 g_assert_no_error (error);
473
474 if (nread == 0)
475 {
476 g_main_loop_quit (proxy->loop);
477 return FALSE;
478 }
479
480 if (socket == proxy->client_sock)
481 out_socket = proxy->server_sock;
482 else
483 out_socket = proxy->client_sock;
484
485 for (total = 0; total < nread; total += nwrote)
486 {
487 nwrote = g_socket_send_with_blocking (out_socket,
488 buffer + total, nread - total,
489 TRUE, NULL, &error);
490 g_assert_no_error (error);
491 }
492
493 return TRUE;
494 }
495
496 static gpointer
proxy_thread(gpointer user_data)497 proxy_thread (gpointer user_data)
498 {
499 ProxyData *proxy = user_data;
500 GError *error = NULL;
501 gssize nread, nwrote;
502 gchar command[2] = { 0, 0 };
503 GMainContext *context;
504 GSource *read_source, *write_source;
505
506 context = g_main_context_new ();
507 proxy->loop = g_main_loop_new (context, FALSE);
508
509 while (TRUE)
510 {
511 proxy->client_sock = g_socket_accept (proxy->server, proxy->cancellable, &error);
512 if (!proxy->client_sock)
513 {
514 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
515 g_error_free (error);
516 break;
517 }
518 else
519 g_assert_no_error (error);
520
521 nread = g_socket_receive (proxy->client_sock, command, 1, NULL, &error);
522 g_assert_no_error (error);
523
524 if (nread == 0)
525 {
526 g_clear_object (&proxy->client_sock);
527 continue;
528 }
529
530 g_assert_cmpint (nread, ==, 1);
531 g_assert_cmpstr (command, ==, proxy->proxy_command);
532
533 *command = g_ascii_toupper (*command);
534 nwrote = g_socket_send (proxy->client_sock, command, 1, NULL, &error);
535 g_assert_no_error (error);
536 g_assert_cmpint (nwrote, ==, 1);
537
538 proxy->server_sock = g_socket_new (G_SOCKET_FAMILY_IPV4,
539 G_SOCKET_TYPE_STREAM,
540 G_SOCKET_PROTOCOL_DEFAULT,
541 &error);
542 g_assert_no_error (error);
543 g_socket_connect (proxy->server_sock, server.server_addr, NULL, &error);
544 g_assert_no_error (error);
545
546 read_source = g_socket_create_source (proxy->client_sock, G_IO_IN, NULL);
547 g_source_set_callback (read_source, (GSourceFunc)proxy_bytes, proxy, NULL);
548 g_source_attach (read_source, context);
549
550 write_source = g_socket_create_source (proxy->server_sock, G_IO_IN, NULL);
551 g_source_set_callback (write_source, (GSourceFunc)proxy_bytes, proxy, NULL);
552 g_source_attach (write_source, context);
553
554 g_main_loop_run (proxy->loop);
555
556 g_socket_close (proxy->client_sock, &error);
557 g_assert_no_error (error);
558 g_clear_object (&proxy->client_sock);
559
560 g_socket_close (proxy->server_sock, &error);
561 g_assert_no_error (error);
562 g_clear_object (&proxy->server_sock);
563
564 g_source_destroy (read_source);
565 g_source_unref (read_source);
566 g_source_destroy (write_source);
567 g_source_unref (write_source);
568 }
569
570 g_main_loop_unref (proxy->loop);
571 g_main_context_unref (context);
572
573 g_object_unref (proxy->server);
574 g_object_unref (proxy->cancellable);
575
576 g_free (proxy->proxy_command);
577 g_free (proxy->supported_protocol);
578 g_free (proxy->uri);
579
580 return NULL;
581 }
582
583 static void
create_proxy(ProxyData * proxy,gchar proxy_protocol,const gchar * destination_protocol,GCancellable * cancellable)584 create_proxy (ProxyData *proxy,
585 gchar proxy_protocol,
586 const gchar *destination_protocol,
587 GCancellable *cancellable)
588 {
589 GError *error = NULL;
590 GSocketAddress *addr;
591 GInetAddress *iaddr;
592
593 proxy->proxy_command = g_strdup_printf ("%c", proxy_protocol);
594 proxy->supported_protocol = g_strdup (destination_protocol);
595 proxy->cancellable = g_object_ref (cancellable);
596
597 proxy->server = g_socket_new (G_SOCKET_FAMILY_IPV4,
598 G_SOCKET_TYPE_STREAM,
599 G_SOCKET_PROTOCOL_DEFAULT,
600 &error);
601 g_assert_no_error (error);
602
603 iaddr = g_inet_address_new_loopback (G_SOCKET_FAMILY_IPV4);
604 addr = g_inet_socket_address_new (iaddr, 0);
605 g_object_unref (iaddr);
606
607 g_socket_bind (proxy->server, addr, TRUE, &error);
608 g_assert_no_error (error);
609 g_object_unref (addr);
610
611 addr = g_socket_get_local_address (proxy->server, &error);
612 proxy->port = g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (addr));
613 proxy->uri = g_strdup_printf ("proxy-%c://127.0.0.1:%u",
614 g_ascii_tolower (proxy_protocol),
615 proxy->port);
616 g_object_unref (addr);
617
618 g_socket_listen (proxy->server, &error);
619 g_assert_no_error (error);
620
621 proxy->thread = g_thread_new ("proxy", proxy_thread, proxy);
622 }
623
624
625
626 /**************************/
627 /* The actual echo server */
628 /**************************/
629
630 static gpointer
echo_server_thread(gpointer user_data)631 echo_server_thread (gpointer user_data)
632 {
633 ServerData *data = user_data;
634 GSocket *sock;
635 GError *error = NULL;
636 gssize nread, nwrote;
637 gchar buf[128];
638
639 while (TRUE)
640 {
641 sock = g_socket_accept (data->server, data->cancellable, &error);
642 if (!sock)
643 {
644 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_CANCELLED);
645 g_error_free (error);
646 break;
647 }
648 else
649 g_assert_no_error (error);
650
651 while (TRUE)
652 {
653 nread = g_socket_receive (sock, buf, sizeof (buf), NULL, &error);
654 g_assert_no_error (error);
655 g_assert_cmpint (nread, >=, 0);
656
657 if (nread == 0)
658 break;
659
660 nwrote = g_socket_send (sock, buf, nread, NULL, &error);
661 g_assert_no_error (error);
662 g_assert_cmpint (nwrote, ==, nread);
663 }
664
665 g_socket_close (sock, &error);
666 g_assert_no_error (error);
667 g_object_unref (sock);
668 }
669
670 g_object_unref (data->server);
671 g_object_unref (data->server_addr);
672 g_object_unref (data->cancellable);
673
674 return NULL;
675 }
676
677 static void
create_server(ServerData * data,GCancellable * cancellable)678 create_server (ServerData *data, GCancellable *cancellable)
679 {
680 GError *error = NULL;
681 GSocketAddress *addr;
682 GInetAddress *iaddr;
683
684 data->cancellable = g_object_ref (cancellable);
685
686 data->server = g_socket_new (G_SOCKET_FAMILY_IPV4,
687 G_SOCKET_TYPE_STREAM,
688 G_SOCKET_PROTOCOL_DEFAULT,
689 &error);
690 g_assert_no_error (error);
691
692 g_socket_set_blocking (data->server, TRUE);
693 iaddr = g_inet_address_new_loopback (G_SOCKET_FAMILY_IPV4);
694 addr = g_inet_socket_address_new (iaddr, 0);
695 g_object_unref (iaddr);
696
697 g_socket_bind (data->server, addr, TRUE, &error);
698 g_assert_no_error (error);
699 g_object_unref (addr);
700
701 data->server_addr = g_socket_get_local_address (data->server, &error);
702 g_assert_no_error (error);
703
704 data->server_port = g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (data->server_addr));
705
706 g_socket_listen (data->server, &error);
707 g_assert_no_error (error);
708
709 data->server_thread = g_thread_new ("server", echo_server_thread, data);
710 }
711
712
713 /******************************************************************/
714 /* Now a GResolver implementation, so the can't-resolve test will */
715 /* pass even if you have an evil DNS-faking ISP. */
716 /******************************************************************/
717
718 typedef GResolver GFakeResolver;
719 typedef GResolverClass GFakeResolverClass;
720
721 static GType g_fake_resolver_get_type (void);
G_DEFINE_TYPE(GFakeResolver,g_fake_resolver,G_TYPE_RESOLVER)722 G_DEFINE_TYPE (GFakeResolver, g_fake_resolver, G_TYPE_RESOLVER)
723
724 static void
725 g_fake_resolver_init (GFakeResolver *gtr)
726 {
727 }
728
729 static GList *
g_fake_resolver_lookup_by_name(GResolver * resolver,const gchar * hostname,GCancellable * cancellable,GError ** error)730 g_fake_resolver_lookup_by_name (GResolver *resolver,
731 const gchar *hostname,
732 GCancellable *cancellable,
733 GError **error)
734 {
735 if (!strcmp (hostname, "example.com"))
736 return g_list_prepend (NULL, g_inet_address_new_from_string ("127.0.0.1"));
737 else
738 {
739 /* Anything else is expected to fail. */
740 g_set_error (error,
741 G_RESOLVER_ERROR,
742 G_RESOLVER_ERROR_NOT_FOUND,
743 "Not found");
744 return NULL;
745 }
746 }
747
748 static void
g_fake_resolver_lookup_by_name_async(GResolver * resolver,const gchar * hostname,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)749 g_fake_resolver_lookup_by_name_async (GResolver *resolver,
750 const gchar *hostname,
751 GCancellable *cancellable,
752 GAsyncReadyCallback callback,
753 gpointer user_data)
754 {
755 GTask *task;
756
757 task = g_task_new (resolver, cancellable, callback, user_data);
758
759 if (!strcmp (hostname, "example.com"))
760 {
761 GList *result;
762
763 result = g_list_prepend (NULL, g_inet_address_new_from_string ("127.0.0.1"));
764 g_task_return_pointer (task, result, (GDestroyNotify) g_resolver_free_addresses);
765 }
766 else
767 {
768 g_task_return_new_error (task,
769 G_RESOLVER_ERROR, G_RESOLVER_ERROR_NOT_FOUND,
770 "Not found");
771 }
772 g_object_unref (task);
773 }
774
775 static void
g_fake_resolver_lookup_by_name_with_flags_async(GResolver * resolver,const gchar * hostname,GResolverNameLookupFlags flags,GCancellable * cancellable,GAsyncReadyCallback callback,gpointer user_data)776 g_fake_resolver_lookup_by_name_with_flags_async (GResolver *resolver,
777 const gchar *hostname,
778 GResolverNameLookupFlags flags,
779 GCancellable *cancellable,
780 GAsyncReadyCallback callback,
781 gpointer user_data)
782 {
783 /* Note this isn't a real implementation as it ignores the flags */
784 g_fake_resolver_lookup_by_name_async (resolver,
785 hostname,
786 cancellable,
787 callback,
788 user_data);
789 }
790
791 static GList *
g_fake_resolver_lookup_by_name_finish(GResolver * resolver,GAsyncResult * result,GError ** error)792 g_fake_resolver_lookup_by_name_finish (GResolver *resolver,
793 GAsyncResult *result,
794 GError **error)
795 {
796 return g_task_propagate_pointer (G_TASK (result), error);
797 }
798
799 static void
g_fake_resolver_class_init(GFakeResolverClass * fake_class)800 g_fake_resolver_class_init (GFakeResolverClass *fake_class)
801 {
802 GResolverClass *resolver_class = G_RESOLVER_CLASS (fake_class);
803
804 resolver_class->lookup_by_name = g_fake_resolver_lookup_by_name;
805 resolver_class->lookup_by_name_async = g_fake_resolver_lookup_by_name_async;
806 resolver_class->lookup_by_name_finish = g_fake_resolver_lookup_by_name_finish;
807 resolver_class->lookup_by_name_with_flags_async = g_fake_resolver_lookup_by_name_with_flags_async;
808 resolver_class->lookup_by_name_with_flags_finish = g_fake_resolver_lookup_by_name_finish;
809 }
810
811
812
813 /****************************************/
814 /* We made it! Now for the actual test! */
815 /****************************************/
816
817 static void
setup_test(gpointer fixture,gconstpointer user_data)818 setup_test (gpointer fixture,
819 gconstpointer user_data)
820 {
821 }
822
823 static void
teardown_test(gpointer fixture,gconstpointer user_data)824 teardown_test (gpointer fixture,
825 gconstpointer user_data)
826 {
827 if (last_proxies)
828 {
829 g_strfreev (last_proxies);
830 last_proxies = NULL;
831 }
832 g_clear_error (&proxy_a.last_error);
833 g_clear_error (&proxy_b.last_error);
834 }
835
836
837 static const gchar *testbuf = "0123456789abcdef";
838
839 static void
do_echo_test(GSocketConnection * conn)840 do_echo_test (GSocketConnection *conn)
841 {
842 GIOStream *iostream = G_IO_STREAM (conn);
843 GInputStream *istream = g_io_stream_get_input_stream (iostream);
844 GOutputStream *ostream = g_io_stream_get_output_stream (iostream);
845 gssize nread, total;
846 gsize nwrote;
847 gchar buf[128];
848 GError *error = NULL;
849
850 g_output_stream_write_all (ostream, testbuf, strlen (testbuf),
851 &nwrote, NULL, &error);
852 g_assert_no_error (error);
853 g_assert_cmpint (nwrote, ==, strlen (testbuf));
854
855 for (total = 0; total < nwrote; total += nread)
856 {
857 nread = g_input_stream_read (istream,
858 buf + total, sizeof (buf) - total,
859 NULL, &error);
860 g_assert_no_error (error);
861 g_assert_cmpint (nread, >, 0);
862 }
863
864 buf[total] = '\0';
865 g_assert_cmpstr (buf, ==, testbuf);
866 }
867
868 static void
async_got_conn(GObject * source,GAsyncResult * result,gpointer user_data)869 async_got_conn (GObject *source,
870 GAsyncResult *result,
871 gpointer user_data)
872 {
873 GSocketConnection **conn = user_data;
874 GError *error = NULL;
875
876 *conn = g_socket_client_connect_finish (G_SOCKET_CLIENT (source),
877 result, &error);
878 g_assert_no_error (error);
879 }
880
881 static void
async_got_error(GObject * source,GAsyncResult * result,gpointer user_data)882 async_got_error (GObject *source,
883 GAsyncResult *result,
884 gpointer user_data)
885 {
886 GError **error = user_data;
887
888 g_assert (error != NULL && *error == NULL);
889 g_socket_client_connect_finish (G_SOCKET_CLIENT (source),
890 result, error);
891 g_assert (*error != NULL);
892 }
893
894
895 static void
assert_direct(GSocketConnection * conn)896 assert_direct (GSocketConnection *conn)
897 {
898 GSocketAddress *addr;
899 GError *error = NULL;
900
901 g_assert_cmpint (g_strv_length (last_proxies), ==, 1);
902 g_assert_cmpstr (last_proxies[0], ==, "direct://");
903 g_assert_no_error (proxy_a.last_error);
904 g_assert_no_error (proxy_b.last_error);
905
906 addr = g_socket_connection_get_remote_address (conn, &error);
907 g_assert_no_error (error);
908 g_assert (addr != NULL && !G_IS_PROXY_ADDRESS (addr));
909 g_object_unref (addr);
910
911 addr = g_socket_connection_get_local_address (conn, &error);
912 g_assert_no_error (error);
913 g_object_unref (addr);
914
915 g_assert (g_socket_connection_is_connected (conn));
916 }
917
918 static void
test_direct_sync(gpointer fixture,gconstpointer user_data)919 test_direct_sync (gpointer fixture,
920 gconstpointer user_data)
921 {
922 GSocketConnection *conn;
923 gchar *uri;
924 GError *error = NULL;
925
926 /* The simple:// URI should not require any proxy. */
927
928 uri = g_strdup_printf ("simple://127.0.0.1:%u", server.server_port);
929 conn = g_socket_client_connect_to_uri (client, uri, 0, NULL, &error);
930 g_free (uri);
931 g_assert_no_error (error);
932
933 assert_direct (conn);
934 do_echo_test (conn);
935 g_object_unref (conn);
936 }
937
938 static void
test_direct_async(gpointer fixture,gconstpointer user_data)939 test_direct_async (gpointer fixture,
940 gconstpointer user_data)
941 {
942 GSocketConnection *conn;
943 gchar *uri;
944
945 /* The simple:// URI should not require any proxy. */
946 uri = g_strdup_printf ("simple://127.0.0.1:%u", server.server_port);
947 conn = NULL;
948 g_socket_client_connect_to_uri_async (client, uri, 0, NULL,
949 async_got_conn, &conn);
950 g_free (uri);
951 while (conn == NULL)
952 g_main_context_iteration (NULL, TRUE);
953
954 assert_direct (conn);
955 do_echo_test (conn);
956 g_object_unref (conn);
957 }
958
959 static void
assert_single(GSocketConnection * conn)960 assert_single (GSocketConnection *conn)
961 {
962 GSocketAddress *addr;
963 const gchar *proxy_uri;
964 gushort proxy_port;
965 GError *error = NULL;
966
967 g_assert_cmpint (g_strv_length (last_proxies), ==, 2);
968 g_assert_cmpstr (last_proxies[0], ==, proxy_a.uri);
969 g_assert_cmpstr (last_proxies[1], ==, proxy_b.uri);
970 g_assert_no_error (proxy_a.last_error);
971 g_assert_no_error (proxy_b.last_error);
972
973 addr = g_socket_connection_get_remote_address (conn, &error);
974 g_assert_no_error (error);
975 g_assert (G_IS_PROXY_ADDRESS (addr));
976 proxy_uri = g_proxy_address_get_uri (G_PROXY_ADDRESS (addr));
977 g_assert_cmpstr (proxy_uri, ==, proxy_a.uri);
978 proxy_port = g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (addr));
979 g_assert_cmpint (proxy_port, ==, proxy_a.port);
980
981 g_object_unref (addr);
982 }
983
984 static void
test_single_sync(gpointer fixture,gconstpointer user_data)985 test_single_sync (gpointer fixture,
986 gconstpointer user_data)
987 {
988 GSocketConnection *conn;
989 GError *error = NULL;
990 gchar *uri;
991
992 /* The alpha:// URI should be proxied via Proxy A */
993 uri = g_strdup_printf ("alpha://127.0.0.1:%u", server.server_port);
994 conn = g_socket_client_connect_to_uri (client, uri, 0, NULL, &error);
995 g_free (uri);
996 g_assert_no_error (error);
997
998 assert_single (conn);
999
1000 do_echo_test (conn);
1001 g_object_unref (conn);
1002 }
1003
1004 static void
test_single_async(gpointer fixture,gconstpointer user_data)1005 test_single_async (gpointer fixture,
1006 gconstpointer user_data)
1007 {
1008 GSocketConnection *conn;
1009 gchar *uri;
1010
1011 /* The alpha:// URI should be proxied via Proxy A */
1012 uri = g_strdup_printf ("alpha://127.0.0.1:%u", server.server_port);
1013 conn = NULL;
1014 g_socket_client_connect_to_uri_async (client, uri, 0, NULL,
1015 async_got_conn, &conn);
1016 g_free (uri);
1017 while (conn == NULL)
1018 g_main_context_iteration (NULL, TRUE);
1019
1020 assert_single (conn);
1021 do_echo_test (conn);
1022 g_object_unref (conn);
1023 }
1024
1025 static void
assert_multiple(GSocketConnection * conn)1026 assert_multiple (GSocketConnection *conn)
1027 {
1028 GSocketAddress *addr;
1029 const gchar *proxy_uri;
1030 gushort proxy_port;
1031 GError *error = NULL;
1032
1033 g_assert_cmpint (g_strv_length (last_proxies), ==, 2);
1034 g_assert_cmpstr (last_proxies[0], ==, proxy_a.uri);
1035 g_assert_cmpstr (last_proxies[1], ==, proxy_b.uri);
1036 g_assert_error (proxy_a.last_error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED);
1037 g_assert_no_error (proxy_b.last_error);
1038
1039 addr = g_socket_connection_get_remote_address (conn, &error);
1040 g_assert_no_error (error);
1041 g_assert (G_IS_PROXY_ADDRESS (addr));
1042 proxy_uri = g_proxy_address_get_uri (G_PROXY_ADDRESS (addr));
1043 g_assert_cmpstr (proxy_uri, ==, proxy_b.uri);
1044 proxy_port = g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (addr));
1045 g_assert_cmpint (proxy_port, ==, proxy_b.port);
1046
1047 g_object_unref (addr);
1048 }
1049
1050 static void
test_multiple_sync(gpointer fixture,gconstpointer user_data)1051 test_multiple_sync (gpointer fixture,
1052 gconstpointer user_data)
1053 {
1054 GSocketConnection *conn;
1055 GError *error = NULL;
1056 gchar *uri;
1057
1058 /* The beta:// URI should be proxied via Proxy B, after failing
1059 * via Proxy A.
1060 */
1061 uri = g_strdup_printf ("beta://127.0.0.1:%u", server.server_port);
1062 conn = g_socket_client_connect_to_uri (client, uri, 0, NULL, &error);
1063 g_free (uri);
1064 g_assert_no_error (error);
1065
1066 assert_multiple (conn);
1067 do_echo_test (conn);
1068 g_object_unref (conn);
1069 }
1070
1071 static void
test_multiple_async(gpointer fixture,gconstpointer user_data)1072 test_multiple_async (gpointer fixture,
1073 gconstpointer user_data)
1074 {
1075 GSocketConnection *conn;
1076 gchar *uri;
1077
1078 /* The beta:// URI should be proxied via Proxy B, after failing
1079 * via Proxy A.
1080 */
1081 uri = g_strdup_printf ("beta://127.0.0.1:%u", server.server_port);
1082 conn = NULL;
1083 g_socket_client_connect_to_uri_async (client, uri, 0, NULL,
1084 async_got_conn, &conn);
1085 g_free (uri);
1086 while (conn == NULL)
1087 g_main_context_iteration (NULL, TRUE);
1088
1089 assert_multiple (conn);
1090 do_echo_test (conn);
1091 g_object_unref (conn);
1092 }
1093
1094 static void
test_dns(gpointer fixture,gconstpointer user_data)1095 test_dns (gpointer fixture,
1096 gconstpointer user_data)
1097 {
1098 GSocketConnection *conn;
1099 GError *error = NULL;
1100 gchar *uri;
1101
1102 /* The simple:// and alpha:// URIs should fail with a DNS error,
1103 * but the beta:// URI should succeed, because we pass it to
1104 * Proxy B without trying to resolve it first
1105 */
1106
1107 /* simple */
1108 uri = g_strdup_printf ("simple://no-such-host.xx:%u", server.server_port);
1109 conn = g_socket_client_connect_to_uri (client, uri, 0, NULL, &error);
1110 g_assert_error (error, G_RESOLVER_ERROR, G_RESOLVER_ERROR_NOT_FOUND);
1111 g_clear_error (&error);
1112
1113 g_assert_no_error (proxy_a.last_error);
1114 g_assert_no_error (proxy_b.last_error);
1115 teardown_test (NULL, NULL);
1116
1117 g_socket_client_connect_to_uri_async (client, uri, 0, NULL,
1118 async_got_error, &error);
1119 while (error == NULL)
1120 g_main_context_iteration (NULL, TRUE);
1121 g_assert_error (error, G_RESOLVER_ERROR, G_RESOLVER_ERROR_NOT_FOUND);
1122 g_clear_error (&error);
1123 g_free (uri);
1124
1125 g_assert_no_error (proxy_a.last_error);
1126 g_assert_no_error (proxy_b.last_error);
1127 teardown_test (NULL, NULL);
1128
1129 /* alpha */
1130 uri = g_strdup_printf ("alpha://no-such-host.xx:%u", server.server_port);
1131 conn = g_socket_client_connect_to_uri (client, uri, 0, NULL, &error);
1132 /* Since Proxy A fails, @client will try Proxy B too, which won't
1133 * load an alpha:// URI.
1134 */
1135 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED);
1136 g_clear_error (&error);
1137
1138 g_assert_no_error (proxy_a.last_error);
1139 g_assert_error (proxy_b.last_error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED);
1140 teardown_test (NULL, NULL);
1141
1142 g_socket_client_connect_to_uri_async (client, uri, 0, NULL,
1143 async_got_error, &error);
1144 while (error == NULL)
1145 g_main_context_iteration (NULL, TRUE);
1146 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED);
1147 g_clear_error (&error);
1148 g_free (uri);
1149
1150 g_assert_no_error (proxy_a.last_error);
1151 g_assert_error (proxy_b.last_error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED);
1152 teardown_test (NULL, NULL);
1153
1154 /* beta */
1155 uri = g_strdup_printf ("beta://no-such-host.xx:%u", server.server_port);
1156 conn = g_socket_client_connect_to_uri (client, uri, 0, NULL, &error);
1157 g_assert_no_error (error);
1158
1159 g_assert_no_error (proxy_a.last_error);
1160 g_assert_no_error (proxy_b.last_error);
1161
1162 do_echo_test (conn);
1163 g_clear_object (&conn);
1164 teardown_test (NULL, NULL);
1165
1166 g_socket_client_connect_to_uri_async (client, uri, 0, NULL,
1167 async_got_conn, &conn);
1168 while (conn == NULL)
1169 g_main_context_iteration (NULL, TRUE);
1170 g_free (uri);
1171
1172 g_assert_no_error (proxy_a.last_error);
1173 g_assert_no_error (proxy_b.last_error);
1174
1175 do_echo_test (conn);
1176 g_clear_object (&conn);
1177 teardown_test (NULL, NULL);
1178 }
1179
1180 static void
assert_override(GSocketConnection * conn)1181 assert_override (GSocketConnection *conn)
1182 {
1183 g_assert_cmpint (g_strv_length (last_proxies), ==, 1);
1184 g_assert_cmpstr (last_proxies[0], ==, proxy_a.uri);
1185
1186 if (conn)
1187 g_assert_no_error (proxy_a.last_error);
1188 else
1189 g_assert_error (proxy_a.last_error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED);
1190 }
1191
1192 static void
test_override(gpointer fixture,gconstpointer user_data)1193 test_override (gpointer fixture,
1194 gconstpointer user_data)
1195 {
1196 GProxyResolver *alt_resolver;
1197 GSocketConnection *conn;
1198 GError *error = NULL;
1199 gchar *uri;
1200
1201 g_assert (g_socket_client_get_proxy_resolver (client) == g_proxy_resolver_get_default ());
1202 alt_resolver = g_object_new (g_test_alt_proxy_resolver_get_type (), NULL);
1203 g_socket_client_set_proxy_resolver (client, alt_resolver);
1204 g_assert (g_socket_client_get_proxy_resolver (client) == alt_resolver);
1205
1206 /* Alt proxy resolver always returns Proxy A, so alpha:// should
1207 * succeed, and simple:// and beta:// should fail.
1208 */
1209
1210 /* simple */
1211 uri = g_strdup_printf ("simple://127.0.0.1:%u", server.server_port);
1212 conn = g_socket_client_connect_to_uri (client, uri, 0, NULL, &error);
1213 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED);
1214 g_clear_error (&error);
1215 assert_override (conn);
1216 teardown_test (NULL, NULL);
1217
1218 g_socket_client_connect_to_uri_async (client, uri, 0, NULL,
1219 async_got_error, &error);
1220 while (error == NULL)
1221 g_main_context_iteration (NULL, TRUE);
1222 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED);
1223 g_clear_error (&error);
1224 assert_override (conn);
1225 g_free (uri);
1226 teardown_test (NULL, NULL);
1227
1228 /* alpha */
1229 uri = g_strdup_printf ("alpha://127.0.0.1:%u", server.server_port);
1230 conn = g_socket_client_connect_to_uri (client, uri, 0, NULL, &error);
1231 g_assert_no_error (error);
1232 assert_override (conn);
1233 do_echo_test (conn);
1234 g_clear_object (&conn);
1235 teardown_test (NULL, NULL);
1236
1237 conn = NULL;
1238 g_socket_client_connect_to_uri_async (client, uri, 0, NULL,
1239 async_got_conn, &conn);
1240 while (conn == NULL)
1241 g_main_context_iteration (NULL, TRUE);
1242 assert_override (conn);
1243 do_echo_test (conn);
1244 g_clear_object (&conn);
1245 g_free (uri);
1246 teardown_test (NULL, NULL);
1247
1248 /* beta */
1249 uri = g_strdup_printf ("beta://127.0.0.1:%u", server.server_port);
1250 conn = g_socket_client_connect_to_uri (client, uri, 0, NULL, &error);
1251 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED);
1252 g_clear_error (&error);
1253 assert_override (conn);
1254 teardown_test (NULL, NULL);
1255
1256 g_socket_client_connect_to_uri_async (client, uri, 0, NULL,
1257 async_got_error, &error);
1258 while (error == NULL)
1259 g_main_context_iteration (NULL, TRUE);
1260 g_assert_error (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED);
1261 g_clear_error (&error);
1262 assert_override (conn);
1263 g_free (uri);
1264 teardown_test (NULL, NULL);
1265
1266 g_assert (g_socket_client_get_proxy_resolver (client) == alt_resolver);
1267 g_socket_client_set_proxy_resolver (client, NULL);
1268 g_assert (g_socket_client_get_proxy_resolver (client) == g_proxy_resolver_get_default ());
1269 g_object_unref (alt_resolver);
1270 }
1271
1272 static void
assert_destination_port(GSocketAddressEnumerator * etor,guint16 port)1273 assert_destination_port (GSocketAddressEnumerator *etor,
1274 guint16 port)
1275 {
1276 GSocketAddress *addr;
1277 GProxyAddress *paddr;
1278 GError *error = NULL;
1279
1280 while ((addr = g_socket_address_enumerator_next (etor, NULL, &error)))
1281 {
1282 g_assert_no_error (error);
1283
1284 g_assert (G_IS_PROXY_ADDRESS (addr));
1285 paddr = G_PROXY_ADDRESS (addr);
1286 g_assert_cmpint (g_proxy_address_get_destination_port (paddr), ==, port);
1287 g_object_unref (addr);
1288 }
1289 g_assert_no_error (error);
1290 }
1291
1292 static void
test_proxy_enumerator_ports(void)1293 test_proxy_enumerator_ports (void)
1294 {
1295 GSocketAddressEnumerator *etor;
1296
1297 etor = g_object_new (G_TYPE_PROXY_ADDRESS_ENUMERATOR,
1298 "uri", "http://example.com/",
1299 NULL);
1300 assert_destination_port (etor, 0);
1301 g_object_unref (etor);
1302
1303 /* Have to call this to clear last_proxies so the next call to
1304 * g_test_proxy_resolver_lookup() won't assert.
1305 */
1306 teardown_test (NULL, NULL);
1307
1308 etor = g_object_new (G_TYPE_PROXY_ADDRESS_ENUMERATOR,
1309 "uri", "http://example.com:8080/",
1310 NULL);
1311 assert_destination_port (etor, 8080);
1312 g_object_unref (etor);
1313
1314 teardown_test (NULL, NULL);
1315
1316 etor = g_object_new (G_TYPE_PROXY_ADDRESS_ENUMERATOR,
1317 "uri", "http://example.com/",
1318 "default-port", 80,
1319 NULL);
1320 assert_destination_port (etor, 80);
1321 g_object_unref (etor);
1322
1323 teardown_test (NULL, NULL);
1324
1325 etor = g_object_new (G_TYPE_PROXY_ADDRESS_ENUMERATOR,
1326 "uri", "http://example.com:8080/",
1327 "default-port", 80,
1328 NULL);
1329 assert_destination_port (etor, 8080);
1330 g_object_unref (etor);
1331
1332 teardown_test (NULL, NULL);
1333 }
1334
1335 int
main(int argc,char * argv[])1336 main (int argc,
1337 char *argv[])
1338 {
1339 GResolver *fake_resolver;
1340 GCancellable *cancellable;
1341 gint result;
1342
1343 g_test_init (&argc, &argv, NULL);
1344
1345 /* Register stuff. The dummy g_proxy_get_default_for_protocol() call
1346 * is to force _g_io_modules_ensure_extension_points_registered() to
1347 * get called, so we can then register a proxy resolver extension
1348 * point.
1349 */
1350 g_proxy_get_default_for_protocol ("foo");
1351 g_test_proxy_resolver_get_type ();
1352 g_proxy_a_get_type ();
1353 g_proxy_b_get_type ();
1354 g_setenv ("GIO_USE_PROXY_RESOLVER", "test", TRUE);
1355
1356 fake_resolver = g_object_new (g_fake_resolver_get_type (), NULL);
1357 g_resolver_set_default (fake_resolver);
1358
1359 cancellable = g_cancellable_new ();
1360 create_server (&server, cancellable);
1361 create_proxy (&proxy_a, 'a', "alpha", cancellable);
1362 create_proxy (&proxy_b, 'b', "beta", cancellable);
1363
1364 client = g_socket_client_new ();
1365 g_assert_cmpint (g_socket_client_get_enable_proxy (client), ==, TRUE);
1366
1367 g_test_add_vtable ("/proxy/direct_sync", 0, NULL, setup_test, test_direct_sync, teardown_test);
1368 g_test_add_vtable ("/proxy/direct_async", 0, NULL, setup_test, test_direct_async, teardown_test);
1369 g_test_add_vtable ("/proxy/single_sync", 0, NULL, setup_test, test_single_sync, teardown_test);
1370 g_test_add_vtable ("/proxy/single_async", 0, NULL, setup_test, test_single_async, teardown_test);
1371 g_test_add_vtable ("/proxy/multiple_sync", 0, NULL, setup_test, test_multiple_sync, teardown_test);
1372 g_test_add_vtable ("/proxy/multiple_async", 0, NULL, setup_test, test_multiple_async, teardown_test);
1373 g_test_add_vtable ("/proxy/dns", 0, NULL, setup_test, test_dns, teardown_test);
1374 g_test_add_vtable ("/proxy/override", 0, NULL, setup_test, test_override, teardown_test);
1375 g_test_add_func ("/proxy/enumerator-ports", test_proxy_enumerator_ports);
1376
1377 result = g_test_run();
1378
1379 g_object_unref (client);
1380
1381 g_cancellable_cancel (cancellable);
1382 g_thread_join (proxy_a.thread);
1383 g_thread_join (proxy_b.thread);
1384 g_thread_join (server.server_thread);
1385
1386 g_object_unref (cancellable);
1387
1388 return result;
1389 }
1390