mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-11-02 15:46:17 +01:00
659 lines
15 KiB
C
659 lines
15 KiB
C
/* GLib testing framework examples and tests
|
|
*
|
|
* Copyright (C) 2010 Collabora, Ltd.
|
|
*
|
|
* This library is free software; you can redistribute it and/or
|
|
* modify it under the terms of the GNU Lesser General Public
|
|
* License as published by the Free Software Foundation; either
|
|
* version 2 of the License, or (at your option) any later version.
|
|
*
|
|
* This library is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
* Lesser General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU Lesser General
|
|
* Public License along with this library; if not, see <http://www.gnu.org/licenses/>.
|
|
*
|
|
* Authors: Nicolas Dufresne <nicolas.dufresne@collabora.co.uk>
|
|
*/
|
|
|
|
#include "config.h"
|
|
|
|
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
|
|
#include <gio/gio.h>
|
|
#include <glib.h>
|
|
|
|
#include "glibintl.h"
|
|
|
|
#ifdef G_OS_UNIX
|
|
#include "gio/gunixsocketaddress.h"
|
|
#endif
|
|
|
|
static const gchar *info = NULL;
|
|
static GCancellable *cancellable = NULL;
|
|
static gint return_value = 0;
|
|
|
|
static void G_GNUC_NORETURN
|
|
usage (void)
|
|
{
|
|
fprintf (stderr, "Usage: proxy [-s] (uri|host:port|ip:port|path|srv/protocol/domain)\n");
|
|
fprintf (stderr, " Use -t to enable threading.\n");
|
|
fprintf (stderr, " Use -s to do synchronous lookups.\n");
|
|
fprintf (stderr, " Use -c to cancel operation.\n");
|
|
fprintf (stderr, " Use -e to use enumerator.\n");
|
|
fprintf (stderr, " Use -inet to use GInetSocketAddress enumerator (ip:port).\n");
|
|
#ifdef G_OS_UNIX
|
|
fprintf (stderr, " Use -unix to use GUnixSocketAddress enumerator (path).\n");
|
|
#endif
|
|
fprintf (stderr, " Use -proxyaddr tp use GProxyAddress enumerator "
|
|
"(ip:port:protocol:dest_host:dest_port[:username[:password]]).\n");
|
|
fprintf (stderr, " Use -netaddr to use GNetworkAddress enumerator (host:port).\n");
|
|
fprintf (stderr, " Use -neturi to use GNetworkAddress enumerator (uri).\n");
|
|
fprintf (stderr, " Use -netsrv to use GNetworkService enumerator (srv/protocol/domain).\n");
|
|
fprintf (stderr, " Use -connect to create a connection using GSocketClient object (uri).\n");
|
|
exit (1);
|
|
}
|
|
|
|
static void
|
|
print_and_free_error (GError *error)
|
|
{
|
|
fprintf (stderr, "Failed to obtain proxies: %s\n", error->message);
|
|
g_error_free (error);
|
|
return_value = 1;
|
|
}
|
|
|
|
static void
|
|
print_proxies (const gchar *info, gchar **proxies)
|
|
{
|
|
printf ("Proxies for URI '%s' are:\n", info);
|
|
|
|
if (proxies == NULL || proxies[0] == NULL)
|
|
printf ("\tnone\n");
|
|
else
|
|
for (; proxies[0]; proxies++)
|
|
printf ("\t%s\n", proxies[0]);
|
|
}
|
|
|
|
static void
|
|
_proxy_lookup_cb (GObject *source_object,
|
|
GAsyncResult *result,
|
|
gpointer user_data)
|
|
{
|
|
GError *error = NULL;
|
|
gchar **proxies;
|
|
GMainLoop *loop = user_data;
|
|
|
|
proxies = g_proxy_resolver_lookup_finish (G_PROXY_RESOLVER (source_object),
|
|
result,
|
|
&error);
|
|
if (error)
|
|
{
|
|
print_and_free_error (error);
|
|
}
|
|
else
|
|
{
|
|
print_proxies (info, proxies);
|
|
g_strfreev (proxies);
|
|
}
|
|
|
|
g_main_loop_quit (loop);
|
|
}
|
|
|
|
static void
|
|
use_resolver (gboolean synchronous)
|
|
{
|
|
GProxyResolver *resolver;
|
|
|
|
resolver = g_proxy_resolver_get_default ();
|
|
|
|
if (synchronous)
|
|
{
|
|
GError *error = NULL;
|
|
gchar **proxies;
|
|
|
|
proxies = g_proxy_resolver_lookup (resolver, info, cancellable, &error);
|
|
|
|
if (error)
|
|
print_and_free_error (error);
|
|
else
|
|
print_proxies (info, proxies);
|
|
|
|
g_strfreev (proxies);
|
|
}
|
|
else
|
|
{
|
|
GMainLoop *loop = g_main_loop_new (NULL, FALSE);
|
|
|
|
g_proxy_resolver_lookup_async (resolver,
|
|
info,
|
|
cancellable,
|
|
_proxy_lookup_cb,
|
|
loop);
|
|
|
|
g_main_loop_run (loop);
|
|
g_main_loop_unref (loop);
|
|
}
|
|
}
|
|
|
|
static void
|
|
print_proxy_address (GSocketAddress *sockaddr)
|
|
{
|
|
GProxyAddress *proxy = NULL;
|
|
|
|
if (sockaddr == NULL)
|
|
{
|
|
printf ("\tdirect://\n");
|
|
return;
|
|
}
|
|
|
|
if (G_IS_PROXY_ADDRESS (sockaddr))
|
|
{
|
|
proxy = G_PROXY_ADDRESS (sockaddr);
|
|
printf ("\t%s://", g_proxy_address_get_protocol(proxy));
|
|
}
|
|
else
|
|
{
|
|
printf ("\tdirect://");
|
|
}
|
|
|
|
if (G_IS_INET_SOCKET_ADDRESS (sockaddr))
|
|
{
|
|
GInetAddress *inetaddr;
|
|
guint port;
|
|
gchar *addr;
|
|
|
|
g_object_get (sockaddr,
|
|
"address", &inetaddr,
|
|
"port", &port,
|
|
NULL);
|
|
|
|
addr = g_inet_address_to_string (inetaddr);
|
|
|
|
printf ("%s:%u", addr, port);
|
|
|
|
g_free (addr);
|
|
}
|
|
|
|
if (proxy)
|
|
{
|
|
if (g_proxy_address_get_username(proxy))
|
|
printf (" (Username: %s Password: %s)",
|
|
g_proxy_address_get_username(proxy),
|
|
g_proxy_address_get_password(proxy));
|
|
printf (" (Hostname: %s, Port: %i)",
|
|
g_proxy_address_get_destination_hostname (proxy),
|
|
g_proxy_address_get_destination_port (proxy));
|
|
}
|
|
|
|
printf ("\n");
|
|
}
|
|
|
|
static void
|
|
_proxy_enumerate_cb (GObject *object,
|
|
GAsyncResult *result,
|
|
gpointer user_data)
|
|
{
|
|
GError *error = NULL;
|
|
GMainLoop *loop = user_data;
|
|
GSocketAddressEnumerator *enumerator = G_SOCKET_ADDRESS_ENUMERATOR (object);
|
|
GSocketAddress *sockaddr;
|
|
|
|
sockaddr = g_socket_address_enumerator_next_finish (enumerator,
|
|
result,
|
|
&error);
|
|
if (sockaddr)
|
|
{
|
|
print_proxy_address (sockaddr);
|
|
g_socket_address_enumerator_next_async (enumerator,
|
|
cancellable,
|
|
_proxy_enumerate_cb,
|
|
loop);
|
|
g_object_unref (sockaddr);
|
|
}
|
|
else
|
|
{
|
|
if (error)
|
|
print_and_free_error (error);
|
|
|
|
g_main_loop_quit (loop);
|
|
}
|
|
}
|
|
|
|
static void
|
|
run_with_enumerator (gboolean synchronous, GSocketAddressEnumerator *enumerator)
|
|
{
|
|
GError *error = NULL;
|
|
|
|
if (synchronous)
|
|
{
|
|
GSocketAddress *sockaddr;
|
|
|
|
while ((sockaddr = g_socket_address_enumerator_next (enumerator,
|
|
cancellable,
|
|
&error)))
|
|
{
|
|
print_proxy_address (sockaddr);
|
|
g_object_unref (sockaddr);
|
|
}
|
|
|
|
if (error)
|
|
print_and_free_error (error);
|
|
}
|
|
else
|
|
{
|
|
GMainLoop *loop = g_main_loop_new (NULL, FALSE);
|
|
|
|
g_socket_address_enumerator_next_async (enumerator,
|
|
cancellable,
|
|
_proxy_enumerate_cb,
|
|
loop);
|
|
g_main_loop_run (loop);
|
|
g_main_loop_unref (loop);
|
|
}
|
|
}
|
|
|
|
static void
|
|
use_enumerator (gboolean synchronous)
|
|
{
|
|
GSocketAddressEnumerator *enumerator;
|
|
|
|
enumerator = g_object_new (G_TYPE_PROXY_ADDRESS_ENUMERATOR,
|
|
"uri", info,
|
|
NULL);
|
|
|
|
printf ("Proxies for URI '%s' are:\n", info);
|
|
run_with_enumerator (synchronous, enumerator);
|
|
|
|
g_object_unref (enumerator);
|
|
}
|
|
|
|
static void
|
|
use_inet_address (gboolean synchronous)
|
|
{
|
|
GSocketAddressEnumerator *enumerator;
|
|
GSocketAddress *sockaddr;
|
|
GInetAddress *addr = NULL;
|
|
guint port = 0;
|
|
gchar **ip_and_port;
|
|
|
|
ip_and_port = g_strsplit (info, ":", 2);
|
|
|
|
if (ip_and_port[0])
|
|
{
|
|
addr = g_inet_address_new_from_string (ip_and_port[0]);
|
|
if (ip_and_port [1])
|
|
port = strtoul (ip_and_port [1], NULL, 10);
|
|
}
|
|
|
|
g_strfreev (ip_and_port);
|
|
|
|
if (addr == NULL || port <= 0 || port >= 65535)
|
|
{
|
|
fprintf (stderr, "Bad 'ip:port' parameter '%s'\n", info);
|
|
if (addr)
|
|
g_object_unref (addr);
|
|
return_value = 1;
|
|
return;
|
|
}
|
|
|
|
sockaddr = g_inet_socket_address_new (addr, port);
|
|
g_object_unref (addr);
|
|
|
|
enumerator =
|
|
g_socket_connectable_proxy_enumerate (G_SOCKET_CONNECTABLE (sockaddr));
|
|
g_object_unref (sockaddr);
|
|
|
|
printf ("Proxies for ip and port '%s' are:\n", info);
|
|
run_with_enumerator (synchronous, enumerator);
|
|
|
|
g_object_unref (enumerator);
|
|
}
|
|
|
|
#ifdef G_OS_UNIX
|
|
static void
|
|
use_unix_address (gboolean synchronous)
|
|
{
|
|
GSocketAddressEnumerator *enumerator;
|
|
GSocketAddress *sockaddr;
|
|
|
|
sockaddr = g_unix_socket_address_new_with_type (info, -1, G_UNIX_SOCKET_ADDRESS_ABSTRACT);
|
|
|
|
if (sockaddr == NULL)
|
|
{
|
|
fprintf (stderr, "Failed to create unix socket with name '%s'\n", info);
|
|
return_value = 1;
|
|
return;
|
|
}
|
|
|
|
enumerator =
|
|
g_socket_connectable_proxy_enumerate (G_SOCKET_CONNECTABLE (sockaddr));
|
|
g_object_unref (sockaddr);
|
|
|
|
printf ("Proxies for path '%s' are:\n", info);
|
|
run_with_enumerator (synchronous, enumerator);
|
|
|
|
g_object_unref (enumerator);
|
|
}
|
|
#endif
|
|
|
|
static void
|
|
use_proxy_address (gboolean synchronous)
|
|
{
|
|
GSocketAddressEnumerator *enumerator;
|
|
GSocketAddress *sockaddr;
|
|
GInetAddress *addr;
|
|
guint port = 0;
|
|
gchar *protocol;
|
|
gchar *dest_host;
|
|
guint dest_port;
|
|
gchar *username = NULL;
|
|
gchar *password = NULL;
|
|
gchar **split_info;
|
|
|
|
split_info = g_strsplit (info, ":", 7);
|
|
|
|
if (!split_info[0]
|
|
|| !split_info[1]
|
|
|| !split_info[2]
|
|
|| !split_info[3]
|
|
|| !split_info[4])
|
|
{
|
|
fprintf (stderr, "Bad 'ip:port:protocol:dest_host:dest_port' parameter '%s'\n", info);
|
|
return_value = 1;
|
|
return;
|
|
}
|
|
|
|
addr = g_inet_address_new_from_string (split_info[0]);
|
|
port = strtoul (split_info [1], NULL, 10);
|
|
protocol = g_strdup (split_info[2]);
|
|
dest_host = g_strdup (split_info[3]);
|
|
dest_port = strtoul (split_info[4], NULL, 10);
|
|
|
|
if (split_info[5])
|
|
{
|
|
username = g_strdup (split_info[5]);
|
|
if (split_info[6])
|
|
password = g_strdup (split_info[6]);
|
|
}
|
|
|
|
g_strfreev (split_info);
|
|
|
|
sockaddr = g_proxy_address_new (addr, port,
|
|
protocol, dest_host, dest_port,
|
|
username, password);
|
|
|
|
g_object_unref (addr);
|
|
g_free (protocol);
|
|
g_free (dest_host);
|
|
g_free (username);
|
|
g_free (password);
|
|
|
|
enumerator =
|
|
g_socket_connectable_proxy_enumerate (G_SOCKET_CONNECTABLE (sockaddr));
|
|
g_object_unref (sockaddr);
|
|
|
|
printf ("Proxies for ip and port '%s' are:\n", info);
|
|
run_with_enumerator (synchronous, enumerator);
|
|
|
|
g_object_unref (enumerator);
|
|
}
|
|
|
|
static void
|
|
use_network_address (gboolean synchronous)
|
|
{
|
|
GError *error = NULL;
|
|
GSocketAddressEnumerator *enumerator;
|
|
GSocketConnectable *connectable;
|
|
|
|
connectable = g_network_address_parse (info, -1, &error);
|
|
|
|
if (error)
|
|
{
|
|
print_and_free_error (error);
|
|
return;
|
|
}
|
|
|
|
enumerator = g_socket_connectable_proxy_enumerate (connectable);
|
|
g_object_unref (connectable);
|
|
|
|
printf ("Proxies for hostname and port '%s' are:\n", info);
|
|
run_with_enumerator (synchronous, enumerator);
|
|
|
|
g_object_unref (enumerator);
|
|
}
|
|
|
|
static void
|
|
use_network_uri (gboolean synchronous)
|
|
{
|
|
GError *error = NULL;
|
|
GSocketAddressEnumerator *enumerator;
|
|
GSocketConnectable *connectable;
|
|
|
|
connectable = g_network_address_parse_uri (info, 0, &error);
|
|
|
|
if (error)
|
|
{
|
|
print_and_free_error (error);
|
|
return;
|
|
}
|
|
|
|
enumerator = g_socket_connectable_proxy_enumerate (connectable);
|
|
g_object_unref (connectable);
|
|
|
|
printf ("Proxies for URI '%s' are:\n", info);
|
|
run_with_enumerator (synchronous, enumerator);
|
|
|
|
g_object_unref (enumerator);
|
|
}
|
|
|
|
static void
|
|
use_network_service (gboolean synchronous)
|
|
{
|
|
GSocketAddressEnumerator *enumerator;
|
|
GSocketConnectable *connectable = NULL;
|
|
gchar **split;
|
|
|
|
split = g_strsplit (info, "/", 3);
|
|
|
|
if (split[0] && split[1] && split[2])
|
|
connectable = g_network_service_new (split[0], split[1], split[2]);
|
|
|
|
g_strfreev (split);
|
|
|
|
if (connectable == NULL)
|
|
{
|
|
fprintf (stderr, "Bad 'srv/protocol/domain' parameter '%s'\n", info);
|
|
return_value = 1;
|
|
return;
|
|
}
|
|
|
|
enumerator = g_socket_connectable_proxy_enumerate (connectable);
|
|
g_object_unref (connectable);
|
|
|
|
printf ("Proxies for hostname and port '%s' are:\n", info);
|
|
run_with_enumerator (synchronous, enumerator);
|
|
|
|
g_object_unref (enumerator);
|
|
}
|
|
|
|
static void
|
|
_socket_connect_cb (GObject *object,
|
|
GAsyncResult *result,
|
|
gpointer user_data)
|
|
{
|
|
GError *error = NULL;
|
|
GMainLoop *loop = user_data;
|
|
GSocketClient *client = G_SOCKET_CLIENT (object);
|
|
GSocketConnection *connection;
|
|
|
|
connection = g_socket_client_connect_to_uri_finish (client,
|
|
result,
|
|
&error);
|
|
if (connection)
|
|
{
|
|
GSocketAddress *proxy_addr;
|
|
proxy_addr = g_socket_connection_get_remote_address (connection, NULL);
|
|
print_proxy_address (proxy_addr);
|
|
}
|
|
else
|
|
{
|
|
print_and_free_error (error);
|
|
}
|
|
|
|
g_main_loop_quit (loop);
|
|
}
|
|
|
|
static void
|
|
use_socket_client (gboolean synchronous)
|
|
{
|
|
GError *error = NULL;
|
|
GSocketClient *client;
|
|
|
|
client = g_socket_client_new ();
|
|
|
|
printf ("Proxies for URI '%s' are:\n", info);
|
|
|
|
if (synchronous)
|
|
{
|
|
GSocketConnection *connection;
|
|
GSocketAddress *proxy_addr;
|
|
|
|
connection = g_socket_client_connect_to_uri (client,
|
|
info,
|
|
0,
|
|
cancellable,
|
|
&error);
|
|
|
|
if (connection)
|
|
{
|
|
proxy_addr = g_socket_connection_get_remote_address (connection, NULL);
|
|
print_proxy_address (proxy_addr);
|
|
}
|
|
else
|
|
{
|
|
print_and_free_error (error);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
GMainLoop *loop = g_main_loop_new (NULL, FALSE);
|
|
|
|
g_socket_client_connect_to_uri_async (client,
|
|
info,
|
|
0,
|
|
cancellable,
|
|
_socket_connect_cb,
|
|
loop);
|
|
|
|
g_main_loop_run (loop);
|
|
g_main_loop_unref (loop);
|
|
}
|
|
|
|
g_object_unref (client);
|
|
}
|
|
|
|
typedef enum
|
|
{
|
|
USE_RESOLVER,
|
|
USE_ENUMERATOR,
|
|
#ifdef G_OS_UNIX
|
|
USE_UNIX_SOCKET_ADDRESS,
|
|
#endif
|
|
USE_INET_SOCKET_ADDRESS,
|
|
USE_PROXY_ADDRESS,
|
|
USE_NETWORK_ADDRESS,
|
|
USE_NETWORK_URI,
|
|
USE_NETWORK_SERVICE,
|
|
USE_SOCKET_CLIENT,
|
|
} ProxyTestType;
|
|
|
|
gint
|
|
main (gint argc, gchar **argv)
|
|
{
|
|
gboolean synchronous = FALSE;
|
|
gboolean cancel = FALSE;
|
|
ProxyTestType type = USE_RESOLVER;
|
|
|
|
while (argc >= 2 && argv[1][0] == '-')
|
|
{
|
|
if (!strcmp (argv[1], "-s"))
|
|
synchronous = TRUE;
|
|
else if (!strcmp (argv[1], "-c"))
|
|
cancel = TRUE;
|
|
else if (!strcmp (argv[1], "-e"))
|
|
type = USE_ENUMERATOR;
|
|
else if (!strcmp (argv[1], "-inet"))
|
|
type = USE_INET_SOCKET_ADDRESS;
|
|
#ifdef G_OS_UNIX
|
|
else if (!strcmp (argv[1], "-unix"))
|
|
type = USE_UNIX_SOCKET_ADDRESS;
|
|
#endif
|
|
else if (!strcmp (argv[1], "-proxyaddr"))
|
|
type = USE_PROXY_ADDRESS;
|
|
else if (!strcmp (argv[1], "-netaddr"))
|
|
type = USE_NETWORK_ADDRESS;
|
|
else if (!strcmp (argv[1], "-neturi"))
|
|
type = USE_NETWORK_URI;
|
|
else if (!strcmp (argv[1], "-netsrv"))
|
|
type = USE_NETWORK_SERVICE;
|
|
else if (!strcmp (argv[1], "-connect"))
|
|
type = USE_SOCKET_CLIENT;
|
|
else
|
|
usage ();
|
|
|
|
argv++;
|
|
argc--;
|
|
}
|
|
|
|
if (argc != 2)
|
|
usage ();
|
|
|
|
/* Save URI for asynchronous callback */
|
|
info = argv[1];
|
|
|
|
if (cancel)
|
|
{
|
|
cancellable = g_cancellable_new ();
|
|
g_cancellable_cancel (cancellable);
|
|
}
|
|
|
|
switch (type)
|
|
{
|
|
case USE_RESOLVER:
|
|
use_resolver (synchronous);
|
|
break;
|
|
case USE_ENUMERATOR:
|
|
use_enumerator (synchronous);
|
|
break;
|
|
case USE_INET_SOCKET_ADDRESS:
|
|
use_inet_address (synchronous);
|
|
break;
|
|
#ifdef G_OS_UNIX
|
|
case USE_UNIX_SOCKET_ADDRESS:
|
|
use_unix_address (synchronous);
|
|
break;
|
|
#endif
|
|
case USE_PROXY_ADDRESS:
|
|
use_proxy_address (synchronous);
|
|
break;
|
|
case USE_NETWORK_ADDRESS:
|
|
use_network_address (synchronous);
|
|
break;
|
|
case USE_NETWORK_URI:
|
|
use_network_uri (synchronous);
|
|
break;
|
|
case USE_NETWORK_SERVICE:
|
|
use_network_service (synchronous);
|
|
break;
|
|
case USE_SOCKET_CLIENT:
|
|
use_socket_client (synchronous);
|
|
break;
|
|
}
|
|
|
|
return return_value;
|
|
}
|