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/gsimpleasyncresult.h>
38 #include <gio/gcancellable.h>
39 #include <gio/gioerror.h>
40 #include <gio/gsocket.h>
41 #include <gio/gnetworkaddress.h>
42 #include <gio/gnetworkservice.h>
43 #include <gio/gpollableiostream.h>
44 #include <gio/gproxy.h>
45 #include <gio/gsocketaddress.h>
46 #include <gio/gtcpconnection.h>
47 #include <gio/gtcpwrapperconnection.h>
52 * SECTION:gsocketclient
53 * @short_description: Helper for connecting to a network service
55 * @see_also: #GSocketConnection, #GSocketListener
57 * #GSocketClient is a high-level utility class for connecting to a
58 * network host using a connection oriented socket type.
60 * You create a #GSocketClient object, set any options you want, then
61 * call a sync or async connect operation, which returns a #GSocketConnection
62 * subclass on success.
64 * The type of the #GSocketConnection object returned depends on the type of
65 * the underlying socket that is in use. For instance, for a TCP/IP connection
66 * it will be a #GTcpConnection.
72 G_DEFINE_TYPE (GSocketClient, g_socket_client, G_TYPE_OBJECT);
85 struct _GSocketClientPrivate
89 GSocketProtocol protocol;
90 GSocketAddress *local_address;
92 gboolean enable_proxy;
93 GHashTable *app_proxies;
97 create_socket (GSocketClient *client,
98 GSocketAddress *dest_address,
101 GSocketFamily family;
104 family = client->priv->family;
105 if (family == G_SOCKET_FAMILY_INVALID &&
106 client->priv->local_address != NULL)
107 family = g_socket_address_get_family (client->priv->local_address);
108 if (family == G_SOCKET_FAMILY_INVALID)
109 family = g_socket_address_get_family (dest_address);
111 socket = g_socket_new (family,
113 client->priv->protocol,
118 if (client->priv->local_address)
120 if (!g_socket_bind (socket,
121 client->priv->local_address,
125 g_object_unref (socket);
130 if (client->priv->timeout)
131 g_socket_set_timeout (socket, client->priv->timeout);
137 can_use_proxy (GSocketClient *client)
139 GSocketClientPrivate *priv = client->priv;
141 return priv->enable_proxy
142 && priv->type == G_SOCKET_TYPE_STREAM;
146 g_socket_client_init (GSocketClient *client)
148 client->priv = G_TYPE_INSTANCE_GET_PRIVATE (client,
149 G_TYPE_SOCKET_CLIENT,
150 GSocketClientPrivate);
151 client->priv->type = G_SOCKET_TYPE_STREAM;
152 client->priv->app_proxies = g_hash_table_new_full (g_str_hash,
159 * g_socket_client_new:
161 * Creates a new #GSocketClient with the default options.
163 * Returns: a #GSocketClient.
164 * Free the returned object with g_object_unref().
169 g_socket_client_new (void)
171 return g_object_new (G_TYPE_SOCKET_CLIENT, NULL);
175 g_socket_client_finalize (GObject *object)
177 GSocketClient *client = G_SOCKET_CLIENT (object);
179 if (client->priv->local_address)
180 g_object_unref (client->priv->local_address);
182 if (G_OBJECT_CLASS (g_socket_client_parent_class)->finalize)
183 (*G_OBJECT_CLASS (g_socket_client_parent_class)->finalize) (object);
185 g_hash_table_unref (client->priv->app_proxies);
189 g_socket_client_get_property (GObject *object,
194 GSocketClient *client = G_SOCKET_CLIENT (object);
199 g_value_set_enum (value, client->priv->family);
203 g_value_set_enum (value, client->priv->type);
207 g_value_set_enum (value, client->priv->protocol);
210 case PROP_LOCAL_ADDRESS:
211 g_value_set_object (value, client->priv->local_address);
215 g_value_set_uint (value, client->priv->timeout);
218 case PROP_ENABLE_PROXY:
219 g_value_set_boolean (value, client->priv->enable_proxy);
223 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
228 g_socket_client_set_property (GObject *object,
233 GSocketClient *client = G_SOCKET_CLIENT (object);
238 g_socket_client_set_family (client, g_value_get_enum (value));
242 g_socket_client_set_socket_type (client, g_value_get_enum (value));
246 g_socket_client_set_protocol (client, g_value_get_enum (value));
249 case PROP_LOCAL_ADDRESS:
250 g_socket_client_set_local_address (client, g_value_get_object (value));
254 g_socket_client_set_timeout (client, g_value_get_uint (value));
257 case PROP_ENABLE_PROXY:
258 g_socket_client_set_enable_proxy (client, g_value_get_boolean (value));
262 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
267 * g_socket_client_get_family:
268 * @client: a #GSocketClient.
270 * Gets the socket family of the socket client.
272 * See g_socket_client_set_family() for details.
274 * Returns: a #GSocketFamily
279 g_socket_client_get_family (GSocketClient *client)
281 return client->priv->family;
285 * g_socket_client_set_family:
286 * @client: a #GSocketClient.
287 * @family: a #GSocketFamily
289 * Sets the socket family of the socket client.
290 * If this is set to something other than %G_SOCKET_FAMILY_INVALID
291 * then the sockets created by this object will be of the specified
294 * This might be useful for instance if you want to force the local
295 * connection to be an ipv4 socket, even though the address might
296 * be an ipv6 mapped to ipv4 address.
301 g_socket_client_set_family (GSocketClient *client,
302 GSocketFamily family)
304 if (client->priv->family == family)
307 client->priv->family = family;
308 g_object_notify (G_OBJECT (client), "family");
312 * g_socket_client_get_socket_type:
313 * @client: a #GSocketClient.
315 * Gets the socket type of the socket client.
317 * See g_socket_client_set_socket_type() for details.
319 * Returns: a #GSocketFamily
324 g_socket_client_get_socket_type (GSocketClient *client)
326 return client->priv->type;
330 * g_socket_client_set_socket_type:
331 * @client: a #GSocketClient.
332 * @type: a #GSocketType
334 * Sets the socket type of the socket client.
335 * The sockets created by this object will be of the specified
338 * It doesn't make sense to specify a type of %G_SOCKET_TYPE_DATAGRAM,
339 * as GSocketClient is used for connection oriented services.
344 g_socket_client_set_socket_type (GSocketClient *client,
347 if (client->priv->type == type)
350 client->priv->type = type;
351 g_object_notify (G_OBJECT (client), "type");
355 * g_socket_client_get_protocol:
356 * @client: a #GSocketClient
358 * Gets the protocol name type of the socket client.
360 * See g_socket_client_set_protocol() for details.
362 * Returns: a #GSocketProtocol
367 g_socket_client_get_protocol (GSocketClient *client)
369 return client->priv->protocol;
373 * g_socket_client_set_protocol:
374 * @client: a #GSocketClient.
375 * @protocol: a #GSocketProtocol
377 * Sets the protocol of the socket client.
378 * The sockets created by this object will use of the specified
381 * If @protocol is %0 that means to use the default
382 * protocol for the socket family and type.
387 g_socket_client_set_protocol (GSocketClient *client,
388 GSocketProtocol protocol)
390 if (client->priv->protocol == protocol)
393 client->priv->protocol = protocol;
394 g_object_notify (G_OBJECT (client), "protocol");
398 * g_socket_client_get_local_address:
399 * @client: a #GSocketClient.
401 * Gets the local address of the socket client.
403 * See g_socket_client_set_local_address() for details.
405 * Returns: (transfer none): a #GSocketAddres or %NULL. don't free
410 g_socket_client_get_local_address (GSocketClient *client)
412 return client->priv->local_address;
416 * g_socket_client_set_local_address:
417 * @client: a #GSocketClient.
418 * @address: a #GSocketAddress, or %NULL
420 * Sets the local address of the socket client.
421 * The sockets created by this object will bound to the
422 * specified address (if not %NULL) before connecting.
424 * This is useful if you want to ensure the the local
425 * side of the connection is on a specific port, or on
426 * a specific interface.
431 g_socket_client_set_local_address (GSocketClient *client,
432 GSocketAddress *address)
435 g_object_ref (address);
437 if (client->priv->local_address)
439 g_object_unref (client->priv->local_address);
441 client->priv->local_address = address;
442 g_object_notify (G_OBJECT (client), "local-address");
446 * g_socket_client_get_timeout:
447 * @client: a #GSocketClient
449 * Gets the I/O timeout time for sockets created by @client.
451 * See g_socket_client_set_timeout() for details.
453 * Returns: the timeout in seconds
458 g_socket_client_get_timeout (GSocketClient *client)
460 return client->priv->timeout;
465 * g_socket_client_set_timeout:
466 * @client: a #GSocketClient.
467 * @timeout: the timeout
469 * Sets the I/O timeout for sockets created by @client. @timeout is a
470 * time in seconds, or 0 for no timeout (the default).
472 * The timeout value affects the initial connection attempt as well,
473 * so setting this may cause calls to g_socket_client_connect(), etc,
474 * to fail with %G_IO_ERROR_TIMED_OUT.
479 g_socket_client_set_timeout (GSocketClient *client,
482 if (client->priv->timeout == timeout)
485 client->priv->timeout = timeout;
486 g_object_notify (G_OBJECT (client), "timeout");
490 * g_socket_client_get_enable_proxy:
491 * @client: a #GSocketClient.
493 * Gets the proxy enable state; see g_socket_client_set_enable_proxy()
495 * Returns: whether proxying is enabled
500 g_socket_client_get_enable_proxy (GSocketClient *client)
502 return client->priv->enable_proxy;
506 * g_socket_client_set_enable_proxy:
507 * @client: a #GSocketClient.
508 * @enable: whether to enable proxies
510 * Sets whether or not @client attempts to make connections via a
511 * proxy server. When enabled (the default), #GSocketClient will use a
512 * #GProxyResolver to determine if a proxy protocol such as SOCKS is
513 * needed, and automatically do the necessary proxy negotiation.
518 g_socket_client_set_enable_proxy (GSocketClient *client,
522 if (client->priv->enable_proxy == enable)
525 client->priv->enable_proxy = enable;
526 g_object_notify (G_OBJECT (client), "enable-proxy");
530 g_socket_client_class_init (GSocketClientClass *class)
532 GObjectClass *gobject_class = G_OBJECT_CLASS (class);
534 g_type_class_add_private (class, sizeof (GSocketClientPrivate));
536 gobject_class->finalize = g_socket_client_finalize;
537 gobject_class->set_property = g_socket_client_set_property;
538 gobject_class->get_property = g_socket_client_get_property;
540 g_object_class_install_property (gobject_class, PROP_FAMILY,
541 g_param_spec_enum ("family",
543 P_("The sockets address family to use for socket construction"),
544 G_TYPE_SOCKET_FAMILY,
545 G_SOCKET_FAMILY_INVALID,
548 G_PARAM_STATIC_STRINGS));
550 g_object_class_install_property (gobject_class, PROP_TYPE,
551 g_param_spec_enum ("type",
553 P_("The sockets type to use for socket construction"),
555 G_SOCKET_TYPE_STREAM,
558 G_PARAM_STATIC_STRINGS));
560 g_object_class_install_property (gobject_class, PROP_PROTOCOL,
561 g_param_spec_enum ("protocol",
562 P_("Socket protocol"),
563 P_("The protocol to use for socket construction, or 0 for default"),
564 G_TYPE_SOCKET_PROTOCOL,
565 G_SOCKET_PROTOCOL_DEFAULT,
568 G_PARAM_STATIC_STRINGS));
570 g_object_class_install_property (gobject_class, PROP_LOCAL_ADDRESS,
571 g_param_spec_object ("local-address",
573 P_("The local address constructed sockets will be bound to"),
574 G_TYPE_SOCKET_ADDRESS,
577 G_PARAM_STATIC_STRINGS));
579 g_object_class_install_property (gobject_class, PROP_TIMEOUT,
580 g_param_spec_uint ("timeout",
581 P_("Socket timeout"),
582 P_("The I/O timeout for sockets, or 0 for none"),
586 G_PARAM_STATIC_STRINGS));
588 g_object_class_install_property (gobject_class, PROP_ENABLE_PROXY,
589 g_param_spec_boolean ("enable-proxy",
591 P_("Enable proxy support"),
595 G_PARAM_STATIC_STRINGS));
600 * g_socket_client_connect:
601 * @client: a #GSocketClient.
602 * @connectable: a #GSocketConnectable specifying the remote address.
603 * @cancellable: optional #GCancellable object, %NULL to ignore.
604 * @error: #GError for error reporting, or %NULL to ignore.
606 * Tries to resolve the @connectable and make a network connection to it..
608 * Upon a successful connection, a new #GSocketConnection is constructed
609 * and returned. The caller owns this new object and must drop their
610 * reference to it when finished with it.
612 * The type of the #GSocketConnection object returned depends on the type of
613 * the underlying socket that is used. For instance, for a TCP/IP connection
614 * it will be a #GTcpConnection.
616 * The socket created will be the same family as the the address that the
617 * @connectable resolves to, unless family is set with g_socket_client_set_family()
618 * or indirectly via g_socket_client_set_local_address(). The socket type
619 * defaults to %G_SOCKET_TYPE_STREAM but can be set with
620 * g_socket_client_set_socket_type().
622 * If a local address is specified with g_socket_client_set_local_address() the
623 * socket will be bound to this address before connecting.
625 * Returns: (transfer full): a #GSocketConnection on success, %NULL on error.
630 g_socket_client_connect (GSocketClient *client,
631 GSocketConnectable *connectable,
632 GCancellable *cancellable,
635 GSocketConnection *connection = NULL;
636 GSocketAddressEnumerator *enumerator = NULL;
637 GError *last_error, *tmp_error;
641 if (can_use_proxy (client))
642 enumerator = g_socket_connectable_proxy_enumerate (connectable);
644 enumerator = g_socket_connectable_enumerate (connectable);
646 while (connection == NULL)
648 GSocketAddress *address = NULL;
651 if (g_cancellable_is_cancelled (cancellable))
653 g_clear_error (error);
654 g_cancellable_set_error_if_cancelled (cancellable, error);
659 address = g_socket_address_enumerator_next (enumerator, cancellable,
666 g_clear_error (&last_error);
667 g_propagate_error (error, tmp_error);
671 g_propagate_error (error, last_error);
674 g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_FAILED,
675 _("Unknown error on connect"));
679 /* clear error from previous attempt */
680 g_clear_error (&last_error);
682 socket = create_socket (client, address, &last_error);
685 g_object_unref (address);
689 if (g_socket_connect (socket, address, cancellable, &last_error))
690 connection = g_socket_connection_factory_create_connection (socket);
693 G_IS_PROXY_ADDRESS (address) &&
694 client->priv->enable_proxy)
696 GProxyAddress *proxy_addr = G_PROXY_ADDRESS (address);
697 const gchar *protocol;
700 protocol = g_proxy_address_get_protocol (proxy_addr);
701 proxy = g_proxy_get_default_for_protocol (protocol);
703 /* The connection should not be anything else then TCP Connection,
704 * but let's put a safety guard in case
706 if (!G_IS_TCP_CONNECTION (connection))
708 g_critical ("Trying to proxy over non-TCP connection, this is "
709 "most likely a bug in GLib IO library.");
711 g_set_error_literal (&last_error,
712 G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
713 _("Trying to proxy over non-TCP connection is not supported."));
715 g_object_unref (connection);
720 GIOStream *io_stream;
722 io_stream = g_proxy_connect (proxy,
723 G_IO_STREAM (connection),
727 g_object_unref (connection);
728 g_object_unref (proxy);
732 if (G_IS_SOCKET_CONNECTION (io_stream))
733 connection = G_SOCKET_CONNECTION (io_stream);
736 connection = g_tcp_wrapper_connection_new (G_POLLABLE_IO_STREAM (io_stream),
738 g_object_unref (io_stream);
746 else if (!g_hash_table_lookup_extended (client->priv->app_proxies,
747 protocol, NULL, NULL))
749 g_set_error (&last_error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
750 _("Proxy protocol '%s' is not supported."),
752 g_object_unref (connection);
757 g_object_unref (socket);
758 g_object_unref (address);
760 g_object_unref (enumerator);
766 * g_socket_client_connect_to_host:
767 * @client: a #GSocketClient
768 * @host_and_port: the name and optionally port of the host to connect to
769 * @default_port: the default port to connect to
770 * @cancellable: a #GCancellable, or %NULL
771 * @error: a pointer to a #GError, or %NULL
773 * This is a helper function for g_socket_client_connect().
775 * Attempts to create a TCP connection to the named host.
777 * @host_and_port may be in any of a number of recognised formats; an IPv6
778 * address, an IPv4 address, or a domain name (in which case a DNS
779 * lookup is performed). Quoting with [] is supported for all address
780 * types. A port override may be specified in the usual way with a
781 * colon. Ports may be given as decimal numbers or symbolic names (in
782 * which case an /etc/services lookup is performed).
784 * If no port override is given in @host_and_port then @default_port will be
785 * used as the port number to connect to.
787 * In general, @host_and_port is expected to be provided by the user (allowing
788 * them to give the hostname, and a port overide if necessary) and
789 * @default_port is expected to be provided by the application.
791 * In the case that an IP address is given, a single connection
792 * attempt is made. In the case that a name is given, multiple
793 * connection attempts may be made, in turn and according to the
794 * number of address records in DNS, until a connection succeeds.
796 * Upon a successful connection, a new #GSocketConnection is constructed
797 * and returned. The caller owns this new object and must drop their
798 * reference to it when finished with it.
800 * In the event of any failure (DNS error, service not found, no hosts
801 * connectable) %NULL is returned and @error (if non-%NULL) is set
804 * Returns: (transfer full): a #GSocketConnection on success, %NULL on error.
809 g_socket_client_connect_to_host (GSocketClient *client,
810 const gchar *host_and_port,
811 guint16 default_port,
812 GCancellable *cancellable,
815 GSocketConnectable *connectable;
816 GSocketConnection *connection;
818 connectable = g_network_address_parse (host_and_port, default_port, error);
819 if (connectable == NULL)
822 connection = g_socket_client_connect (client, connectable,
824 g_object_unref (connectable);
830 * g_socket_client_connect_to_service:
831 * @client: a #GSocketConnection
832 * @domain: a domain name
833 * @service: the name of the service to connect to
834 * @cancellable: a #GCancellable, or %NULL
835 * @error: a pointer to a #GError, or %NULL
836 * @returns: (transfer full): a #GSocketConnection if successful, or %NULL on error
838 * Attempts to create a TCP connection to a service.
840 * This call looks up the SRV record for @service at @domain for the
841 * "tcp" protocol. It then attempts to connect, in turn, to each of
842 * the hosts providing the service until either a connection succeeds
843 * or there are no hosts remaining.
845 * Upon a successful connection, a new #GSocketConnection is constructed
846 * and returned. The caller owns this new object and must drop their
847 * reference to it when finished with it.
849 * In the event of any failure (DNS error, service not found, no hosts
850 * connectable) %NULL is returned and @error (if non-%NULL) is set
854 g_socket_client_connect_to_service (GSocketClient *client,
856 const gchar *service,
857 GCancellable *cancellable,
860 GSocketConnectable *connectable;
861 GSocketConnection *connection;
863 connectable = g_network_service_new (service, "tcp", domain);
864 connection = g_socket_client_connect (client, connectable,
866 g_object_unref (connectable);
872 * g_socket_client_connect_to_uri:
873 * @client: a #GSocketClient
874 * @uri: A network URI
875 * @default_port: the default port to connect to
876 * @cancellable: a #GCancellable, or %NULL
877 * @error: a pointer to a #GError, or %NULL
879 * This is a helper function for g_socket_client_connect().
881 * Attempts to create a TCP connection with a network URI.
883 * @uri may be any valid URI containing an "authority" (hostname/port)
884 * component. If a port is not specified in the URI, @default_port
887 * Using this rather than g_socket_client_connect() or
888 * g_socket_client_connect_to_host() allows #GSocketClient to
889 * determine when to use application-specific proxy protocols.
891 * Upon a successful connection, a new #GSocketConnection is constructed
892 * and returned. The caller owns this new object and must drop their
893 * reference to it when finished with it.
895 * In the event of any failure (DNS error, service not found, no hosts
896 * connectable) %NULL is returned and @error (if non-%NULL) is set
899 * Returns: (transfer full): a #GSocketConnection on success, %NULL on error.
904 g_socket_client_connect_to_uri (GSocketClient *client,
906 guint16 default_port,
907 GCancellable *cancellable,
910 GSocketConnectable *connectable;
911 GSocketConnection *connection;
913 connectable = g_network_address_parse_uri (uri, default_port, error);
914 if (connectable == NULL)
917 connection = g_socket_client_connect (client, connectable,
919 g_object_unref (connectable);
926 GSimpleAsyncResult *result;
927 GCancellable *cancellable;
928 GSocketClient *client;
930 GSocketAddressEnumerator *enumerator;
931 GProxyAddress *proxy_addr;
932 GSocket *current_socket;
933 GSocketConnection *connection;
936 } GSocketClientAsyncConnectData;
939 g_socket_client_async_connect_complete (GSocketClientAsyncConnectData *data)
941 if (data->last_error)
943 g_simple_async_result_take_error (data->result, data->last_error);
947 g_assert (data->connection);
949 g_simple_async_result_set_op_res_gpointer (data->result,
954 g_simple_async_result_complete (data->result);
955 g_object_unref (data->result);
956 g_object_unref (data->enumerator);
957 if (data->cancellable)
958 g_object_unref (data->cancellable);
959 if (data->current_socket)
960 g_object_unref (data->current_socket);
961 if (data->proxy_addr)
962 g_object_unref (data->proxy_addr);
963 g_slice_free (GSocketClientAsyncConnectData, data);
968 g_socket_client_enumerator_callback (GObject *object,
969 GAsyncResult *result,
973 set_last_error (GSocketClientAsyncConnectData *data,
976 g_clear_error (&data->last_error);
977 data->last_error = error;
981 enumerator_next_async (GSocketClientAsyncConnectData *data)
983 g_socket_address_enumerator_next_async (data->enumerator,
985 g_socket_client_enumerator_callback,
990 g_socket_client_proxy_connect_callback (GObject *object,
991 GAsyncResult *result,
994 GSocketClientAsyncConnectData *data = user_data;
995 GIOStream *io_stream;
997 io_stream = g_proxy_connect_finish (G_PROXY (object),
1000 g_object_unref (data->connection);
1004 if (G_IS_SOCKET_CONNECTION (io_stream))
1005 data->connection = G_SOCKET_CONNECTION (io_stream);
1008 data->connection = g_tcp_wrapper_connection_new (G_POLLABLE_IO_STREAM (io_stream),
1009 data->current_socket);
1010 g_object_unref (io_stream);
1015 data->connection = NULL;
1016 g_object_unref (data->current_socket);
1017 data->current_socket = NULL;
1020 g_socket_client_async_connect_complete (data);
1024 g_socket_client_proxy_connect (GSocketClientAsyncConnectData *data)
1027 const gchar *protocol = g_proxy_address_get_protocol (data->proxy_addr);
1029 proxy = g_proxy_get_default_for_protocol (protocol);
1031 /* The connection should not be anything else then TCP Connection,
1032 * but let's put a safety guard in case
1034 if (!G_IS_TCP_CONNECTION (data->connection))
1036 g_critical ("Trying to proxy over non-TCP connection, this is "
1037 "most likely a bug in GLib IO library.");
1039 g_set_error_literal (&data->last_error,
1040 G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
1041 _("Trying to proxy over non-TCP connection is not supported."));
1043 g_object_unref (data->connection);
1044 data->connection = NULL;
1045 g_object_unref (data->current_socket);
1046 data->current_socket = NULL;
1048 enumerator_next_async (data);
1052 g_proxy_connect_async (proxy,
1053 G_IO_STREAM (data->connection),
1056 g_socket_client_proxy_connect_callback,
1058 g_object_unref (proxy);
1060 else if (!g_hash_table_lookup_extended (data->client->priv->app_proxies,
1061 protocol, NULL, NULL))
1063 g_clear_error (&data->last_error);
1065 g_set_error (&data->last_error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED,
1066 _("Proxy protocol '%s' is not supported."),
1069 g_object_unref (data->connection);
1070 data->connection = NULL;
1071 g_object_unref (data->current_socket);
1072 data->current_socket = NULL;
1074 enumerator_next_async (data);
1079 g_socket_client_socket_connected (GSocketClientAsyncConnectData *data)
1081 g_socket_set_blocking (data->current_socket, TRUE);
1084 g_socket_connection_factory_create_connection (data->current_socket);
1086 if (data->proxy_addr)
1087 g_socket_client_proxy_connect (data);
1089 g_socket_client_async_connect_complete (data);
1093 g_socket_client_socket_callback (GSocket *socket,
1094 GIOCondition condition,
1095 GSocketClientAsyncConnectData *data)
1097 GError *error = NULL;
1099 if (g_cancellable_is_cancelled (data->cancellable))
1101 /* Cancelled, return done with last error being cancelled */
1102 g_clear_error (&data->last_error);
1103 g_object_unref (data->current_socket);
1104 data->current_socket = NULL;
1105 g_cancellable_set_error_if_cancelled (data->cancellable,
1108 g_socket_client_async_connect_complete (data);
1113 /* socket is ready for writing means connect done, did it succeed? */
1114 if (!g_socket_check_connect_result (data->current_socket, &error))
1116 set_last_error (data, error);
1117 g_object_unref (data->current_socket);
1118 data->current_socket = NULL;
1121 enumerator_next_async (data);
1127 g_socket_client_socket_connected (data);
1132 g_socket_client_enumerator_callback (GObject *object,
1133 GAsyncResult *result,
1136 GSocketClientAsyncConnectData *data = user_data;
1137 GSocketAddress *address = NULL;
1139 GError *tmp_error = NULL;
1141 if (g_cancellable_is_cancelled (data->cancellable))
1143 g_clear_error (&data->last_error);
1144 g_cancellable_set_error_if_cancelled (data->cancellable, &data->last_error);
1145 g_socket_client_async_connect_complete (data);
1149 address = g_socket_address_enumerator_next_finish (data->enumerator,
1150 result, &tmp_error);
1152 if (address == NULL)
1155 set_last_error (data, tmp_error);
1156 else if (data->last_error == NULL)
1157 g_set_error_literal (&data->last_error, G_IO_ERROR, G_IO_ERROR_FAILED,
1158 _("Unknown error on connect"));
1160 g_socket_client_async_connect_complete (data);
1164 if (G_IS_PROXY_ADDRESS (address) &&
1165 data->client->priv->enable_proxy)
1166 data->proxy_addr = g_object_ref (G_PROXY_ADDRESS (address));
1168 g_clear_error (&data->last_error);
1170 socket = create_socket (data->client, address, &data->last_error);
1173 g_socket_set_blocking (socket, FALSE);
1174 if (g_socket_connect (socket, address, data->cancellable, &tmp_error))
1176 data->current_socket = socket;
1177 g_socket_client_socket_connected (data);
1179 g_object_unref (address);
1182 else if (g_error_matches (tmp_error, G_IO_ERROR, G_IO_ERROR_PENDING))
1186 data->current_socket = socket;
1187 g_error_free (tmp_error);
1189 source = g_socket_create_source (socket, G_IO_OUT,
1191 g_source_set_callback (source,
1192 (GSourceFunc) g_socket_client_socket_callback,
1194 g_source_attach (source, g_main_context_get_thread_default ());
1195 g_source_unref (source);
1197 g_object_unref (address);
1202 data->last_error = tmp_error;
1203 g_object_unref (socket);
1207 g_object_unref (address);
1208 enumerator_next_async (data);
1212 * g_socket_client_connect_async:
1213 * @client: a #GTcpClient
1214 * @connectable: a #GSocketConnectable specifying the remote address.
1215 * @cancellable: a #GCancellable, or %NULL
1216 * @callback: a #GAsyncReadyCallback
1217 * @user_data: user data for the callback
1219 * This is the asynchronous version of g_socket_client_connect().
1221 * When the operation is finished @callback will be
1222 * called. You can then call g_socket_client_connect_finish() to get
1223 * the result of the operation.
1228 g_socket_client_connect_async (GSocketClient *client,
1229 GSocketConnectable *connectable,
1230 GCancellable *cancellable,
1231 GAsyncReadyCallback callback,
1234 GSocketClientAsyncConnectData *data;
1236 g_return_if_fail (G_IS_SOCKET_CLIENT (client));
1238 data = g_slice_new0 (GSocketClientAsyncConnectData);
1240 data->result = g_simple_async_result_new (G_OBJECT (client),
1241 callback, user_data,
1242 g_socket_client_connect_async);
1243 data->client = client;
1245 data->cancellable = g_object_ref (cancellable);
1247 if (can_use_proxy (client))
1248 data->enumerator = g_socket_connectable_proxy_enumerate (connectable);
1250 data->enumerator = g_socket_connectable_enumerate (connectable);
1252 enumerator_next_async (data);
1256 * g_socket_client_connect_to_host_async:
1257 * @client: a #GTcpClient
1258 * @host_and_port: the name and optionally the port of the host to connect to
1259 * @default_port: the default port to connect to
1260 * @cancellable: a #GCancellable, or %NULL
1261 * @callback: a #GAsyncReadyCallback
1262 * @user_data: user data for the callback
1264 * This is the asynchronous version of g_socket_client_connect_to_host().
1266 * When the operation is finished @callback will be
1267 * called. You can then call g_socket_client_connect_to_host_finish() to get
1268 * the result of the operation.
1273 g_socket_client_connect_to_host_async (GSocketClient *client,
1274 const gchar *host_and_port,
1275 guint16 default_port,
1276 GCancellable *cancellable,
1277 GAsyncReadyCallback callback,
1280 GSocketConnectable *connectable;
1284 connectable = g_network_address_parse (host_and_port, default_port,
1286 if (connectable == NULL)
1288 g_simple_async_report_take_gerror_in_idle (G_OBJECT (client),
1289 callback, user_data, error);
1293 g_socket_client_connect_async (client,
1294 connectable, cancellable,
1295 callback, user_data);
1296 g_object_unref (connectable);
1301 * g_socket_client_connect_to_service_async:
1302 * @client: a #GSocketClient
1303 * @domain: a domain name
1304 * @service: the name of the service to connect to
1305 * @cancellable: a #GCancellable, or %NULL
1306 * @callback: a #GAsyncReadyCallback
1307 * @user_data: user data for the callback
1309 * This is the asynchronous version of
1310 * g_socket_client_connect_to_service().
1315 g_socket_client_connect_to_service_async (GSocketClient *client,
1316 const gchar *domain,
1317 const gchar *service,
1318 GCancellable *cancellable,
1319 GAsyncReadyCallback callback,
1322 GSocketConnectable *connectable;
1324 connectable = g_network_service_new (service, "tcp", domain);
1325 g_socket_client_connect_async (client,
1326 connectable, cancellable,
1327 callback, user_data);
1328 g_object_unref (connectable);
1332 * g_socket_client_connect_to_uri_async:
1333 * @client: a #GSocketClient
1334 * @uri: a network uri
1335 * @default_port: the default port to connect to
1336 * @cancellable: a #GCancellable, or %NULL
1337 * @callback: a #GAsyncReadyCallback
1338 * @user_data: user data for the callback
1340 * This is the asynchronous version of g_socket_client_connect_to_uri().
1342 * When the operation is finished @callback will be
1343 * called. You can then call g_socket_client_connect_to_uri_finish() to get
1344 * the result of the operation.
1349 g_socket_client_connect_to_uri_async (GSocketClient *client,
1351 guint16 default_port,
1352 GCancellable *cancellable,
1353 GAsyncReadyCallback callback,
1356 GSocketConnectable *connectable;
1360 connectable = g_network_address_parse_uri (uri, default_port, &error);
1361 if (connectable == NULL)
1363 g_simple_async_report_take_gerror_in_idle (G_OBJECT (client),
1364 callback, user_data, error);
1368 g_socket_client_connect_async (client,
1369 connectable, cancellable,
1370 callback, user_data);
1371 g_object_unref (connectable);
1377 * g_socket_client_connect_finish:
1378 * @client: a #GSocketClient.
1379 * @result: a #GAsyncResult.
1380 * @error: a #GError location to store the error occuring, or %NULL to
1383 * Finishes an async connect operation. See g_socket_client_connect_async()
1385 * Returns: (transfer full): a #GSocketConnection on success, %NULL on error.
1390 g_socket_client_connect_finish (GSocketClient *client,
1391 GAsyncResult *result,
1394 GSimpleAsyncResult *simple = G_SIMPLE_ASYNC_RESULT (result);
1396 if (g_simple_async_result_propagate_error (simple, error))
1399 return g_object_ref (g_simple_async_result_get_op_res_gpointer (simple));
1403 * g_socket_client_connect_to_host_finish:
1404 * @client: a #GSocketClient.
1405 * @result: a #GAsyncResult.
1406 * @error: a #GError location to store the error occuring, or %NULL to
1409 * Finishes an async connect operation. See g_socket_client_connect_to_host_async()
1411 * Returns: (transfer full): a #GSocketConnection on success, %NULL on error.
1416 g_socket_client_connect_to_host_finish (GSocketClient *client,
1417 GAsyncResult *result,
1420 return g_socket_client_connect_finish (client, result, error);
1424 * g_socket_client_connect_to_service_finish:
1425 * @client: a #GSocketClient.
1426 * @result: a #GAsyncResult.
1427 * @error: a #GError location to store the error occuring, or %NULL to
1430 * Finishes an async connect operation. See g_socket_client_connect_to_service_async()
1432 * Returns: (transfer full): a #GSocketConnection on success, %NULL on error.
1437 g_socket_client_connect_to_service_finish (GSocketClient *client,
1438 GAsyncResult *result,
1441 return g_socket_client_connect_finish (client, result, error);
1445 * g_socket_client_connect_to_uri_finish:
1446 * @client: a #GSocketClient.
1447 * @result: a #GAsyncResult.
1448 * @error: a #GError location to store the error occuring, or %NULL to
1451 * Finishes an async connect operation. See g_socket_client_connect_to_uri_async()
1453 * Returns: (transfer full): a #GSocketConnection on success, %NULL on error.
1458 g_socket_client_connect_to_uri_finish (GSocketClient *client,
1459 GAsyncResult *result,
1462 return g_socket_client_connect_finish (client, result, error);
1466 * g_socket_client_add_application_proxy:
1467 * @client: a #GSocketClient
1468 * @protocol: The proxy protocol
1470 * Enable proxy protocols to be handled by the application. When the
1471 * indicated proxy protocol is returned by the #GProxyResolver,
1472 * #GSocketClient will consider this protocol as supported but will
1473 * not try find a #GProxy instance to handle handshaking. The
1474 * application must check for this case by calling
1475 * g_socket_connection_get_remote_address() on the returned
1476 * #GSocketConnection, and seeing if it's a #GProxyAddress of the
1477 * appropriate type, to determine whether or not it needs to handle
1478 * the proxy handshaking itself.
1480 * This should be used for proxy protocols that are dialects of
1481 * another protocol such as HTTP proxy. It also allows cohabitation of
1482 * proxy protocols that are reused between protocols. A good example
1483 * is HTTP. It can be used to proxy HTTP, FTP and Gopher and can also
1484 * be use as generic socket proxy through the HTTP CONNECT method.
1487 g_socket_client_add_application_proxy (GSocketClient *client,
1488 const gchar *protocol)
1490 g_hash_table_insert (client->priv->app_proxies, g_strdup (protocol), NULL);