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 };
66 SoupAddress *local_addr, *remote_addr;
67 GIOChannel *iochannel;
74 GMainContext *async_context;
76 GSource *read_src, *write_src;
77 GSource *read_timeout, *write_timeout;
78 GSource *connect_timeout;
81 GMutex *iolock, *addrlock;
84 #define SOUP_SOCKET_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SOUP_TYPE_SOCKET, SoupSocketPrivate))
87 #define soup_sockaddr_max sockaddr_in6
89 #define soup_sockaddr_max sockaddr_in
92 static void set_property (GObject *object, guint prop_id,
93 const GValue *value, GParamSpec *pspec);
94 static void get_property (GObject *object, guint prop_id,
95 GValue *value, GParamSpec *pspec);
98 #define SOUP_IS_SOCKET_ERROR(status) ((status) == SOCKET_ERROR)
99 #define SOUP_IS_INVALID_SOCKET(socket) ((socket) == INVALID_SOCKET)
100 #define SOUP_IS_CONNECT_STATUS_INPROGRESS() (WSAGetLastError () == WSAEWOULDBLOCK)
101 #define SHUT_RDWR SD_BOTH
103 #define SOUP_IS_SOCKET_ERROR(status) ((status) == -1)
104 #define SOUP_IS_INVALID_SOCKET(socket) ((socket) < 0)
105 #define SOUP_IS_CONNECT_STATUS_INPROGRESS() (errno == EINPROGRESS)
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 g_io_channel_unref (priv->iochannel);
124 priv->iochannel = NULL;
127 if (priv->read_src) {
128 g_source_destroy (priv->read_src);
129 priv->read_src = NULL;
131 if (priv->write_src) {
132 g_source_destroy (priv->write_src);
133 priv->write_src = NULL;
135 if (priv->read_timeout) {
136 g_source_destroy (priv->read_timeout);
137 priv->read_timeout = NULL;
139 if (priv->write_timeout) {
140 g_source_destroy (priv->write_timeout);
141 priv->write_timeout = NULL;
146 finalize (GObject *object)
148 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (object);
151 disconnect_internal (priv);
153 if (priv->local_addr)
154 g_object_unref (priv->local_addr);
155 if (priv->remote_addr)
156 g_object_unref (priv->remote_addr);
159 g_source_destroy (priv->watch_src);
160 if (priv->connect_timeout)
161 g_source_destroy (priv->connect_timeout);
162 if (priv->async_context)
163 g_main_context_unref (priv->async_context);
166 g_byte_array_free (priv->read_buf, TRUE);
168 g_mutex_free (priv->addrlock);
169 g_mutex_free (priv->iolock);
171 G_OBJECT_CLASS (soup_socket_parent_class)->finalize (object);
175 soup_socket_class_init (SoupSocketClass *socket_class)
177 GObjectClass *object_class = G_OBJECT_CLASS (socket_class);
180 signal (SIGPIPE, SIG_IGN);
183 g_type_class_add_private (socket_class, sizeof (SoupSocketPrivate));
185 /* virtual method override */
186 object_class->finalize = finalize;
187 object_class->set_property = set_property;
188 object_class->get_property = get_property;
193 * SoupSocket::readable:
196 * Emitted when an async socket is readable. See
197 * soup_socket_read(), soup_socket_read_until() and
198 * #SoupSocket:non-blocking.
201 g_signal_new ("readable",
202 G_OBJECT_CLASS_TYPE (object_class),
204 G_STRUCT_OFFSET (SoupSocketClass, readable),
206 soup_marshal_NONE__NONE,
210 * SoupSocket::writable:
213 * Emitted when an async socket is writable. See
214 * soup_socket_write() and #SoupSocket:non-blocking.
217 g_signal_new ("writable",
218 G_OBJECT_CLASS_TYPE (object_class),
220 G_STRUCT_OFFSET (SoupSocketClass, writable),
222 soup_marshal_NONE__NONE,
226 * SoupSocket::disconnected:
229 * Emitted when the socket is disconnected, for whatever
232 signals[DISCONNECTED] =
233 g_signal_new ("disconnected",
234 G_OBJECT_CLASS_TYPE (object_class),
236 G_STRUCT_OFFSET (SoupSocketClass, disconnected),
238 soup_marshal_NONE__NONE,
242 * SoupSocket::new-connection:
244 * @new: the new socket
246 * Emitted when a listening socket (set up with
247 * soup_socket_listen()) receives a new connection.
249 * You must ref the @new if you want to keep it; otherwise it
250 * will be destroyed after the signal is emitted.
252 signals[NEW_CONNECTION] =
253 g_signal_new ("new_connection",
254 G_OBJECT_CLASS_TYPE (object_class),
256 G_STRUCT_OFFSET (SoupSocketClass, new_connection),
258 soup_marshal_NONE__OBJECT,
264 * SOUP_SOCKET_LOCAL_ADDRESS:
266 * Alias for the #SoupSocket:local-address property. (Address
267 * of local end of socket.)
269 g_object_class_install_property (
270 object_class, PROP_LOCAL_ADDRESS,
271 g_param_spec_object (SOUP_SOCKET_LOCAL_ADDRESS,
273 "Address of local end of socket",
275 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
277 * SOUP_SOCKET_REMOTE_ADDRESS:
279 * Alias for the #SoupSocket:remote-address property. (Address
280 * of remote end of socket.)
282 g_object_class_install_property (
283 object_class, PROP_REMOTE_ADDRESS,
284 g_param_spec_object (SOUP_SOCKET_REMOTE_ADDRESS,
286 "Address of remote end of socket",
288 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
290 * SoupSocket:non-blocking:
292 * Whether or not the socket uses non-blocking I/O.
294 * #SoupSocket's I/O methods are designed around the idea of
295 * using a single codepath for both synchronous and
296 * asynchronous I/O. If you want to read off a #SoupSocket,
297 * the "correct" way to do it is to call soup_socket_read() or
298 * soup_socket_read_until() repeatedly until you have read
299 * everything you want. If it returns %SOUP_SOCKET_WOULD_BLOCK
300 * at any point, stop reading and wait for it to emit the
301 * #SoupSocket::readable signal. Then go back to the
302 * reading-as-much-as-you-can loop. Likewise, for writing to a
303 * #SoupSocket, you should call soup_socket_write() either
304 * until you have written everything, or it returns
305 * %SOUP_SOCKET_WOULD_BLOCK (in which case you wait for
306 * #SoupSocket::writable and then go back into the loop).
308 * Code written this way will work correctly with both
309 * blocking and non-blocking sockets; blocking sockets will
310 * simply never return %SOUP_SOCKET_WOULD_BLOCK, and so the
311 * code that handles that case just won't get used for them.
314 * SOUP_SOCKET_FLAG_NONBLOCKING:
316 * Alias for the #SoupSocket:non-blocking property. (Whether
317 * or not the socket uses non-blocking I/O.)
319 g_object_class_install_property (
320 object_class, PROP_NON_BLOCKING,
321 g_param_spec_boolean (SOUP_SOCKET_FLAG_NONBLOCKING,
323 "Whether or not the socket uses non-blocking I/O",
327 * SOUP_SOCKET_IS_SERVER:
329 * Alias for the #SoupSocket:is-server property. (Whether or
330 * not the socket is a server socket.)
332 g_object_class_install_property (
333 object_class, PROP_IS_SERVER,
334 g_param_spec_boolean (SOUP_SOCKET_IS_SERVER,
336 "Whether or not the socket is a server socket",
340 * SOUP_SOCKET_SSL_CREDENTIALS:
342 * Alias for the #SoupSocket:ssl-credentials property.
343 * (SSL credential information.)
345 g_object_class_install_property (
346 object_class, PROP_SSL_CREDENTIALS,
347 g_param_spec_pointer (SOUP_SOCKET_SSL_CREDENTIALS,
349 "SSL credential information, passed from the session to the SSL implementation",
352 * SOUP_SOCKET_ASYNC_CONTEXT:
354 * Alias for the #SoupSocket:async-context property. (The
355 * socket's #GMainContext.)
357 g_object_class_install_property (
358 object_class, PROP_ASYNC_CONTEXT,
359 g_param_spec_pointer (SOUP_SOCKET_ASYNC_CONTEXT,
360 "Async GMainContext",
361 "The GMainContext to dispatch this socket's async I/O in",
362 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
365 * SOUP_SOCKET_TIMEOUT:
367 * Alias for the #SoupSocket:timeout property. (The timeout
368 * in seconds for blocking socket I/O operations.)
370 g_object_class_install_property (
371 object_class, PROP_TIMEOUT,
372 g_param_spec_uint (SOUP_SOCKET_TIMEOUT,
374 "Value in seconds to timeout a blocking I/O",
379 /* Make sure WSAStartup() gets called. */
380 soup_address_get_type ();
386 set_nonblocking (SoupSocketPrivate *priv)
394 if (priv->sockfd == -1)
398 flags = fcntl (priv->sockfd, F_GETFL, 0);
400 if (priv->non_blocking)
403 flags &= ~O_NONBLOCK;
404 fcntl (priv->sockfd, F_SETFL, flags);
407 val = priv->non_blocking ? 1 : 0;
408 ioctlsocket (priv->sockfd, FIONBIO, &val);
413 set_fdflags (SoupSocketPrivate *priv)
417 struct timeval timeout;
421 if (priv->sockfd == -1)
424 set_nonblocking (priv);
427 flags = fcntl (priv->sockfd, F_GETFD, 0);
430 fcntl (priv->sockfd, F_SETFD, flags);
435 setsockopt (priv->sockfd, IPPROTO_TCP,
436 TCP_NODELAY, (void *) &opt, sizeof (opt));
437 setsockopt (priv->sockfd, SOL_SOCKET,
438 SO_REUSEADDR, (void *) &opt, sizeof (opt));
441 timeout.tv_sec = priv->timeout;
443 setsockopt (priv->sockfd, SOL_SOCKET,
444 SO_RCVTIMEO, (void *) &timeout, sizeof (timeout));
446 timeout.tv_sec = priv->timeout;
448 setsockopt (priv->sockfd, SOL_SOCKET,
449 SO_SNDTIMEO, (void *) &timeout, sizeof (timeout));
451 if (priv->timeout < G_MAXINT / 1000)
452 opt = priv->timeout * 1000;
456 setsockopt (priv->sockfd, SOL_SOCKET,
457 SO_RCVTIMEO, (void *) &opt, sizeof (opt));
459 setsockopt (priv->sockfd, SOL_SOCKET,
460 SO_SNDTIMEO, (void *) &opt, sizeof (opt));
465 g_io_channel_unix_new (priv->sockfd);
468 g_io_channel_win32_new_socket (priv->sockfd);
470 g_io_channel_set_close_on_unref (priv->iochannel, TRUE);
471 g_io_channel_set_encoding (priv->iochannel, NULL, NULL);
472 g_io_channel_set_buffered (priv->iochannel, FALSE);
476 set_property (GObject *object, guint prop_id,
477 const GValue *value, GParamSpec *pspec)
479 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (object);
482 case PROP_LOCAL_ADDRESS:
483 priv->local_addr = (SoupAddress *)g_value_dup_object (value);
485 case PROP_REMOTE_ADDRESS:
486 priv->remote_addr = (SoupAddress *)g_value_dup_object (value);
488 case PROP_NON_BLOCKING:
489 priv->non_blocking = g_value_get_boolean (value);
490 set_nonblocking (priv);
492 case PROP_SSL_CREDENTIALS:
493 priv->ssl_creds = g_value_get_pointer (value);
495 case PROP_ASYNC_CONTEXT:
496 priv->async_context = g_value_get_pointer (value);
497 if (priv->async_context)
498 g_main_context_ref (priv->async_context);
501 priv->timeout = g_value_get_uint (value);
504 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
510 get_property (GObject *object, guint prop_id,
511 GValue *value, GParamSpec *pspec)
513 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (object);
516 case PROP_LOCAL_ADDRESS:
517 g_value_set_object (value, soup_socket_get_local_address (SOUP_SOCKET (object)));
519 case PROP_REMOTE_ADDRESS:
520 g_value_set_object (value, soup_socket_get_remote_address (SOUP_SOCKET (object)));
522 case PROP_NON_BLOCKING:
523 g_value_set_boolean (value, priv->non_blocking);
526 g_value_set_boolean (value, priv->is_server);
528 case PROP_SSL_CREDENTIALS:
529 g_value_set_pointer (value, priv->ssl_creds);
531 case PROP_ASYNC_CONTEXT:
532 g_value_set_pointer (value, priv->async_context ? g_main_context_ref (priv->async_context) : NULL);
535 g_value_set_uint (value, priv->timeout);
538 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
546 * @optname1: name of first property to set (or %NULL)
547 * @...: value of @optname1, followed by additional property/value pairs
549 * Creates a new (disconnected) socket
551 * Return value: the new socket
554 soup_socket_new (const char *optname1, ...)
559 va_start (ap, optname1);
560 sock = (SoupSocket *)g_object_new_valist (SOUP_TYPE_SOCKET,
569 GCancellable *cancellable;
571 SoupSocketCallback callback;
573 } SoupSocketAsyncConnectData;
576 idle_connect_result (gpointer user_data)
578 SoupSocketAsyncConnectData *sacd = user_data;
579 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sacd->sock);
582 priv->watch_src = NULL;
584 g_signal_handler_disconnect (sacd->cancellable, sacd->cancel_id);
586 if (priv->sockfd == -1) {
587 if (g_cancellable_is_cancelled (sacd->cancellable))
588 status = SOUP_STATUS_CANCELLED;
590 status = SOUP_STATUS_CANT_CONNECT;
592 status = SOUP_STATUS_OK;
594 sacd->callback (sacd->sock, status, sacd->user_data);
595 g_slice_free (SoupSocketAsyncConnectData, sacd);
600 connect_watch (GIOChannel* iochannel, GIOCondition condition, gpointer data)
602 SoupSocketAsyncConnectData *sacd = data;
603 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sacd->sock);
605 int len = sizeof (error);
607 /* Remove the watch now in case we don't return immediately */
608 g_source_destroy (priv->watch_src);
609 priv->watch_src = NULL;
610 if (priv->connect_timeout) {
611 g_source_destroy (priv->connect_timeout);
612 priv->connect_timeout = NULL;
615 if ((condition & ~(G_IO_IN | G_IO_OUT)) ||
616 (getsockopt (priv->sockfd, SOL_SOCKET, SO_ERROR,
617 (void *)&error, (void *)&len) != 0) ||
619 disconnect_internal (priv);
621 return idle_connect_result (sacd);
625 connect_timeout (gpointer data)
627 SoupSocketAsyncConnectData *sacd = data;
628 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sacd->sock);
630 /* Remove the watch now in case we don't return immediately */
631 g_source_destroy (priv->watch_src);
632 priv->watch_src = NULL;
633 g_source_destroy (priv->connect_timeout);
634 priv->connect_timeout = NULL;
636 disconnect_internal (priv);
637 return idle_connect_result (sacd);
641 got_address (SoupAddress *addr, guint status, gpointer user_data)
643 SoupSocketAsyncConnectData *sacd = user_data;
645 if (!SOUP_STATUS_IS_SUCCESSFUL (status)) {
646 sacd->callback (sacd->sock, status, sacd->user_data);
647 g_slice_free (SoupSocketAsyncConnectData, sacd);
651 soup_socket_connect_async (sacd->sock, sacd->cancellable,
652 sacd->callback, sacd->user_data);
653 g_slice_free (SoupSocketAsyncConnectData, sacd);
657 async_cancel (GCancellable *cancellable, gpointer user_data)
659 SoupSocketAsyncConnectData *sacd = user_data;
660 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sacd->sock);
663 g_source_destroy (priv->watch_src);
664 disconnect_internal (priv);
665 priv->watch_src = soup_add_completion (priv->async_context,
666 idle_connect_result, sacd);
670 socket_connect_internal (SoupSocket *sock)
672 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
676 sa = soup_address_get_sockaddr (priv->remote_addr, &len);
678 return SOUP_STATUS_CANT_RESOLVE;
680 priv->sockfd = socket (sa->sa_family, SOCK_STREAM, 0);
681 if (SOUP_IS_INVALID_SOCKET (priv->sockfd))
682 return SOUP_STATUS_CANT_CONNECT;
685 status = connect (priv->sockfd, sa, len);
687 if (SOUP_IS_SOCKET_ERROR (status)) {
688 if (SOUP_IS_CONNECT_STATUS_INPROGRESS ())
689 return SOUP_STATUS_CONTINUE;
691 disconnect_internal (priv);
692 return SOUP_STATUS_CANT_CONNECT;
694 return SOUP_STATUS_OK;
698 * SoupSocketCallback:
699 * @sock: the #SoupSocket
700 * @status: an HTTP status code indicating success or failure
701 * @user_data: the data passed to soup_socket_connect_async()
703 * The callback function passed to soup_socket_connect_async().
707 * soup_socket_connect_async:
708 * @sock: a client #SoupSocket (which must not already be connected)
709 * @cancellable: a #GCancellable, or %NULL
710 * @callback: callback to call after connecting
711 * @user_data: data to pass to @callback
713 * Begins asynchronously connecting to @sock's remote address. The
714 * socket will call @callback when it succeeds or fails (but not
715 * before returning from this function).
717 * If @cancellable is non-%NULL, it can be used to cancel the
718 * connection. @callback will still be invoked in this case, with a
719 * status of %SOUP_STATUS_CANCELLED.
722 soup_socket_connect_async (SoupSocket *sock, GCancellable *cancellable,
723 SoupSocketCallback callback, gpointer user_data)
725 SoupSocketPrivate *priv;
726 SoupSocketAsyncConnectData *sacd;
729 g_return_if_fail (SOUP_IS_SOCKET (sock));
730 priv = SOUP_SOCKET_GET_PRIVATE (sock);
731 g_return_if_fail (priv->remote_addr != NULL);
733 sacd = g_slice_new0 (SoupSocketAsyncConnectData);
735 sacd->cancellable = cancellable;
736 sacd->callback = callback;
737 sacd->user_data = user_data;
739 if (!soup_address_get_sockaddr (priv->remote_addr, NULL)) {
740 soup_address_resolve_async (priv->remote_addr,
747 status = socket_connect_internal (sock);
748 if (status == SOUP_STATUS_CONTINUE) {
749 /* Wait for connect to succeed or fail */
751 soup_add_io_watch (priv->async_context,
754 G_IO_PRI | G_IO_ERR |
755 G_IO_HUP | G_IO_NVAL,
756 connect_watch, sacd);
758 priv->connect_timeout =
759 soup_add_timeout (priv->async_context,
760 priv->timeout * 1000,
761 connect_timeout, sacd);
765 g_signal_connect (cancellable, "cancelled",
766 G_CALLBACK (async_cancel),
770 priv->watch_src = soup_add_completion (priv->async_context,
771 idle_connect_result, sacd);
776 sync_cancel (GCancellable *cancellable, gpointer sock)
778 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
780 shutdown (priv->sockfd, SHUT_RDWR);
784 * soup_socket_connect_sync:
785 * @sock: a client #SoupSocket (which must not already be connected)
786 * @cancellable: a #GCancellable, or %NULL
788 * Attempt to synchronously connect @sock to its remote address.
790 * If @cancellable is non-%NULL, it can be used to cancel the
791 * connection, in which case soup_socket_connect_sync() will return
792 * %SOUP_STATUS_CANCELLED.
794 * Return value: a success or failure code.
797 soup_socket_connect_sync (SoupSocket *sock, GCancellable *cancellable)
799 SoupSocketPrivate *priv;
800 guint status, cancel_id;
802 g_return_val_if_fail (SOUP_IS_SOCKET (sock), SOUP_STATUS_MALFORMED);
803 priv = SOUP_SOCKET_GET_PRIVATE (sock);
804 g_return_val_if_fail (!priv->is_server, SOUP_STATUS_MALFORMED);
805 g_return_val_if_fail (priv->sockfd == -1, SOUP_STATUS_MALFORMED);
806 g_return_val_if_fail (priv->remote_addr != NULL, SOUP_STATUS_MALFORMED);
808 if (!soup_address_get_sockaddr (priv->remote_addr, NULL)) {
809 status = soup_address_resolve_sync (priv->remote_addr,
811 if (!SOUP_STATUS_IS_SUCCESSFUL (status))
816 cancel_id = g_signal_connect (cancellable, "cancelled",
817 G_CALLBACK (sync_cancel), sock);
820 status = socket_connect_internal (sock);
823 if (status != SOUP_STATUS_OK &&
824 g_cancellable_is_cancelled (cancellable)) {
825 status = SOUP_STATUS_CANCELLED;
826 disconnect_internal (priv);
828 g_signal_handler_disconnect (cancellable, cancel_id);
835 soup_socket_get_fd (SoupSocket *sock)
837 g_return_val_if_fail (SOUP_IS_SOCKET (sock), -1);
839 return SOUP_SOCKET_GET_PRIVATE (sock)->sockfd;
843 listen_watch (GIOChannel* iochannel, GIOCondition condition, gpointer data)
845 SoupSocket *sock = data, *new;
846 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock), *new_priv;
847 struct soup_sockaddr_max sa;
850 if (condition & (G_IO_HUP | G_IO_ERR)) {
851 g_source_destroy (priv->watch_src);
852 priv->watch_src = NULL;
856 sa_len = sizeof (sa);
857 sockfd = accept (priv->sockfd, (struct sockaddr *)&sa, (void *)&sa_len);
858 if (SOUP_IS_INVALID_SOCKET (sockfd))
861 new = g_object_new (SOUP_TYPE_SOCKET, NULL);
862 new_priv = SOUP_SOCKET_GET_PRIVATE (new);
863 new_priv->sockfd = sockfd;
864 if (priv->async_context)
865 new_priv->async_context = g_main_context_ref (priv->async_context);
866 new_priv->non_blocking = priv->non_blocking;
867 new_priv->is_server = TRUE;
868 new_priv->ssl_creds = priv->ssl_creds;
869 set_fdflags (new_priv);
871 new_priv->remote_addr = soup_address_new_from_sockaddr ((struct sockaddr *)&sa, sa_len);
873 if (new_priv->ssl_creds) {
874 if (!soup_socket_start_ssl (new, NULL)) {
875 g_object_unref (new);
880 g_signal_emit (sock, signals[NEW_CONNECTION], 0, new);
881 g_object_unref (new);
887 * soup_socket_listen:
888 * @sock: a server #SoupSocket (which must not already be connected or
891 * Makes @sock start listening on its local address. When connections
892 * come in, @sock will emit %new_connection.
894 * Return value: whether or not @sock is now listening.
897 soup_socket_listen (SoupSocket *sock)
900 SoupSocketPrivate *priv;
904 g_return_val_if_fail (SOUP_IS_SOCKET (sock), FALSE);
905 priv = SOUP_SOCKET_GET_PRIVATE (sock);
906 g_return_val_if_fail (priv->sockfd == -1, FALSE);
907 g_return_val_if_fail (priv->local_addr != NULL, FALSE);
909 priv->is_server = TRUE;
911 /* @local_addr may have its port set to 0. So we intentionally
912 * don't store it in priv->local_addr, so that if the
913 * caller calls soup_socket_get_local_address() later, we'll
914 * have to make a new addr by calling getsockname(), which
915 * will have the right port number.
917 sa = soup_address_get_sockaddr (priv->local_addr, &sa_len);
918 g_return_val_if_fail (sa != NULL, FALSE);
920 priv->sockfd = socket (sa->sa_family, SOCK_STREAM, 0);
921 if (SOUP_IS_INVALID_SOCKET (priv->sockfd))
926 if (bind (priv->sockfd, sa, sa_len) != 0)
928 /* Force local_addr to be re-resolved now */
929 g_object_unref (priv->local_addr);
930 priv->local_addr = NULL;
933 if (listen (priv->sockfd, 10) != 0)
936 priv->watch_src = soup_add_io_watch (priv->async_context,
938 G_IO_IN | G_IO_ERR | G_IO_HUP,
944 disconnect_internal (priv);
950 * soup_socket_start_ssl:
952 * @cancellable: a #GCancellable
954 * Starts using SSL on @socket.
956 * Return value: success or failure
959 soup_socket_start_ssl (SoupSocket *sock, GCancellable *cancellable)
961 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
963 return soup_socket_start_proxy_ssl (sock, soup_address_get_name (priv->remote_addr), cancellable);
967 * soup_socket_start_proxy_ssl:
969 * @ssl_host: hostname of the SSL server
970 * @cancellable: a #GCancellable
972 * Starts using SSL on @socket, expecting to find a host named
975 * Return value: success or failure
978 soup_socket_start_proxy_ssl (SoupSocket *sock, const char *ssl_host,
979 GCancellable *cancellable)
981 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
982 GIOChannel *ssl_chan;
983 GIOChannel *real_chan;
985 real_chan = priv->iochannel;
986 ssl_chan = soup_ssl_wrap_iochannel (
987 real_chan, priv->non_blocking, priv->is_server ?
988 SOUP_SSL_TYPE_SERVER : SOUP_SSL_TYPE_CLIENT,
989 ssl_host, priv->ssl_creds);
994 priv->iochannel = ssl_chan;
995 g_io_channel_unref (real_chan);
1001 * soup_socket_is_ssl:
1002 * @sock: a #SoupSocket
1004 * Tests if @sock is set up to do SSL. Note that this simply means
1005 * that the %SOUP_SOCKET_SSL_CREDENTIALS property has been set; it
1006 * does not mean that soup_socket_start_ssl() has been called.
1008 * Return value: %TRUE if @sock has SSL credentials set
1011 soup_socket_is_ssl (SoupSocket *sock)
1013 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
1015 return priv->ssl_creds != NULL;
1019 * soup_socket_disconnect:
1020 * @sock: a #SoupSocket
1022 * Disconnects @sock. Any further read or write attempts on it will
1026 soup_socket_disconnect (SoupSocket *sock)
1028 SoupSocketPrivate *priv;
1029 gboolean already_disconnected = FALSE;
1031 g_return_if_fail (SOUP_IS_SOCKET (sock));
1032 priv = SOUP_SOCKET_GET_PRIVATE (sock);
1034 if (g_mutex_trylock (priv->iolock)) {
1035 if (priv->iochannel)
1036 disconnect_internal (priv);
1038 already_disconnected = TRUE;
1039 g_mutex_unlock (priv->iolock);
1043 /* Another thread is currently doing IO, so
1044 * we can't close the iochannel. So just shutdown
1045 * the file descriptor to force the I/O to fail.
1046 * (It will actually be closed when the socket is
1049 sockfd = priv->sockfd;
1053 already_disconnected = TRUE;
1055 shutdown (sockfd, SHUT_RDWR);
1058 if (already_disconnected)
1061 /* Give all readers a chance to notice the connection close */
1062 g_signal_emit (sock, signals[READABLE], 0);
1064 /* FIXME: can't disconnect until all data is read */
1066 /* Then let everyone know we're disconnected */
1067 g_signal_emit (sock, signals[DISCONNECTED], 0);
1071 * soup_socket_is_connected:
1072 * @sock: a #SoupSocket
1074 * Tests if @sock is connected to another host
1076 * Return value: %TRUE or %FALSE.
1079 soup_socket_is_connected (SoupSocket *sock)
1081 SoupSocketPrivate *priv;
1083 g_return_val_if_fail (SOUP_IS_SOCKET (sock), FALSE);
1084 priv = SOUP_SOCKET_GET_PRIVATE (sock);
1086 return priv->iochannel != NULL;
1090 * soup_socket_get_local_address:
1091 * @sock: a #SoupSocket
1093 * Returns the #SoupAddress corresponding to the local end of @sock.
1095 * Return value: the #SoupAddress
1098 soup_socket_get_local_address (SoupSocket *sock)
1100 SoupSocketPrivate *priv;
1102 g_return_val_if_fail (SOUP_IS_SOCKET (sock), NULL);
1103 priv = SOUP_SOCKET_GET_PRIVATE (sock);
1105 g_mutex_lock (priv->addrlock);
1106 if (!priv->local_addr) {
1107 struct soup_sockaddr_max bound_sa;
1110 sa_len = sizeof (bound_sa);
1111 getsockname (priv->sockfd, (struct sockaddr *)&bound_sa, (void *)&sa_len);
1112 priv->local_addr = soup_address_new_from_sockaddr ((struct sockaddr *)&bound_sa, sa_len);
1114 g_mutex_unlock (priv->addrlock);
1116 return priv->local_addr;
1120 * soup_socket_get_remote_address:
1121 * @sock: a #SoupSocket
1123 * Returns the #SoupAddress corresponding to the remote end of @sock.
1125 * Return value: the #SoupAddress
1128 soup_socket_get_remote_address (SoupSocket *sock)
1130 SoupSocketPrivate *priv;
1132 g_return_val_if_fail (SOUP_IS_SOCKET (sock), NULL);
1133 priv = SOUP_SOCKET_GET_PRIVATE (sock);
1135 g_mutex_lock (priv->addrlock);
1136 if (!priv->remote_addr) {
1137 struct soup_sockaddr_max bound_sa;
1140 sa_len = sizeof (bound_sa);
1141 getpeername (priv->sockfd, (struct sockaddr *)&bound_sa, (void *)&sa_len);
1142 priv->remote_addr = soup_address_new_from_sockaddr ((struct sockaddr *)&bound_sa, sa_len);
1144 g_mutex_unlock (priv->addrlock);
1146 return priv->remote_addr;
1151 socket_timeout (gpointer sock)
1153 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
1154 gboolean readable = FALSE, writable = FALSE;
1156 priv->timed_out = TRUE;
1157 if (priv->read_timeout) {
1158 priv->read_timeout = NULL;
1161 if (priv->write_timeout) {
1162 priv->write_timeout = NULL;
1167 g_signal_emit (sock, signals[READABLE], 0);
1169 g_signal_emit (sock, signals[WRITABLE], 0);
1175 socket_read_watch (GIOChannel *chan, GIOCondition cond, gpointer user_data)
1177 SoupSocket *sock = user_data;
1178 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
1180 priv->read_src = NULL;
1181 if (priv->read_timeout) {
1182 g_source_destroy (priv->read_timeout);
1183 priv->read_timeout = NULL;
1186 if (cond & (G_IO_ERR | G_IO_HUP))
1187 soup_socket_disconnect (sock);
1189 g_signal_emit (sock, signals[READABLE], 0);
1194 static SoupSocketIOStatus
1195 read_from_network (SoupSocket *sock, gpointer buffer, gsize len,
1196 gsize *nread, GError **error)
1198 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
1200 GIOCondition cond = G_IO_IN;
1201 GError *my_err = NULL;
1205 if (!priv->iochannel)
1206 return SOUP_SOCKET_EOF;
1208 if (priv->timed_out)
1209 return SOUP_SOCKET_ERROR;
1211 status = g_io_channel_read_chars (priv->iochannel,
1212 buffer, len, nread, &my_err);
1214 if (my_err->domain == SOUP_SSL_ERROR &&
1215 my_err->code == SOUP_SSL_ERROR_HANDSHAKE_NEEDS_WRITE)
1217 g_propagate_error (error, my_err);
1221 case G_IO_STATUS_NORMAL:
1222 case G_IO_STATUS_AGAIN:
1224 g_clear_error (error);
1225 return SOUP_SOCKET_OK;
1228 /* If the socket is sync and we get EAGAIN, then it is
1229 * a socket timeout and should be treated as an error
1232 if (!priv->non_blocking)
1233 return SOUP_SOCKET_ERROR;
1235 if (!priv->read_src) {
1237 soup_add_io_watch (priv->async_context,
1239 cond | G_IO_HUP | G_IO_ERR,
1240 socket_read_watch, sock);
1241 if (priv->timeout) {
1242 priv->read_timeout =
1243 soup_add_timeout (priv->async_context,
1244 priv->timeout * 1000,
1245 socket_timeout, sock);
1248 g_clear_error (error);
1249 return SOUP_SOCKET_WOULD_BLOCK;
1251 case G_IO_STATUS_EOF:
1252 g_clear_error (error);
1253 return SOUP_SOCKET_EOF;
1256 return SOUP_SOCKET_ERROR;
1260 static SoupSocketIOStatus
1261 read_from_buf (SoupSocket *sock, gpointer buffer, gsize len, gsize *nread)
1263 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
1264 GByteArray *read_buf = priv->read_buf;
1266 *nread = MIN (read_buf->len, len);
1267 memcpy (buffer, read_buf->data, *nread);
1269 if (*nread == read_buf->len) {
1270 g_byte_array_free (read_buf, TRUE);
1271 priv->read_buf = NULL;
1273 memmove (read_buf->data, read_buf->data + *nread,
1274 read_buf->len - *nread);
1275 g_byte_array_set_size (read_buf, read_buf->len - *nread);
1278 return SOUP_SOCKET_OK;
1282 * SoupSocketIOStatus:
1283 * @SOUP_SOCKET_OK: Success
1284 * @SOUP_SOCKET_WOULD_BLOCK: Cannot read/write any more at this time
1285 * @SOUP_SOCKET_EOF: End of file
1286 * @SOUP_SOCKET_ERROR: Other error
1288 * Return value from the #SoupSocket IO methods.
1294 * @buffer: buffer to read into
1295 * @len: size of @buffer in bytes
1296 * @nread: on return, the number of bytes read into @buffer
1297 * @cancellable: a #GCancellable, or %NULL
1298 * @error: error pointer
1300 * Attempts to read up to @len bytes from @sock into @buffer. If some
1301 * data is successfully read, soup_socket_read() will return
1302 * %SOUP_SOCKET_OK, and *@nread will contain the number of bytes
1303 * actually read (which may be less than @len).
1305 * If @sock is non-blocking, and no data is available, the return
1306 * value will be %SOUP_SOCKET_WOULD_BLOCK. In this case, the caller
1307 * can connect to the #SoupSocket::readable signal to know when there
1308 * is more data to read. (NB: You MUST read all available data off the
1309 * socket first. #SoupSocket::readable is only emitted after
1310 * soup_socket_read() returns %SOUP_SOCKET_WOULD_BLOCK, and it is only
1311 * emitted once. See the documentation for #SoupSocket:non-blocking.)
1313 * Return value: a #SoupSocketIOStatus, as described above (or
1314 * %SOUP_SOCKET_EOF if the socket is no longer connected, or
1315 * %SOUP_SOCKET_ERROR on any other error, in which case @error will
1319 soup_socket_read (SoupSocket *sock, gpointer buffer, gsize len,
1320 gsize *nread, GCancellable *cancellable, GError **error)
1322 SoupSocketPrivate *priv;
1323 SoupSocketIOStatus status;
1325 g_return_val_if_fail (SOUP_IS_SOCKET (sock), SOUP_SOCKET_ERROR);
1326 g_return_val_if_fail (nread != NULL, SOUP_SOCKET_ERROR);
1328 priv = SOUP_SOCKET_GET_PRIVATE (sock);
1330 g_mutex_lock (priv->iolock);
1332 status = read_from_buf (sock, buffer, len, nread);
1334 status = read_from_network (sock, buffer, len, nread, error);
1335 g_mutex_unlock (priv->iolock);
1341 * soup_socket_read_until:
1343 * @buffer: buffer to read into
1344 * @len: size of @buffer in bytes
1345 * @boundary: boundary to read until
1346 * @boundary_len: length of @boundary in bytes
1347 * @nread: on return, the number of bytes read into @buffer
1348 * @got_boundary: on return, whether or not the data in @buffer
1349 * ends with the boundary string
1350 * @cancellable: a #GCancellable, or %NULL
1351 * @error: error pointer
1353 * Like soup_socket_read(), but reads no further than the first
1354 * occurrence of @boundary. (If the boundary is found, it will be
1355 * included in the returned data, and *@got_boundary will be set to
1356 * %TRUE.) Any data after the boundary will returned in future reads.
1358 * soup_socket_read_until() will almost always return fewer than @len
1359 * bytes: if the boundary is found, then it will only return the bytes
1360 * up until the end of the boundary, and if the boundary is not found,
1361 * then it will leave the last <literal>(boundary_len - 1)</literal>
1362 * bytes in its internal buffer, in case they form the start of the
1363 * boundary string. Thus, @len normally needs to be at least 1 byte
1364 * longer than @boundary_len if you want to make any progress at all.
1366 * Return value: as for soup_socket_read()
1369 soup_socket_read_until (SoupSocket *sock, gpointer buffer, gsize len,
1370 gconstpointer boundary, gsize boundary_len,
1371 gsize *nread, gboolean *got_boundary,
1372 GCancellable *cancellable, GError **error)
1374 SoupSocketPrivate *priv;
1375 SoupSocketIOStatus status;
1376 GByteArray *read_buf;
1377 guint match_len, prev_len;
1380 g_return_val_if_fail (SOUP_IS_SOCKET (sock), SOUP_SOCKET_ERROR);
1381 g_return_val_if_fail (nread != NULL, SOUP_SOCKET_ERROR);
1382 g_return_val_if_fail (len >= boundary_len, SOUP_SOCKET_ERROR);
1384 priv = SOUP_SOCKET_GET_PRIVATE (sock);
1386 g_mutex_lock (priv->iolock);
1388 *got_boundary = FALSE;
1390 if (!priv->read_buf)
1391 priv->read_buf = g_byte_array_new ();
1392 read_buf = priv->read_buf;
1394 if (read_buf->len < boundary_len) {
1395 prev_len = read_buf->len;
1396 g_byte_array_set_size (read_buf, len);
1397 status = read_from_network (sock,
1398 read_buf->data + prev_len,
1399 len - prev_len, nread, error);
1400 read_buf->len = prev_len + *nread;
1402 if (status != SOUP_SOCKET_OK) {
1403 g_mutex_unlock (priv->iolock);
1408 /* Scan for the boundary */
1409 end = read_buf->data + read_buf->len;
1410 for (p = read_buf->data; p <= end - boundary_len; p++) {
1411 if (!memcmp (p, boundary, boundary_len)) {
1413 *got_boundary = TRUE;
1418 /* Return everything up to 'p' (which is either just after the
1419 * boundary, or @boundary_len - 1 bytes before the end of the
1422 match_len = p - read_buf->data;
1423 status = read_from_buf (sock, buffer, MIN (len, match_len), nread);
1425 g_mutex_unlock (priv->iolock);
1430 socket_write_watch (GIOChannel *chan, GIOCondition cond, gpointer user_data)
1432 SoupSocket *sock = user_data;
1433 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
1435 priv->write_src = NULL;
1436 if (priv->write_timeout) {
1437 g_source_destroy (priv->write_timeout);
1438 priv->write_timeout = NULL;
1441 if (cond & (G_IO_ERR | G_IO_HUP))
1442 soup_socket_disconnect (sock);
1444 g_signal_emit (sock, signals[WRITABLE], 0);
1450 * soup_socket_write:
1452 * @buffer: data to write
1453 * @len: size of @buffer, in bytes
1454 * @nwrote: on return, number of bytes written
1455 * @cancellable: a #GCancellable, or %NULL
1456 * @error: error pointer
1458 * Attempts to write @len bytes from @buffer to @sock. If some data is
1459 * successfully written, the return status will be %SOUP_SOCKET_OK,
1460 * and *@nwrote will contain the number of bytes actually written
1461 * (which may be less than @len).
1463 * If @sock is non-blocking, and no data could be written right away,
1464 * the return value will be %SOUP_SOCKET_WOULD_BLOCK. In this case,
1465 * the caller can connect to the #SoupSocket::writable signal to know
1466 * when more data can be written. (NB: #SoupSocket::writable is only
1467 * emitted after soup_socket_write() returns %SOUP_SOCKET_WOULD_BLOCK,
1468 * and it is only emitted once. See the documentation for
1469 * #SoupSocket:non-blocking.)
1471 * Return value: a #SoupSocketIOStatus, as described above (or
1472 * %SOUP_SOCKET_EOF or %SOUP_SOCKET_ERROR. @error will be set if the
1473 * return value is %SOUP_SOCKET_ERROR.)
1476 soup_socket_write (SoupSocket *sock, gconstpointer buffer,
1477 gsize len, gsize *nwrote,
1478 GCancellable *cancellable, GError **error)
1480 SoupSocketPrivate *priv;
1482 GIOCondition cond = G_IO_OUT;
1483 GError *my_err = NULL;
1485 g_return_val_if_fail (SOUP_IS_SOCKET (sock), SOUP_SOCKET_ERROR);
1486 g_return_val_if_fail (nwrote != NULL, SOUP_SOCKET_ERROR);
1488 priv = SOUP_SOCKET_GET_PRIVATE (sock);
1490 g_mutex_lock (priv->iolock);
1492 if (!priv->iochannel) {
1493 g_mutex_unlock (priv->iolock);
1494 return SOUP_SOCKET_EOF;
1496 if (priv->timed_out) {
1497 g_mutex_unlock (priv->iolock);
1498 return SOUP_SOCKET_ERROR;
1500 if (priv->write_src) {
1501 g_mutex_unlock (priv->iolock);
1502 return SOUP_SOCKET_WOULD_BLOCK;
1505 status = g_io_channel_write_chars (priv->iochannel,
1506 buffer, len, nwrote, &my_err);
1508 if (my_err->domain == SOUP_SSL_ERROR &&
1509 my_err->code == SOUP_SSL_ERROR_HANDSHAKE_NEEDS_READ)
1511 g_propagate_error (error, my_err);
1514 /* If the socket is sync and we get EAGAIN, then it is a
1515 * socket timeout and should be treated as an error condition.
1517 if (!priv->non_blocking && status == G_IO_STATUS_AGAIN) {
1518 g_mutex_unlock (priv->iolock);
1519 return SOUP_SOCKET_ERROR;
1522 if (status != G_IO_STATUS_NORMAL && status != G_IO_STATUS_AGAIN) {
1523 g_mutex_unlock (priv->iolock);
1524 return SOUP_SOCKET_ERROR;
1527 g_clear_error (error);
1530 g_mutex_unlock (priv->iolock);
1531 return SOUP_SOCKET_OK;
1535 soup_add_io_watch (priv->async_context,
1537 cond | G_IO_HUP | G_IO_ERR,
1538 socket_write_watch, sock);
1539 if (priv->timeout) {
1540 priv->write_timeout = soup_add_timeout (priv->async_context,
1541 priv->timeout * 1000,
1542 socket_timeout, sock);
1545 g_mutex_unlock (priv->iolock);
1546 return SOUP_SOCKET_WOULD_BLOCK;