1 /* GIO - GLib Input, Output and Streaming Library
3 * Copyright © 2008, 2009 codethink
4 * Copyright © 2009 Red Hat, Inc
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General
17 * Public License along with this library; if not, write to the
18 * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
19 * Boston, MA 02111-1307, USA.
21 * Authors: Ryan Lortie <desrt@desrt.ca>
22 * Alexander Larsson <alexl@redhat.com>
26 #include "gsocketclient.h"
31 #include <gio/gioenumtypes.h>
32 #include <gio/gsocketaddressenumerator.h>
33 #include <gio/gsocketconnectable.h>
34 #include <gio/gsocketconnection.h>
35 #include <gio/gproxyaddressenumerator.h>
36 #include <gio/gproxyaddress.h>
37 #include <gio/gproxyconnection.h>
38 #include <gio/gsimpleasyncresult.h>
39 #include <gio/gcancellable.h>
40 #include <gio/gioerror.h>
41 #include <gio/gsocket.h>
42 #include <gio/gnetworkaddress.h>
43 #include <gio/gnetworkservice.h>
44 #include <gio/gproxy.h>
45 #include <gio/gsocketaddress.h>
46 #include <gio/gtcpconnection.h>
51 * SECTION:gsocketclient
52 * @short_description: Helper for connecting to a network service
54 * @see_also: #GSocketConnection, #GSocketListener
56 * #GSocketClient is a high-level utility class for connecting to a
57 * network host using a connection oriented socket type.
59 * You create a #GSocketClient object, set any options you want, then
60 * call a sync or async connect operation, which returns a #GSocketConnection
61 * subclass on success.
63 * The type of the #GSocketConnection object returned depends on the type of
64 * the underlying socket that is in use. For instance, for a TCP/IP connection
65 * it will be a #GTcpConnection.
71 G_DEFINE_TYPE (GSocketClient, g_socket_client, G_TYPE_OBJECT);
84 struct _GSocketClientPrivate
88 GSocketProtocol protocol;
89 GSocketAddress *local_address;
91 gboolean enable_proxy;
92 GHashTable *app_proxies;
96 create_socket (GSocketClient *client,
97 GSocketAddress *dest_address,
100 GSocketFamily family;
103 family = client->priv->family;
104 if (family == G_SOCKET_FAMILY_INVALID &&
105 client->priv->local_address != NULL)
106 family = g_socket_address_get_family (client->priv->local_address);
107 if (family == G_SOCKET_FAMILY_INVALID)
108 family = g_socket_address_get_family (dest_address);
110 socket = g_socket_new (family,
112 client->priv->protocol,
117 if (client->priv->local_address)
119 if (!g_socket_bind (socket,
120 client->priv->local_address,
124 g_object_unref (socket);
129 if (client->priv->timeout)
130 g_socket_set_timeout (socket, client->priv->timeout);
136 can_use_proxy (GSocketClient *client)
138 GSocketClientPrivate *priv = client->priv;
140 return priv->enable_proxy
141 && priv->type == G_SOCKET_TYPE_STREAM;
145 g_socket_client_init (GSocketClient *client)
147 client->priv = G_TYPE_INSTANCE_GET_PRIVATE (client,
148 G_TYPE_SOCKET_CLIENT,
149 GSocketClientPrivate);
150 client->priv->type = G_SOCKET_TYPE_STREAM;
151 client->priv->app_proxies = g_hash_table_new_full (g_str_hash,
158 * g_socket_client_new:
160 * Creates a new #GSocketClient with the default options.
162 * Returns: a #GSocketClient.
163 * Free the returned object with g_object_unref().
168 g_socket_client_new (void)
170 return g_object_new (G_TYPE_SOCKET_CLIENT, NULL);
174 g_socket_client_finalize (GObject *object)
176 GSocketClient *client = G_SOCKET_CLIENT (object);
178 if (client->priv->local_address)
179 g_object_unref (client->priv->local_address);
181 if (G_OBJECT_CLASS (g_socket_client_parent_class)->finalize)
182 (*G_OBJECT_CLASS (g_socket_client_parent_class)->finalize) (object);
184 g_hash_table_unref (client->priv->app_proxies);
188 g_socket_client_get_property (GObject *object,
193 GSocketClient *client = G_SOCKET_CLIENT (object);
198 g_value_set_enum (value, client->priv->family);
202 g_value_set_enum (value, client->priv->type);
206 g_value_set_enum (value, client->priv->protocol);
209 case PROP_LOCAL_ADDRESS:
210 g_value_set_object (value, client->priv->local_address);
214 g_value_set_uint (value, client->priv->timeout);
217 case PROP_ENABLE_PROXY:
218 g_value_set_boolean (value, client->priv->enable_proxy);
222 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
227 g_socket_client_set_property (GObject *object,
232 GSocketClient *client = G_SOCKET_CLIENT (object);
237 g_socket_client_set_family (client, g_value_get_enum (value));
241 g_socket_client_set_socket_type (client, g_value_get_enum (value));
245 g_socket_client_set_protocol (client, g_value_get_enum (value));
248 case PROP_LOCAL_ADDRESS:
249 g_socket_client_set_local_address (client, g_value_get_object (value));
253 g_socket_client_set_timeout (client, g_value_get_uint (value));
256 case PROP_ENABLE_PROXY:
257 g_socket_client_set_enable_proxy (client, g_value_get_boolean (value));
261 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
266 * g_socket_client_get_family:
267 * @client: a #GSocketClient.
269 * Gets the socket family of the socket client.
271 * See g_socket_client_set_family() for details.
273 * Returns: a #GSocketFamily
278 g_socket_client_get_family (GSocketClient *client)
280 return client->priv->family;
284 * g_socket_client_set_family:
285 * @client: a #GSocketClient.
286 * @family: a #GSocketFamily
288 * Sets the socket family of the socket client.
289 * If this is set to something other than %G_SOCKET_FAMILY_INVALID
290 * then the sockets created by this object will be of the specified
293 * This might be useful for instance if you want to force the local
294 * connection to be an ipv4 socket, even though the address might
295 * be an ipv6 mapped to ipv4 address.
300 g_socket_client_set_family (GSocketClient *client,
301 GSocketFamily family)
303 if (client->priv->family == family)
306 client->priv->family = family;
307 g_object_notify (G_OBJECT (client), "family");
311 * g_socket_client_get_socket_type:
312 * @client: a #GSocketClient.
314 * Gets the socket type of the socket client.
316 * See g_socket_client_set_socket_type() for details.
318 * Returns: a #GSocketFamily
323 g_socket_client_get_socket_type (GSocketClient *client)
325 return client->priv->type;
329 * g_socket_client_set_socket_type:
330 * @client: a #GSocketClient.
331 * @type: a #GSocketType
333 * Sets the socket type of the socket client.
334 * The sockets created by this object will be of the specified
337 * It doesn't make sense to specify a type of %G_SOCKET_TYPE_DATAGRAM,
338 * as GSocketClient is used for connection oriented services.
343 g_socket_client_set_socket_type (GSocketClient *client,
346 if (client->priv->type == type)
349 client->priv->type = type;
350 g_object_notify (G_OBJECT (client), "type");
354 * g_socket_client_get_protocol:
355 * @client: a #GSocketClient
357 * Gets the protocol name type of the socket client.
359 * See g_socket_client_set_protocol() for details.
361 * Returns: a #GSocketProtocol
366 g_socket_client_get_protocol (GSocketClient *client)
368 return client->priv->protocol;
372 * g_socket_client_set_protocol:
373 * @client: a #GSocketClient.
374 * @protocol: a #GSocketProtocol
376 * Sets the protocol of the socket client.
377 * The sockets created by this object will use of the specified
380 * If @protocol is %0 that means to use the default
381 * protocol for the socket family and type.
386 g_socket_client_set_protocol (GSocketClient *client,
387 GSocketProtocol protocol)
389 if (client->priv->protocol == protocol)
392 client->priv->protocol = protocol;
393 g_object_notify (G_OBJECT (client), "protocol");
397 * g_socket_client_get_local_address:
398 * @client: a #GSocketClient.
400 * Gets the local address of the socket client.
402 * See g_socket_client_set_local_address() for details.
404 * Returns: (transfer none): a #GSocketAddres or %NULL. don't free
409 g_socket_client_get_local_address (GSocketClient *client)
411 return client->priv->local_address;
415 * g_socket_client_set_local_address:
416 * @client: a #GSocketClient.
417 * @address: a #GSocketAddress, or %NULL
419 * Sets the local address of the socket client.
420 * The sockets created by this object will bound to the
421 * specified address (if not %NULL) before connecting.
423 * This is useful if you want to ensure the the local
424 * side of the connection is on a specific port, or on
425 * a specific interface.
430 g_socket_client_set_local_address (GSocketClient *client,
431 GSocketAddress *address)
434 g_object_ref (address);
436 if (client->priv->local_address)
438 g_object_unref (client->priv->local_address);
440 client->priv->local_address = address;
441 g_object_notify (G_OBJECT (client), "local-address");
445 * g_socket_client_get_timeout:
446 * @client: a #GSocketClient
448 * Gets the I/O timeout time for sockets created by @client.
450 * See g_socket_client_set_timeout() for details.
452 * Returns: the timeout in seconds
457 g_socket_client_get_timeout (GSocketClient *client)
459 return client->priv->timeout;
464 * g_socket_client_set_timeout:
465 * @client: a #GSocketClient.
466 * @timeout: the timeout
468 * Sets the I/O timeout for sockets created by @client. @timeout is a
469 * time in seconds, or 0 for no timeout (the default).
471 * The timeout value affects the initial connection attempt as well,
472 * so setting this may cause calls to g_socket_client_connect(), etc,
473 * to fail with %G_IO_ERROR_TIMED_OUT.
478 g_socket_client_set_timeout (GSocketClient *client,
481 if (client->priv->timeout == timeout)
484 client->priv->timeout = timeout;
485 g_object_notify (G_OBJECT (client), "timeout");
489 * g_socket_client_get_enable_proxy:
490 * @client: a #GSocketClient.
492 * Gets the proxy enable state; see g_socket_client_set_enable_proxy()
494 * Returns: whether proxying is enabled
499 g_socket_client_get_enable_proxy (GSocketClient *client)
501 return client->priv->enable_proxy;
505 * g_socket_client_set_enable_proxy:
506 * @client: a #GSocketClient.
507 * @enable: whether to enable proxies
509 * Sets whether or not @client attempts to make connections via a
510 * proxy server. When enabled (the default), #GSocketClient will use a
511 * #GProxyResolver to determine if a proxy protocol such as SOCKS is
512 * needed, and automatically do the necessary proxy negotiation.
517 g_socket_client_set_enable_proxy (GSocketClient *client,
521 if (client->priv->enable_proxy == enable)
524 client->priv->enable_proxy = enable;
525 g_object_notify (G_OBJECT (client), "enable-proxy");
529 g_socket_client_class_init (GSocketClientClass *class)
531 GObjectClass *gobject_class = G_OBJECT_CLASS (class);
533 g_type_class_add_private (class, sizeof (GSocketClientPrivate));
535 gobject_class->finalize = g_socket_client_finalize;
536 gobject_class->set_property = g_socket_client_set_property;
537 gobject_class->get_property = g_socket_client_get_property;
539 g_object_class_install_property (gobject_class, PROP_FAMILY,
540 g_param_spec_enum ("family",
542 P_("The sockets address family to use for socket construction"),
543 G_TYPE_SOCKET_FAMILY,
544 G_SOCKET_FAMILY_INVALID,
547 G_PARAM_STATIC_STRINGS));
549 g_object_class_install_property (gobject_class, PROP_TYPE,
550 g_param_spec_enum ("type",
552 P_("The sockets type to use for socket construction"),
554 G_SOCKET_TYPE_STREAM,
557 G_PARAM_STATIC_STRINGS));
559 g_object_class_install_property (gobject_class, PROP_PROTOCOL,
560 g_param_spec_enum ("protocol",
561 P_("Socket protocol"),
562 P_("The protocol to use for socket construction, or 0 for default"),
563 G_TYPE_SOCKET_PROTOCOL,
564 G_SOCKET_PROTOCOL_DEFAULT,
567 G_PARAM_STATIC_STRINGS));
569 g_object_class_install_property (gobject_class, PROP_LOCAL_ADDRESS,
570 g_param_spec_object ("local-address",
572 P_("The local address constructed sockets will be bound to"),
573 G_TYPE_SOCKET_ADDRESS,
576 G_PARAM_STATIC_STRINGS));
578 g_object_class_install_property (gobject_class, PROP_TIMEOUT,
579 g_param_spec_uint ("timeout",
580 P_("Socket timeout"),
581 P_("The I/O timeout for sockets, or 0 for none"),
585 G_PARAM_STATIC_STRINGS));
587 g_object_class_install_property (gobject_class, PROP_ENABLE_PROXY,
588 g_param_spec_boolean ("enable-proxy",
590 P_("Enable proxy support"),
594 G_PARAM_STATIC_STRINGS));
599 * g_socket_client_connect:
600 * @client: a #GSocketClient.
601 * @connectable: a #GSocketConnectable specifying the remote address.
602 * @cancellable: optional #GCancellable object, %NULL to ignore.
603 * @error: #GError for error reporting, or %NULL to ignore.
605 * Tries to resolve the @connectable and make a network connection to it..
607 * Upon a successful connection, a new #GSocketConnection is constructed
608 * and returned. The caller owns this new object and must drop their
609 * reference to it when finished with it.
611 * The type of the #GSocketConnection object returned depends on the type of
612 * the underlying socket that is used. For instance, for a TCP/IP connection
613 * it will be a #GTcpConnection.
615 * The socket created will be the same family as the the address that the
616 * @connectable resolves to, unless family is set with g_socket_client_set_family()
617 * or indirectly via g_socket_client_set_local_address(). The socket type
618 * defaults to %G_SOCKET_TYPE_STREAM but can be set with
619 * g_socket_client_set_socket_type().
621 * If a local address is specified with g_socket_client_set_local_address() the
622 * socket will be bound to this address before connecting.
624 * Returns: a #GSocketConnection on success, %NULL on error.
629 g_socket_client_connect (GSocketClient *client,
630 GSocketConnectable *connectable,
631 GCancellable *cancellable,
634 GSocketConnection *connection = NULL;
635 GSocketAddressEnumerator *enumerator = NULL;
636 GError *last_error, *tmp_error;
640 if (can_use_proxy (client))
641 enumerator = g_socket_connectable_proxy_enumerate (connectable);
643 enumerator = g_socket_connectable_enumerate (connectable);
645 while (connection == NULL)
647 GSocketAddress *address = NULL;
650 if (g_cancellable_is_cancelled (cancellable))
652 g_clear_error (error);
653 g_cancellable_set_error_if_cancelled (cancellable, error);
658 address = g_socket_address_enumerator_next (enumerator, cancellable,
665 g_clear_error (&last_error);
666 g_propagate_error (error, tmp_error);
670 g_propagate_error (error, last_error);
673 g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
674 _("Unknown error on connect"));
678 /* clear error from previous attempt */
679 g_clear_error (&last_error);
681 socket = create_socket (client, address, &last_error);
684 if (g_socket_connect (socket, address, cancellable, &last_error))
685 connection = g_socket_connection_factory_create_connection (socket);
687 g_object_unref (socket);
691 G_IS_PROXY_ADDRESS (address) &&
692 client->priv->enable_proxy)
694 GProxyAddress *proxy_addr = G_PROXY_ADDRESS (address);
695 const gchar *protocol;
698 protocol = g_proxy_address_get_protocol (proxy_addr);
699 proxy = g_proxy_get_default_for_protocol (protocol);
701 /* The connection should not be anything else then TCP Connection,
702 * but let's put a safety guard in case
704 if (!G_IS_TCP_CONNECTION (connection))
706 g_critical ("Trying to proxy over non-TCP connection, this is "
707 "most likely a bug in GLib IO library.");
709 g_set_error_literal (&last_error,
710 G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
711 _("Trying to proxy over non-TCP connection is not supported."));
713 g_object_unref (connection);
718 GIOStream *io_stream;
719 GTcpConnection *old_connection = G_TCP_CONNECTION (connection);
721 io_stream = g_proxy_connect (proxy,
722 G_IO_STREAM (old_connection),
729 if (G_IS_SOCKET_CONNECTION (io_stream))
730 connection = G_SOCKET_CONNECTION (g_object_ref (io_stream));
732 connection = _g_proxy_connection_new (old_connection,
735 g_object_unref (io_stream);
742 g_object_unref (old_connection);
743 g_object_unref (proxy);
745 else if (!g_hash_table_lookup_extended (client->priv->app_proxies,
746 protocol, NULL, NULL))
748 g_set_error (&last_error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
749 _("Proxy protocol '%s' is not supported."),
751 g_object_unref (connection);
756 g_object_unref (address);
758 g_object_unref (enumerator);
764 * g_socket_client_connect_to_host:
765 * @client: a #GSocketClient
766 * @host_and_port: the name and optionally port of the host to connect to
767 * @default_port: the default port to connect to
768 * @cancellable: a #GCancellable, or %NULL
769 * @error: a pointer to a #GError, or %NULL
771 * This is a helper function for g_socket_client_connect().
773 * Attempts to create a TCP connection to the named host.
775 * @host_and_port may be in any of a number of recognised formats: an IPv6
776 * address, an IPv4 address, or a domain name (in which case a DNS
777 * lookup is performed). Quoting with [] is supported for all address
778 * types. A port override may be specified in the usual way with a
779 * colon. Ports may be given as decimal numbers or symbolic names (in
780 * which case an /etc/services lookup is performed).
782 * If no port override is given in @host_and_port then @default_port will be
783 * used as the port number to connect to.
785 * In general, @host_and_port is expected to be provided by the user (allowing
786 * them to give the hostname, and a port overide if necessary) and
787 * @default_port is expected to be provided by the application.
789 * In the case that an IP address is given, a single connection
790 * attempt is made. In the case that a name is given, multiple
791 * connection attempts may be made, in turn and according to the
792 * number of address records in DNS, until a connection succeeds.
794 * Upon a successful connection, a new #GSocketConnection is constructed
795 * and returned. The caller owns this new object and must drop their
796 * reference to it when finished with it.
798 * In the event of any failure (DNS error, service not found, no hosts
799 * connectable) %NULL is returned and @error (if non-%NULL) is set
802 Returns: a #GSocketConnection on success, %NULL on error.
807 g_socket_client_connect_to_host (GSocketClient *client,
808 const gchar *host_and_port,
809 guint16 default_port,
810 GCancellable *cancellable,
813 GSocketConnectable *connectable;
814 GSocketConnection *connection;
816 connectable = g_network_address_parse (host_and_port, default_port, error);
817 if (connectable == NULL)
820 connection = g_socket_client_connect (client, connectable,
822 g_object_unref (connectable);
828 * g_socket_client_connect_to_service:
829 * @client: a #GSocketConnection
830 * @domain: a domain name
831 * @service: the name of the service to connect to
832 * @cancellable: a #GCancellable, or %NULL
833 * @error: a pointer to a #GError, or %NULL
834 * @returns: a #GSocketConnection if successful, or %NULL on error
836 * Attempts to create a TCP connection to a service.
838 * This call looks up the SRV record for @service at @domain for the
839 * "tcp" protocol. It then attempts to connect, in turn, to each of
840 * the hosts providing the service until either a connection succeeds
841 * or there are no hosts remaining.
843 * Upon a successful connection, a new #GSocketConnection is constructed
844 * and returned. The caller owns this new object and must drop their
845 * reference to it when finished with it.
847 * In the event of any failure (DNS error, service not found, no hosts
848 * connectable) %NULL is returned and @error (if non-%NULL) is set
852 g_socket_client_connect_to_service (GSocketClient *client,
854 const gchar *service,
855 GCancellable *cancellable,
858 GSocketConnectable *connectable;
859 GSocketConnection *connection;
861 connectable = g_network_service_new (service, "tcp", domain);
862 connection = g_socket_client_connect (client, connectable,
864 g_object_unref (connectable);
870 * g_socket_client_connect_to_uri:
871 * @client: a #GSocketClient
872 * @uri: A network URI
873 * @default_port: the default port to connect to
874 * @cancellable: a #GCancellable, or %NULL
875 * @error: a pointer to a #GError, or %NULL
877 * This is a helper function for g_socket_client_connect().
879 * Attempts to create a TCP connection with a network URI.
881 * @uri may be any valid URI containing an "authority" (hostname/port)
882 * component. If a port is not specified in the URI, @default_port
885 * Using this rather than g_socket_client_connect() or
886 * g_socket_client_connect_to_host() allows #GSocketClient to
887 * determine when to use application-specific proxy protocols.
889 * Upon a successful connection, a new #GSocketConnection is constructed
890 * and returned. The caller owns this new object and must drop their
891 * reference to it when finished with it.
893 * In the event of any failure (DNS error, service not found, no hosts
894 * connectable) %NULL is returned and @error (if non-%NULL) is set
897 * Returns: a #GSocketConnection on success, %NULL on error.
902 g_socket_client_connect_to_uri (GSocketClient *client,
904 guint16 default_port,
905 GCancellable *cancellable,
908 GSocketConnectable *connectable;
909 GSocketConnection *connection;
911 connectable = g_network_address_parse_uri (uri, default_port, error);
912 if (connectable == NULL)
915 connection = g_socket_client_connect (client, connectable,
917 g_object_unref (connectable);
924 GSimpleAsyncResult *result;
925 GCancellable *cancellable;
926 GSocketClient *client;
928 GSocketAddressEnumerator *enumerator;
929 GProxyAddress *proxy_addr;
930 GSocket *current_socket;
931 GSocketConnection *connection;
934 } GSocketClientAsyncConnectData;
937 g_socket_client_async_connect_complete (GSocketClientAsyncConnectData *data)
939 if (data->last_error)
941 g_simple_async_result_set_from_error (data->result, data->last_error);
942 g_error_free (data->last_error);
946 g_assert (data->connection);
948 g_simple_async_result_set_op_res_gpointer (data->result,
953 g_simple_async_result_complete (data->result);
954 g_object_unref (data->result);
955 g_object_unref (data->enumerator);
956 if (data->cancellable)
957 g_object_unref (data->cancellable);
958 if (data->current_socket)
959 g_object_unref (data->current_socket);
960 if (data->proxy_addr)
961 g_object_unref (data->proxy_addr);
962 g_slice_free (GSocketClientAsyncConnectData, data);
967 g_socket_client_enumerator_callback (GObject *object,
968 GAsyncResult *result,
972 set_last_error (GSocketClientAsyncConnectData *data,
975 g_clear_error (&data->last_error);
976 data->last_error = error;
980 enumerator_next_async (GSocketClientAsyncConnectData *data)
982 g_socket_address_enumerator_next_async (data->enumerator,
984 g_socket_client_enumerator_callback,
989 g_socket_client_proxy_connect_callback (GObject *object,
990 GAsyncResult *result,
993 GSocketClientAsyncConnectData *data = user_data;
994 GIOStream *io_stream;
995 GTcpConnection *old_connection = G_TCP_CONNECTION (data->connection);
997 io_stream = g_proxy_connect_finish (G_PROXY (object),
1003 if (G_IS_SOCKET_CONNECTION (io_stream))
1004 data->connection = G_SOCKET_CONNECTION (g_object_ref (io_stream));
1006 data->connection = _g_proxy_connection_new (old_connection,
1008 g_object_unref (io_stream);
1012 data->connection = NULL;
1015 g_object_unref (old_connection);
1017 g_socket_client_async_connect_complete (data);
1021 g_socket_client_proxy_connect (GSocketClientAsyncConnectData *data)
1024 const gchar *protocol = g_proxy_address_get_protocol (data->proxy_addr);
1026 proxy = g_proxy_get_default_for_protocol (protocol);
1028 /* The connection should not be anything else then TCP Connection,
1029 * but let's put a safety guard in case
1031 if (!G_IS_TCP_CONNECTION (data->connection))
1033 g_critical ("Trying to proxy over non-TCP connection, this is "
1034 "most likely a bug in GLib IO library.");
1036 g_set_error_literal (&data->last_error,
1037 G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
1038 _("Trying to proxy over non-TCP connection is not supported."));
1040 g_object_unref (data->connection);
1041 data->connection = NULL;
1043 enumerator_next_async (data);
1047 g_proxy_connect_async (proxy,
1048 G_IO_STREAM (data->connection),
1051 g_socket_client_proxy_connect_callback,
1053 g_object_unref (proxy);
1055 else if (!g_hash_table_lookup_extended (data->client->priv->app_proxies,
1056 protocol, NULL, NULL))
1058 g_clear_error (&data->last_error);
1060 g_set_error (&data->last_error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
1061 _("Proxy protocol '%s' is not supported."),
1064 g_object_unref (data->connection);
1065 data->connection = NULL;
1067 enumerator_next_async (data);
1072 g_socket_client_socket_connected (GSocketClientAsyncConnectData *data)
1074 g_socket_set_blocking (data->current_socket, TRUE);
1077 g_socket_connection_factory_create_connection (data->current_socket);
1078 g_object_unref (data->current_socket);
1079 data->current_socket = NULL;
1081 if (data->proxy_addr)
1082 g_socket_client_proxy_connect (data);
1084 g_socket_client_async_connect_complete (data);
1088 g_socket_client_socket_callback (GSocket *socket,
1089 GIOCondition condition,
1090 GSocketClientAsyncConnectData *data)
1092 GError *error = NULL;
1094 if (g_cancellable_is_cancelled (data->cancellable))
1096 /* Cancelled, return done with last error being cancelled */
1097 g_clear_error (&data->last_error);
1098 g_object_unref (data->current_socket);
1099 data->current_socket = NULL;
1100 g_cancellable_set_error_if_cancelled (data->cancellable,
1103 g_socket_client_async_connect_complete (data);
1108 /* socket is ready for writing means connect done, did it succeed? */
1109 if (!g_socket_check_connect_result (data->current_socket, &error))
1111 set_last_error (data, error);
1112 g_object_unref (data->current_socket);
1113 data->current_socket = NULL;
1116 enumerator_next_async (data);
1122 g_socket_client_socket_connected (data);
1127 g_socket_client_enumerator_callback (GObject *object,
1128 GAsyncResult *result,
1131 GSocketClientAsyncConnectData *data = user_data;
1132 GSocketAddress *address = NULL;
1134 GError *tmp_error = NULL;
1136 if (g_cancellable_is_cancelled (data->cancellable))
1138 g_clear_error (&data->last_error);
1139 g_cancellable_set_error_if_cancelled (data->cancellable, &data->last_error);
1140 g_socket_client_async_connect_complete (data);
1144 address = g_socket_address_enumerator_next_finish (data->enumerator,
1145 result, &tmp_error);
1147 if (address == NULL)
1150 set_last_error (data, tmp_error);
1151 else if (data->last_error == NULL)
1152 g_set_error_literal (&data->last_error, G_IO_ERROR, G_IO_ERROR_FAILED,
1153 _("Unknown error on connect"));
1155 g_socket_client_async_connect_complete (data);
1159 if (G_IS_PROXY_ADDRESS (address) &&
1160 data->client->priv->enable_proxy)
1161 data->proxy_addr = g_object_ref (G_PROXY_ADDRESS (address));
1163 g_clear_error (&data->last_error);
1165 socket = create_socket (data->client, address, &data->last_error);
1168 g_socket_set_blocking (socket, FALSE);
1169 if (g_socket_connect (socket, address, data->cancellable, &tmp_error))
1171 data->current_socket = socket;
1172 g_socket_client_socket_connected (data);
1174 g_object_unref (address);
1177 else if (g_error_matches (tmp_error, G_IO_ERROR, G_IO_ERROR_PENDING))
1181 data->current_socket = socket;
1182 g_error_free (tmp_error);
1184 source = g_socket_create_source (socket, G_IO_OUT,
1186 g_source_set_callback (source,
1187 (GSourceFunc) g_socket_client_socket_callback,
1189 g_source_attach (source, g_main_context_get_thread_default ());
1190 g_source_unref (source);
1192 g_object_unref (address);
1197 data->last_error = tmp_error;
1198 g_object_unref (socket);
1202 g_object_unref (address);
1203 enumerator_next_async (data);
1207 * g_socket_client_connect_async:
1208 * @client: a #GTcpClient
1209 * @connectable: a #GSocketConnectable specifying the remote address.
1210 * @cancellable: a #GCancellable, or %NULL
1211 * @callback: a #GAsyncReadyCallback
1212 * @user_data: user data for the callback
1214 * This is the asynchronous version of g_socket_client_connect().
1216 * When the operation is finished @callback will be
1217 * called. You can then call g_socket_client_connect_finish() to get
1218 * the result of the operation.
1223 g_socket_client_connect_async (GSocketClient *client,
1224 GSocketConnectable *connectable,
1225 GCancellable *cancellable,
1226 GAsyncReadyCallback callback,
1229 GSocketClientAsyncConnectData *data;
1231 g_return_if_fail (G_IS_SOCKET_CLIENT (client));
1233 data = g_slice_new0 (GSocketClientAsyncConnectData);
1235 data->result = g_simple_async_result_new (G_OBJECT (client),
1236 callback, user_data,
1237 g_socket_client_connect_async);
1238 data->client = client;
1240 data->cancellable = g_object_ref (cancellable);
1242 if (can_use_proxy (client))
1243 data->enumerator = g_socket_connectable_proxy_enumerate (connectable);
1245 data->enumerator = g_socket_connectable_enumerate (connectable);
1247 enumerator_next_async (data);
1251 * g_socket_client_connect_to_host_async:
1252 * @client: a #GTcpClient
1253 * @host_and_port: the name and optionally the port of the host to connect to
1254 * @default_port: the default port to connect to
1255 * @cancellable: a #GCancellable, or %NULL
1256 * @callback: a #GAsyncReadyCallback
1257 * @user_data: user data for the callback
1259 * This is the asynchronous version of g_socket_client_connect_to_host().
1261 * When the operation is finished @callback will be
1262 * called. You can then call g_socket_client_connect_to_host_finish() to get
1263 * the result of the operation.
1268 g_socket_client_connect_to_host_async (GSocketClient *client,
1269 const gchar *host_and_port,
1270 guint16 default_port,
1271 GCancellable *cancellable,
1272 GAsyncReadyCallback callback,
1275 GSocketConnectable *connectable;
1279 connectable = g_network_address_parse (host_and_port, default_port,
1281 if (connectable == NULL)
1283 g_simple_async_report_gerror_in_idle (G_OBJECT (client),
1284 callback, user_data, error);
1285 g_error_free (error);
1289 g_socket_client_connect_async (client,
1290 connectable, cancellable,
1291 callback, user_data);
1292 g_object_unref (connectable);
1297 * g_socket_client_connect_to_service_async:
1298 * @client: a #GSocketClient
1299 * @domain: a domain name
1300 * @service: the name of the service to connect to
1301 * @cancellable: a #GCancellable, or %NULL
1302 * @callback: a #GAsyncReadyCallback
1303 * @user_data: user data for the callback
1305 * This is the asynchronous version of
1306 * g_socket_client_connect_to_service().
1311 g_socket_client_connect_to_service_async (GSocketClient *client,
1312 const gchar *domain,
1313 const gchar *service,
1314 GCancellable *cancellable,
1315 GAsyncReadyCallback callback,
1318 GSocketConnectable *connectable;
1320 connectable = g_network_service_new (service, "tcp", domain);
1321 g_socket_client_connect_async (client,
1322 connectable, cancellable,
1323 callback, user_data);
1324 g_object_unref (connectable);
1328 * g_socket_client_connect_to_uri_async:
1329 * @client: a #GSocketClient
1330 * @uri: a network uri
1331 * @default_port: the default port to connect to
1332 * @cancellable: a #GCancellable, or %NULL
1333 * @callback: a #GAsyncReadyCallback
1334 * @user_data: user data for the callback
1336 * This is the asynchronous version of g_socket_client_connect_to_uri().
1338 * When the operation is finished @callback will be
1339 * called. You can then call g_socket_client_connect_to_uri_finish() to get
1340 * the result of the operation.
1345 g_socket_client_connect_to_uri_async (GSocketClient *client,
1347 guint16 default_port,
1348 GCancellable *cancellable,
1349 GAsyncReadyCallback callback,
1352 GSocketConnectable *connectable;
1356 connectable = g_network_address_parse_uri (uri, default_port, &error);
1357 if (connectable == NULL)
1359 g_simple_async_report_gerror_in_idle (G_OBJECT (client),
1360 callback, user_data, error);
1361 g_error_free (error);
1365 g_socket_client_connect_async (client,
1366 connectable, cancellable,
1367 callback, user_data);
1368 g_object_unref (connectable);
1374 * g_socket_client_connect_finish:
1375 * @client: a #GSocketClient.
1376 * @result: a #GAsyncResult.
1377 * @error: a #GError location to store the error occuring, or %NULL to
1380 * Finishes an async connect operation. See g_socket_client_connect_async()
1382 * Returns: a #GSocketConnection on success, %NULL on error.
1387 g_socket_client_connect_finish (GSocketClient *client,
1388 GAsyncResult *result,
1391 GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
1393 if (g_simple_async_result_propagate_error (simple, error))
1396 return g_object_ref (g_simple_async_result_get_op_res_gpointer (simple));
1400 * g_socket_client_connect_to_host_finish:
1401 * @client: a #GSocketClient.
1402 * @result: a #GAsyncResult.
1403 * @error: a #GError location to store the error occuring, or %NULL to
1406 * Finishes an async connect operation. See g_socket_client_connect_to_host_async()
1408 * Returns: a #GSocketConnection on success, %NULL on error.
1413 g_socket_client_connect_to_host_finish (GSocketClient *client,
1414 GAsyncResult *result,
1417 return g_socket_client_connect_finish (client, result, error);
1421 * g_socket_client_connect_to_service_finish:
1422 * @client: a #GSocketClient.
1423 * @result: a #GAsyncResult.
1424 * @error: a #GError location to store the error occuring, or %NULL to
1427 * Finishes an async connect operation. See g_socket_client_connect_to_service_async()
1429 * Returns: a #GSocketConnection on success, %NULL on error.
1434 g_socket_client_connect_to_service_finish (GSocketClient *client,
1435 GAsyncResult *result,
1438 return g_socket_client_connect_finish (client, result, error);
1442 * g_socket_client_connect_to_uri_finish:
1443 * @client: a #GSocketClient.
1444 * @result: a #GAsyncResult.
1445 * @error: a #GError location to store the error occuring, or %NULL to
1448 * Finishes an async connect operation. See g_socket_client_connect_to_uri_async()
1450 * Returns: a #GSocketConnection on success, %NULL on error.
1455 g_socket_client_connect_to_uri_finish (GSocketClient *client,
1456 GAsyncResult *result,
1459 return g_socket_client_connect_finish (client, result, error);
1463 * g_socket_client_add_application_proxy:
1464 * @client: a #GSocketClient
1465 * @protocol: The proxy protocol
1467 * Enable proxy protocols to be handled by the application. When the
1468 * indicated proxy protocol is returned by the #GProxyResolver,
1469 * #GSocketClient will consider this protocol as supported but will
1470 * not try find a #GProxy instance to handle handshaking. The
1471 * application must check for this case by calling
1472 * g_socket_connection_get_remote_address() on the returned
1473 * #GSocketConnection, and seeing if it's a #GProxyAddress of the
1474 * appropriate type, to determine whether or not it needs to handle
1475 * the proxy handshaking itself.
1477 * This should be used for proxy protocols that are dialects of
1478 * another protocol such as HTTP proxy. It also allows cohabitation of
1479 * proxy protocols that are reused between protocols. A good example
1480 * is HTTP. It can be used to proxy HTTP, FTP and Gopher and can also
1481 * be use as generic socket proxy through the HTTP CONNECT method.
1484 g_socket_client_add_application_proxy (GSocketClient *client,
1485 const gchar *protocol)
1487 g_hash_table_insert (client->priv->app_proxies, g_strdup (protocol), NULL);