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"
27 * @short_description: A network socket
29 * #SoupSocket is libsoup's TCP socket type. While it is primarily
30 * intended for internal use, #SoupSocket<!-- -->s are exposed in the
31 * API in various places, and some of their methods (eg,
32 * soup_socket_get_remote_address()) may be useful to applications.
35 G_DEFINE_TYPE (SoupSocket, soup_socket, G_TYPE_OBJECT)
46 static guint signals[LAST_SIGNAL] = { 0 };
59 PROP_USE_THREAD_CONTEXT,
61 PROP_TRUSTED_CERTIFICATE,
70 SoupAddress *local_addr, *remote_addr;
73 GPollableInputStream *istream;
74 GPollableOutputStream *ostream;
75 GTlsCertificateFlags tls_errors;
82 guint clean_dispose:1;
83 guint use_thread_context:1;
86 GMainContext *async_context;
88 GSource *read_src, *write_src;
91 GMutex iolock, addrlock;
94 GCancellable *connect_cancel;
96 #define SOUP_SOCKET_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SOUP_TYPE_SOCKET, SoupSocketPrivate))
98 static void set_property (GObject *object, guint prop_id,
99 const GValue *value, GParamSpec *pspec);
100 static void get_property (GObject *object, guint prop_id,
101 GValue *value, GParamSpec *pspec);
103 static void soup_socket_peer_certificate_changed (GObject *conn,
108 soup_socket_init (SoupSocket *sock)
110 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
112 priv->non_blocking = TRUE;
113 g_mutex_init (&priv->addrlock);
114 g_mutex_init (&priv->iolock);
118 disconnect_internal (SoupSocket *sock)
120 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
123 g_socket_close (priv->gsock, NULL);
124 g_object_unref (priv->gsock);
128 if (G_IS_TLS_CONNECTION (priv->conn))
129 g_signal_handlers_disconnect_by_func (priv->conn, soup_socket_peer_certificate_changed, sock);
130 g_object_unref (priv->conn);
132 priv->istream = NULL;
133 priv->ostream = NULL;
136 if (priv->read_src) {
137 g_source_destroy (priv->read_src);
138 priv->read_src = NULL;
140 if (priv->write_src) {
141 g_source_destroy (priv->write_src);
142 priv->write_src = NULL;
147 finalize (GObject *object)
149 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (object);
151 if (priv->connect_cancel) {
152 if (priv->clean_dispose)
153 g_warning ("Disposing socket %p during connect", object);
154 g_object_unref (priv->connect_cancel);
157 if (priv->clean_dispose)
158 g_warning ("Disposing socket %p while still connected", object);
159 disconnect_internal (SOUP_SOCKET (object));
162 if (priv->local_addr)
163 g_object_unref (priv->local_addr);
164 if (priv->remote_addr)
165 g_object_unref (priv->remote_addr);
167 if (priv->watch_src) {
168 if (priv->clean_dispose && !priv->is_server)
169 g_warning ("Disposing socket %p during async op", object);
170 g_source_destroy (priv->watch_src);
172 if (priv->async_context)
173 g_main_context_unref (priv->async_context);
176 g_byte_array_free (priv->read_buf, TRUE);
178 g_mutex_clear (&priv->addrlock);
179 g_mutex_clear (&priv->iolock);
181 G_OBJECT_CLASS (soup_socket_parent_class)->finalize (object);
185 soup_socket_class_init (SoupSocketClass *socket_class)
187 GObjectClass *object_class = G_OBJECT_CLASS (socket_class);
189 g_type_class_add_private (socket_class, sizeof (SoupSocketPrivate));
191 /* virtual method override */
192 object_class->finalize = finalize;
193 object_class->set_property = set_property;
194 object_class->get_property = get_property;
199 * SoupSocket::readable:
202 * Emitted when an async socket is readable. See
203 * soup_socket_read(), soup_socket_read_until() and
204 * #SoupSocket:non-blocking.
207 g_signal_new ("readable",
208 G_OBJECT_CLASS_TYPE (object_class),
210 G_STRUCT_OFFSET (SoupSocketClass, readable),
212 _soup_marshal_NONE__NONE,
216 * SoupSocket::writable:
219 * Emitted when an async socket is writable. See
220 * soup_socket_write() and #SoupSocket:non-blocking.
223 g_signal_new ("writable",
224 G_OBJECT_CLASS_TYPE (object_class),
226 G_STRUCT_OFFSET (SoupSocketClass, writable),
228 _soup_marshal_NONE__NONE,
232 * SoupSocket::disconnected:
235 * Emitted when the socket is disconnected, for whatever
238 signals[DISCONNECTED] =
239 g_signal_new ("disconnected",
240 G_OBJECT_CLASS_TYPE (object_class),
242 G_STRUCT_OFFSET (SoupSocketClass, disconnected),
244 _soup_marshal_NONE__NONE,
248 * SoupSocket::new-connection:
250 * @new: the new socket
252 * Emitted when a listening socket (set up with
253 * soup_socket_listen()) receives a new connection.
255 * You must ref the @new if you want to keep it; otherwise it
256 * will be destroyed after the signal is emitted.
258 signals[NEW_CONNECTION] =
259 g_signal_new ("new_connection",
260 G_OBJECT_CLASS_TYPE (object_class),
262 G_STRUCT_OFFSET (SoupSocketClass, new_connection),
264 _soup_marshal_NONE__OBJECT,
270 * @event: the event that occurred
271 * @connection: the current connection state
273 * Emitted when a network-related event occurs. See
274 * #GSocketClient::event for more details.
279 g_signal_new ("event",
280 G_OBJECT_CLASS_TYPE (object_class),
286 G_TYPE_SOCKET_CLIENT_EVENT,
292 * SOUP_SOCKET_LOCAL_ADDRESS:
294 * Alias for the #SoupSocket:local-address property. (Address
295 * of local end of socket.)
297 g_object_class_install_property (
298 object_class, PROP_LOCAL_ADDRESS,
299 g_param_spec_object (SOUP_SOCKET_LOCAL_ADDRESS,
301 "Address of local end of socket",
303 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
305 * SOUP_SOCKET_REMOTE_ADDRESS:
307 * Alias for the #SoupSocket:remote-address property. (Address
308 * of remote end of socket.)
310 g_object_class_install_property (
311 object_class, PROP_REMOTE_ADDRESS,
312 g_param_spec_object (SOUP_SOCKET_REMOTE_ADDRESS,
314 "Address of remote end of socket",
316 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
318 * SoupSocket:non-blocking:
320 * Whether or not the socket uses non-blocking I/O.
322 * #SoupSocket's I/O methods are designed around the idea of
323 * using a single codepath for both synchronous and
324 * asynchronous I/O. If you want to read off a #SoupSocket,
325 * the "correct" way to do it is to call soup_socket_read() or
326 * soup_socket_read_until() repeatedly until you have read
327 * everything you want. If it returns %SOUP_SOCKET_WOULD_BLOCK
328 * at any point, stop reading and wait for it to emit the
329 * #SoupSocket::readable signal. Then go back to the
330 * reading-as-much-as-you-can loop. Likewise, for writing to a
331 * #SoupSocket, you should call soup_socket_write() either
332 * until you have written everything, or it returns
333 * %SOUP_SOCKET_WOULD_BLOCK (in which case you wait for
334 * #SoupSocket::writable and then go back into the loop).
336 * Code written this way will work correctly with both
337 * blocking and non-blocking sockets; blocking sockets will
338 * simply never return %SOUP_SOCKET_WOULD_BLOCK, and so the
339 * code that handles that case just won't get used for them.
342 * SOUP_SOCKET_FLAG_NONBLOCKING:
344 * Alias for the #SoupSocket:non-blocking property. (Whether
345 * or not the socket uses non-blocking I/O.)
347 g_object_class_install_property (
348 object_class, PROP_NON_BLOCKING,
349 g_param_spec_boolean (SOUP_SOCKET_FLAG_NONBLOCKING,
351 "Whether or not the socket uses non-blocking I/O",
355 * SOUP_SOCKET_IS_SERVER:
357 * Alias for the #SoupSocket:is-server property. (Whether or
358 * not the socket is a server socket.)
360 g_object_class_install_property (
361 object_class, PROP_IS_SERVER,
362 g_param_spec_boolean (SOUP_SOCKET_IS_SERVER,
364 "Whether or not the socket is a server socket",
368 * SOUP_SOCKET_SSL_CREDENTIALS:
370 * Alias for the #SoupSocket:ssl-creds property.
371 * (SSL credential information.)
373 /* For historical reasons, there's only a single property
374 * here, which is a GTlsDatabase for client sockets, and
375 * a GTlsCertificate for server sockets. Whee!
377 g_object_class_install_property (
378 object_class, PROP_SSL_CREDENTIALS,
379 g_param_spec_pointer (SOUP_SOCKET_SSL_CREDENTIALS,
381 "SSL credential information, passed from the session to the SSL implementation",
384 * SOUP_SOCKET_SSL_STRICT:
386 * Alias for the #SoupSocket:ssl-strict property.
388 g_object_class_install_property (
389 object_class, PROP_SSL_STRICT,
390 g_param_spec_boolean (SOUP_SOCKET_SSL_STRICT,
391 "Strictly validate SSL certificates",
392 "Whether certificate errors should be considered a connection error",
394 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
396 * SOUP_SOCKET_SSL_FALLBACK:
398 * Alias for the #SoupSocket:ssl-fallback property.
400 g_object_class_install_property (
401 object_class, PROP_SSL_FALLBACK,
402 g_param_spec_boolean (SOUP_SOCKET_SSL_FALLBACK,
404 "Use SSLv3 instead of TLS (client-side only)",
406 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
408 * SOUP_SOCKET_TRUSTED_CERTIFICATE:
410 * Alias for the #SoupSocket:trusted-certificate
413 g_object_class_install_property (
414 object_class, PROP_TRUSTED_CERTIFICATE,
415 g_param_spec_boolean (SOUP_SOCKET_TRUSTED_CERTIFICATE,
416 "Trusted Certificate",
417 "Whether the server certificate is trusted, if this is an SSL socket",
421 * SOUP_SOCKET_ASYNC_CONTEXT:
423 * Alias for the #SoupSocket:async-context property. (The
424 * socket's #GMainContext.)
426 g_object_class_install_property (
427 object_class, PROP_ASYNC_CONTEXT,
428 g_param_spec_pointer (SOUP_SOCKET_ASYNC_CONTEXT,
429 "Async GMainContext",
430 "The GMainContext to dispatch this socket's async I/O in",
431 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
434 * SOUP_SOCKET_USE_THREAD_CONTEXT:
436 * Alias for the #SoupSocket:use-thread-context property. (Use
437 * g_main_context_get_thread_default())
442 * SoupSocket:use-thread-context:
444 * Use g_main_context_get_thread_default().
448 g_object_class_install_property (
449 object_class, PROP_USE_THREAD_CONTEXT,
450 g_param_spec_boolean (SOUP_SOCKET_USE_THREAD_CONTEXT,
451 "Use thread context",
452 "Use g_main_context_get_thread_default",
454 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
457 * SOUP_SOCKET_TIMEOUT:
459 * Alias for the #SoupSocket:timeout property. (The timeout
460 * in seconds for blocking socket I/O operations.)
462 g_object_class_install_property (
463 object_class, PROP_TIMEOUT,
464 g_param_spec_uint (SOUP_SOCKET_TIMEOUT,
466 "Value in seconds to timeout a blocking I/O",
470 g_object_class_install_property (
471 object_class, PROP_CLEAN_DISPOSE,
472 g_param_spec_boolean ("clean-dispose",
474 "Warn on unclean dispose",
476 G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
478 * SOUP_SOCKET_TLS_CERTIFICATE:
480 * Alias for the #SoupSocket:tls-certificate
481 * property. Note that this property's value is only useful
482 * if the socket is for a TLS connection, and only reliable
483 * after some data has been transferred to or from it.
487 g_object_class_install_property (
488 object_class, PROP_TLS_CERTIFICATE,
489 g_param_spec_object (SOUP_SOCKET_TLS_CERTIFICATE,
491 "The peer's TLS certificate",
492 G_TYPE_TLS_CERTIFICATE,
495 * SOUP_SOCKET_TLS_ERRORS:
497 * Alias for the #SoupSocket:tls-errors
498 * property. Note that this property's value is only useful
499 * if the socket is for a TLS connection, and only reliable
500 * after some data has been transferred to or from it.
504 g_object_class_install_property (
505 object_class, PROP_TLS_ERRORS,
506 g_param_spec_flags (SOUP_SOCKET_TLS_ERRORS,
508 "Errors with the peer's TLS certificate",
509 G_TYPE_TLS_CERTIFICATE_FLAGS, 0,
515 finish_socket_setup (SoupSocketPrivate *priv)
521 priv->conn = (GIOStream *)g_socket_connection_factory_create_connection (priv->gsock);
523 priv->istream = G_POLLABLE_INPUT_STREAM (g_io_stream_get_input_stream (priv->conn));
525 priv->ostream = G_POLLABLE_OUTPUT_STREAM (g_io_stream_get_output_stream (priv->conn));
527 g_socket_set_timeout (priv->gsock, priv->timeout);
531 set_property (GObject *object, guint prop_id,
532 const GValue *value, GParamSpec *pspec)
534 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (object);
537 case PROP_LOCAL_ADDRESS:
538 priv->local_addr = (SoupAddress *)g_value_dup_object (value);
540 case PROP_REMOTE_ADDRESS:
541 priv->remote_addr = (SoupAddress *)g_value_dup_object (value);
543 case PROP_NON_BLOCKING:
544 priv->non_blocking = g_value_get_boolean (value);
546 case PROP_SSL_CREDENTIALS:
547 priv->ssl_creds = g_value_get_pointer (value);
549 case PROP_SSL_STRICT:
550 priv->ssl_strict = g_value_get_boolean (value);
552 case PROP_SSL_FALLBACK:
553 priv->ssl_fallback = g_value_get_boolean (value);
555 case PROP_ASYNC_CONTEXT:
556 priv->async_context = g_value_get_pointer (value);
557 if (priv->async_context)
558 g_main_context_ref (priv->async_context);
560 case PROP_USE_THREAD_CONTEXT:
561 priv->use_thread_context = g_value_get_boolean (value);
564 priv->timeout = g_value_get_uint (value);
566 g_socket_set_timeout (priv->gsock, priv->timeout);
568 case PROP_CLEAN_DISPOSE:
569 priv->clean_dispose = g_value_get_boolean (value);
572 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
578 get_property (GObject *object, guint prop_id,
579 GValue *value, GParamSpec *pspec)
581 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (object);
584 case PROP_LOCAL_ADDRESS:
585 g_value_set_object (value, soup_socket_get_local_address (SOUP_SOCKET (object)));
587 case PROP_REMOTE_ADDRESS:
588 g_value_set_object (value, soup_socket_get_remote_address (SOUP_SOCKET (object)));
590 case PROP_NON_BLOCKING:
591 g_value_set_boolean (value, priv->non_blocking);
594 g_value_set_boolean (value, priv->is_server);
596 case PROP_SSL_CREDENTIALS:
597 g_value_set_pointer (value, priv->ssl_creds);
599 case PROP_SSL_STRICT:
600 g_value_set_boolean (value, priv->ssl_strict);
602 case PROP_SSL_FALLBACK:
603 g_value_set_boolean (value, priv->ssl_fallback);
605 case PROP_TRUSTED_CERTIFICATE:
606 g_value_set_boolean (value, priv->tls_errors == 0);
608 case PROP_ASYNC_CONTEXT:
609 g_value_set_pointer (value, priv->async_context ? g_main_context_ref (priv->async_context) : NULL);
611 case PROP_USE_THREAD_CONTEXT:
612 g_value_set_boolean (value, priv->use_thread_context);
615 g_value_set_uint (value, priv->timeout);
617 case PROP_TLS_CERTIFICATE:
618 if (G_IS_TLS_CONNECTION (priv->conn))
619 g_value_set_object (value, g_tls_connection_get_peer_certificate (G_TLS_CONNECTION (priv->conn)));
621 g_value_set_object (value, NULL);
623 case PROP_TLS_ERRORS:
624 g_value_set_flags (value, priv->tls_errors);
627 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
635 * @optname1: name of first property to set (or %NULL)
636 * @...: value of @optname1, followed by additional property/value pairs
638 * Creates a new (disconnected) socket
640 * Return value: the new socket
643 soup_socket_new (const char *optname1, ...)
648 va_start (ap, optname1);
649 sock = (SoupSocket *)g_object_new_valist (SOUP_TYPE_SOCKET,
657 proxy_socket_client_event (GSocketClient *client,
658 GSocketClientEvent event,
659 GSocketConnectable *connectable,
660 GIOStream *connection,
663 SoupSocket *sock = user_data;
665 g_signal_emit (sock, signals[EVENT], 0,
670 socket_connected (SoupSocket *sock, GSocketConnection *conn, GError *error)
672 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
674 g_object_unref (priv->connect_cancel);
675 priv->connect_cancel = NULL;
678 if (error->domain == G_RESOLVER_ERROR) {
679 g_error_free (error);
680 return SOUP_STATUS_CANT_RESOLVE;
682 g_error_free (error);
683 return SOUP_STATUS_CANT_CONNECT;
687 priv->conn = (GIOStream *)conn;
688 priv->gsock = g_object_ref (g_socket_connection_get_socket (conn));
689 finish_socket_setup (priv);
691 return SOUP_STATUS_OK;
695 * SoupSocketCallback:
696 * @sock: the #SoupSocket
697 * @status: an HTTP status code indicating success or failure
698 * @user_data: the data passed to soup_socket_connect_async()
700 * The callback function passed to soup_socket_connect_async().
705 SoupSocketCallback callback;
707 } SoupSocketAsyncConnectData;
710 async_connected (GObject *client, GAsyncResult *result, gpointer data)
712 SoupSocketAsyncConnectData *sacd = data;
713 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sacd->sock);
714 GError *error = NULL;
715 GSocketConnection *conn;
718 if (priv->async_context && !priv->use_thread_context)
719 g_main_context_pop_thread_default (priv->async_context);
721 conn = g_socket_client_connect_finish (G_SOCKET_CLIENT (client),
723 status = socket_connected (sacd->sock, conn, error);
725 sacd->callback (sacd->sock, status, sacd->user_data);
726 g_object_unref (sacd->sock);
727 g_slice_free (SoupSocketAsyncConnectData, sacd);
731 * soup_socket_connect_async:
732 * @sock: a client #SoupSocket (which must not already be connected)
733 * @cancellable: a #GCancellable, or %NULL
734 * @callback: (scope async): callback to call after connecting
735 * @user_data: data to pass to @callback
737 * Begins asynchronously connecting to @sock's remote address. The
738 * socket will call @callback when it succeeds or fails (but not
739 * before returning from this function).
741 * If @cancellable is non-%NULL, it can be used to cancel the
742 * connection. @callback will still be invoked in this case, with a
743 * status of %SOUP_STATUS_CANCELLED.
746 soup_socket_connect_async (SoupSocket *sock, GCancellable *cancellable,
747 SoupSocketCallback callback, gpointer user_data)
749 SoupSocketPrivate *priv;
750 SoupSocketAsyncConnectData *sacd;
751 GSocketClient *client;
753 g_return_if_fail (SOUP_IS_SOCKET (sock));
754 priv = SOUP_SOCKET_GET_PRIVATE (sock);
755 g_return_if_fail (priv->remote_addr != NULL);
757 sacd = g_slice_new0 (SoupSocketAsyncConnectData);
758 sacd->sock = g_object_ref (sock);
759 sacd->callback = callback;
760 sacd->user_data = user_data;
762 priv->connect_cancel = cancellable ? g_object_ref (cancellable) : g_cancellable_new ();
764 if (priv->async_context && !priv->use_thread_context)
765 g_main_context_push_thread_default (priv->async_context);
767 client = g_socket_client_new ();
768 g_signal_connect (client, "event",
769 G_CALLBACK (proxy_socket_client_event), sock);
771 g_socket_client_set_timeout (client, priv->timeout);
772 g_socket_client_connect_async (client,
773 G_SOCKET_CONNECTABLE (priv->remote_addr),
774 priv->connect_cancel,
775 async_connected, sacd);
776 g_object_unref (client);
780 * soup_socket_connect_sync:
781 * @sock: a client #SoupSocket (which must not already be connected)
782 * @cancellable: a #GCancellable, or %NULL
784 * Attempt to synchronously connect @sock to its remote address.
786 * If @cancellable is non-%NULL, it can be used to cancel the
787 * connection, in which case soup_socket_connect_sync() will return
788 * %SOUP_STATUS_CANCELLED.
790 * Return value: a success or failure code.
793 soup_socket_connect_sync (SoupSocket *sock, GCancellable *cancellable)
795 SoupSocketPrivate *priv;
796 GSocketClient *client;
797 GSocketConnection *conn;
798 GError *error = NULL;
800 g_return_val_if_fail (SOUP_IS_SOCKET (sock), SOUP_STATUS_MALFORMED);
801 priv = SOUP_SOCKET_GET_PRIVATE (sock);
802 g_return_val_if_fail (!priv->is_server, SOUP_STATUS_MALFORMED);
803 g_return_val_if_fail (priv->gsock == NULL, SOUP_STATUS_MALFORMED);
804 g_return_val_if_fail (priv->remote_addr != NULL, SOUP_STATUS_MALFORMED);
807 g_object_ref (cancellable);
809 cancellable = g_cancellable_new ();
810 priv->connect_cancel = cancellable;
812 client = g_socket_client_new ();
813 g_signal_connect (client, "event",
814 G_CALLBACK (proxy_socket_client_event), sock);
816 g_socket_client_set_timeout (client, priv->timeout);
817 conn = g_socket_client_connect (client,
818 G_SOCKET_CONNECTABLE (priv->remote_addr),
819 priv->connect_cancel, &error);
820 g_object_unref (client);
822 return socket_connected (sock, conn, error);
826 soup_socket_get_fd (SoupSocket *sock)
828 g_return_val_if_fail (SOUP_IS_SOCKET (sock), -1);
830 return g_socket_get_fd (SOUP_SOCKET_GET_PRIVATE (sock)->gsock);
834 soup_socket_get_gsocket (SoupSocket *sock)
836 g_return_val_if_fail (SOUP_IS_SOCKET (sock), NULL);
838 return SOUP_SOCKET_GET_PRIVATE (sock)->gsock;
842 soup_socket_get_iostream (SoupSocket *sock)
844 g_return_val_if_fail (SOUP_IS_SOCKET (sock), NULL);
846 return SOUP_SOCKET_GET_PRIVATE (sock)->conn;
850 soup_socket_create_watch (SoupSocketPrivate *priv, GIOCondition cond,
851 GPollableSourceFunc callback, gpointer user_data,
852 GCancellable *cancellable)
855 GMainContext *async_context;
858 watch = g_pollable_input_stream_create_source (priv->istream, cancellable);
860 watch = g_pollable_output_stream_create_source (priv->ostream, cancellable);
861 g_source_set_callback (watch, (GSourceFunc)callback, user_data, NULL);
863 if (priv->use_thread_context)
864 async_context = g_main_context_get_thread_default ();
866 async_context = priv->async_context;
868 g_source_attach (watch, async_context);
869 g_source_unref (watch);
875 listen_watch (GObject *pollable, gpointer data)
877 SoupSocket *sock = data, *new;
878 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock), *new_priv;
881 new_gsock = g_socket_accept (priv->gsock, NULL, NULL);
885 new = g_object_new (SOUP_TYPE_SOCKET, NULL);
886 new_priv = SOUP_SOCKET_GET_PRIVATE (new);
887 new_priv->gsock = new_gsock;
888 if (priv->async_context)
889 new_priv->async_context = g_main_context_ref (priv->async_context);
890 new_priv->use_thread_context = priv->use_thread_context;
891 new_priv->non_blocking = priv->non_blocking;
892 new_priv->is_server = TRUE;
893 new_priv->ssl = priv->ssl;
895 new_priv->ssl_creds = priv->ssl_creds;
896 finish_socket_setup (new_priv);
898 if (new_priv->ssl_creds) {
899 if (!soup_socket_start_proxy_ssl (new, NULL, NULL)) {
900 g_object_unref (new);
905 g_signal_emit (sock, signals[NEW_CONNECTION], 0, new);
906 g_object_unref (new);
912 * soup_socket_listen:
913 * @sock: a server #SoupSocket (which must not already be connected or
916 * Makes @sock start listening on its local address. When connections
917 * come in, @sock will emit #SoupSocket::new_connection.
919 * Return value: whether or not @sock is now listening.
922 soup_socket_listen (SoupSocket *sock)
925 SoupSocketPrivate *priv;
926 GSocketAddress *addr;
928 g_return_val_if_fail (SOUP_IS_SOCKET (sock), FALSE);
929 priv = SOUP_SOCKET_GET_PRIVATE (sock);
930 g_return_val_if_fail (priv->gsock == NULL, FALSE);
931 g_return_val_if_fail (priv->local_addr != NULL, FALSE);
933 priv->is_server = TRUE;
935 /* @local_addr may have its port set to 0. So we intentionally
936 * don't store it in priv->local_addr, so that if the
937 * caller calls soup_socket_get_local_address() later, we'll
938 * have to make a new addr by calling getsockname(), which
939 * will have the right port number.
941 addr = soup_address_get_gsockaddr (priv->local_addr);
942 g_return_val_if_fail (addr != NULL, FALSE);
944 priv->gsock = g_socket_new (g_socket_address_get_family (addr),
945 G_SOCKET_TYPE_STREAM,
946 G_SOCKET_PROTOCOL_DEFAULT,
950 finish_socket_setup (priv);
953 if (!g_socket_bind (priv->gsock, addr, TRUE, NULL))
955 /* Force local_addr to be re-resolved now */
956 g_object_unref (priv->local_addr);
957 priv->local_addr = NULL;
960 if (!g_socket_listen (priv->gsock, NULL))
963 priv->watch_src = soup_socket_create_watch (priv, G_IO_IN,
966 g_object_unref (addr);
971 disconnect_internal (sock);
972 g_object_unref (addr);
978 soup_socket_peer_certificate_changed (GObject *conn, GParamSpec *pspec,
981 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
983 priv->tls_errors = g_tls_connection_get_peer_certificate_errors (G_TLS_CONNECTION (priv->conn));
985 g_object_notify (sock, "tls-certificate");
986 g_object_notify (sock, "tls-errors");
990 soup_socket_accept_certificate (GTlsConnection *conn, GTlsCertificate *cert,
991 GTlsCertificateFlags errors, gpointer sock)
997 * soup_socket_start_ssl:
999 * @cancellable: a #GCancellable
1001 * Starts using SSL on @socket.
1003 * Return value: success or failure
1006 soup_socket_start_ssl (SoupSocket *sock, GCancellable *cancellable)
1008 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
1010 return soup_socket_start_proxy_ssl (sock, soup_address_get_name (priv->remote_addr), cancellable);
1014 * soup_socket_start_proxy_ssl:
1016 * @ssl_host: hostname of the SSL server
1017 * @cancellable: a #GCancellable
1019 * Starts using SSL on @socket, expecting to find a host named
1022 * Return value: success or failure
1025 soup_socket_start_proxy_ssl (SoupSocket *sock, const char *ssl_host,
1026 GCancellable *cancellable)
1028 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
1029 GTlsBackend *backend = g_tls_backend_get_default ();
1031 if (G_IS_TLS_CONNECTION (priv->conn))
1036 if (!priv->is_server) {
1037 GTlsClientConnection *conn;
1038 GSocketConnectable *identity;
1040 identity = g_network_address_new (ssl_host, 0);
1041 conn = g_initable_new (g_tls_backend_get_client_connection_type (backend),
1043 "base-io-stream", priv->conn,
1044 "server-identity", identity,
1045 "database", priv->ssl_creds,
1046 "require-close-notify", FALSE,
1047 "use-ssl3", priv->ssl_fallback,
1049 g_object_unref (identity);
1054 g_object_unref (priv->conn);
1055 priv->conn = G_IO_STREAM (conn);
1057 if (!priv->ssl_strict) {
1058 g_signal_connect (conn, "accept-certificate",
1059 G_CALLBACK (soup_socket_accept_certificate),
1063 GTlsServerConnection *conn;
1065 conn = g_initable_new (g_tls_backend_get_server_connection_type (backend),
1067 "base-io-stream", priv->conn,
1068 "certificate", priv->ssl_creds,
1069 "use-system-certdb", FALSE,
1070 "require-close-notify", FALSE,
1075 g_object_unref (priv->conn);
1076 priv->conn = G_IO_STREAM (conn);
1079 g_signal_connect (priv->conn, "notify::peer-certificate",
1080 G_CALLBACK (soup_socket_peer_certificate_changed), sock);
1082 priv->istream = G_POLLABLE_INPUT_STREAM (g_io_stream_get_input_stream (priv->conn));
1083 priv->ostream = G_POLLABLE_OUTPUT_STREAM (g_io_stream_get_output_stream (priv->conn));
1088 soup_socket_handshake_sync (SoupSocket *sock,
1089 GCancellable *cancellable)
1091 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
1092 GError *error = NULL;
1095 if (g_tls_connection_handshake (G_TLS_CONNECTION (priv->conn),
1096 cancellable, &error))
1097 return SOUP_STATUS_OK;
1098 else if (!priv->ssl_fallback &&
1099 g_error_matches (error, G_TLS_ERROR, G_TLS_ERROR_NOT_TLS)) {
1100 g_error_free (error);
1101 return SOUP_STATUS_TLS_FAILED;
1103 g_error_free (error);
1104 return SOUP_STATUS_SSL_FAILED;
1109 handshake_async_ready (GObject *source, GAsyncResult *result, gpointer user_data)
1111 SoupSocketAsyncConnectData *data = user_data;
1112 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (data->sock);
1113 GError *error = NULL;
1116 if (priv->async_context && !priv->use_thread_context)
1117 g_main_context_pop_thread_default (priv->async_context);
1119 if (g_tls_connection_handshake_finish (G_TLS_CONNECTION (priv->conn),
1121 status = SOUP_STATUS_OK;
1122 else if (!priv->ssl_fallback &&
1123 g_error_matches (error, G_TLS_ERROR, G_TLS_ERROR_NOT_TLS))
1124 status = SOUP_STATUS_TLS_FAILED;
1126 status = SOUP_STATUS_SSL_FAILED;
1127 g_clear_error (&error);
1129 data->callback (data->sock, status, data->user_data);
1130 g_object_unref (data->sock);
1131 g_slice_free (SoupSocketAsyncConnectData, data);
1135 soup_socket_handshake_async (SoupSocket *sock,
1136 GCancellable *cancellable,
1137 SoupSocketCallback callback,
1140 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
1141 SoupSocketAsyncConnectData *data;
1145 data = g_slice_new (SoupSocketAsyncConnectData);
1146 data->sock = g_object_ref (sock);
1147 data->callback = callback;
1148 data->user_data = user_data;
1150 if (priv->async_context && !priv->use_thread_context)
1151 g_main_context_push_thread_default (priv->async_context);
1152 g_tls_connection_handshake_async (G_TLS_CONNECTION (priv->conn),
1154 cancellable, handshake_async_ready,
1159 * soup_socket_is_ssl:
1160 * @sock: a #SoupSocket
1162 * Tests if @sock is doing (or has attempted to do) SSL.
1164 * Return value: %TRUE if @sock has SSL credentials set
1167 soup_socket_is_ssl (SoupSocket *sock)
1169 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
1175 * soup_socket_disconnect:
1176 * @sock: a #SoupSocket
1178 * Disconnects @sock. Any further read or write attempts on it will
1182 soup_socket_disconnect (SoupSocket *sock)
1184 SoupSocketPrivate *priv;
1185 gboolean already_disconnected = FALSE;
1187 g_return_if_fail (SOUP_IS_SOCKET (sock));
1188 priv = SOUP_SOCKET_GET_PRIVATE (sock);
1190 if (priv->connect_cancel) {
1191 g_cancellable_cancel (priv->connect_cancel);
1193 } else if (g_mutex_trylock (&priv->iolock)) {
1195 disconnect_internal (sock);
1197 already_disconnected = TRUE;
1198 g_mutex_unlock (&priv->iolock);
1200 /* Another thread is currently doing IO, so
1201 * we can't close the socket. So just shutdown
1202 * the file descriptor to force the I/O to fail.
1203 * (It will actually be closed when the socket
1206 g_socket_shutdown (priv->gsock, TRUE, TRUE, NULL);
1209 if (already_disconnected)
1212 /* Keep ref around signals in case the object is unreferenced
1215 g_object_ref (sock);
1217 /* Give all readers a chance to notice the connection close */
1218 g_signal_emit (sock, signals[READABLE], 0);
1220 /* FIXME: can't disconnect until all data is read */
1222 /* Then let everyone know we're disconnected */
1223 g_signal_emit (sock, signals[DISCONNECTED], 0);
1225 g_object_unref (sock);
1229 * soup_socket_is_connected:
1230 * @sock: a #SoupSocket
1232 * Tests if @sock is connected to another host
1234 * Return value: %TRUE or %FALSE.
1237 soup_socket_is_connected (SoupSocket *sock)
1239 SoupSocketPrivate *priv;
1241 g_return_val_if_fail (SOUP_IS_SOCKET (sock), FALSE);
1242 priv = SOUP_SOCKET_GET_PRIVATE (sock);
1244 return priv->conn != NULL;
1248 * soup_socket_get_local_address:
1249 * @sock: a #SoupSocket
1251 * Returns the #SoupAddress corresponding to the local end of @sock.
1253 * Return value: (transfer none): the #SoupAddress
1256 soup_socket_get_local_address (SoupSocket *sock)
1258 SoupSocketPrivate *priv;
1260 g_return_val_if_fail (SOUP_IS_SOCKET (sock), NULL);
1261 priv = SOUP_SOCKET_GET_PRIVATE (sock);
1263 g_mutex_lock (&priv->addrlock);
1264 if (!priv->local_addr) {
1265 GSocketAddress *addr;
1266 struct sockaddr_storage sa;
1269 addr = g_socket_get_local_address (priv->gsock, NULL);
1270 sa_len = g_socket_address_get_native_size (addr);
1271 g_socket_address_to_native (addr, &sa, sa_len, NULL);
1272 priv->local_addr = soup_address_new_from_sockaddr ((struct sockaddr *)&sa, sa_len);
1273 g_object_unref (addr);
1275 g_mutex_unlock (&priv->addrlock);
1277 return priv->local_addr;
1281 * soup_socket_get_remote_address:
1282 * @sock: a #SoupSocket
1284 * Returns the #SoupAddress corresponding to the remote end of @sock.
1286 * Return value: (transfer none): the #SoupAddress
1289 soup_socket_get_remote_address (SoupSocket *sock)
1291 SoupSocketPrivate *priv;
1293 g_return_val_if_fail (SOUP_IS_SOCKET (sock), NULL);
1294 priv = SOUP_SOCKET_GET_PRIVATE (sock);
1296 g_mutex_lock (&priv->addrlock);
1297 if (!priv->remote_addr) {
1298 GSocketAddress *addr;
1299 struct sockaddr_storage sa;
1302 addr = g_socket_get_remote_address (priv->gsock, NULL);
1303 sa_len = g_socket_address_get_native_size (addr);
1304 g_socket_address_to_native (addr, &sa, sa_len, NULL);
1305 priv->remote_addr = soup_address_new_from_sockaddr ((struct sockaddr *)&sa, sa_len);
1306 g_object_unref (addr);
1308 g_mutex_unlock (&priv->addrlock);
1310 return priv->remote_addr;
1315 socket_read_watch (GObject *pollable, gpointer user_data)
1317 SoupSocket *sock = user_data;
1318 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
1320 priv->read_src = NULL;
1321 g_signal_emit (sock, signals[READABLE], 0);
1325 static SoupSocketIOStatus
1326 read_from_network (SoupSocket *sock, gpointer buffer, gsize len,
1327 gsize *nread, GCancellable *cancellable, GError **error)
1329 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
1330 GError *my_err = NULL;
1336 return SOUP_SOCKET_EOF;
1338 if (!priv->non_blocking) {
1339 my_nread = g_input_stream_read (G_INPUT_STREAM (priv->istream),
1341 cancellable, &my_err);
1343 my_nread = g_pollable_input_stream_read_nonblocking (
1344 priv->istream, buffer, len,
1345 cancellable, &my_err);
1349 g_clear_error (&my_err);
1351 return SOUP_SOCKET_OK;
1352 } else if (my_nread == 0) {
1353 g_clear_error (&my_err);
1355 return SOUP_SOCKET_EOF;
1356 } else if (g_error_matches (my_err, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) {
1357 g_clear_error (&my_err);
1358 if (!priv->read_src) {
1360 soup_socket_create_watch (priv, G_IO_IN,
1361 socket_read_watch, sock,
1364 return SOUP_SOCKET_WOULD_BLOCK;
1367 g_propagate_error (error, my_err);
1368 return SOUP_SOCKET_ERROR;
1371 static SoupSocketIOStatus
1372 read_from_buf (SoupSocket *sock, gpointer buffer, gsize len, gsize *nread)
1374 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
1375 GByteArray *read_buf = priv->read_buf;
1377 *nread = MIN (read_buf->len, len);
1378 memcpy (buffer, read_buf->data, *nread);
1380 if (*nread == read_buf->len) {
1381 g_byte_array_free (read_buf, TRUE);
1382 priv->read_buf = NULL;
1384 memmove (read_buf->data, read_buf->data + *nread,
1385 read_buf->len - *nread);
1386 g_byte_array_set_size (read_buf, read_buf->len - *nread);
1389 return SOUP_SOCKET_OK;
1393 * SoupSocketIOStatus:
1394 * @SOUP_SOCKET_OK: Success
1395 * @SOUP_SOCKET_WOULD_BLOCK: Cannot read/write any more at this time
1396 * @SOUP_SOCKET_EOF: End of file
1397 * @SOUP_SOCKET_ERROR: Other error
1399 * Return value from the #SoupSocket IO methods.
1405 * @buffer: buffer to read into
1406 * @len: size of @buffer in bytes
1407 * @nread: (out): on return, the number of bytes read into @buffer
1408 * @cancellable: a #GCancellable, or %NULL
1409 * @error: error pointer
1411 * Attempts to read up to @len bytes from @sock into @buffer. If some
1412 * data is successfully read, soup_socket_read() will return
1413 * %SOUP_SOCKET_OK, and *@nread will contain the number of bytes
1414 * actually read (which may be less than @len).
1416 * If @sock is non-blocking, and no data is available, the return
1417 * value will be %SOUP_SOCKET_WOULD_BLOCK. In this case, the caller
1418 * can connect to the #SoupSocket::readable signal to know when there
1419 * is more data to read. (NB: You MUST read all available data off the
1420 * socket first. #SoupSocket::readable is only emitted after
1421 * soup_socket_read() returns %SOUP_SOCKET_WOULD_BLOCK, and it is only
1422 * emitted once. See the documentation for #SoupSocket:non-blocking.)
1424 * Return value: a #SoupSocketIOStatus, as described above (or
1425 * %SOUP_SOCKET_EOF if the socket is no longer connected, or
1426 * %SOUP_SOCKET_ERROR on any other error, in which case @error will
1430 soup_socket_read (SoupSocket *sock, gpointer buffer, gsize len,
1431 gsize *nread, GCancellable *cancellable, GError **error)
1433 SoupSocketPrivate *priv;
1434 SoupSocketIOStatus status;
1436 g_return_val_if_fail (SOUP_IS_SOCKET (sock), SOUP_SOCKET_ERROR);
1437 g_return_val_if_fail (nread != NULL, SOUP_SOCKET_ERROR);
1439 priv = SOUP_SOCKET_GET_PRIVATE (sock);
1441 g_mutex_lock (&priv->iolock);
1443 status = read_from_buf (sock, buffer, len, nread);
1445 status = read_from_network (sock, buffer, len, nread, cancellable, error);
1446 g_mutex_unlock (&priv->iolock);
1452 * soup_socket_read_until:
1454 * @buffer: buffer to read into
1455 * @len: size of @buffer in bytes
1456 * @boundary: boundary to read until
1457 * @boundary_len: length of @boundary in bytes
1458 * @nread: (out): on return, the number of bytes read into @buffer
1459 * @got_boundary: on return, whether or not the data in @buffer
1460 * ends with the boundary string
1461 * @cancellable: a #GCancellable, or %NULL
1462 * @error: error pointer
1464 * Like soup_socket_read(), but reads no further than the first
1465 * occurrence of @boundary. (If the boundary is found, it will be
1466 * included in the returned data, and *@got_boundary will be set to
1467 * %TRUE.) Any data after the boundary will returned in future reads.
1469 * soup_socket_read_until() will almost always return fewer than @len
1470 * bytes: if the boundary is found, then it will only return the bytes
1471 * up until the end of the boundary, and if the boundary is not found,
1472 * then it will leave the last <literal>(boundary_len - 1)</literal>
1473 * bytes in its internal buffer, in case they form the start of the
1474 * boundary string. Thus, @len normally needs to be at least 1 byte
1475 * longer than @boundary_len if you want to make any progress at all.
1477 * Return value: as for soup_socket_read()
1480 soup_socket_read_until (SoupSocket *sock, gpointer buffer, gsize len,
1481 gconstpointer boundary, gsize boundary_len,
1482 gsize *nread, gboolean *got_boundary,
1483 GCancellable *cancellable, GError **error)
1485 SoupSocketPrivate *priv;
1486 SoupSocketIOStatus status;
1487 GByteArray *read_buf;
1488 guint match_len, prev_len;
1491 g_return_val_if_fail (SOUP_IS_SOCKET (sock), SOUP_SOCKET_ERROR);
1492 g_return_val_if_fail (nread != NULL, SOUP_SOCKET_ERROR);
1493 g_return_val_if_fail (len >= boundary_len, SOUP_SOCKET_ERROR);
1495 priv = SOUP_SOCKET_GET_PRIVATE (sock);
1497 g_mutex_lock (&priv->iolock);
1499 *got_boundary = FALSE;
1501 if (!priv->read_buf)
1502 priv->read_buf = g_byte_array_new ();
1503 read_buf = priv->read_buf;
1505 if (read_buf->len < boundary_len) {
1506 prev_len = read_buf->len;
1507 g_byte_array_set_size (read_buf, len);
1508 status = read_from_network (sock,
1509 read_buf->data + prev_len,
1510 len - prev_len, nread, cancellable, error);
1511 read_buf->len = prev_len + *nread;
1513 if (status != SOUP_SOCKET_OK) {
1514 g_mutex_unlock (&priv->iolock);
1519 /* Scan for the boundary */
1520 end = read_buf->data + read_buf->len;
1521 for (p = read_buf->data; p <= end - boundary_len; p++) {
1522 if (!memcmp (p, boundary, boundary_len)) {
1524 *got_boundary = TRUE;
1529 /* Return everything up to 'p' (which is either just after the
1530 * boundary, or @boundary_len - 1 bytes before the end of the
1533 match_len = p - read_buf->data;
1534 status = read_from_buf (sock, buffer, MIN (len, match_len), nread);
1536 g_mutex_unlock (&priv->iolock);
1541 socket_write_watch (GObject *pollable, gpointer user_data)
1543 SoupSocket *sock = user_data;
1544 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
1546 priv->write_src = NULL;
1547 g_signal_emit (sock, signals[WRITABLE], 0);
1552 * soup_socket_write:
1554 * @buffer: data to write
1555 * @len: size of @buffer, in bytes
1556 * @nwrote: (out): on return, number of bytes written
1557 * @cancellable: a #GCancellable, or %NULL
1558 * @error: error pointer
1560 * Attempts to write @len bytes from @buffer to @sock. If some data is
1561 * successfully written, the return status will be %SOUP_SOCKET_OK,
1562 * and *@nwrote will contain the number of bytes actually written
1563 * (which may be less than @len).
1565 * If @sock is non-blocking, and no data could be written right away,
1566 * the return value will be %SOUP_SOCKET_WOULD_BLOCK. In this case,
1567 * the caller can connect to the #SoupSocket::writable signal to know
1568 * when more data can be written. (NB: #SoupSocket::writable is only
1569 * emitted after soup_socket_write() returns %SOUP_SOCKET_WOULD_BLOCK,
1570 * and it is only emitted once. See the documentation for
1571 * #SoupSocket:non-blocking.)
1573 * Return value: a #SoupSocketIOStatus, as described above (or
1574 * %SOUP_SOCKET_EOF or %SOUP_SOCKET_ERROR. @error will be set if the
1575 * return value is %SOUP_SOCKET_ERROR.)
1578 soup_socket_write (SoupSocket *sock, gconstpointer buffer,
1579 gsize len, gsize *nwrote,
1580 GCancellable *cancellable, GError **error)
1582 SoupSocketPrivate *priv;
1583 GError *my_err = NULL;
1586 g_return_val_if_fail (SOUP_IS_SOCKET (sock), SOUP_SOCKET_ERROR);
1587 g_return_val_if_fail (nwrote != NULL, SOUP_SOCKET_ERROR);
1589 priv = SOUP_SOCKET_GET_PRIVATE (sock);
1591 g_mutex_lock (&priv->iolock);
1594 g_mutex_unlock (&priv->iolock);
1595 return SOUP_SOCKET_EOF;
1597 if (priv->write_src) {
1598 g_mutex_unlock (&priv->iolock);
1599 return SOUP_SOCKET_WOULD_BLOCK;
1602 if (!priv->non_blocking) {
1603 my_nwrote = g_output_stream_write (G_OUTPUT_STREAM (priv->ostream),
1605 cancellable, &my_err);
1607 my_nwrote = g_pollable_output_stream_write_nonblocking (
1608 priv->ostream, buffer, len,
1609 cancellable, &my_err);
1612 if (my_nwrote > 0) {
1613 g_mutex_unlock (&priv->iolock);
1614 g_clear_error (&my_err);
1615 *nwrote = my_nwrote;
1616 return SOUP_SOCKET_OK;
1619 if (g_error_matches (my_err, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) {
1620 g_mutex_unlock (&priv->iolock);
1621 g_clear_error (&my_err);
1624 soup_socket_create_watch (priv,
1626 socket_write_watch, sock, cancellable);
1627 return SOUP_SOCKET_WOULD_BLOCK;
1630 g_mutex_unlock (&priv->iolock);
1631 g_propagate_error (error, my_err);
1632 return SOUP_SOCKET_ERROR;