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"
23 #include "soup-misc-private.h"
28 * @short_description: A network socket
30 * #SoupSocket is libsoup's TCP socket type. While it is primarily
31 * intended for internal use, #SoupSocket<!-- -->s are exposed in the
32 * API in various places, and some of their methods (eg,
33 * soup_socket_get_remote_address()) may be useful to applications.
36 G_DEFINE_TYPE (SoupSocket, soup_socket, G_TYPE_OBJECT)
46 static guint signals[LAST_SIGNAL] = { 0 };
60 PROP_TRUSTED_CERTIFICATE,
69 SoupAddress *local_addr, *remote_addr;
72 GPollableInputStream *istream;
73 GPollableOutputStream *ostream;
74 GTlsCertificateFlags tls_errors;
80 guint ssl_ca_in_creds:1;
81 guint clean_dispose:1;
84 GMainContext *async_context;
86 GSource *read_src, *write_src;
89 GMutex *iolock, *addrlock;
92 GCancellable *connect_cancel;
94 #define SOUP_SOCKET_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SOUP_TYPE_SOCKET, SoupSocketPrivate))
96 static void set_property (GObject *object, guint prop_id,
97 const GValue *value, GParamSpec *pspec);
98 static void get_property (GObject *object, guint prop_id,
99 GValue *value, GParamSpec *pspec);
101 static void soup_socket_peer_certificate_changed (GObject *conn,
106 soup_socket_init (SoupSocket *sock)
108 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
110 priv->non_blocking = TRUE;
111 priv->addrlock = g_mutex_new ();
112 priv->iolock = g_mutex_new ();
116 disconnect_internal (SoupSocket *sock)
118 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
121 g_socket_close (priv->gsock, NULL);
122 g_object_unref (priv->gsock);
126 if (G_IS_TLS_CONNECTION (priv->conn))
127 g_signal_handlers_disconnect_by_func (priv->conn, soup_socket_peer_certificate_changed, sock);
128 g_object_unref (priv->conn);
130 priv->istream = NULL;
131 priv->ostream = NULL;
134 if (priv->read_src) {
135 g_source_destroy (priv->read_src);
136 priv->read_src = NULL;
138 if (priv->write_src) {
139 g_source_destroy (priv->write_src);
140 priv->write_src = NULL;
145 finalize (GObject *object)
147 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (object);
149 if (priv->connect_cancel) {
150 if (priv->clean_dispose)
151 g_warning ("Disposing socket %p during connect", object);
152 g_object_unref (priv->connect_cancel);
155 if (priv->clean_dispose)
156 g_warning ("Disposing socket %p while still connected", object);
157 disconnect_internal (SOUP_SOCKET (object));
160 if (priv->local_addr)
161 g_object_unref (priv->local_addr);
162 if (priv->remote_addr)
163 g_object_unref (priv->remote_addr);
165 if (priv->watch_src) {
166 if (priv->clean_dispose && !priv->is_server)
167 g_warning ("Disposing socket %p during async op", object);
168 g_source_destroy (priv->watch_src);
170 if (priv->async_context)
171 g_main_context_unref (priv->async_context);
174 g_byte_array_free (priv->read_buf, TRUE);
176 g_mutex_free (priv->addrlock);
177 g_mutex_free (priv->iolock);
179 G_OBJECT_CLASS (soup_socket_parent_class)->finalize (object);
183 soup_socket_class_init (SoupSocketClass *socket_class)
185 GObjectClass *object_class = G_OBJECT_CLASS (socket_class);
187 g_type_class_add_private (socket_class, sizeof (SoupSocketPrivate));
189 /* virtual method override */
190 object_class->finalize = finalize;
191 object_class->set_property = set_property;
192 object_class->get_property = get_property;
197 * SoupSocket::readable:
200 * Emitted when an async socket is readable. See
201 * soup_socket_read(), soup_socket_read_until() and
202 * #SoupSocket:non-blocking.
205 g_signal_new ("readable",
206 G_OBJECT_CLASS_TYPE (object_class),
208 G_STRUCT_OFFSET (SoupSocketClass, readable),
210 soup_marshal_NONE__NONE,
214 * SoupSocket::writable:
217 * Emitted when an async socket is writable. See
218 * soup_socket_write() and #SoupSocket:non-blocking.
221 g_signal_new ("writable",
222 G_OBJECT_CLASS_TYPE (object_class),
224 G_STRUCT_OFFSET (SoupSocketClass, writable),
226 soup_marshal_NONE__NONE,
230 * SoupSocket::disconnected:
233 * Emitted when the socket is disconnected, for whatever
236 signals[DISCONNECTED] =
237 g_signal_new ("disconnected",
238 G_OBJECT_CLASS_TYPE (object_class),
240 G_STRUCT_OFFSET (SoupSocketClass, disconnected),
242 soup_marshal_NONE__NONE,
246 * SoupSocket::new-connection:
248 * @new: the new socket
250 * Emitted when a listening socket (set up with
251 * soup_socket_listen()) receives a new connection.
253 * You must ref the @new if you want to keep it; otherwise it
254 * will be destroyed after the signal is emitted.
256 signals[NEW_CONNECTION] =
257 g_signal_new ("new_connection",
258 G_OBJECT_CLASS_TYPE (object_class),
260 G_STRUCT_OFFSET (SoupSocketClass, new_connection),
262 soup_marshal_NONE__OBJECT,
268 * SOUP_SOCKET_LOCAL_ADDRESS:
270 * Alias for the #SoupSocket:local-address property. (Address
271 * of local end of socket.)
273 g_object_class_install_property (
274 object_class, PROP_LOCAL_ADDRESS,
275 g_param_spec_object (SOUP_SOCKET_LOCAL_ADDRESS,
277 "Address of local end of socket",
279 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
281 * SOUP_SOCKET_REMOTE_ADDRESS:
283 * Alias for the #SoupSocket:remote-address property. (Address
284 * of remote end of socket.)
286 g_object_class_install_property (
287 object_class, PROP_REMOTE_ADDRESS,
288 g_param_spec_object (SOUP_SOCKET_REMOTE_ADDRESS,
290 "Address of remote end of socket",
292 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
294 * SoupSocket:non-blocking:
296 * Whether or not the socket uses non-blocking I/O.
298 * #SoupSocket's I/O methods are designed around the idea of
299 * using a single codepath for both synchronous and
300 * asynchronous I/O. If you want to read off a #SoupSocket,
301 * the "correct" way to do it is to call soup_socket_read() or
302 * soup_socket_read_until() repeatedly until you have read
303 * everything you want. If it returns %SOUP_SOCKET_WOULD_BLOCK
304 * at any point, stop reading and wait for it to emit the
305 * #SoupSocket::readable signal. Then go back to the
306 * reading-as-much-as-you-can loop. Likewise, for writing to a
307 * #SoupSocket, you should call soup_socket_write() either
308 * until you have written everything, or it returns
309 * %SOUP_SOCKET_WOULD_BLOCK (in which case you wait for
310 * #SoupSocket::writable and then go back into the loop).
312 * Code written this way will work correctly with both
313 * blocking and non-blocking sockets; blocking sockets will
314 * simply never return %SOUP_SOCKET_WOULD_BLOCK, and so the
315 * code that handles that case just won't get used for them.
318 * SOUP_SOCKET_FLAG_NONBLOCKING:
320 * Alias for the #SoupSocket:non-blocking property. (Whether
321 * or not the socket uses non-blocking I/O.)
323 g_object_class_install_property (
324 object_class, PROP_NON_BLOCKING,
325 g_param_spec_boolean (SOUP_SOCKET_FLAG_NONBLOCKING,
327 "Whether or not the socket uses non-blocking I/O",
331 * SOUP_SOCKET_IS_SERVER:
333 * Alias for the #SoupSocket:is-server property. (Whether or
334 * not the socket is a server socket.)
336 g_object_class_install_property (
337 object_class, PROP_IS_SERVER,
338 g_param_spec_boolean (SOUP_SOCKET_IS_SERVER,
340 "Whether or not the socket is a server socket",
344 * SOUP_SOCKET_SSL_CREDENTIALS:
346 * Alias for the #SoupSocket:ssl-credentials property.
347 * (SSL credential information.)
349 g_object_class_install_property (
350 object_class, PROP_SSL_CREDENTIALS,
351 g_param_spec_pointer (SOUP_SOCKET_SSL_CREDENTIALS,
353 "SSL credential information, passed from the session to the SSL implementation",
356 * SOUP_SOCKET_SSL_STRICT:
358 * Alias for the #SoupSocket:ssl-strict property.
360 g_object_class_install_property (
361 object_class, PROP_SSL_STRICT,
362 g_param_spec_boolean (SOUP_SOCKET_SSL_STRICT,
363 "Strictly validate SSL certificates",
364 "Whether certificate errors should be considered a connection error",
366 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
368 * SOUP_SOCKET_SSL_FALLBACK:
370 * Alias for the #SoupSocket:ssl-fallback property.
372 g_object_class_install_property (
373 object_class, PROP_SSL_FALLBACK,
374 g_param_spec_boolean (SOUP_SOCKET_SSL_FALLBACK,
376 "Use SSLv3 instead of TLS (client-side only)",
378 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
380 * SOUP_SOCKET_TRUSTED_CERTIFICATE:
382 * Alias for the #SoupSocket:trusted-certificate
385 g_object_class_install_property (
386 object_class, PROP_TRUSTED_CERTIFICATE,
387 g_param_spec_boolean (SOUP_SOCKET_TRUSTED_CERTIFICATE,
388 "Trusted Certificate",
389 "Whether the server certificate is trusted, if this is an SSL socket",
393 * SOUP_SOCKET_ASYNC_CONTEXT:
395 * Alias for the #SoupSocket:async-context property. (The
396 * socket's #GMainContext.)
398 g_object_class_install_property (
399 object_class, PROP_ASYNC_CONTEXT,
400 g_param_spec_pointer (SOUP_SOCKET_ASYNC_CONTEXT,
401 "Async GMainContext",
402 "The GMainContext to dispatch this socket's async I/O in",
403 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
406 * SOUP_SOCKET_TIMEOUT:
408 * Alias for the #SoupSocket:timeout property. (The timeout
409 * in seconds for blocking socket I/O operations.)
411 g_object_class_install_property (
412 object_class, PROP_TIMEOUT,
413 g_param_spec_uint (SOUP_SOCKET_TIMEOUT,
415 "Value in seconds to timeout a blocking I/O",
419 g_object_class_install_property (
420 object_class, PROP_CLEAN_DISPOSE,
421 g_param_spec_boolean ("clean-dispose",
423 "Warn on unclean dispose",
425 G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
427 * SOUP_SOCKET_TLS_CERTIFICATE:
429 * Alias for the #SoupSocket:tls-certificate
430 * property. Note that this property's value is only useful
431 * if the socket is for a TLS connection, and only reliable
432 * after some data has been transferred to or from it.
436 g_object_class_install_property (
437 object_class, PROP_TLS_CERTIFICATE,
438 g_param_spec_object (SOUP_SOCKET_TLS_CERTIFICATE,
440 "The peer's TLS certificate",
441 G_TYPE_TLS_CERTIFICATE,
444 * SOUP_SOCKET_TLS_ERRORS:
446 * Alias for the #SoupSocket:tls-errors
447 * property. Note that this property's value is only useful
448 * if the socket is for a TLS connection, and only reliable
449 * after some data has been transferred to or from it.
453 g_object_class_install_property (
454 object_class, PROP_TLS_ERRORS,
455 g_param_spec_flags (SOUP_SOCKET_TLS_ERRORS,
457 "Errors with the peer's TLS certificate",
458 G_TYPE_TLS_CERTIFICATE_FLAGS, 0,
464 finish_socket_setup (SoupSocketPrivate *priv)
470 priv->conn = (GIOStream *)g_socket_connection_factory_create_connection (priv->gsock);
472 priv->istream = G_POLLABLE_INPUT_STREAM (g_io_stream_get_input_stream (priv->conn));
474 priv->ostream = G_POLLABLE_OUTPUT_STREAM (g_io_stream_get_output_stream (priv->conn));
476 g_socket_set_timeout (priv->gsock, priv->timeout);
480 set_property (GObject *object, guint prop_id,
481 const GValue *value, GParamSpec *pspec)
483 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (object);
486 case PROP_LOCAL_ADDRESS:
487 priv->local_addr = (SoupAddress *)g_value_dup_object (value);
489 case PROP_REMOTE_ADDRESS:
490 priv->remote_addr = (SoupAddress *)g_value_dup_object (value);
492 case PROP_NON_BLOCKING:
493 priv->non_blocking = g_value_get_boolean (value);
495 case PROP_SSL_CREDENTIALS:
496 priv->ssl_creds = g_value_get_pointer (value);
498 case PROP_SSL_STRICT:
499 priv->ssl_strict = g_value_get_boolean (value);
501 case PROP_SSL_FALLBACK:
502 priv->ssl_fallback = g_value_get_boolean (value);
504 case PROP_ASYNC_CONTEXT:
505 priv->async_context = g_value_get_pointer (value);
506 if (priv->async_context)
507 g_main_context_ref (priv->async_context);
510 priv->timeout = g_value_get_uint (value);
512 g_socket_set_timeout (priv->gsock, priv->timeout);
514 case PROP_CLEAN_DISPOSE:
515 priv->clean_dispose = g_value_get_boolean (value);
518 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
524 get_property (GObject *object, guint prop_id,
525 GValue *value, GParamSpec *pspec)
527 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (object);
530 case PROP_LOCAL_ADDRESS:
531 g_value_set_object (value, soup_socket_get_local_address (SOUP_SOCKET (object)));
533 case PROP_REMOTE_ADDRESS:
534 g_value_set_object (value, soup_socket_get_remote_address (SOUP_SOCKET (object)));
536 case PROP_NON_BLOCKING:
537 g_value_set_boolean (value, priv->non_blocking);
540 g_value_set_boolean (value, priv->is_server);
542 case PROP_SSL_CREDENTIALS:
543 g_value_set_pointer (value, priv->ssl_creds);
545 case PROP_SSL_STRICT:
546 g_value_set_boolean (value, priv->ssl_strict);
548 case PROP_SSL_FALLBACK:
549 g_value_set_boolean (value, priv->ssl_fallback);
551 case PROP_TRUSTED_CERTIFICATE:
552 g_value_set_boolean (value, priv->tls_errors == 0);
554 case PROP_ASYNC_CONTEXT:
555 g_value_set_pointer (value, priv->async_context ? g_main_context_ref (priv->async_context) : NULL);
558 g_value_set_uint (value, priv->timeout);
560 case PROP_TLS_CERTIFICATE:
561 if (G_IS_TLS_CONNECTION (priv->conn))
562 g_value_set_object (value, g_tls_connection_get_peer_certificate (G_TLS_CONNECTION (priv->conn)));
564 g_value_set_object (value, NULL);
566 case PROP_TLS_ERRORS:
567 g_value_set_flags (value, priv->tls_errors);
570 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
578 * @optname1: name of first property to set (or %NULL)
579 * @...: value of @optname1, followed by additional property/value pairs
581 * Creates a new (disconnected) socket
583 * Return value: the new socket
586 soup_socket_new (const char *optname1, ...)
591 va_start (ap, optname1);
592 sock = (SoupSocket *)g_object_new_valist (SOUP_TYPE_SOCKET,
600 socket_connected (SoupSocket *sock, GSocketConnection *conn, GError *error)
602 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
604 g_object_unref (priv->connect_cancel);
605 priv->connect_cancel = NULL;
608 if (error->domain == G_RESOLVER_ERROR) {
609 g_error_free (error);
610 return SOUP_STATUS_CANT_RESOLVE;
612 g_error_free (error);
613 return SOUP_STATUS_CANT_CONNECT;
617 priv->conn = (GIOStream *)conn;
618 priv->gsock = g_object_ref (g_socket_connection_get_socket (conn));
619 finish_socket_setup (priv);
621 return SOUP_STATUS_OK;
625 * SoupSocketCallback:
626 * @sock: the #SoupSocket
627 * @status: an HTTP status code indicating success or failure
628 * @user_data: the data passed to soup_socket_connect_async()
630 * The callback function passed to soup_socket_connect_async().
635 SoupSocketCallback callback;
637 } SoupSocketAsyncConnectData;
640 async_connected (GObject *client, GAsyncResult *result, gpointer data)
642 SoupSocketAsyncConnectData *sacd = data;
643 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sacd->sock);
644 GError *error = NULL;
645 GSocketConnection *conn;
648 if (priv->async_context)
649 g_main_context_pop_thread_default (priv->async_context);
651 conn = g_socket_client_connect_finish (G_SOCKET_CLIENT (client),
653 status = socket_connected (sacd->sock, conn, error);
655 sacd->callback (sacd->sock, status, sacd->user_data);
656 g_object_unref (sacd->sock);
657 g_slice_free (SoupSocketAsyncConnectData, sacd);
661 * soup_socket_connect_async:
662 * @sock: a client #SoupSocket (which must not already be connected)
663 * @cancellable: a #GCancellable, or %NULL
664 * @callback: (scope async): callback to call after connecting
665 * @user_data: data to pass to @callback
667 * Begins asynchronously connecting to @sock's remote address. The
668 * socket will call @callback when it succeeds or fails (but not
669 * before returning from this function).
671 * If @cancellable is non-%NULL, it can be used to cancel the
672 * connection. @callback will still be invoked in this case, with a
673 * status of %SOUP_STATUS_CANCELLED.
676 soup_socket_connect_async (SoupSocket *sock, GCancellable *cancellable,
677 SoupSocketCallback callback, gpointer user_data)
679 SoupSocketPrivate *priv;
680 SoupSocketAsyncConnectData *sacd;
681 GSocketClient *client;
683 g_return_if_fail (SOUP_IS_SOCKET (sock));
684 priv = SOUP_SOCKET_GET_PRIVATE (sock);
685 g_return_if_fail (priv->remote_addr != NULL);
687 sacd = g_slice_new0 (SoupSocketAsyncConnectData);
688 sacd->sock = g_object_ref (sock);
689 sacd->callback = callback;
690 sacd->user_data = user_data;
692 priv->connect_cancel = cancellable ? g_object_ref (cancellable) : g_cancellable_new ();
694 if (priv->async_context)
695 g_main_context_push_thread_default (priv->async_context);
697 client = g_socket_client_new ();
699 g_socket_client_set_timeout (client, priv->timeout);
700 g_socket_client_connect_async (client,
701 G_SOCKET_CONNECTABLE (priv->remote_addr),
702 priv->connect_cancel,
703 async_connected, sacd);
704 g_object_unref (client);
708 * soup_socket_connect_sync:
709 * @sock: a client #SoupSocket (which must not already be connected)
710 * @cancellable: a #GCancellable, or %NULL
712 * Attempt to synchronously connect @sock to its remote address.
714 * If @cancellable is non-%NULL, it can be used to cancel the
715 * connection, in which case soup_socket_connect_sync() will return
716 * %SOUP_STATUS_CANCELLED.
718 * Return value: a success or failure code.
721 soup_socket_connect_sync (SoupSocket *sock, GCancellable *cancellable)
723 SoupSocketPrivate *priv;
724 GSocketClient *client;
725 GSocketConnection *conn;
726 GError *error = NULL;
728 g_return_val_if_fail (SOUP_IS_SOCKET (sock), SOUP_STATUS_MALFORMED);
729 priv = SOUP_SOCKET_GET_PRIVATE (sock);
730 g_return_val_if_fail (!priv->is_server, SOUP_STATUS_MALFORMED);
731 g_return_val_if_fail (priv->gsock == NULL, SOUP_STATUS_MALFORMED);
732 g_return_val_if_fail (priv->remote_addr != NULL, SOUP_STATUS_MALFORMED);
735 g_object_ref (cancellable);
737 cancellable = g_cancellable_new ();
738 priv->connect_cancel = cancellable;
740 client = g_socket_client_new ();
742 g_socket_client_set_timeout (client, priv->timeout);
743 conn = g_socket_client_connect (client,
744 G_SOCKET_CONNECTABLE (priv->remote_addr),
745 priv->connect_cancel, &error);
746 g_object_unref (client);
748 return socket_connected (sock, conn, error);
752 soup_socket_get_fd (SoupSocket *sock)
754 g_return_val_if_fail (SOUP_IS_SOCKET (sock), -1);
756 return g_socket_get_fd (SOUP_SOCKET_GET_PRIVATE (sock)->gsock);
760 soup_socket_create_watch (SoupSocketPrivate *priv, GIOCondition cond,
761 GPollableSourceFunc callback, gpointer user_data,
762 GCancellable *cancellable)
767 watch = g_pollable_input_stream_create_source (priv->istream, cancellable);
769 watch = g_pollable_output_stream_create_source (priv->ostream, cancellable);
770 g_source_set_callback (watch, (GSourceFunc)callback, user_data, NULL);
771 g_source_attach (watch, priv->async_context);
772 g_source_unref (watch);
778 listen_watch (GObject *pollable, gpointer data)
780 SoupSocket *sock = data, *new;
781 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock), *new_priv;
784 new_gsock = g_socket_accept (priv->gsock, NULL, NULL);
788 new = g_object_new (SOUP_TYPE_SOCKET, NULL);
789 new_priv = SOUP_SOCKET_GET_PRIVATE (new);
790 new_priv->gsock = new_gsock;
791 if (priv->async_context)
792 new_priv->async_context = g_main_context_ref (priv->async_context);
793 new_priv->non_blocking = priv->non_blocking;
794 new_priv->is_server = TRUE;
796 new_priv->ssl_creds = priv->ssl_creds;
797 finish_socket_setup (new_priv);
799 if (new_priv->ssl_creds) {
800 if (!soup_socket_start_proxy_ssl (new, NULL, NULL)) {
801 g_object_unref (new);
806 g_signal_emit (sock, signals[NEW_CONNECTION], 0, new);
807 g_object_unref (new);
813 * soup_socket_listen:
814 * @sock: a server #SoupSocket (which must not already be connected or
817 * Makes @sock start listening on its local address. When connections
818 * come in, @sock will emit %new_connection.
820 * Return value: whether or not @sock is now listening.
823 soup_socket_listen (SoupSocket *sock)
826 SoupSocketPrivate *priv;
827 GSocketAddress *addr;
829 g_return_val_if_fail (SOUP_IS_SOCKET (sock), FALSE);
830 priv = SOUP_SOCKET_GET_PRIVATE (sock);
831 g_return_val_if_fail (priv->gsock == NULL, FALSE);
832 g_return_val_if_fail (priv->local_addr != NULL, FALSE);
834 priv->is_server = TRUE;
836 /* @local_addr may have its port set to 0. So we intentionally
837 * don't store it in priv->local_addr, so that if the
838 * caller calls soup_socket_get_local_address() later, we'll
839 * have to make a new addr by calling getsockname(), which
840 * will have the right port number.
842 addr = soup_address_get_gsockaddr (priv->local_addr);
843 g_return_val_if_fail (addr != NULL, FALSE);
845 priv->gsock = g_socket_new (g_socket_address_get_family (addr),
846 G_SOCKET_TYPE_STREAM,
847 G_SOCKET_PROTOCOL_DEFAULT,
851 finish_socket_setup (priv);
854 if (!g_socket_bind (priv->gsock, addr, TRUE, NULL))
856 /* Force local_addr to be re-resolved now */
857 g_object_unref (priv->local_addr);
858 priv->local_addr = NULL;
861 if (!g_socket_listen (priv->gsock, NULL))
864 priv->watch_src = soup_socket_create_watch (priv, G_IO_IN,
867 g_object_unref (addr);
872 disconnect_internal (sock);
873 g_object_unref (addr);
879 soup_socket_peer_certificate_changed (GObject *conn, GParamSpec *pspec,
882 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
884 priv->tls_errors = g_tls_connection_get_peer_certificate_errors (G_TLS_CONNECTION (priv->conn));
885 if (priv->ssl_ca_in_creds)
886 priv->tls_errors &= ~G_TLS_CERTIFICATE_UNKNOWN_CA;
888 g_object_notify (sock, "tls-certificate");
889 g_object_notify (sock, "tls-errors");
893 soup_socket_accept_certificate (GTlsConnection *conn, GTlsCertificate *cert,
894 GTlsCertificateFlags errors, gpointer sock)
896 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
898 if (soup_ssl_credentials_verify_certificate (priv->ssl_creds,
900 priv->ssl_ca_in_creds = TRUE;
904 return !priv->ssl_strict;
908 * soup_socket_start_ssl:
910 * @cancellable: a #GCancellable
912 * Starts using SSL on @socket.
914 * Return value: success or failure
917 soup_socket_start_ssl (SoupSocket *sock, GCancellable *cancellable)
919 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
921 return soup_socket_start_proxy_ssl (sock, soup_address_get_name (priv->remote_addr), cancellable);
925 * soup_socket_start_proxy_ssl:
927 * @ssl_host: hostname of the SSL server
928 * @cancellable: a #GCancellable
930 * Starts using SSL on @socket, expecting to find a host named
933 * Return value: success or failure
936 soup_socket_start_proxy_ssl (SoupSocket *sock, const char *ssl_host,
937 GCancellable *cancellable)
939 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
940 GTlsBackend *backend = g_tls_backend_get_default ();
942 if (G_IS_TLS_CONNECTION (priv->conn))
944 if (!priv->ssl_creds)
947 if (!priv->is_server) {
948 GTlsClientConnection *conn;
949 GSocketConnectable *identity;
951 identity = g_network_address_new (ssl_host, 0);
952 conn = g_initable_new (g_tls_backend_get_client_connection_type (backend),
954 "base-io-stream", priv->conn,
955 "server-identity", identity,
956 "use-system-certdb", FALSE,
957 "require-close-notify", FALSE,
960 g_object_unref (identity);
965 g_object_unref (priv->conn);
966 priv->conn = G_IO_STREAM (conn);
968 g_signal_connect (conn, "accept-certificate",
969 G_CALLBACK (soup_socket_accept_certificate),
972 GTlsServerConnection *conn;
974 conn = g_initable_new (g_tls_backend_get_server_connection_type (backend),
976 "base-io-stream", priv->conn,
977 "certificate", soup_ssl_credentials_get_certificate (priv->ssl_creds),
978 "use-system-certdb", FALSE,
979 "require-close-notify", FALSE,
984 g_object_unref (priv->conn);
985 priv->conn = G_IO_STREAM (conn);
988 priv->ssl_ca_in_creds = FALSE;
989 g_signal_connect (priv->conn, "notify::peer-certificate",
990 G_CALLBACK (soup_socket_peer_certificate_changed), sock);
992 priv->istream = G_POLLABLE_INPUT_STREAM (g_io_stream_get_input_stream (priv->conn));
993 priv->ostream = G_POLLABLE_OUTPUT_STREAM (g_io_stream_get_output_stream (priv->conn));
998 soup_socket_handshake_sync (SoupSocket *sock,
999 GCancellable *cancellable)
1001 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
1002 GError *error = NULL;
1004 if (g_tls_connection_handshake (G_TLS_CONNECTION (priv->conn),
1005 cancellable, &error))
1006 return SOUP_STATUS_OK;
1007 else if (!priv->ssl_fallback &&
1008 g_error_matches (error, G_TLS_ERROR, G_TLS_ERROR_NOT_TLS)) {
1009 g_error_free (error);
1010 return SOUP_STATUS_TLS_FAILED;
1012 g_error_free (error);
1013 return SOUP_STATUS_SSL_FAILED;
1018 handshake_async_ready (GObject *source, GAsyncResult *result, gpointer user_data)
1020 SoupSocketAsyncConnectData *data = user_data;
1021 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (data->sock);
1022 GError *error = NULL;
1025 if (priv->async_context)
1026 g_main_context_pop_thread_default (priv->async_context);
1028 if (g_tls_connection_handshake_finish (G_TLS_CONNECTION (priv->conn),
1030 status = SOUP_STATUS_OK;
1031 else if (!priv->ssl_fallback &&
1032 g_error_matches (error, G_TLS_ERROR, G_TLS_ERROR_NOT_TLS))
1033 status = SOUP_STATUS_TLS_FAILED;
1035 status = SOUP_STATUS_SSL_FAILED;
1036 g_clear_error (&error);
1038 data->callback (data->sock, status, data->user_data);
1039 g_object_unref (data->sock);
1040 g_slice_free (SoupSocketAsyncConnectData, data);
1044 soup_socket_handshake_async (SoupSocket *sock,
1045 GCancellable *cancellable,
1046 SoupSocketCallback callback,
1049 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
1050 SoupSocketAsyncConnectData *data;
1052 data = g_slice_new (SoupSocketAsyncConnectData);
1053 data->sock = g_object_ref (sock);
1054 data->callback = callback;
1055 data->user_data = user_data;
1057 if (priv->async_context)
1058 g_main_context_push_thread_default (priv->async_context);
1059 g_tls_connection_handshake_async (G_TLS_CONNECTION (priv->conn),
1061 cancellable, handshake_async_ready,
1066 * soup_socket_is_ssl:
1067 * @sock: a #SoupSocket
1069 * Tests if @sock is set up to do SSL. Note that this simply means
1070 * that the %SOUP_SOCKET_SSL_CREDENTIALS property has been set; it
1071 * does not mean that soup_socket_start_ssl() has been called.
1073 * Return value: %TRUE if @sock has SSL credentials set
1076 soup_socket_is_ssl (SoupSocket *sock)
1078 g_return_if_fail (SOUP_IS_SOCKET (sock));
1079 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
1081 return priv->ssl_creds != NULL;
1085 * soup_socket_disconnect:
1086 * @sock: a #SoupSocket
1088 * Disconnects @sock. Any further read or write attempts on it will
1092 soup_socket_disconnect (SoupSocket *sock)
1094 SoupSocketPrivate *priv;
1095 gboolean already_disconnected = FALSE;
1097 g_return_if_fail (SOUP_IS_SOCKET (sock));
1098 priv = SOUP_SOCKET_GET_PRIVATE (sock);
1100 if (priv->connect_cancel) {
1101 g_cancellable_cancel (priv->connect_cancel);
1103 } else if (g_mutex_trylock (priv->iolock)) {
1105 disconnect_internal (sock);
1107 already_disconnected = TRUE;
1108 g_mutex_unlock (priv->iolock);
1110 /* Another thread is currently doing IO, so
1111 * we can't close the socket. So just shutdown
1112 * the file descriptor to force the I/O to fail.
1113 * (It will actually be closed when the socket
1116 g_socket_shutdown (priv->gsock, TRUE, TRUE, NULL);
1119 if (already_disconnected)
1122 /* Keep ref around signals in case the object is unreferenced
1125 g_object_ref (sock);
1127 /* Give all readers a chance to notice the connection close */
1128 g_signal_emit (sock, signals[READABLE], 0);
1130 /* FIXME: can't disconnect until all data is read */
1132 /* Then let everyone know we're disconnected */
1133 g_signal_emit (sock, signals[DISCONNECTED], 0);
1135 g_object_unref (sock);
1139 * soup_socket_is_connected:
1140 * @sock: a #SoupSocket
1142 * Tests if @sock is connected to another host
1144 * Return value: %TRUE or %FALSE.
1147 soup_socket_is_connected (SoupSocket *sock)
1149 SoupSocketPrivate *priv;
1151 g_return_val_if_fail (SOUP_IS_SOCKET (sock), FALSE);
1152 priv = SOUP_SOCKET_GET_PRIVATE (sock);
1154 return priv->conn != NULL;
1158 * soup_socket_get_local_address:
1159 * @sock: a #SoupSocket
1161 * Returns the #SoupAddress corresponding to the local end of @sock.
1163 * Return value: (transfer none): the #SoupAddress
1166 soup_socket_get_local_address (SoupSocket *sock)
1168 SoupSocketPrivate *priv;
1170 g_return_val_if_fail (SOUP_IS_SOCKET (sock), NULL);
1171 priv = SOUP_SOCKET_GET_PRIVATE (sock);
1173 g_mutex_lock (priv->addrlock);
1174 if (!priv->local_addr) {
1175 GSocketAddress *addr;
1176 struct sockaddr_storage sa;
1179 addr = g_socket_get_local_address (priv->gsock, NULL);
1180 sa_len = g_socket_address_get_native_size (addr);
1181 g_socket_address_to_native (addr, &sa, sa_len, NULL);
1182 priv->local_addr = soup_address_new_from_sockaddr ((struct sockaddr *)&sa, sa_len);
1183 g_object_unref (addr);
1185 g_mutex_unlock (priv->addrlock);
1187 return priv->local_addr;
1191 * soup_socket_get_remote_address:
1192 * @sock: a #SoupSocket
1194 * Returns the #SoupAddress corresponding to the remote end of @sock.
1196 * Return value: (transfer none): the #SoupAddress
1199 soup_socket_get_remote_address (SoupSocket *sock)
1201 SoupSocketPrivate *priv;
1203 g_return_val_if_fail (SOUP_IS_SOCKET (sock), NULL);
1204 priv = SOUP_SOCKET_GET_PRIVATE (sock);
1206 g_mutex_lock (priv->addrlock);
1207 if (!priv->remote_addr) {
1208 GSocketAddress *addr;
1209 struct sockaddr_storage sa;
1212 addr = g_socket_get_remote_address (priv->gsock, NULL);
1213 sa_len = g_socket_address_get_native_size (addr);
1214 g_socket_address_to_native (addr, &sa, sa_len, NULL);
1215 priv->remote_addr = soup_address_new_from_sockaddr ((struct sockaddr *)&sa, sa_len);
1216 g_object_unref (addr);
1218 g_mutex_unlock (priv->addrlock);
1220 return priv->remote_addr;
1225 socket_read_watch (GObject *pollable, gpointer user_data)
1227 SoupSocket *sock = user_data;
1228 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
1230 priv->read_src = NULL;
1231 g_signal_emit (sock, signals[READABLE], 0);
1235 static SoupSocketIOStatus
1236 read_from_network (SoupSocket *sock, gpointer buffer, gsize len,
1237 gsize *nread, GCancellable *cancellable, GError **error)
1239 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
1240 GError *my_err = NULL;
1246 return SOUP_SOCKET_EOF;
1248 if (!priv->non_blocking) {
1249 my_nread = g_input_stream_read (G_INPUT_STREAM (priv->istream),
1251 cancellable, &my_err);
1253 my_nread = g_pollable_input_stream_read_nonblocking (
1254 priv->istream, buffer, len,
1255 cancellable, &my_err);
1259 g_clear_error (&my_err);
1261 return SOUP_SOCKET_OK;
1262 } else if (my_nread == 0) {
1263 g_clear_error (&my_err);
1265 return SOUP_SOCKET_EOF;
1266 } else if (g_error_matches (my_err, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) {
1267 g_clear_error (&my_err);
1268 if (!priv->read_src) {
1270 soup_socket_create_watch (priv, G_IO_IN,
1271 socket_read_watch, sock,
1274 return SOUP_SOCKET_WOULD_BLOCK;
1275 } else if (g_error_matches (my_err, G_TLS_ERROR, G_TLS_ERROR_HANDSHAKE)) {
1276 my_err->domain = SOUP_SSL_ERROR;
1277 my_err->code = SOUP_SSL_ERROR_CERTIFICATE;
1280 g_propagate_error (error, my_err);
1281 return SOUP_SOCKET_ERROR;
1284 static SoupSocketIOStatus
1285 read_from_buf (SoupSocket *sock, gpointer buffer, gsize len, gsize *nread)
1287 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
1288 GByteArray *read_buf = priv->read_buf;
1290 *nread = MIN (read_buf->len, len);
1291 memcpy (buffer, read_buf->data, *nread);
1293 if (*nread == read_buf->len) {
1294 g_byte_array_free (read_buf, TRUE);
1295 priv->read_buf = NULL;
1297 memmove (read_buf->data, read_buf->data + *nread,
1298 read_buf->len - *nread);
1299 g_byte_array_set_size (read_buf, read_buf->len - *nread);
1302 return SOUP_SOCKET_OK;
1306 * SoupSocketIOStatus:
1307 * @SOUP_SOCKET_OK: Success
1308 * @SOUP_SOCKET_WOULD_BLOCK: Cannot read/write any more at this time
1309 * @SOUP_SOCKET_EOF: End of file
1310 * @SOUP_SOCKET_ERROR: Other error
1312 * Return value from the #SoupSocket IO methods.
1318 * @buffer: buffer to read into
1319 * @len: size of @buffer in bytes
1320 * @nread: (out): on return, the number of bytes read into @buffer
1321 * @cancellable: a #GCancellable, or %NULL
1322 * @error: error pointer
1324 * Attempts to read up to @len bytes from @sock into @buffer. If some
1325 * data is successfully read, soup_socket_read() will return
1326 * %SOUP_SOCKET_OK, and *@nread will contain the number of bytes
1327 * actually read (which may be less than @len).
1329 * If @sock is non-blocking, and no data is available, the return
1330 * value will be %SOUP_SOCKET_WOULD_BLOCK. In this case, the caller
1331 * can connect to the #SoupSocket::readable signal to know when there
1332 * is more data to read. (NB: You MUST read all available data off the
1333 * socket first. #SoupSocket::readable is only emitted after
1334 * soup_socket_read() returns %SOUP_SOCKET_WOULD_BLOCK, and it is only
1335 * emitted once. See the documentation for #SoupSocket:non-blocking.)
1337 * Return value: a #SoupSocketIOStatus, as described above (or
1338 * %SOUP_SOCKET_EOF if the socket is no longer connected, or
1339 * %SOUP_SOCKET_ERROR on any other error, in which case @error will
1343 soup_socket_read (SoupSocket *sock, gpointer buffer, gsize len,
1344 gsize *nread, GCancellable *cancellable, GError **error)
1346 SoupSocketPrivate *priv;
1347 SoupSocketIOStatus status;
1349 g_return_val_if_fail (SOUP_IS_SOCKET (sock), SOUP_SOCKET_ERROR);
1350 g_return_val_if_fail (nread != NULL, SOUP_SOCKET_ERROR);
1352 priv = SOUP_SOCKET_GET_PRIVATE (sock);
1354 g_mutex_lock (priv->iolock);
1356 status = read_from_buf (sock, buffer, len, nread);
1358 status = read_from_network (sock, buffer, len, nread, cancellable, error);
1359 g_mutex_unlock (priv->iolock);
1365 * soup_socket_read_until:
1367 * @buffer: buffer to read into
1368 * @len: size of @buffer in bytes
1369 * @boundary: boundary to read until
1370 * @boundary_len: length of @boundary in bytes
1371 * @nread: (out): on return, the number of bytes read into @buffer
1372 * @got_boundary: on return, whether or not the data in @buffer
1373 * ends with the boundary string
1374 * @cancellable: a #GCancellable, or %NULL
1375 * @error: error pointer
1377 * Like soup_socket_read(), but reads no further than the first
1378 * occurrence of @boundary. (If the boundary is found, it will be
1379 * included in the returned data, and *@got_boundary will be set to
1380 * %TRUE.) Any data after the boundary will returned in future reads.
1382 * soup_socket_read_until() will almost always return fewer than @len
1383 * bytes: if the boundary is found, then it will only return the bytes
1384 * up until the end of the boundary, and if the boundary is not found,
1385 * then it will leave the last <literal>(boundary_len - 1)</literal>
1386 * bytes in its internal buffer, in case they form the start of the
1387 * boundary string. Thus, @len normally needs to be at least 1 byte
1388 * longer than @boundary_len if you want to make any progress at all.
1390 * Return value: as for soup_socket_read()
1393 soup_socket_read_until (SoupSocket *sock, gpointer buffer, gsize len,
1394 gconstpointer boundary, gsize boundary_len,
1395 gsize *nread, gboolean *got_boundary,
1396 GCancellable *cancellable, GError **error)
1398 SoupSocketPrivate *priv;
1399 SoupSocketIOStatus status;
1400 GByteArray *read_buf;
1401 guint match_len, prev_len;
1404 g_return_val_if_fail (SOUP_IS_SOCKET (sock), SOUP_SOCKET_ERROR);
1405 g_return_val_if_fail (nread != NULL, SOUP_SOCKET_ERROR);
1406 g_return_val_if_fail (len >= boundary_len, SOUP_SOCKET_ERROR);
1408 priv = SOUP_SOCKET_GET_PRIVATE (sock);
1410 g_mutex_lock (priv->iolock);
1412 *got_boundary = FALSE;
1414 if (!priv->read_buf)
1415 priv->read_buf = g_byte_array_new ();
1416 read_buf = priv->read_buf;
1418 if (read_buf->len < boundary_len) {
1419 prev_len = read_buf->len;
1420 g_byte_array_set_size (read_buf, len);
1421 status = read_from_network (sock,
1422 read_buf->data + prev_len,
1423 len - prev_len, nread, cancellable, error);
1424 read_buf->len = prev_len + *nread;
1426 if (status != SOUP_SOCKET_OK) {
1427 g_mutex_unlock (priv->iolock);
1432 /* Scan for the boundary */
1433 end = read_buf->data + read_buf->len;
1434 for (p = read_buf->data; p <= end - boundary_len; p++) {
1435 if (!memcmp (p, boundary, boundary_len)) {
1437 *got_boundary = TRUE;
1442 /* Return everything up to 'p' (which is either just after the
1443 * boundary, or @boundary_len - 1 bytes before the end of the
1446 match_len = p - read_buf->data;
1447 status = read_from_buf (sock, buffer, MIN (len, match_len), nread);
1449 g_mutex_unlock (priv->iolock);
1454 socket_write_watch (GObject *pollable, gpointer user_data)
1456 SoupSocket *sock = user_data;
1457 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
1459 priv->write_src = NULL;
1460 g_signal_emit (sock, signals[WRITABLE], 0);
1465 * soup_socket_write:
1467 * @buffer: data to write
1468 * @len: size of @buffer, in bytes
1469 * @nwrote: (out): on return, number of bytes written
1470 * @cancellable: a #GCancellable, or %NULL
1471 * @error: error pointer
1473 * Attempts to write @len bytes from @buffer to @sock. If some data is
1474 * successfully written, the return status will be %SOUP_SOCKET_OK,
1475 * and *@nwrote will contain the number of bytes actually written
1476 * (which may be less than @len).
1478 * If @sock is non-blocking, and no data could be written right away,
1479 * the return value will be %SOUP_SOCKET_WOULD_BLOCK. In this case,
1480 * the caller can connect to the #SoupSocket::writable signal to know
1481 * when more data can be written. (NB: #SoupSocket::writable is only
1482 * emitted after soup_socket_write() returns %SOUP_SOCKET_WOULD_BLOCK,
1483 * and it is only emitted once. See the documentation for
1484 * #SoupSocket:non-blocking.)
1486 * Return value: a #SoupSocketIOStatus, as described above (or
1487 * %SOUP_SOCKET_EOF or %SOUP_SOCKET_ERROR. @error will be set if the
1488 * return value is %SOUP_SOCKET_ERROR.)
1491 soup_socket_write (SoupSocket *sock, gconstpointer buffer,
1492 gsize len, gsize *nwrote,
1493 GCancellable *cancellable, GError **error)
1495 SoupSocketPrivate *priv;
1496 GError *my_err = NULL;
1499 g_return_val_if_fail (SOUP_IS_SOCKET (sock), SOUP_SOCKET_ERROR);
1500 g_return_val_if_fail (nwrote != NULL, SOUP_SOCKET_ERROR);
1502 priv = SOUP_SOCKET_GET_PRIVATE (sock);
1504 g_mutex_lock (priv->iolock);
1507 g_mutex_unlock (priv->iolock);
1508 return SOUP_SOCKET_EOF;
1510 if (priv->write_src) {
1511 g_mutex_unlock (priv->iolock);
1512 return SOUP_SOCKET_WOULD_BLOCK;
1515 if (!priv->non_blocking) {
1516 my_nwrote = g_output_stream_write (G_OUTPUT_STREAM (priv->ostream),
1518 cancellable, &my_err);
1520 my_nwrote = g_pollable_output_stream_write_nonblocking (
1521 priv->ostream, buffer, len,
1522 cancellable, &my_err);
1525 if (my_nwrote > 0) {
1526 g_mutex_unlock (priv->iolock);
1527 g_clear_error (&my_err);
1528 *nwrote = my_nwrote;
1529 return SOUP_SOCKET_OK;
1532 if (g_error_matches (my_err, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) {
1533 g_mutex_unlock (priv->iolock);
1534 g_clear_error (&my_err);
1537 soup_socket_create_watch (priv,
1539 socket_write_watch, sock, cancellable);
1540 return SOUP_SOCKET_WOULD_BLOCK;
1541 } else if (g_error_matches (my_err, G_TLS_ERROR, G_TLS_ERROR_HANDSHAKE)) {
1542 my_err->domain = SOUP_SSL_ERROR;
1543 my_err->code = SOUP_SSL_ERROR_CERTIFICATE;
1546 g_mutex_unlock (priv->iolock);
1547 g_propagate_error (error, my_err);
1548 return SOUP_SOCKET_ERROR;