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))
86 static void set_property (GObject *object, guint prop_id,
87 const GValue *value, GParamSpec *pspec);
88 static void get_property (GObject *object, guint prop_id,
89 GValue *value, GParamSpec *pspec);
92 #define SOUP_IS_SOCKET_ERROR(status) ((status) == SOCKET_ERROR)
93 #define SOUP_IS_INVALID_SOCKET(socket) ((socket) == INVALID_SOCKET)
94 #define SOUP_IS_CONNECT_STATUS_INPROGRESS() (WSAGetLastError () == WSAEWOULDBLOCK)
95 #define SHUT_RDWR SD_BOTH
97 #define SOUP_IS_SOCKET_ERROR(status) ((status) == -1)
98 #define SOUP_IS_INVALID_SOCKET(socket) ((socket) < 0)
99 #define SOUP_IS_CONNECT_STATUS_INPROGRESS() (errno == EINPROGRESS)
103 soup_socket_init (SoupSocket *sock)
105 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
108 priv->non_blocking = TRUE;
109 priv->addrlock = g_mutex_new ();
110 priv->iolock = g_mutex_new ();
115 disconnect_internal (SoupSocketPrivate *priv)
117 g_io_channel_unref (priv->iochannel);
118 priv->iochannel = NULL;
121 if (priv->read_src) {
122 g_source_destroy (priv->read_src);
123 priv->read_src = NULL;
125 if (priv->write_src) {
126 g_source_destroy (priv->write_src);
127 priv->write_src = NULL;
129 if (priv->read_timeout) {
130 g_source_destroy (priv->read_timeout);
131 priv->read_timeout = NULL;
133 if (priv->write_timeout) {
134 g_source_destroy (priv->write_timeout);
135 priv->write_timeout = NULL;
140 finalize (GObject *object)
142 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (object);
145 disconnect_internal (priv);
147 if (priv->local_addr)
148 g_object_unref (priv->local_addr);
149 if (priv->remote_addr)
150 g_object_unref (priv->remote_addr);
153 g_source_destroy (priv->watch_src);
154 if (priv->connect_timeout)
155 g_source_destroy (priv->connect_timeout);
156 if (priv->async_context)
157 g_main_context_unref (priv->async_context);
160 g_byte_array_free (priv->read_buf, TRUE);
162 g_mutex_free (priv->addrlock);
163 g_mutex_free (priv->iolock);
165 G_OBJECT_CLASS (soup_socket_parent_class)->finalize (object);
169 soup_socket_class_init (SoupSocketClass *socket_class)
171 GObjectClass *object_class = G_OBJECT_CLASS (socket_class);
174 signal (SIGPIPE, SIG_IGN);
177 g_type_class_add_private (socket_class, sizeof (SoupSocketPrivate));
179 /* virtual method override */
180 object_class->finalize = finalize;
181 object_class->set_property = set_property;
182 object_class->get_property = get_property;
187 * SoupSocket::readable:
190 * Emitted when an async socket is readable. See
191 * soup_socket_read(), soup_socket_read_until() and
192 * #SoupSocket:non-blocking.
195 g_signal_new ("readable",
196 G_OBJECT_CLASS_TYPE (object_class),
198 G_STRUCT_OFFSET (SoupSocketClass, readable),
200 soup_marshal_NONE__NONE,
204 * SoupSocket::writable:
207 * Emitted when an async socket is writable. See
208 * soup_socket_write() and #SoupSocket:non-blocking.
211 g_signal_new ("writable",
212 G_OBJECT_CLASS_TYPE (object_class),
214 G_STRUCT_OFFSET (SoupSocketClass, writable),
216 soup_marshal_NONE__NONE,
220 * SoupSocket::disconnected:
223 * Emitted when the socket is disconnected, for whatever
226 signals[DISCONNECTED] =
227 g_signal_new ("disconnected",
228 G_OBJECT_CLASS_TYPE (object_class),
230 G_STRUCT_OFFSET (SoupSocketClass, disconnected),
232 soup_marshal_NONE__NONE,
236 * SoupSocket::new-connection:
238 * @new: the new socket
240 * Emitted when a listening socket (set up with
241 * soup_socket_listen()) receives a new connection.
243 * You must ref the @new if you want to keep it; otherwise it
244 * will be destroyed after the signal is emitted.
246 signals[NEW_CONNECTION] =
247 g_signal_new ("new_connection",
248 G_OBJECT_CLASS_TYPE (object_class),
250 G_STRUCT_OFFSET (SoupSocketClass, new_connection),
252 soup_marshal_NONE__OBJECT,
258 * SOUP_SOCKET_LOCAL_ADDRESS:
260 * Alias for the #SoupSocket:local-address property. (Address
261 * of local end of socket.)
263 g_object_class_install_property (
264 object_class, PROP_LOCAL_ADDRESS,
265 g_param_spec_object (SOUP_SOCKET_LOCAL_ADDRESS,
267 "Address of local end of socket",
269 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
271 * SOUP_SOCKET_REMOTE_ADDRESS:
273 * Alias for the #SoupSocket:remote-address property. (Address
274 * of remote end of socket.)
276 g_object_class_install_property (
277 object_class, PROP_REMOTE_ADDRESS,
278 g_param_spec_object (SOUP_SOCKET_REMOTE_ADDRESS,
280 "Address of remote end of socket",
282 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
284 * SoupSocket:non-blocking:
286 * Whether or not the socket uses non-blocking I/O.
288 * #SoupSocket's I/O methods are designed around the idea of
289 * using a single codepath for both synchronous and
290 * asynchronous I/O. If you want to read off a #SoupSocket,
291 * the "correct" way to do it is to call soup_socket_read() or
292 * soup_socket_read_until() repeatedly until you have read
293 * everything you want. If it returns %SOUP_SOCKET_WOULD_BLOCK
294 * at any point, stop reading and wait for it to emit the
295 * #SoupSocket::readable signal. Then go back to the
296 * reading-as-much-as-you-can loop. Likewise, for writing to a
297 * #SoupSocket, you should call soup_socket_write() either
298 * until you have written everything, or it returns
299 * %SOUP_SOCKET_WOULD_BLOCK (in which case you wait for
300 * #SoupSocket::writable and then go back into the loop).
302 * Code written this way will work correctly with both
303 * blocking and non-blocking sockets; blocking sockets will
304 * simply never return %SOUP_SOCKET_WOULD_BLOCK, and so the
305 * code that handles that case just won't get used for them.
308 * SOUP_SOCKET_FLAG_NONBLOCKING:
310 * Alias for the #SoupSocket:non-blocking property. (Whether
311 * or not the socket uses non-blocking I/O.)
313 g_object_class_install_property (
314 object_class, PROP_NON_BLOCKING,
315 g_param_spec_boolean (SOUP_SOCKET_FLAG_NONBLOCKING,
317 "Whether or not the socket uses non-blocking I/O",
321 * SOUP_SOCKET_IS_SERVER:
323 * Alias for the #SoupSocket:is-server property. (Whether or
324 * not the socket is a server socket.)
326 g_object_class_install_property (
327 object_class, PROP_IS_SERVER,
328 g_param_spec_boolean (SOUP_SOCKET_IS_SERVER,
330 "Whether or not the socket is a server socket",
334 * SOUP_SOCKET_SSL_CREDENTIALS:
336 * Alias for the #SoupSocket:ssl-credentials property.
337 * (SSL credential information.)
339 g_object_class_install_property (
340 object_class, PROP_SSL_CREDENTIALS,
341 g_param_spec_pointer (SOUP_SOCKET_SSL_CREDENTIALS,
343 "SSL credential information, passed from the session to the SSL implementation",
346 * SOUP_SOCKET_ASYNC_CONTEXT:
348 * Alias for the #SoupSocket:async-context property. (The
349 * socket's #GMainContext.)
351 g_object_class_install_property (
352 object_class, PROP_ASYNC_CONTEXT,
353 g_param_spec_pointer (SOUP_SOCKET_ASYNC_CONTEXT,
354 "Async GMainContext",
355 "The GMainContext to dispatch this socket's async I/O in",
356 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
359 * SOUP_SOCKET_TIMEOUT:
361 * Alias for the #SoupSocket:timeout property. (The timeout
362 * in seconds for blocking socket I/O operations.)
364 g_object_class_install_property (
365 object_class, PROP_TIMEOUT,
366 g_param_spec_uint (SOUP_SOCKET_TIMEOUT,
368 "Value in seconds to timeout a blocking I/O",
373 /* Make sure WSAStartup() gets called. */
374 soup_address_get_type ();
380 set_nonblocking (SoupSocketPrivate *priv)
388 if (priv->sockfd == -1)
392 flags = fcntl (priv->sockfd, F_GETFL, 0);
394 if (priv->non_blocking)
397 flags &= ~O_NONBLOCK;
398 fcntl (priv->sockfd, F_SETFL, flags);
401 val = priv->non_blocking ? 1 : 0;
402 ioctlsocket (priv->sockfd, FIONBIO, &val);
407 set_fdflags (SoupSocketPrivate *priv)
411 struct timeval timeout;
415 if (priv->sockfd == -1)
418 set_nonblocking (priv);
421 flags = fcntl (priv->sockfd, F_GETFD, 0);
424 fcntl (priv->sockfd, F_SETFD, flags);
429 setsockopt (priv->sockfd, IPPROTO_TCP,
430 TCP_NODELAY, (void *) &opt, sizeof (opt));
431 setsockopt (priv->sockfd, SOL_SOCKET,
432 SO_REUSEADDR, (void *) &opt, sizeof (opt));
435 timeout.tv_sec = priv->timeout;
437 setsockopt (priv->sockfd, SOL_SOCKET,
438 SO_RCVTIMEO, (void *) &timeout, sizeof (timeout));
440 timeout.tv_sec = priv->timeout;
442 setsockopt (priv->sockfd, SOL_SOCKET,
443 SO_SNDTIMEO, (void *) &timeout, sizeof (timeout));
445 if (priv->timeout < G_MAXINT / 1000)
446 opt = priv->timeout * 1000;
450 setsockopt (priv->sockfd, SOL_SOCKET,
451 SO_RCVTIMEO, (void *) &opt, sizeof (opt));
453 setsockopt (priv->sockfd, SOL_SOCKET,
454 SO_SNDTIMEO, (void *) &opt, sizeof (opt));
459 g_io_channel_unix_new (priv->sockfd);
462 g_io_channel_win32_new_socket (priv->sockfd);
464 g_io_channel_set_close_on_unref (priv->iochannel, TRUE);
465 g_io_channel_set_encoding (priv->iochannel, NULL, NULL);
466 g_io_channel_set_buffered (priv->iochannel, FALSE);
470 set_property (GObject *object, guint prop_id,
471 const GValue *value, GParamSpec *pspec)
473 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (object);
476 case PROP_LOCAL_ADDRESS:
477 priv->local_addr = (SoupAddress *)g_value_dup_object (value);
479 case PROP_REMOTE_ADDRESS:
480 priv->remote_addr = (SoupAddress *)g_value_dup_object (value);
482 case PROP_NON_BLOCKING:
483 priv->non_blocking = g_value_get_boolean (value);
484 set_nonblocking (priv);
486 case PROP_SSL_CREDENTIALS:
487 priv->ssl_creds = g_value_get_pointer (value);
489 case PROP_ASYNC_CONTEXT:
490 priv->async_context = g_value_get_pointer (value);
491 if (priv->async_context)
492 g_main_context_ref (priv->async_context);
495 priv->timeout = g_value_get_uint (value);
498 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
504 get_property (GObject *object, guint prop_id,
505 GValue *value, GParamSpec *pspec)
507 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (object);
510 case PROP_LOCAL_ADDRESS:
511 g_value_set_object (value, soup_socket_get_local_address (SOUP_SOCKET (object)));
513 case PROP_REMOTE_ADDRESS:
514 g_value_set_object (value, soup_socket_get_remote_address (SOUP_SOCKET (object)));
516 case PROP_NON_BLOCKING:
517 g_value_set_boolean (value, priv->non_blocking);
520 g_value_set_boolean (value, priv->is_server);
522 case PROP_SSL_CREDENTIALS:
523 g_value_set_pointer (value, priv->ssl_creds);
525 case PROP_ASYNC_CONTEXT:
526 g_value_set_pointer (value, priv->async_context ? g_main_context_ref (priv->async_context) : NULL);
529 g_value_set_uint (value, priv->timeout);
532 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
540 * @optname1: name of first property to set (or %NULL)
541 * @...: value of @optname1, followed by additional property/value pairs
543 * Creates a new (disconnected) socket
545 * Return value: the new socket
548 soup_socket_new (const char *optname1, ...)
553 va_start (ap, optname1);
554 sock = (SoupSocket *)g_object_new_valist (SOUP_TYPE_SOCKET,
563 GCancellable *cancellable;
565 SoupSocketCallback callback;
567 } SoupSocketAsyncConnectData;
570 idle_connect_result (gpointer user_data)
572 SoupSocketAsyncConnectData *sacd = user_data;
573 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sacd->sock);
576 priv->watch_src = NULL;
578 g_signal_handler_disconnect (sacd->cancellable, sacd->cancel_id);
580 if (priv->sockfd == -1) {
581 if (g_cancellable_is_cancelled (sacd->cancellable))
582 status = SOUP_STATUS_CANCELLED;
584 status = SOUP_STATUS_CANT_CONNECT;
586 status = SOUP_STATUS_OK;
588 sacd->callback (sacd->sock, status, sacd->user_data);
589 g_slice_free (SoupSocketAsyncConnectData, sacd);
594 connect_watch (GIOChannel* iochannel, GIOCondition condition, gpointer data)
596 SoupSocketAsyncConnectData *sacd = data;
597 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sacd->sock);
599 int len = sizeof (error);
601 /* Remove the watch now in case we don't return immediately */
602 g_source_destroy (priv->watch_src);
603 priv->watch_src = NULL;
604 if (priv->connect_timeout) {
605 g_source_destroy (priv->connect_timeout);
606 priv->connect_timeout = NULL;
609 if ((condition & ~(G_IO_IN | G_IO_OUT)) ||
610 (getsockopt (priv->sockfd, SOL_SOCKET, SO_ERROR,
611 (void *)&error, (void *)&len) != 0) ||
613 disconnect_internal (priv);
615 return idle_connect_result (sacd);
619 connect_timeout (gpointer data)
621 SoupSocketAsyncConnectData *sacd = data;
622 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sacd->sock);
624 /* Remove the watch now in case we don't return immediately */
625 g_source_destroy (priv->watch_src);
626 priv->watch_src = NULL;
627 g_source_destroy (priv->connect_timeout);
628 priv->connect_timeout = NULL;
630 disconnect_internal (priv);
631 return idle_connect_result (sacd);
635 got_address (SoupAddress *addr, guint status, gpointer user_data)
637 SoupSocketAsyncConnectData *sacd = user_data;
639 if (!SOUP_STATUS_IS_SUCCESSFUL (status)) {
640 sacd->callback (sacd->sock, status, sacd->user_data);
641 g_slice_free (SoupSocketAsyncConnectData, sacd);
645 soup_socket_connect_async (sacd->sock, sacd->cancellable,
646 sacd->callback, sacd->user_data);
647 g_slice_free (SoupSocketAsyncConnectData, sacd);
651 async_cancel (GCancellable *cancellable, gpointer user_data)
653 SoupSocketAsyncConnectData *sacd = user_data;
654 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sacd->sock);
657 g_source_destroy (priv->watch_src);
658 disconnect_internal (priv);
659 priv->watch_src = soup_add_completion (priv->async_context,
660 idle_connect_result, sacd);
664 socket_connect_internal (SoupSocket *sock)
666 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
670 sa = soup_address_get_sockaddr (priv->remote_addr, &len);
672 return SOUP_STATUS_CANT_RESOLVE;
674 priv->sockfd = socket (sa->sa_family, SOCK_STREAM, 0);
675 if (SOUP_IS_INVALID_SOCKET (priv->sockfd))
676 return SOUP_STATUS_CANT_CONNECT;
679 status = connect (priv->sockfd, sa, len);
681 if (SOUP_IS_SOCKET_ERROR (status)) {
682 if (SOUP_IS_CONNECT_STATUS_INPROGRESS ())
683 return SOUP_STATUS_CONTINUE;
685 disconnect_internal (priv);
686 return SOUP_STATUS_CANT_CONNECT;
688 return SOUP_STATUS_OK;
692 * SoupSocketCallback:
693 * @sock: the #SoupSocket
694 * @status: an HTTP status code indicating success or failure
695 * @user_data: the data passed to soup_socket_connect_async()
697 * The callback function passed to soup_socket_connect_async().
701 * soup_socket_connect_async:
702 * @sock: a client #SoupSocket (which must not already be connected)
703 * @cancellable: a #GCancellable, or %NULL
704 * @callback: callback to call after connecting
705 * @user_data: data to pass to @callback
707 * Begins asynchronously connecting to @sock's remote address. The
708 * socket will call @callback when it succeeds or fails (but not
709 * before returning from this function).
711 * If @cancellable is non-%NULL, it can be used to cancel the
712 * connection. @callback will still be invoked in this case, with a
713 * status of %SOUP_STATUS_CANCELLED.
716 soup_socket_connect_async (SoupSocket *sock, GCancellable *cancellable,
717 SoupSocketCallback callback, gpointer user_data)
719 SoupSocketPrivate *priv;
720 SoupSocketAsyncConnectData *sacd;
723 g_return_if_fail (SOUP_IS_SOCKET (sock));
724 priv = SOUP_SOCKET_GET_PRIVATE (sock);
725 g_return_if_fail (priv->remote_addr != NULL);
727 sacd = g_slice_new0 (SoupSocketAsyncConnectData);
729 sacd->cancellable = cancellable;
730 sacd->callback = callback;
731 sacd->user_data = user_data;
733 if (!soup_address_get_sockaddr (priv->remote_addr, NULL)) {
734 soup_address_resolve_async (priv->remote_addr,
741 status = socket_connect_internal (sock);
742 if (status == SOUP_STATUS_CONTINUE) {
743 /* Wait for connect to succeed or fail */
745 soup_add_io_watch (priv->async_context,
748 G_IO_PRI | G_IO_ERR |
749 G_IO_HUP | G_IO_NVAL,
750 connect_watch, sacd);
752 priv->connect_timeout =
753 soup_add_timeout (priv->async_context,
754 priv->timeout * 1000,
755 connect_timeout, sacd);
759 g_signal_connect (cancellable, "cancelled",
760 G_CALLBACK (async_cancel),
764 priv->watch_src = soup_add_completion (priv->async_context,
765 idle_connect_result, sacd);
770 sync_cancel (GCancellable *cancellable, gpointer sock)
772 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
774 shutdown (priv->sockfd, SHUT_RDWR);
778 * soup_socket_connect_sync:
779 * @sock: a client #SoupSocket (which must not already be connected)
780 * @cancellable: a #GCancellable, or %NULL
782 * Attempt to synchronously connect @sock to its remote address.
784 * If @cancellable is non-%NULL, it can be used to cancel the
785 * connection, in which case soup_socket_connect_sync() will return
786 * %SOUP_STATUS_CANCELLED.
788 * Return value: a success or failure code.
791 soup_socket_connect_sync (SoupSocket *sock, GCancellable *cancellable)
793 SoupSocketPrivate *priv;
794 guint status, cancel_id;
796 g_return_val_if_fail (SOUP_IS_SOCKET (sock), SOUP_STATUS_MALFORMED);
797 priv = SOUP_SOCKET_GET_PRIVATE (sock);
798 g_return_val_if_fail (!priv->is_server, SOUP_STATUS_MALFORMED);
799 g_return_val_if_fail (priv->sockfd == -1, SOUP_STATUS_MALFORMED);
800 g_return_val_if_fail (priv->remote_addr != NULL, SOUP_STATUS_MALFORMED);
802 if (!soup_address_get_sockaddr (priv->remote_addr, NULL)) {
803 status = soup_address_resolve_sync (priv->remote_addr,
805 if (!SOUP_STATUS_IS_SUCCESSFUL (status))
810 cancel_id = g_signal_connect (cancellable, "cancelled",
811 G_CALLBACK (sync_cancel), sock);
814 status = socket_connect_internal (sock);
817 if (status != SOUP_STATUS_OK &&
818 g_cancellable_is_cancelled (cancellable)) {
819 status = SOUP_STATUS_CANCELLED;
820 disconnect_internal (priv);
822 g_signal_handler_disconnect (cancellable, cancel_id);
829 soup_socket_get_fd (SoupSocket *sock)
831 g_return_val_if_fail (SOUP_IS_SOCKET (sock), -1);
833 return SOUP_SOCKET_GET_PRIVATE (sock)->sockfd;
837 listen_watch (GIOChannel* iochannel, GIOCondition condition, gpointer data)
839 SoupSocket *sock = data, *new;
840 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock), *new_priv;
841 struct sockaddr_storage sa;
844 if (condition & (G_IO_HUP | G_IO_ERR)) {
845 g_source_destroy (priv->watch_src);
846 priv->watch_src = NULL;
850 sa_len = sizeof (sa);
851 sockfd = accept (priv->sockfd, (struct sockaddr *)&sa, (void *)&sa_len);
852 if (SOUP_IS_INVALID_SOCKET (sockfd))
855 new = g_object_new (SOUP_TYPE_SOCKET, NULL);
856 new_priv = SOUP_SOCKET_GET_PRIVATE (new);
857 new_priv->sockfd = sockfd;
858 if (priv->async_context)
859 new_priv->async_context = g_main_context_ref (priv->async_context);
860 new_priv->non_blocking = priv->non_blocking;
861 new_priv->is_server = TRUE;
862 new_priv->ssl_creds = priv->ssl_creds;
863 set_fdflags (new_priv);
865 new_priv->remote_addr = soup_address_new_from_sockaddr ((struct sockaddr *)&sa, sa_len);
867 if (new_priv->ssl_creds) {
868 if (!soup_socket_start_ssl (new, NULL)) {
869 g_object_unref (new);
874 g_signal_emit (sock, signals[NEW_CONNECTION], 0, new);
875 g_object_unref (new);
881 * soup_socket_listen:
882 * @sock: a server #SoupSocket (which must not already be connected or
885 * Makes @sock start listening on its local address. When connections
886 * come in, @sock will emit %new_connection.
888 * Return value: whether or not @sock is now listening.
891 soup_socket_listen (SoupSocket *sock)
894 SoupSocketPrivate *priv;
898 g_return_val_if_fail (SOUP_IS_SOCKET (sock), FALSE);
899 priv = SOUP_SOCKET_GET_PRIVATE (sock);
900 g_return_val_if_fail (priv->sockfd == -1, FALSE);
901 g_return_val_if_fail (priv->local_addr != NULL, FALSE);
903 priv->is_server = TRUE;
905 /* @local_addr may have its port set to 0. So we intentionally
906 * don't store it in priv->local_addr, so that if the
907 * caller calls soup_socket_get_local_address() later, we'll
908 * have to make a new addr by calling getsockname(), which
909 * will have the right port number.
911 sa = soup_address_get_sockaddr (priv->local_addr, &sa_len);
912 g_return_val_if_fail (sa != NULL, FALSE);
914 priv->sockfd = socket (sa->sa_family, SOCK_STREAM, 0);
915 if (SOUP_IS_INVALID_SOCKET (priv->sockfd))
920 if (bind (priv->sockfd, sa, sa_len) != 0)
922 /* Force local_addr to be re-resolved now */
923 g_object_unref (priv->local_addr);
924 priv->local_addr = NULL;
927 if (listen (priv->sockfd, 10) != 0)
930 priv->watch_src = soup_add_io_watch (priv->async_context,
932 G_IO_IN | G_IO_ERR | G_IO_HUP,
938 disconnect_internal (priv);
944 * soup_socket_start_ssl:
946 * @cancellable: a #GCancellable
948 * Starts using SSL on @socket.
950 * Return value: success or failure
953 soup_socket_start_ssl (SoupSocket *sock, GCancellable *cancellable)
955 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
957 return soup_socket_start_proxy_ssl (sock, soup_address_get_name (priv->remote_addr), cancellable);
961 * soup_socket_start_proxy_ssl:
963 * @ssl_host: hostname of the SSL server
964 * @cancellable: a #GCancellable
966 * Starts using SSL on @socket, expecting to find a host named
969 * Return value: success or failure
972 soup_socket_start_proxy_ssl (SoupSocket *sock, const char *ssl_host,
973 GCancellable *cancellable)
975 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
976 GIOChannel *ssl_chan;
977 GIOChannel *real_chan;
979 real_chan = priv->iochannel;
980 ssl_chan = soup_ssl_wrap_iochannel (
981 real_chan, priv->non_blocking, priv->is_server ?
982 SOUP_SSL_TYPE_SERVER : SOUP_SSL_TYPE_CLIENT,
983 ssl_host, priv->ssl_creds);
988 priv->iochannel = ssl_chan;
989 g_io_channel_unref (real_chan);
995 * soup_socket_is_ssl:
996 * @sock: a #SoupSocket
998 * Tests if @sock is set up to do SSL. Note that this simply means
999 * that the %SOUP_SOCKET_SSL_CREDENTIALS property has been set; it
1000 * does not mean that soup_socket_start_ssl() has been called.
1002 * Return value: %TRUE if @sock has SSL credentials set
1005 soup_socket_is_ssl (SoupSocket *sock)
1007 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
1009 return priv->ssl_creds != NULL;
1013 * soup_socket_disconnect:
1014 * @sock: a #SoupSocket
1016 * Disconnects @sock. Any further read or write attempts on it will
1020 soup_socket_disconnect (SoupSocket *sock)
1022 SoupSocketPrivate *priv;
1023 gboolean already_disconnected = FALSE;
1025 g_return_if_fail (SOUP_IS_SOCKET (sock));
1026 priv = SOUP_SOCKET_GET_PRIVATE (sock);
1028 if (g_mutex_trylock (priv->iolock)) {
1029 if (priv->iochannel)
1030 disconnect_internal (priv);
1032 already_disconnected = TRUE;
1033 g_mutex_unlock (priv->iolock);
1037 /* Another thread is currently doing IO, so
1038 * we can't close the iochannel. So just shutdown
1039 * the file descriptor to force the I/O to fail.
1040 * (It will actually be closed when the socket is
1043 sockfd = priv->sockfd;
1047 already_disconnected = TRUE;
1049 shutdown (sockfd, SHUT_RDWR);
1052 if (already_disconnected)
1055 /* Keep ref around signals in case the object is unreferenced
1058 g_object_ref (sock);
1060 /* Give all readers a chance to notice the connection close */
1061 g_signal_emit (sock, signals[READABLE], 0);
1063 /* FIXME: can't disconnect until all data is read */
1065 /* Then let everyone know we're disconnected */
1066 g_signal_emit (sock, signals[DISCONNECTED], 0);
1068 g_object_unref (sock);
1072 * soup_socket_is_connected:
1073 * @sock: a #SoupSocket
1075 * Tests if @sock is connected to another host
1077 * Return value: %TRUE or %FALSE.
1080 soup_socket_is_connected (SoupSocket *sock)
1082 SoupSocketPrivate *priv;
1084 g_return_val_if_fail (SOUP_IS_SOCKET (sock), FALSE);
1085 priv = SOUP_SOCKET_GET_PRIVATE (sock);
1087 return priv->iochannel != NULL;
1091 * soup_socket_get_local_address:
1092 * @sock: a #SoupSocket
1094 * Returns the #SoupAddress corresponding to the local end of @sock.
1096 * Return value: the #SoupAddress
1099 soup_socket_get_local_address (SoupSocket *sock)
1101 SoupSocketPrivate *priv;
1103 g_return_val_if_fail (SOUP_IS_SOCKET (sock), NULL);
1104 priv = SOUP_SOCKET_GET_PRIVATE (sock);
1106 g_mutex_lock (priv->addrlock);
1107 if (!priv->local_addr) {
1108 struct sockaddr_storage bound_sa;
1111 sa_len = sizeof (bound_sa);
1112 getsockname (priv->sockfd, (struct sockaddr *)&bound_sa, (void *)&sa_len);
1113 priv->local_addr = soup_address_new_from_sockaddr ((struct sockaddr *)&bound_sa, sa_len);
1115 g_mutex_unlock (priv->addrlock);
1117 return priv->local_addr;
1121 * soup_socket_get_remote_address:
1122 * @sock: a #SoupSocket
1124 * Returns the #SoupAddress corresponding to the remote end of @sock.
1126 * Return value: the #SoupAddress
1129 soup_socket_get_remote_address (SoupSocket *sock)
1131 SoupSocketPrivate *priv;
1133 g_return_val_if_fail (SOUP_IS_SOCKET (sock), NULL);
1134 priv = SOUP_SOCKET_GET_PRIVATE (sock);
1136 g_mutex_lock (priv->addrlock);
1137 if (!priv->remote_addr) {
1138 struct sockaddr_storage bound_sa;
1141 sa_len = sizeof (bound_sa);
1142 getpeername (priv->sockfd, (struct sockaddr *)&bound_sa, (void *)&sa_len);
1143 priv->remote_addr = soup_address_new_from_sockaddr ((struct sockaddr *)&bound_sa, sa_len);
1145 g_mutex_unlock (priv->addrlock);
1147 return priv->remote_addr;
1152 socket_timeout (gpointer sock)
1154 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
1155 gboolean readable = FALSE, writable = FALSE;
1157 priv->timed_out = TRUE;
1158 if (priv->read_timeout) {
1159 priv->read_timeout = NULL;
1162 if (priv->write_timeout) {
1163 priv->write_timeout = NULL;
1168 g_signal_emit (sock, signals[READABLE], 0);
1170 g_signal_emit (sock, signals[WRITABLE], 0);
1176 socket_read_watch (GIOChannel *chan, GIOCondition cond, gpointer user_data)
1178 SoupSocket *sock = user_data;
1179 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
1181 priv->read_src = NULL;
1182 if (priv->read_timeout) {
1183 g_source_destroy (priv->read_timeout);
1184 priv->read_timeout = NULL;
1187 if (cond & (G_IO_ERR | G_IO_HUP))
1188 soup_socket_disconnect (sock);
1190 g_signal_emit (sock, signals[READABLE], 0);
1195 static SoupSocketIOStatus
1196 read_from_network (SoupSocket *sock, gpointer buffer, gsize len,
1197 gsize *nread, GError **error)
1199 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
1201 GIOCondition cond = G_IO_IN;
1202 GError *my_err = NULL;
1206 if (!priv->iochannel)
1207 return SOUP_SOCKET_EOF;
1209 if (priv->timed_out)
1210 return SOUP_SOCKET_ERROR;
1212 status = g_io_channel_read_chars (priv->iochannel,
1213 buffer, len, nread, &my_err);
1215 if (my_err->domain == SOUP_SSL_ERROR &&
1216 my_err->code == SOUP_SSL_ERROR_HANDSHAKE_NEEDS_WRITE)
1218 g_propagate_error (error, my_err);
1222 case G_IO_STATUS_NORMAL:
1223 case G_IO_STATUS_AGAIN:
1225 g_clear_error (error);
1226 return SOUP_SOCKET_OK;
1229 /* If the socket is sync and we get EAGAIN, then it is
1230 * a socket timeout and should be treated as an error
1233 if (!priv->non_blocking)
1234 return SOUP_SOCKET_ERROR;
1236 if (!priv->read_src) {
1238 soup_add_io_watch (priv->async_context,
1240 cond | G_IO_HUP | G_IO_ERR,
1241 socket_read_watch, sock);
1242 if (priv->timeout) {
1243 priv->read_timeout =
1244 soup_add_timeout (priv->async_context,
1245 priv->timeout * 1000,
1246 socket_timeout, sock);
1249 g_clear_error (error);
1250 return SOUP_SOCKET_WOULD_BLOCK;
1252 case G_IO_STATUS_EOF:
1253 g_clear_error (error);
1254 return SOUP_SOCKET_EOF;
1257 return SOUP_SOCKET_ERROR;
1261 static SoupSocketIOStatus
1262 read_from_buf (SoupSocket *sock, gpointer buffer, gsize len, gsize *nread)
1264 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
1265 GByteArray *read_buf = priv->read_buf;
1267 *nread = MIN (read_buf->len, len);
1268 memcpy (buffer, read_buf->data, *nread);
1270 if (*nread == read_buf->len) {
1271 g_byte_array_free (read_buf, TRUE);
1272 priv->read_buf = NULL;
1274 memmove (read_buf->data, read_buf->data + *nread,
1275 read_buf->len - *nread);
1276 g_byte_array_set_size (read_buf, read_buf->len - *nread);
1279 return SOUP_SOCKET_OK;
1283 * SoupSocketIOStatus:
1284 * @SOUP_SOCKET_OK: Success
1285 * @SOUP_SOCKET_WOULD_BLOCK: Cannot read/write any more at this time
1286 * @SOUP_SOCKET_EOF: End of file
1287 * @SOUP_SOCKET_ERROR: Other error
1289 * Return value from the #SoupSocket IO methods.
1295 * @buffer: buffer to read into
1296 * @len: size of @buffer in bytes
1297 * @nread: on return, the number of bytes read into @buffer
1298 * @cancellable: a #GCancellable, or %NULL
1299 * @error: error pointer
1301 * Attempts to read up to @len bytes from @sock into @buffer. If some
1302 * data is successfully read, soup_socket_read() will return
1303 * %SOUP_SOCKET_OK, and *@nread will contain the number of bytes
1304 * actually read (which may be less than @len).
1306 * If @sock is non-blocking, and no data is available, the return
1307 * value will be %SOUP_SOCKET_WOULD_BLOCK. In this case, the caller
1308 * can connect to the #SoupSocket::readable signal to know when there
1309 * is more data to read. (NB: You MUST read all available data off the
1310 * socket first. #SoupSocket::readable is only emitted after
1311 * soup_socket_read() returns %SOUP_SOCKET_WOULD_BLOCK, and it is only
1312 * emitted once. See the documentation for #SoupSocket:non-blocking.)
1314 * Return value: a #SoupSocketIOStatus, as described above (or
1315 * %SOUP_SOCKET_EOF if the socket is no longer connected, or
1316 * %SOUP_SOCKET_ERROR on any other error, in which case @error will
1320 soup_socket_read (SoupSocket *sock, gpointer buffer, gsize len,
1321 gsize *nread, GCancellable *cancellable, GError **error)
1323 SoupSocketPrivate *priv;
1324 SoupSocketIOStatus status;
1326 g_return_val_if_fail (SOUP_IS_SOCKET (sock), SOUP_SOCKET_ERROR);
1327 g_return_val_if_fail (nread != NULL, SOUP_SOCKET_ERROR);
1329 priv = SOUP_SOCKET_GET_PRIVATE (sock);
1331 g_mutex_lock (priv->iolock);
1333 status = read_from_buf (sock, buffer, len, nread);
1335 status = read_from_network (sock, buffer, len, nread, error);
1336 g_mutex_unlock (priv->iolock);
1342 * soup_socket_read_until:
1344 * @buffer: buffer to read into
1345 * @len: size of @buffer in bytes
1346 * @boundary: boundary to read until
1347 * @boundary_len: length of @boundary in bytes
1348 * @nread: on return, the number of bytes read into @buffer
1349 * @got_boundary: on return, whether or not the data in @buffer
1350 * ends with the boundary string
1351 * @cancellable: a #GCancellable, or %NULL
1352 * @error: error pointer
1354 * Like soup_socket_read(), but reads no further than the first
1355 * occurrence of @boundary. (If the boundary is found, it will be
1356 * included in the returned data, and *@got_boundary will be set to
1357 * %TRUE.) Any data after the boundary will returned in future reads.
1359 * soup_socket_read_until() will almost always return fewer than @len
1360 * bytes: if the boundary is found, then it will only return the bytes
1361 * up until the end of the boundary, and if the boundary is not found,
1362 * then it will leave the last <literal>(boundary_len - 1)</literal>
1363 * bytes in its internal buffer, in case they form the start of the
1364 * boundary string. Thus, @len normally needs to be at least 1 byte
1365 * longer than @boundary_len if you want to make any progress at all.
1367 * Return value: as for soup_socket_read()
1370 soup_socket_read_until (SoupSocket *sock, gpointer buffer, gsize len,
1371 gconstpointer boundary, gsize boundary_len,
1372 gsize *nread, gboolean *got_boundary,
1373 GCancellable *cancellable, GError **error)
1375 SoupSocketPrivate *priv;
1376 SoupSocketIOStatus status;
1377 GByteArray *read_buf;
1378 guint match_len, prev_len;
1381 g_return_val_if_fail (SOUP_IS_SOCKET (sock), SOUP_SOCKET_ERROR);
1382 g_return_val_if_fail (nread != NULL, SOUP_SOCKET_ERROR);
1383 g_return_val_if_fail (len >= boundary_len, SOUP_SOCKET_ERROR);
1385 priv = SOUP_SOCKET_GET_PRIVATE (sock);
1387 g_mutex_lock (priv->iolock);
1389 *got_boundary = FALSE;
1391 if (!priv->read_buf)
1392 priv->read_buf = g_byte_array_new ();
1393 read_buf = priv->read_buf;
1395 if (read_buf->len < boundary_len) {
1396 prev_len = read_buf->len;
1397 g_byte_array_set_size (read_buf, len);
1398 status = read_from_network (sock,
1399 read_buf->data + prev_len,
1400 len - prev_len, nread, error);
1401 read_buf->len = prev_len + *nread;
1403 if (status != SOUP_SOCKET_OK) {
1404 g_mutex_unlock (priv->iolock);
1409 /* Scan for the boundary */
1410 end = read_buf->data + read_buf->len;
1411 for (p = read_buf->data; p <= end - boundary_len; p++) {
1412 if (!memcmp (p, boundary, boundary_len)) {
1414 *got_boundary = TRUE;
1419 /* Return everything up to 'p' (which is either just after the
1420 * boundary, or @boundary_len - 1 bytes before the end of the
1423 match_len = p - read_buf->data;
1424 status = read_from_buf (sock, buffer, MIN (len, match_len), nread);
1426 g_mutex_unlock (priv->iolock);
1431 socket_write_watch (GIOChannel *chan, GIOCondition cond, gpointer user_data)
1433 SoupSocket *sock = user_data;
1434 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
1436 priv->write_src = NULL;
1437 if (priv->write_timeout) {
1438 g_source_destroy (priv->write_timeout);
1439 priv->write_timeout = NULL;
1442 if (cond & (G_IO_ERR | G_IO_HUP))
1443 soup_socket_disconnect (sock);
1445 g_signal_emit (sock, signals[WRITABLE], 0);
1451 * soup_socket_write:
1453 * @buffer: data to write
1454 * @len: size of @buffer, in bytes
1455 * @nwrote: on return, number of bytes written
1456 * @cancellable: a #GCancellable, or %NULL
1457 * @error: error pointer
1459 * Attempts to write @len bytes from @buffer to @sock. If some data is
1460 * successfully written, the return status will be %SOUP_SOCKET_OK,
1461 * and *@nwrote will contain the number of bytes actually written
1462 * (which may be less than @len).
1464 * If @sock is non-blocking, and no data could be written right away,
1465 * the return value will be %SOUP_SOCKET_WOULD_BLOCK. In this case,
1466 * the caller can connect to the #SoupSocket::writable signal to know
1467 * when more data can be written. (NB: #SoupSocket::writable is only
1468 * emitted after soup_socket_write() returns %SOUP_SOCKET_WOULD_BLOCK,
1469 * and it is only emitted once. See the documentation for
1470 * #SoupSocket:non-blocking.)
1472 * Return value: a #SoupSocketIOStatus, as described above (or
1473 * %SOUP_SOCKET_EOF or %SOUP_SOCKET_ERROR. @error will be set if the
1474 * return value is %SOUP_SOCKET_ERROR.)
1477 soup_socket_write (SoupSocket *sock, gconstpointer buffer,
1478 gsize len, gsize *nwrote,
1479 GCancellable *cancellable, GError **error)
1481 SoupSocketPrivate *priv;
1483 GIOCondition cond = G_IO_OUT;
1484 GError *my_err = NULL;
1486 g_return_val_if_fail (SOUP_IS_SOCKET (sock), SOUP_SOCKET_ERROR);
1487 g_return_val_if_fail (nwrote != NULL, SOUP_SOCKET_ERROR);
1489 priv = SOUP_SOCKET_GET_PRIVATE (sock);
1491 g_mutex_lock (priv->iolock);
1493 if (!priv->iochannel) {
1494 g_mutex_unlock (priv->iolock);
1495 return SOUP_SOCKET_EOF;
1497 if (priv->timed_out) {
1498 g_mutex_unlock (priv->iolock);
1499 return SOUP_SOCKET_ERROR;
1501 if (priv->write_src) {
1502 g_mutex_unlock (priv->iolock);
1503 return SOUP_SOCKET_WOULD_BLOCK;
1506 status = g_io_channel_write_chars (priv->iochannel,
1507 buffer, len, nwrote, &my_err);
1509 if (my_err->domain == SOUP_SSL_ERROR &&
1510 my_err->code == SOUP_SSL_ERROR_HANDSHAKE_NEEDS_READ)
1512 g_propagate_error (error, my_err);
1515 /* If the socket is sync and we get EAGAIN, then it is a
1516 * socket timeout and should be treated as an error condition.
1518 if (!priv->non_blocking && status == G_IO_STATUS_AGAIN) {
1519 g_mutex_unlock (priv->iolock);
1520 return SOUP_SOCKET_ERROR;
1523 if (status != G_IO_STATUS_NORMAL && status != G_IO_STATUS_AGAIN) {
1524 g_mutex_unlock (priv->iolock);
1525 return SOUP_SOCKET_ERROR;
1528 g_clear_error (error);
1531 g_mutex_unlock (priv->iolock);
1532 return SOUP_SOCKET_OK;
1536 soup_add_io_watch (priv->async_context,
1538 cond | G_IO_HUP | G_IO_ERR,
1539 socket_write_watch, sock);
1540 if (priv->timeout) {
1541 priv->write_timeout = soup_add_timeout (priv->async_context,
1542 priv->timeout * 1000,
1543 socket_timeout, sock);
1546 g_mutex_unlock (priv->iolock);
1547 return SOUP_SOCKET_WOULD_BLOCK;