1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
3 * soup-socket.c: Socket networking code.
5 * Copyright (C) 2000-2003, Ximian, Inc.
19 #include "soup-address.h"
20 #include "soup-socket.h"
21 #include "soup-marshal.h"
22 #include "soup-misc.h"
26 #include <sys/types.h>
30 * @short_description: A network socket
32 * #SoupSocket is libsoup's TCP socket type. While it is primarily
33 * intended for internal use, #SoupSocket<!-- -->s are exposed in the
34 * API in various places, and some of their methods (eg,
35 * soup_socket_get_remote_address()) may be useful to applications.
38 G_DEFINE_TYPE (SoupSocket, soup_socket, G_TYPE_OBJECT)
48 static guint signals[LAST_SIGNAL] = { 0 };
61 PROP_TRUSTED_CERTIFICATE,
69 SoupAddress *local_addr, *remote_addr;
70 GIOChannel *iochannel;
71 GSocketConnection *conn;
77 guint trusted_certificate:1;
78 guint clean_dispose:1;
81 GMainContext *async_context;
83 GSource *read_src, *write_src;
84 GSource *read_timeout, *write_timeout;
87 GMutex *iolock, *addrlock;
90 GCancellable *connect_cancel;
92 #define SOUP_SOCKET_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SOUP_TYPE_SOCKET, SoupSocketPrivate))
94 static void set_property (GObject *object, guint prop_id,
95 const GValue *value, GParamSpec *pspec);
96 static void get_property (GObject *object, guint prop_id,
97 GValue *value, GParamSpec *pspec);
100 #define SOUP_IS_SOCKET_ERROR(status) ((status) == SOCKET_ERROR)
101 #define SOUP_IS_INVALID_SOCKET(socket) ((socket) == INVALID_SOCKET)
102 #define SHUT_RDWR SD_BOTH
104 #define SOUP_IS_SOCKET_ERROR(status) ((status) == -1)
105 #define SOUP_IS_INVALID_SOCKET(socket) ((socket) < 0)
109 soup_socket_init (SoupSocket *sock)
111 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
114 priv->non_blocking = TRUE;
115 priv->addrlock = g_mutex_new ();
116 priv->iolock = g_mutex_new ();
121 disconnect_internal (SoupSocketPrivate *priv)
123 if (priv->iochannel) {
124 g_io_channel_unref (priv->iochannel);
125 priv->iochannel = NULL;
128 g_object_unref (priv->conn);
133 if (priv->read_src) {
134 g_source_destroy (priv->read_src);
135 priv->read_src = NULL;
137 if (priv->write_src) {
138 g_source_destroy (priv->write_src);
139 priv->write_src = NULL;
141 if (priv->read_timeout) {
142 g_source_destroy (priv->read_timeout);
143 priv->read_timeout = NULL;
145 if (priv->write_timeout) {
146 g_source_destroy (priv->write_timeout);
147 priv->write_timeout = NULL;
152 finalize (GObject *object)
154 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (object);
156 if (priv->connect_cancel) {
157 if (priv->clean_dispose)
158 g_warning ("Disposing socket %p during connect", object);
159 g_object_unref (priv->connect_cancel);
161 if (priv->iochannel) {
162 if (priv->clean_dispose)
163 g_warning ("Disposing socket %p while still connected", object);
164 disconnect_internal (priv);
167 if (priv->local_addr)
168 g_object_unref (priv->local_addr);
169 if (priv->remote_addr)
170 g_object_unref (priv->remote_addr);
172 if (priv->watch_src) {
173 if (priv->clean_dispose && !priv->is_server)
174 g_warning ("Disposing socket %p during async op", object);
175 g_source_destroy (priv->watch_src);
177 if (priv->async_context)
178 g_main_context_unref (priv->async_context);
181 g_byte_array_free (priv->read_buf, TRUE);
183 g_mutex_free (priv->addrlock);
184 g_mutex_free (priv->iolock);
186 G_OBJECT_CLASS (soup_socket_parent_class)->finalize (object);
190 soup_socket_class_init (SoupSocketClass *socket_class)
192 GObjectClass *object_class = G_OBJECT_CLASS (socket_class);
194 g_type_class_add_private (socket_class, sizeof (SoupSocketPrivate));
196 /* virtual method override */
197 object_class->finalize = finalize;
198 object_class->set_property = set_property;
199 object_class->get_property = get_property;
204 * SoupSocket::readable:
207 * Emitted when an async socket is readable. See
208 * soup_socket_read(), soup_socket_read_until() and
209 * #SoupSocket:non-blocking.
212 g_signal_new ("readable",
213 G_OBJECT_CLASS_TYPE (object_class),
215 G_STRUCT_OFFSET (SoupSocketClass, readable),
217 soup_marshal_NONE__NONE,
221 * SoupSocket::writable:
224 * Emitted when an async socket is writable. See
225 * soup_socket_write() and #SoupSocket:non-blocking.
228 g_signal_new ("writable",
229 G_OBJECT_CLASS_TYPE (object_class),
231 G_STRUCT_OFFSET (SoupSocketClass, writable),
233 soup_marshal_NONE__NONE,
237 * SoupSocket::disconnected:
240 * Emitted when the socket is disconnected, for whatever
243 signals[DISCONNECTED] =
244 g_signal_new ("disconnected",
245 G_OBJECT_CLASS_TYPE (object_class),
247 G_STRUCT_OFFSET (SoupSocketClass, disconnected),
249 soup_marshal_NONE__NONE,
253 * SoupSocket::new-connection:
255 * @new: the new socket
257 * Emitted when a listening socket (set up with
258 * soup_socket_listen()) receives a new connection.
260 * You must ref the @new if you want to keep it; otherwise it
261 * will be destroyed after the signal is emitted.
263 signals[NEW_CONNECTION] =
264 g_signal_new ("new_connection",
265 G_OBJECT_CLASS_TYPE (object_class),
267 G_STRUCT_OFFSET (SoupSocketClass, new_connection),
269 soup_marshal_NONE__OBJECT,
275 * SOUP_SOCKET_LOCAL_ADDRESS:
277 * Alias for the #SoupSocket:local-address property. (Address
278 * of local end of socket.)
280 g_object_class_install_property (
281 object_class, PROP_LOCAL_ADDRESS,
282 g_param_spec_object (SOUP_SOCKET_LOCAL_ADDRESS,
284 "Address of local end of socket",
286 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
288 * SOUP_SOCKET_REMOTE_ADDRESS:
290 * Alias for the #SoupSocket:remote-address property. (Address
291 * of remote end of socket.)
293 g_object_class_install_property (
294 object_class, PROP_REMOTE_ADDRESS,
295 g_param_spec_object (SOUP_SOCKET_REMOTE_ADDRESS,
297 "Address of remote end of socket",
299 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
301 * SoupSocket:non-blocking:
303 * Whether or not the socket uses non-blocking I/O.
305 * #SoupSocket's I/O methods are designed around the idea of
306 * using a single codepath for both synchronous and
307 * asynchronous I/O. If you want to read off a #SoupSocket,
308 * the "correct" way to do it is to call soup_socket_read() or
309 * soup_socket_read_until() repeatedly until you have read
310 * everything you want. If it returns %SOUP_SOCKET_WOULD_BLOCK
311 * at any point, stop reading and wait for it to emit the
312 * #SoupSocket::readable signal. Then go back to the
313 * reading-as-much-as-you-can loop. Likewise, for writing to a
314 * #SoupSocket, you should call soup_socket_write() either
315 * until you have written everything, or it returns
316 * %SOUP_SOCKET_WOULD_BLOCK (in which case you wait for
317 * #SoupSocket::writable and then go back into the loop).
319 * Code written this way will work correctly with both
320 * blocking and non-blocking sockets; blocking sockets will
321 * simply never return %SOUP_SOCKET_WOULD_BLOCK, and so the
322 * code that handles that case just won't get used for them.
325 * SOUP_SOCKET_FLAG_NONBLOCKING:
327 * Alias for the #SoupSocket:non-blocking property. (Whether
328 * or not the socket uses non-blocking I/O.)
330 g_object_class_install_property (
331 object_class, PROP_NON_BLOCKING,
332 g_param_spec_boolean (SOUP_SOCKET_FLAG_NONBLOCKING,
334 "Whether or not the socket uses non-blocking I/O",
338 * SOUP_SOCKET_IS_SERVER:
340 * Alias for the #SoupSocket:is-server property. (Whether or
341 * not the socket is a server socket.)
343 g_object_class_install_property (
344 object_class, PROP_IS_SERVER,
345 g_param_spec_boolean (SOUP_SOCKET_IS_SERVER,
347 "Whether or not the socket is a server socket",
351 * SOUP_SOCKET_SSL_CREDENTIALS:
353 * Alias for the #SoupSocket:ssl-credentials property.
354 * (SSL credential information.)
356 g_object_class_install_property (
357 object_class, PROP_SSL_CREDENTIALS,
358 g_param_spec_pointer (SOUP_SOCKET_SSL_CREDENTIALS,
360 "SSL credential information, passed from the session to the SSL implementation",
363 * SOUP_SOCKET_SSL_STRICT:
365 * Alias for the #SoupSocket:ignore-ssl-cert-errors property.
367 g_object_class_install_property (
368 object_class, PROP_SSL_STRICT,
369 g_param_spec_boolean (SOUP_SOCKET_SSL_STRICT,
370 "Strictly validate SSL certificates",
371 "Whether certificate errors should be considered a connection error",
373 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
375 * SOUP_SOCKET_TRUSTED_CERTIFICATE:
377 * Alias for the #SoupSocket:trusted-certificate
378 * property. Notice that this property's value is only useful
379 * if the socket is for an SSL connection, and only reliable
380 * after some data has been transferred to or from it.
382 g_object_class_install_property (
383 object_class, PROP_TRUSTED_CERTIFICATE,
384 g_param_spec_boolean (SOUP_SOCKET_TRUSTED_CERTIFICATE,
385 "Trusted Certificate",
386 "Whether the server certificate is trusted, if this is an SSL socket",
388 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
390 * SOUP_SOCKET_ASYNC_CONTEXT:
392 * Alias for the #SoupSocket:async-context property. (The
393 * socket's #GMainContext.)
395 g_object_class_install_property (
396 object_class, PROP_ASYNC_CONTEXT,
397 g_param_spec_pointer (SOUP_SOCKET_ASYNC_CONTEXT,
398 "Async GMainContext",
399 "The GMainContext to dispatch this socket's async I/O in",
400 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
403 * SOUP_SOCKET_TIMEOUT:
405 * Alias for the #SoupSocket:timeout property. (The timeout
406 * in seconds for blocking socket I/O operations.)
408 g_object_class_install_property (
409 object_class, PROP_TIMEOUT,
410 g_param_spec_uint (SOUP_SOCKET_TIMEOUT,
412 "Value in seconds to timeout a blocking I/O",
416 g_object_class_install_property (
417 object_class, PROP_CLEAN_DISPOSE,
418 g_param_spec_boolean ("clean-dispose",
420 "Warn on unclean dispose",
422 G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
427 set_nonblocking (SoupSocketPrivate *priv)
435 if (priv->sockfd == -1)
439 flags = fcntl (priv->sockfd, F_GETFL, 0);
441 if (priv->non_blocking)
444 flags &= ~O_NONBLOCK;
445 fcntl (priv->sockfd, F_SETFL, flags);
448 val = priv->non_blocking ? 1 : 0;
449 ioctlsocket (priv->sockfd, FIONBIO, &val);
454 set_fdflags (SoupSocketPrivate *priv)
458 struct timeval timeout;
462 if (priv->sockfd == -1)
465 set_nonblocking (priv);
468 flags = fcntl (priv->sockfd, F_GETFD, 0);
471 fcntl (priv->sockfd, F_SETFD, flags);
476 setsockopt (priv->sockfd, IPPROTO_TCP,
477 TCP_NODELAY, (void *) &opt, sizeof (opt));
478 setsockopt (priv->sockfd, SOL_SOCKET,
479 SO_REUSEADDR, (void *) &opt, sizeof (opt));
482 timeout.tv_sec = priv->timeout;
484 setsockopt (priv->sockfd, SOL_SOCKET,
485 SO_RCVTIMEO, (void *) &timeout, sizeof (timeout));
487 timeout.tv_sec = priv->timeout;
489 setsockopt (priv->sockfd, SOL_SOCKET,
490 SO_SNDTIMEO, (void *) &timeout, sizeof (timeout));
492 if (priv->timeout < G_MAXINT / 1000)
493 opt = priv->timeout * 1000;
497 setsockopt (priv->sockfd, SOL_SOCKET,
498 SO_RCVTIMEO, (void *) &opt, sizeof (opt));
500 setsockopt (priv->sockfd, SOL_SOCKET,
501 SO_SNDTIMEO, (void *) &opt, sizeof (opt));
506 g_io_channel_unix_new (priv->sockfd);
509 g_io_channel_win32_new_socket (priv->sockfd);
511 g_io_channel_set_close_on_unref (priv->iochannel, priv->conn == NULL);
512 g_io_channel_set_encoding (priv->iochannel, NULL, NULL);
513 g_io_channel_set_buffered (priv->iochannel, FALSE);
517 set_property (GObject *object, guint prop_id,
518 const GValue *value, GParamSpec *pspec)
520 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (object);
523 case PROP_LOCAL_ADDRESS:
524 priv->local_addr = (SoupAddress *)g_value_dup_object (value);
526 case PROP_REMOTE_ADDRESS:
527 priv->remote_addr = (SoupAddress *)g_value_dup_object (value);
529 case PROP_NON_BLOCKING:
530 priv->non_blocking = g_value_get_boolean (value);
531 set_nonblocking (priv);
533 case PROP_SSL_CREDENTIALS:
534 priv->ssl_creds = g_value_get_pointer (value);
536 case PROP_SSL_STRICT:
537 priv->ssl_strict = g_value_get_boolean (value);
539 case PROP_TRUSTED_CERTIFICATE:
540 priv->trusted_certificate = g_value_get_boolean (value);
542 case PROP_ASYNC_CONTEXT:
543 priv->async_context = g_value_get_pointer (value);
544 if (priv->async_context)
545 g_main_context_ref (priv->async_context);
548 priv->timeout = g_value_get_uint (value);
550 case PROP_CLEAN_DISPOSE:
551 priv->clean_dispose = g_value_get_boolean (value);
554 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
560 get_property (GObject *object, guint prop_id,
561 GValue *value, GParamSpec *pspec)
563 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (object);
566 case PROP_LOCAL_ADDRESS:
567 g_value_set_object (value, soup_socket_get_local_address (SOUP_SOCKET (object)));
569 case PROP_REMOTE_ADDRESS:
570 g_value_set_object (value, soup_socket_get_remote_address (SOUP_SOCKET (object)));
572 case PROP_NON_BLOCKING:
573 g_value_set_boolean (value, priv->non_blocking);
576 g_value_set_boolean (value, priv->is_server);
578 case PROP_SSL_CREDENTIALS:
579 g_value_set_pointer (value, priv->ssl_creds);
581 case PROP_SSL_STRICT:
582 g_value_set_boolean (value, priv->ssl_strict);
584 case PROP_TRUSTED_CERTIFICATE:
585 g_value_set_boolean (value, priv->trusted_certificate);
587 case PROP_ASYNC_CONTEXT:
588 g_value_set_pointer (value, priv->async_context ? g_main_context_ref (priv->async_context) : NULL);
591 g_value_set_uint (value, priv->timeout);
594 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
602 * @optname1: name of first property to set (or %NULL)
603 * @...: value of @optname1, followed by additional property/value pairs
605 * Creates a new (disconnected) socket
607 * Return value: the new socket
610 soup_socket_new (const char *optname1, ...)
615 va_start (ap, optname1);
616 sock = (SoupSocket *)g_object_new_valist (SOUP_TYPE_SOCKET,
624 socket_connected (SoupSocket *sock, GSocketConnection *conn, GError *error)
626 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
629 g_object_unref (priv->connect_cancel);
630 priv->connect_cancel = NULL;
633 if (error->domain == G_RESOLVER_ERROR) {
634 g_error_free (error);
635 return SOUP_STATUS_CANT_RESOLVE;
637 g_error_free (error);
638 return SOUP_STATUS_CANT_CONNECT;
642 /* We keep the GSocketConnection around because its GSocket
643 * will close the fd when it's destroyed.
647 gsock = g_socket_connection_get_socket (conn);
648 priv->sockfd = g_socket_get_fd (gsock);
651 return SOUP_STATUS_OK;
655 * SoupSocketCallback:
656 * @sock: the #SoupSocket
657 * @status: an HTTP status code indicating success or failure
658 * @user_data: the data passed to soup_socket_connect_async()
660 * The callback function passed to soup_socket_connect_async().
665 SoupSocketCallback callback;
667 } SoupSocketAsyncConnectData;
670 async_connected (GObject *client, GAsyncResult *result, gpointer data)
672 SoupSocketAsyncConnectData *sacd = data;
673 GError *error = NULL;
674 GSocketConnection *conn;
677 conn = g_socket_client_connect_finish (G_SOCKET_CLIENT (client),
679 status = socket_connected (sacd->sock, conn, error);
681 sacd->callback (sacd->sock, status, sacd->user_data);
682 g_object_unref (sacd->sock);
683 g_slice_free (SoupSocketAsyncConnectData, sacd);
687 * soup_socket_connect_async:
688 * @sock: a client #SoupSocket (which must not already be connected)
689 * @cancellable: a #GCancellable, or %NULL
690 * @callback: (scope async): callback to call after connecting
691 * @user_data: data to pass to @callback
693 * Begins asynchronously connecting to @sock's remote address. The
694 * socket will call @callback when it succeeds or fails (but not
695 * before returning from this function).
697 * If @cancellable is non-%NULL, it can be used to cancel the
698 * connection. @callback will still be invoked in this case, with a
699 * status of %SOUP_STATUS_CANCELLED.
702 soup_socket_connect_async (SoupSocket *sock, GCancellable *cancellable,
703 SoupSocketCallback callback, gpointer user_data)
705 SoupSocketPrivate *priv;
706 SoupSocketAsyncConnectData *sacd;
707 GSocketClient *client;
709 g_return_if_fail (SOUP_IS_SOCKET (sock));
710 priv = SOUP_SOCKET_GET_PRIVATE (sock);
711 g_return_if_fail (priv->remote_addr != NULL);
713 sacd = g_slice_new0 (SoupSocketAsyncConnectData);
714 sacd->sock = g_object_ref (sock);
715 sacd->callback = callback;
716 sacd->user_data = user_data;
718 priv->connect_cancel = cancellable ? g_object_ref (cancellable) : g_cancellable_new ();
720 if (priv->async_context)
721 g_main_context_push_thread_default (priv->async_context);
723 client = g_socket_client_new ();
725 /* FIXME: temporary workaround for not-new-enough glib */
726 if (g_object_class_find_property (G_OBJECT_GET_CLASS (client), "timeout")) {
727 g_object_set (G_OBJECT (client),
728 "timeout", priv->timeout,
732 g_socket_client_connect_async (client,
733 G_SOCKET_CONNECTABLE (priv->remote_addr),
734 priv->connect_cancel,
735 async_connected, sacd);
736 g_object_unref (client);
738 if (priv->async_context)
739 g_main_context_pop_thread_default (priv->async_context);
743 * soup_socket_connect_sync:
744 * @sock: a client #SoupSocket (which must not already be connected)
745 * @cancellable: a #GCancellable, or %NULL
747 * Attempt to synchronously connect @sock to its remote address.
749 * If @cancellable is non-%NULL, it can be used to cancel the
750 * connection, in which case soup_socket_connect_sync() will return
751 * %SOUP_STATUS_CANCELLED.
753 * Return value: a success or failure code.
756 soup_socket_connect_sync (SoupSocket *sock, GCancellable *cancellable)
758 SoupSocketPrivate *priv;
759 GSocketClient *client;
760 GSocketConnection *conn;
761 GError *error = NULL;
763 g_return_val_if_fail (SOUP_IS_SOCKET (sock), SOUP_STATUS_MALFORMED);
764 priv = SOUP_SOCKET_GET_PRIVATE (sock);
765 g_return_val_if_fail (!priv->is_server, SOUP_STATUS_MALFORMED);
766 g_return_val_if_fail (priv->sockfd == -1, SOUP_STATUS_MALFORMED);
767 g_return_val_if_fail (priv->remote_addr != NULL, SOUP_STATUS_MALFORMED);
770 g_object_ref (cancellable);
772 cancellable = g_cancellable_new ();
773 priv->connect_cancel = cancellable;
775 client = g_socket_client_new ();
777 /* FIXME: temporary workaround for not-new-enough glib */
778 if (g_object_class_find_property (G_OBJECT_GET_CLASS (client), "timeout")) {
779 g_object_set (G_OBJECT (client),
780 "timeout", priv->timeout,
784 conn = g_socket_client_connect (client,
785 G_SOCKET_CONNECTABLE (priv->remote_addr),
786 priv->connect_cancel, &error);
787 g_object_unref (client);
789 return socket_connected (sock, conn, error);
793 soup_socket_get_fd (SoupSocket *sock)
795 g_return_val_if_fail (SOUP_IS_SOCKET (sock), -1);
797 return SOUP_SOCKET_GET_PRIVATE (sock)->sockfd;
801 listen_watch (GIOChannel* iochannel, GIOCondition condition, gpointer data)
803 SoupSocket *sock = data, *new;
804 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock), *new_priv;
805 struct sockaddr_storage sa;
808 if (condition & (G_IO_HUP | G_IO_ERR)) {
809 priv->watch_src = NULL;
813 sa_len = sizeof (sa);
814 sockfd = accept (priv->sockfd, (struct sockaddr *)&sa, (void *)&sa_len);
815 if (SOUP_IS_INVALID_SOCKET (sockfd))
818 new = g_object_new (SOUP_TYPE_SOCKET, NULL);
819 new_priv = SOUP_SOCKET_GET_PRIVATE (new);
820 new_priv->sockfd = sockfd;
821 if (priv->async_context)
822 new_priv->async_context = g_main_context_ref (priv->async_context);
823 new_priv->non_blocking = priv->non_blocking;
824 new_priv->is_server = TRUE;
825 new_priv->ssl_creds = priv->ssl_creds;
826 set_fdflags (new_priv);
828 new_priv->remote_addr = soup_address_new_from_sockaddr ((struct sockaddr *)&sa, sa_len);
830 if (new_priv->ssl_creds) {
831 if (!soup_socket_start_ssl (new, NULL)) {
832 g_object_unref (new);
837 g_signal_emit (sock, signals[NEW_CONNECTION], 0, new);
838 g_object_unref (new);
844 * soup_socket_listen:
845 * @sock: a server #SoupSocket (which must not already be connected or
848 * Makes @sock start listening on its local address. When connections
849 * come in, @sock will emit %new_connection.
851 * Return value: whether or not @sock is now listening.
854 soup_socket_listen (SoupSocket *sock)
857 SoupSocketPrivate *priv;
858 struct sockaddr_storage sa;
860 GSocketAddress *addr;
862 g_return_val_if_fail (SOUP_IS_SOCKET (sock), FALSE);
863 priv = SOUP_SOCKET_GET_PRIVATE (sock);
864 g_return_val_if_fail (priv->sockfd == -1, FALSE);
865 g_return_val_if_fail (priv->local_addr != NULL, FALSE);
867 priv->is_server = TRUE;
869 /* @local_addr may have its port set to 0. So we intentionally
870 * don't store it in priv->local_addr, so that if the
871 * caller calls soup_socket_get_local_address() later, we'll
872 * have to make a new addr by calling getsockname(), which
873 * will have the right port number.
875 addr = soup_address_get_gsockaddr (priv->local_addr);
876 g_return_val_if_fail (addr != NULL, FALSE);
878 sa_len = g_socket_address_get_native_size (addr);
879 g_socket_address_to_native (addr, &sa, sizeof (sa), NULL);
880 g_object_unref (addr);
882 priv->sockfd = socket (sa.ss_family, SOCK_STREAM, 0);
883 if (SOUP_IS_INVALID_SOCKET (priv->sockfd))
888 if (bind (priv->sockfd, (struct sockaddr *)&sa, sa_len) != 0)
890 /* Force local_addr to be re-resolved now */
891 g_object_unref (priv->local_addr);
892 priv->local_addr = NULL;
895 if (listen (priv->sockfd, 10) != 0)
898 priv->watch_src = soup_add_io_watch (priv->async_context,
900 G_IO_IN | G_IO_ERR | G_IO_HUP,
906 disconnect_internal (priv);
912 * soup_socket_start_ssl:
914 * @cancellable: a #GCancellable
916 * Starts using SSL on @socket.
918 * Return value: success or failure
921 soup_socket_start_ssl (SoupSocket *sock, GCancellable *cancellable)
923 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
925 return soup_socket_start_proxy_ssl (sock, soup_address_get_name (priv->remote_addr), cancellable);
929 * soup_socket_start_proxy_ssl:
931 * @ssl_host: hostname of the SSL server
932 * @cancellable: a #GCancellable
934 * Starts using SSL on @socket, expecting to find a host named
937 * Return value: success or failure
940 soup_socket_start_proxy_ssl (SoupSocket *sock, const char *ssl_host,
941 GCancellable *cancellable)
943 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
944 GIOChannel *ssl_chan;
945 GIOChannel *real_chan;
947 real_chan = priv->iochannel;
948 ssl_chan = soup_ssl_wrap_iochannel (
949 real_chan, priv->non_blocking, priv->is_server ?
950 SOUP_SSL_TYPE_SERVER : SOUP_SSL_TYPE_CLIENT,
951 ssl_host, priv->ssl_creds);
956 /* This is optimistic, we will set this to false if we get a
957 * cert error from one of the I/O calls
960 priv->trusted_certificate = TRUE;
962 priv->iochannel = ssl_chan;
963 g_io_channel_unref (real_chan);
969 * soup_socket_is_ssl:
970 * @sock: a #SoupSocket
972 * Tests if @sock is set up to do SSL. Note that this simply means
973 * that the %SOUP_SOCKET_SSL_CREDENTIALS property has been set; it
974 * does not mean that soup_socket_start_ssl() has been called.
976 * Return value: %TRUE if @sock has SSL credentials set
979 soup_socket_is_ssl (SoupSocket *sock)
981 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
983 return priv->ssl_creds != NULL;
987 * soup_socket_disconnect:
988 * @sock: a #SoupSocket
990 * Disconnects @sock. Any further read or write attempts on it will
994 soup_socket_disconnect (SoupSocket *sock)
996 SoupSocketPrivate *priv;
997 gboolean already_disconnected = FALSE;
999 g_return_if_fail (SOUP_IS_SOCKET (sock));
1000 priv = SOUP_SOCKET_GET_PRIVATE (sock);
1002 if (priv->connect_cancel) {
1003 g_cancellable_cancel (priv->connect_cancel);
1005 } else if (g_mutex_trylock (priv->iolock)) {
1006 if (priv->iochannel)
1007 disconnect_internal (priv);
1009 already_disconnected = TRUE;
1010 g_mutex_unlock (priv->iolock);
1014 /* Another thread is currently doing IO, so
1015 * we can't close the iochannel. So just shutdown
1016 * the file descriptor to force the I/O to fail.
1017 * (It will actually be closed when the socket is
1020 sockfd = priv->sockfd;
1024 already_disconnected = TRUE;
1026 shutdown (sockfd, SHUT_RDWR);
1029 if (already_disconnected)
1032 /* Keep ref around signals in case the object is unreferenced
1035 g_object_ref (sock);
1037 /* Give all readers a chance to notice the connection close */
1038 g_signal_emit (sock, signals[READABLE], 0);
1040 /* FIXME: can't disconnect until all data is read */
1042 /* Then let everyone know we're disconnected */
1043 g_signal_emit (sock, signals[DISCONNECTED], 0);
1045 g_object_unref (sock);
1049 * soup_socket_is_connected:
1050 * @sock: a #SoupSocket
1052 * Tests if @sock is connected to another host
1054 * Return value: %TRUE or %FALSE.
1057 soup_socket_is_connected (SoupSocket *sock)
1059 SoupSocketPrivate *priv;
1061 g_return_val_if_fail (SOUP_IS_SOCKET (sock), FALSE);
1062 priv = SOUP_SOCKET_GET_PRIVATE (sock);
1064 return priv->iochannel != NULL;
1068 * soup_socket_get_local_address:
1069 * @sock: a #SoupSocket
1071 * Returns the #SoupAddress corresponding to the local end of @sock.
1073 * Return value: (transfer none): the #SoupAddress
1076 soup_socket_get_local_address (SoupSocket *sock)
1078 SoupSocketPrivate *priv;
1080 g_return_val_if_fail (SOUP_IS_SOCKET (sock), NULL);
1081 priv = SOUP_SOCKET_GET_PRIVATE (sock);
1083 g_mutex_lock (priv->addrlock);
1084 if (!priv->local_addr) {
1085 struct sockaddr_storage bound_sa;
1088 sa_len = sizeof (bound_sa);
1089 getsockname (priv->sockfd, (struct sockaddr *)&bound_sa, (void *)&sa_len);
1090 priv->local_addr = soup_address_new_from_sockaddr ((struct sockaddr *)&bound_sa, sa_len);
1092 g_mutex_unlock (priv->addrlock);
1094 return priv->local_addr;
1098 * soup_socket_get_remote_address:
1099 * @sock: a #SoupSocket
1101 * Returns the #SoupAddress corresponding to the remote end of @sock.
1103 * Return value: (transfer none): the #SoupAddress
1106 soup_socket_get_remote_address (SoupSocket *sock)
1108 SoupSocketPrivate *priv;
1110 g_return_val_if_fail (SOUP_IS_SOCKET (sock), NULL);
1111 priv = SOUP_SOCKET_GET_PRIVATE (sock);
1113 g_mutex_lock (priv->addrlock);
1114 if (!priv->remote_addr) {
1115 struct sockaddr_storage bound_sa;
1118 sa_len = sizeof (bound_sa);
1119 getpeername (priv->sockfd, (struct sockaddr *)&bound_sa, (void *)&sa_len);
1120 priv->remote_addr = soup_address_new_from_sockaddr ((struct sockaddr *)&bound_sa, sa_len);
1122 g_mutex_unlock (priv->addrlock);
1124 return priv->remote_addr;
1129 socket_timeout (gpointer sock)
1131 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
1132 gboolean readable = FALSE, writable = FALSE;
1134 priv->timed_out = TRUE;
1135 if (priv->read_timeout) {
1136 priv->read_timeout = NULL;
1139 if (priv->write_timeout) {
1140 priv->write_timeout = NULL;
1145 g_signal_emit (sock, signals[READABLE], 0);
1147 g_signal_emit (sock, signals[WRITABLE], 0);
1153 socket_read_watch (GIOChannel *chan, GIOCondition cond, gpointer user_data)
1155 SoupSocket *sock = user_data;
1156 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
1158 priv->read_src = NULL;
1159 if (priv->read_timeout) {
1160 g_source_destroy (priv->read_timeout);
1161 priv->read_timeout = NULL;
1164 if (cond & (G_IO_ERR | G_IO_HUP))
1165 soup_socket_disconnect (sock);
1167 g_signal_emit (sock, signals[READABLE], 0);
1172 static SoupSocketIOStatus
1173 read_from_network (SoupSocket *sock, gpointer buffer, gsize len,
1174 gsize *nread, GError **error)
1176 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
1178 GIOCondition cond = G_IO_IN;
1179 GError *my_err = NULL;
1183 if (!priv->iochannel)
1184 return SOUP_SOCKET_EOF;
1186 if (priv->timed_out) {
1187 g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_TIMED_OUT,
1189 return SOUP_SOCKET_ERROR;
1193 status = g_io_channel_read_chars (priv->iochannel,
1194 buffer, len, nread, &my_err);
1196 if (g_error_matches (my_err, SOUP_SSL_ERROR,
1197 SOUP_SSL_ERROR_CERTIFICATE) &&
1198 !priv->ssl_strict) {
1199 priv->trusted_certificate = FALSE;
1200 g_clear_error (&my_err);
1204 if (g_error_matches (my_err, SOUP_SSL_ERROR,
1205 SOUP_SSL_ERROR_HANDSHAKE_NEEDS_WRITE))
1207 g_propagate_error (error, my_err);
1211 case G_IO_STATUS_NORMAL:
1212 case G_IO_STATUS_AGAIN:
1214 g_clear_error (error);
1215 return SOUP_SOCKET_OK;
1218 /* If the socket is sync and we get EAGAIN, then it is
1219 * a socket timeout and should be treated as an error
1222 if (!priv->non_blocking) {
1223 g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_TIMED_OUT,
1225 return SOUP_SOCKET_ERROR;
1228 if (!priv->read_src) {
1230 soup_add_io_watch (priv->async_context,
1232 cond | G_IO_HUP | G_IO_ERR,
1233 socket_read_watch, sock);
1234 if (priv->timeout) {
1235 priv->read_timeout =
1236 soup_add_timeout (priv->async_context,
1237 priv->timeout * 1000,
1238 socket_timeout, sock);
1241 g_clear_error (error);
1242 return SOUP_SOCKET_WOULD_BLOCK;
1244 case G_IO_STATUS_EOF:
1245 g_clear_error (error);
1246 return SOUP_SOCKET_EOF;
1249 return SOUP_SOCKET_ERROR;
1253 static SoupSocketIOStatus
1254 read_from_buf (SoupSocket *sock, gpointer buffer, gsize len, gsize *nread)
1256 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
1257 GByteArray *read_buf = priv->read_buf;
1259 *nread = MIN (read_buf->len, len);
1260 memcpy (buffer, read_buf->data, *nread);
1262 if (*nread == read_buf->len) {
1263 g_byte_array_free (read_buf, TRUE);
1264 priv->read_buf = NULL;
1266 memmove (read_buf->data, read_buf->data + *nread,
1267 read_buf->len - *nread);
1268 g_byte_array_set_size (read_buf, read_buf->len - *nread);
1271 return SOUP_SOCKET_OK;
1275 * SoupSocketIOStatus:
1276 * @SOUP_SOCKET_OK: Success
1277 * @SOUP_SOCKET_WOULD_BLOCK: Cannot read/write any more at this time
1278 * @SOUP_SOCKET_EOF: End of file
1279 * @SOUP_SOCKET_ERROR: Other error
1281 * Return value from the #SoupSocket IO methods.
1287 * @buffer: buffer to read into
1288 * @len: size of @buffer in bytes
1289 * @nread: on return, the number of bytes read into @buffer
1290 * @cancellable: a #GCancellable, or %NULL
1291 * @error: error pointer
1293 * Attempts to read up to @len bytes from @sock into @buffer. If some
1294 * data is successfully read, soup_socket_read() will return
1295 * %SOUP_SOCKET_OK, and *@nread will contain the number of bytes
1296 * actually read (which may be less than @len).
1298 * If @sock is non-blocking, and no data is available, the return
1299 * value will be %SOUP_SOCKET_WOULD_BLOCK. In this case, the caller
1300 * can connect to the #SoupSocket::readable signal to know when there
1301 * is more data to read. (NB: You MUST read all available data off the
1302 * socket first. #SoupSocket::readable is only emitted after
1303 * soup_socket_read() returns %SOUP_SOCKET_WOULD_BLOCK, and it is only
1304 * emitted once. See the documentation for #SoupSocket:non-blocking.)
1306 * Return value: a #SoupSocketIOStatus, as described above (or
1307 * %SOUP_SOCKET_EOF if the socket is no longer connected, or
1308 * %SOUP_SOCKET_ERROR on any other error, in which case @error will
1312 soup_socket_read (SoupSocket *sock, gpointer buffer, gsize len,
1313 gsize *nread, GCancellable *cancellable, GError **error)
1315 SoupSocketPrivate *priv;
1316 SoupSocketIOStatus status;
1318 g_return_val_if_fail (SOUP_IS_SOCKET (sock), SOUP_SOCKET_ERROR);
1319 g_return_val_if_fail (nread != NULL, SOUP_SOCKET_ERROR);
1321 priv = SOUP_SOCKET_GET_PRIVATE (sock);
1323 g_mutex_lock (priv->iolock);
1325 status = read_from_buf (sock, buffer, len, nread);
1327 status = read_from_network (sock, buffer, len, nread, error);
1328 g_mutex_unlock (priv->iolock);
1334 * soup_socket_read_until:
1336 * @buffer: buffer to read into
1337 * @len: size of @buffer in bytes
1338 * @boundary: boundary to read until
1339 * @boundary_len: length of @boundary in bytes
1340 * @nread: on return, the number of bytes read into @buffer
1341 * @got_boundary: on return, whether or not the data in @buffer
1342 * ends with the boundary string
1343 * @cancellable: a #GCancellable, or %NULL
1344 * @error: error pointer
1346 * Like soup_socket_read(), but reads no further than the first
1347 * occurrence of @boundary. (If the boundary is found, it will be
1348 * included in the returned data, and *@got_boundary will be set to
1349 * %TRUE.) Any data after the boundary will returned in future reads.
1351 * soup_socket_read_until() will almost always return fewer than @len
1352 * bytes: if the boundary is found, then it will only return the bytes
1353 * up until the end of the boundary, and if the boundary is not found,
1354 * then it will leave the last <literal>(boundary_len - 1)</literal>
1355 * bytes in its internal buffer, in case they form the start of the
1356 * boundary string. Thus, @len normally needs to be at least 1 byte
1357 * longer than @boundary_len if you want to make any progress at all.
1359 * Return value: as for soup_socket_read()
1362 soup_socket_read_until (SoupSocket *sock, gpointer buffer, gsize len,
1363 gconstpointer boundary, gsize boundary_len,
1364 gsize *nread, gboolean *got_boundary,
1365 GCancellable *cancellable, GError **error)
1367 SoupSocketPrivate *priv;
1368 SoupSocketIOStatus status;
1369 GByteArray *read_buf;
1370 guint match_len, prev_len;
1373 g_return_val_if_fail (SOUP_IS_SOCKET (sock), SOUP_SOCKET_ERROR);
1374 g_return_val_if_fail (nread != NULL, SOUP_SOCKET_ERROR);
1375 g_return_val_if_fail (len >= boundary_len, SOUP_SOCKET_ERROR);
1377 priv = SOUP_SOCKET_GET_PRIVATE (sock);
1379 g_mutex_lock (priv->iolock);
1381 *got_boundary = FALSE;
1383 if (!priv->read_buf)
1384 priv->read_buf = g_byte_array_new ();
1385 read_buf = priv->read_buf;
1387 if (read_buf->len < boundary_len) {
1388 prev_len = read_buf->len;
1389 g_byte_array_set_size (read_buf, len);
1390 status = read_from_network (sock,
1391 read_buf->data + prev_len,
1392 len - prev_len, nread, error);
1393 read_buf->len = prev_len + *nread;
1395 if (status != SOUP_SOCKET_OK) {
1396 g_mutex_unlock (priv->iolock);
1401 /* Scan for the boundary */
1402 end = read_buf->data + read_buf->len;
1403 for (p = read_buf->data; p <= end - boundary_len; p++) {
1404 if (!memcmp (p, boundary, boundary_len)) {
1406 *got_boundary = TRUE;
1411 /* Return everything up to 'p' (which is either just after the
1412 * boundary, or @boundary_len - 1 bytes before the end of the
1415 match_len = p - read_buf->data;
1416 status = read_from_buf (sock, buffer, MIN (len, match_len), nread);
1418 g_mutex_unlock (priv->iolock);
1423 socket_write_watch (GIOChannel *chan, GIOCondition cond, gpointer user_data)
1425 SoupSocket *sock = user_data;
1426 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
1428 priv->write_src = NULL;
1429 if (priv->write_timeout) {
1430 g_source_destroy (priv->write_timeout);
1431 priv->write_timeout = NULL;
1434 if (cond & (G_IO_ERR | G_IO_HUP))
1435 soup_socket_disconnect (sock);
1437 g_signal_emit (sock, signals[WRITABLE], 0);
1443 * soup_socket_write:
1445 * @buffer: data to write
1446 * @len: size of @buffer, in bytes
1447 * @nwrote: on return, number of bytes written
1448 * @cancellable: a #GCancellable, or %NULL
1449 * @error: error pointer
1451 * Attempts to write @len bytes from @buffer to @sock. If some data is
1452 * successfully written, the return status will be %SOUP_SOCKET_OK,
1453 * and *@nwrote will contain the number of bytes actually written
1454 * (which may be less than @len).
1456 * If @sock is non-blocking, and no data could be written right away,
1457 * the return value will be %SOUP_SOCKET_WOULD_BLOCK. In this case,
1458 * the caller can connect to the #SoupSocket::writable signal to know
1459 * when more data can be written. (NB: #SoupSocket::writable is only
1460 * emitted after soup_socket_write() returns %SOUP_SOCKET_WOULD_BLOCK,
1461 * and it is only emitted once. See the documentation for
1462 * #SoupSocket:non-blocking.)
1464 * Return value: a #SoupSocketIOStatus, as described above (or
1465 * %SOUP_SOCKET_EOF or %SOUP_SOCKET_ERROR. @error will be set if the
1466 * return value is %SOUP_SOCKET_ERROR.)
1469 soup_socket_write (SoupSocket *sock, gconstpointer buffer,
1470 gsize len, gsize *nwrote,
1471 GCancellable *cancellable, GError **error)
1473 SoupSocketPrivate *priv;
1475 GIOCondition cond = G_IO_OUT;
1476 GError *my_err = NULL;
1478 g_return_val_if_fail (SOUP_IS_SOCKET (sock), SOUP_SOCKET_ERROR);
1479 g_return_val_if_fail (nwrote != NULL, SOUP_SOCKET_ERROR);
1481 priv = SOUP_SOCKET_GET_PRIVATE (sock);
1483 g_mutex_lock (priv->iolock);
1485 if (!priv->iochannel) {
1486 g_mutex_unlock (priv->iolock);
1487 return SOUP_SOCKET_EOF;
1489 if (priv->timed_out) {
1490 g_mutex_unlock (priv->iolock);
1491 g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_TIMED_OUT,
1493 return SOUP_SOCKET_ERROR;
1495 if (priv->write_src) {
1496 g_mutex_unlock (priv->iolock);
1497 return SOUP_SOCKET_WOULD_BLOCK;
1501 status = g_io_channel_write_chars (priv->iochannel,
1502 buffer, len, nwrote, &my_err);
1504 if (g_error_matches (my_err, SOUP_SSL_ERROR,
1505 SOUP_SSL_ERROR_CERTIFICATE) &&
1506 !priv->ssl_strict) {
1507 priv->trusted_certificate = FALSE;
1508 g_clear_error (&my_err);
1512 if (g_error_matches (my_err, SOUP_SSL_ERROR,
1513 SOUP_SSL_ERROR_HANDSHAKE_NEEDS_READ))
1515 g_propagate_error (error, my_err);
1518 /* If the socket is sync and we get EAGAIN, then it is a
1519 * socket timeout and should be treated as an error condition.
1521 if (!priv->non_blocking && status == G_IO_STATUS_AGAIN) {
1522 g_mutex_unlock (priv->iolock);
1523 g_set_error_literal (error, G_IO_ERROR, G_IO_ERROR_TIMED_OUT,
1525 return SOUP_SOCKET_ERROR;
1528 if (status != G_IO_STATUS_NORMAL && status != G_IO_STATUS_AGAIN) {
1529 g_mutex_unlock (priv->iolock);
1530 return SOUP_SOCKET_ERROR;
1533 g_clear_error (error);
1536 g_mutex_unlock (priv->iolock);
1537 return SOUP_SOCKET_OK;
1541 soup_add_io_watch (priv->async_context,
1543 cond | G_IO_HUP | G_IO_ERR,
1544 socket_write_watch, sock);
1545 if (priv->timeout) {
1546 priv->write_timeout = soup_add_timeout (priv->async_context,
1547 priv->timeout * 1000,
1548 socket_timeout, sock);
1551 g_mutex_unlock (priv->iolock);
1552 return SOUP_SOCKET_WOULD_BLOCK;