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: (transfer full): 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: (transfer full): 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: (transfer full): 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: (transfer full): 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_take_error (data->result, data->last_error);
945 g_assert (data->connection);
947 g_simple_async_result_set_op_res_gpointer (data->result,
952 g_simple_async_result_complete (data->result);
953 g_object_unref (data->result);
954 g_object_unref (data->enumerator);
955 if (data->cancellable)
956 g_object_unref (data->cancellable);
957 if (data->current_socket)
958 g_object_unref (data->current_socket);
959 if (data->proxy_addr)
960 g_object_unref (data->proxy_addr);
961 g_slice_free (GSocketClientAsyncConnectData, data);
966 g_socket_client_enumerator_callback (GObject *object,
967 GAsyncResult *result,
971 set_last_error (GSocketClientAsyncConnectData *data,
974 g_clear_error (&data->last_error);
975 data->last_error = error;
979 enumerator_next_async (GSocketClientAsyncConnectData *data)
981 g_socket_address_enumerator_next_async (data->enumerator,
983 g_socket_client_enumerator_callback,
988 g_socket_client_proxy_connect_callback (GObject *object,
989 GAsyncResult *result,
992 GSocketClientAsyncConnectData *data = user_data;
993 GIOStream *io_stream;
994 GTcpConnection *old_connection = G_TCP_CONNECTION (data->connection);
996 io_stream = g_proxy_connect_finish (G_PROXY (object),
1002 if (G_IS_SOCKET_CONNECTION (io_stream))
1003 data->connection = G_SOCKET_CONNECTION (g_object_ref (io_stream));
1005 data->connection = _g_proxy_connection_new (old_connection,
1007 g_object_unref (io_stream);
1011 data->connection = NULL;
1014 g_object_unref (old_connection);
1016 g_socket_client_async_connect_complete (data);
1020 g_socket_client_proxy_connect (GSocketClientAsyncConnectData *data)
1023 const gchar *protocol = g_proxy_address_get_protocol (data->proxy_addr);
1025 proxy = g_proxy_get_default_for_protocol (protocol);
1027 /* The connection should not be anything else then TCP Connection,
1028 * but let's put a safety guard in case
1030 if (!G_IS_TCP_CONNECTION (data->connection))
1032 g_critical ("Trying to proxy over non-TCP connection, this is "
1033 "most likely a bug in GLib IO library.");
1035 g_set_error_literal (&data->last_error,
1036 G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
1037 _("Trying to proxy over non-TCP connection is not supported."));
1039 g_object_unref (data->connection);
1040 data->connection = NULL;
1042 enumerator_next_async (data);
1046 g_proxy_connect_async (proxy,
1047 G_IO_STREAM (data->connection),
1050 g_socket_client_proxy_connect_callback,
1052 g_object_unref (proxy);
1054 else if (!g_hash_table_lookup_extended (data->client->priv->app_proxies,
1055 protocol, NULL, NULL))
1057 g_clear_error (&data->last_error);
1059 g_set_error (&data->last_error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
1060 _("Proxy protocol '%s' is not supported."),
1063 g_object_unref (data->connection);
1064 data->connection = NULL;
1066 enumerator_next_async (data);
1071 g_socket_client_socket_connected (GSocketClientAsyncConnectData *data)
1073 g_socket_set_blocking (data->current_socket, TRUE);
1076 g_socket_connection_factory_create_connection (data->current_socket);
1077 g_object_unref (data->current_socket);
1078 data->current_socket = NULL;
1080 if (data->proxy_addr)
1081 g_socket_client_proxy_connect (data);
1083 g_socket_client_async_connect_complete (data);
1087 g_socket_client_socket_callback (GSocket *socket,
1088 GIOCondition condition,
1089 GSocketClientAsyncConnectData *data)
1091 GError *error = NULL;
1093 if (g_cancellable_is_cancelled (data->cancellable))
1095 /* Cancelled, return done with last error being cancelled */
1096 g_clear_error (&data->last_error);
1097 g_object_unref (data->current_socket);
1098 data->current_socket = NULL;
1099 g_cancellable_set_error_if_cancelled (data->cancellable,
1102 g_socket_client_async_connect_complete (data);
1107 /* socket is ready for writing means connect done, did it succeed? */
1108 if (!g_socket_check_connect_result (data->current_socket, &error))
1110 set_last_error (data, error);
1111 g_object_unref (data->current_socket);
1112 data->current_socket = NULL;
1115 enumerator_next_async (data);
1121 g_socket_client_socket_connected (data);
1126 g_socket_client_enumerator_callback (GObject *object,
1127 GAsyncResult *result,
1130 GSocketClientAsyncConnectData *data = user_data;
1131 GSocketAddress *address = NULL;
1133 GError *tmp_error = NULL;
1135 if (g_cancellable_is_cancelled (data->cancellable))
1137 g_clear_error (&data->last_error);
1138 g_cancellable_set_error_if_cancelled (data->cancellable, &data->last_error);
1139 g_socket_client_async_connect_complete (data);
1143 address = g_socket_address_enumerator_next_finish (data->enumerator,
1144 result, &tmp_error);
1146 if (address == NULL)
1149 set_last_error (data, tmp_error);
1150 else if (data->last_error == NULL)
1151 g_set_error_literal (&data->last_error, G_IO_ERROR, G_IO_ERROR_FAILED,
1152 _("Unknown error on connect"));
1154 g_socket_client_async_connect_complete (data);
1158 if (G_IS_PROXY_ADDRESS (address) &&
1159 data->client->priv->enable_proxy)
1160 data->proxy_addr = g_object_ref (G_PROXY_ADDRESS (address));
1162 g_clear_error (&data->last_error);
1164 socket = create_socket (data->client, address, &data->last_error);
1167 g_socket_set_blocking (socket, FALSE);
1168 if (g_socket_connect (socket, address, data->cancellable, &tmp_error))
1170 data->current_socket = socket;
1171 g_socket_client_socket_connected (data);
1173 g_object_unref (address);
1176 else if (g_error_matches (tmp_error, G_IO_ERROR, G_IO_ERROR_PENDING))
1180 data->current_socket = socket;
1181 g_error_free (tmp_error);
1183 source = g_socket_create_source (socket, G_IO_OUT,
1185 g_source_set_callback (source,
1186 (GSourceFunc) g_socket_client_socket_callback,
1188 g_source_attach (source, g_main_context_get_thread_default ());
1189 g_source_unref (source);
1191 g_object_unref (address);
1196 data->last_error = tmp_error;
1197 g_object_unref (socket);
1201 g_object_unref (address);
1202 enumerator_next_async (data);
1206 * g_socket_client_connect_async:
1207 * @client: a #GTcpClient
1208 * @connectable: a #GSocketConnectable specifying the remote address.
1209 * @cancellable: a #GCancellable, or %NULL
1210 * @callback: a #GAsyncReadyCallback
1211 * @user_data: user data for the callback
1213 * This is the asynchronous version of g_socket_client_connect().
1215 * When the operation is finished @callback will be
1216 * called. You can then call g_socket_client_connect_finish() to get
1217 * the result of the operation.
1222 g_socket_client_connect_async (GSocketClient *client,
1223 GSocketConnectable *connectable,
1224 GCancellable *cancellable,
1225 GAsyncReadyCallback callback,
1228 GSocketClientAsyncConnectData *data;
1230 g_return_if_fail (G_IS_SOCKET_CLIENT (client));
1232 data = g_slice_new0 (GSocketClientAsyncConnectData);
1234 data->result = g_simple_async_result_new (G_OBJECT (client),
1235 callback, user_data,
1236 g_socket_client_connect_async);
1237 data->client = client;
1239 data->cancellable = g_object_ref (cancellable);
1241 if (can_use_proxy (client))
1242 data->enumerator = g_socket_connectable_proxy_enumerate (connectable);
1244 data->enumerator = g_socket_connectable_enumerate (connectable);
1246 enumerator_next_async (data);
1250 * g_socket_client_connect_to_host_async:
1251 * @client: a #GTcpClient
1252 * @host_and_port: the name and optionally the port of the host to connect to
1253 * @default_port: the default port to connect to
1254 * @cancellable: a #GCancellable, or %NULL
1255 * @callback: a #GAsyncReadyCallback
1256 * @user_data: user data for the callback
1258 * This is the asynchronous version of g_socket_client_connect_to_host().
1260 * When the operation is finished @callback will be
1261 * called. You can then call g_socket_client_connect_to_host_finish() to get
1262 * the result of the operation.
1267 g_socket_client_connect_to_host_async (GSocketClient *client,
1268 const gchar *host_and_port,
1269 guint16 default_port,
1270 GCancellable *cancellable,
1271 GAsyncReadyCallback callback,
1274 GSocketConnectable *connectable;
1278 connectable = g_network_address_parse (host_and_port, default_port,
1280 if (connectable == NULL)
1282 g_simple_async_report_gerror_in_idle (G_OBJECT (client),
1283 callback, user_data, error);
1284 g_error_free (error);
1288 g_socket_client_connect_async (client,
1289 connectable, cancellable,
1290 callback, user_data);
1291 g_object_unref (connectable);
1296 * g_socket_client_connect_to_service_async:
1297 * @client: a #GSocketClient
1298 * @domain: a domain name
1299 * @service: the name of the service to connect to
1300 * @cancellable: a #GCancellable, or %NULL
1301 * @callback: a #GAsyncReadyCallback
1302 * @user_data: user data for the callback
1304 * This is the asynchronous version of
1305 * g_socket_client_connect_to_service().
1310 g_socket_client_connect_to_service_async (GSocketClient *client,
1311 const gchar *domain,
1312 const gchar *service,
1313 GCancellable *cancellable,
1314 GAsyncReadyCallback callback,
1317 GSocketConnectable *connectable;
1319 connectable = g_network_service_new (service, "tcp", domain);
1320 g_socket_client_connect_async (client,
1321 connectable, cancellable,
1322 callback, user_data);
1323 g_object_unref (connectable);
1327 * g_socket_client_connect_to_uri_async:
1328 * @client: a #GSocketClient
1329 * @uri: a network uri
1330 * @default_port: the default port to connect to
1331 * @cancellable: a #GCancellable, or %NULL
1332 * @callback: a #GAsyncReadyCallback
1333 * @user_data: user data for the callback
1335 * This is the asynchronous version of g_socket_client_connect_to_uri().
1337 * When the operation is finished @callback will be
1338 * called. You can then call g_socket_client_connect_to_uri_finish() to get
1339 * the result of the operation.
1344 g_socket_client_connect_to_uri_async (GSocketClient *client,
1346 guint16 default_port,
1347 GCancellable *cancellable,
1348 GAsyncReadyCallback callback,
1351 GSocketConnectable *connectable;
1355 connectable = g_network_address_parse_uri (uri, default_port, &error);
1356 if (connectable == NULL)
1358 g_simple_async_report_gerror_in_idle (G_OBJECT (client),
1359 callback, user_data, error);
1360 g_error_free (error);
1364 g_socket_client_connect_async (client,
1365 connectable, cancellable,
1366 callback, user_data);
1367 g_object_unref (connectable);
1373 * g_socket_client_connect_finish:
1374 * @client: a #GSocketClient.
1375 * @result: a #GAsyncResult.
1376 * @error: a #GError location to store the error occuring, or %NULL to
1379 * Finishes an async connect operation. See g_socket_client_connect_async()
1381 * Returns: (transfer full): a #GSocketConnection on success, %NULL on error.
1386 g_socket_client_connect_finish (GSocketClient *client,
1387 GAsyncResult *result,
1390 GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
1392 if (g_simple_async_result_propagate_error (simple, error))
1395 return g_object_ref (g_simple_async_result_get_op_res_gpointer (simple));
1399 * g_socket_client_connect_to_host_finish:
1400 * @client: a #GSocketClient.
1401 * @result: a #GAsyncResult.
1402 * @error: a #GError location to store the error occuring, or %NULL to
1405 * Finishes an async connect operation. See g_socket_client_connect_to_host_async()
1407 * Returns: (transfer full): a #GSocketConnection on success, %NULL on error.
1412 g_socket_client_connect_to_host_finish (GSocketClient *client,
1413 GAsyncResult *result,
1416 return g_socket_client_connect_finish (client, result, error);
1420 * g_socket_client_connect_to_service_finish:
1421 * @client: a #GSocketClient.
1422 * @result: a #GAsyncResult.
1423 * @error: a #GError location to store the error occuring, or %NULL to
1426 * Finishes an async connect operation. See g_socket_client_connect_to_service_async()
1428 * Returns: (transfer full): a #GSocketConnection on success, %NULL on error.
1433 g_socket_client_connect_to_service_finish (GSocketClient *client,
1434 GAsyncResult *result,
1437 return g_socket_client_connect_finish (client, result, error);
1441 * g_socket_client_connect_to_uri_finish:
1442 * @client: a #GSocketClient.
1443 * @result: a #GAsyncResult.
1444 * @error: a #GError location to store the error occuring, or %NULL to
1447 * Finishes an async connect operation. See g_socket_client_connect_to_uri_async()
1449 * Returns: (transfer full): a #GSocketConnection on success, %NULL on error.
1454 g_socket_client_connect_to_uri_finish (GSocketClient *client,
1455 GAsyncResult *result,
1458 return g_socket_client_connect_finish (client, result, error);
1462 * g_socket_client_add_application_proxy:
1463 * @client: a #GSocketClient
1464 * @protocol: The proxy protocol
1466 * Enable proxy protocols to be handled by the application. When the
1467 * indicated proxy protocol is returned by the #GProxyResolver,
1468 * #GSocketClient will consider this protocol as supported but will
1469 * not try find a #GProxy instance to handle handshaking. The
1470 * application must check for this case by calling
1471 * g_socket_connection_get_remote_address() on the returned
1472 * #GSocketConnection, and seeing if it's a #GProxyAddress of the
1473 * appropriate type, to determine whether or not it needs to handle
1474 * the proxy handshaking itself.
1476 * This should be used for proxy protocols that are dialects of
1477 * another protocol such as HTTP proxy. It also allows cohabitation of
1478 * proxy protocols that are reused between protocols. A good example
1479 * is HTTP. It can be used to proxy HTTP, FTP and Gopher and can also
1480 * be use as generic socket proxy through the HTTP CONNECT method.
1483 g_socket_client_add_application_proxy (GSocketClient *client,
1484 const gchar *protocol)
1486 g_hash_table_insert (client->priv->app_proxies, g_strdup (protocol), NULL);