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"
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)
45 static guint signals[LAST_SIGNAL] = { 0 };
58 PROP_TRUSTED_CERTIFICATE,
67 SoupAddress *local_addr, *remote_addr;
70 GPollableInputStream *istream;
71 GPollableOutputStream *ostream;
72 GTlsCertificateFlags tls_errors;
77 guint ssl_ca_in_creds:1;
78 guint clean_dispose:1;
81 GMainContext *async_context;
83 GSource *read_src, *write_src;
86 GMutex *iolock, *addrlock;
89 GCancellable *connect_cancel;
91 #define SOUP_SOCKET_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SOUP_TYPE_SOCKET, SoupSocketPrivate))
93 static void set_property (GObject *object, guint prop_id,
94 const GValue *value, GParamSpec *pspec);
95 static void get_property (GObject *object, guint prop_id,
96 GValue *value, GParamSpec *pspec);
98 static void soup_socket_peer_certificate_changed (GObject *conn,
103 soup_socket_init (SoupSocket *sock)
105 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
107 priv->non_blocking = TRUE;
108 priv->addrlock = g_mutex_new ();
109 priv->iolock = g_mutex_new ();
113 disconnect_internal (SoupSocket *sock)
115 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
118 g_socket_close (priv->gsock, NULL);
119 g_object_unref (priv->gsock);
123 if (G_IS_TLS_CONNECTION (priv->conn))
124 g_signal_handlers_disconnect_by_func (priv->conn, soup_socket_peer_certificate_changed, sock);
125 g_object_unref (priv->conn);
127 priv->istream = NULL;
128 priv->ostream = NULL;
131 if (priv->read_src) {
132 g_source_destroy (priv->read_src);
133 priv->read_src = NULL;
135 if (priv->write_src) {
136 g_source_destroy (priv->write_src);
137 priv->write_src = NULL;
142 finalize (GObject *object)
144 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (object);
146 if (priv->connect_cancel) {
147 if (priv->clean_dispose)
148 g_warning ("Disposing socket %p during connect", object);
149 g_object_unref (priv->connect_cancel);
152 if (priv->clean_dispose)
153 g_warning ("Disposing socket %p while still connected", object);
154 disconnect_internal (SOUP_SOCKET (object));
157 if (priv->local_addr)
158 g_object_unref (priv->local_addr);
159 if (priv->remote_addr)
160 g_object_unref (priv->remote_addr);
162 if (priv->watch_src) {
163 if (priv->clean_dispose && !priv->is_server)
164 g_warning ("Disposing socket %p during async op", object);
165 g_source_destroy (priv->watch_src);
167 if (priv->async_context)
168 g_main_context_unref (priv->async_context);
171 g_byte_array_free (priv->read_buf, TRUE);
173 g_mutex_free (priv->addrlock);
174 g_mutex_free (priv->iolock);
176 G_OBJECT_CLASS (soup_socket_parent_class)->finalize (object);
180 soup_socket_class_init (SoupSocketClass *socket_class)
182 GObjectClass *object_class = G_OBJECT_CLASS (socket_class);
184 g_type_class_add_private (socket_class, sizeof (SoupSocketPrivate));
186 /* virtual method override */
187 object_class->finalize = finalize;
188 object_class->set_property = set_property;
189 object_class->get_property = get_property;
194 * SoupSocket::readable:
197 * Emitted when an async socket is readable. See
198 * soup_socket_read(), soup_socket_read_until() and
199 * #SoupSocket:non-blocking.
202 g_signal_new ("readable",
203 G_OBJECT_CLASS_TYPE (object_class),
205 G_STRUCT_OFFSET (SoupSocketClass, readable),
207 soup_marshal_NONE__NONE,
211 * SoupSocket::writable:
214 * Emitted when an async socket is writable. See
215 * soup_socket_write() and #SoupSocket:non-blocking.
218 g_signal_new ("writable",
219 G_OBJECT_CLASS_TYPE (object_class),
221 G_STRUCT_OFFSET (SoupSocketClass, writable),
223 soup_marshal_NONE__NONE,
227 * SoupSocket::disconnected:
230 * Emitted when the socket is disconnected, for whatever
233 signals[DISCONNECTED] =
234 g_signal_new ("disconnected",
235 G_OBJECT_CLASS_TYPE (object_class),
237 G_STRUCT_OFFSET (SoupSocketClass, disconnected),
239 soup_marshal_NONE__NONE,
243 * SoupSocket::new-connection:
245 * @new: the new socket
247 * Emitted when a listening socket (set up with
248 * soup_socket_listen()) receives a new connection.
250 * You must ref the @new if you want to keep it; otherwise it
251 * will be destroyed after the signal is emitted.
253 signals[NEW_CONNECTION] =
254 g_signal_new ("new_connection",
255 G_OBJECT_CLASS_TYPE (object_class),
257 G_STRUCT_OFFSET (SoupSocketClass, new_connection),
259 soup_marshal_NONE__OBJECT,
265 * SOUP_SOCKET_LOCAL_ADDRESS:
267 * Alias for the #SoupSocket:local-address property. (Address
268 * of local end of socket.)
270 g_object_class_install_property (
271 object_class, PROP_LOCAL_ADDRESS,
272 g_param_spec_object (SOUP_SOCKET_LOCAL_ADDRESS,
274 "Address of local end of socket",
276 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
278 * SOUP_SOCKET_REMOTE_ADDRESS:
280 * Alias for the #SoupSocket:remote-address property. (Address
281 * of remote end of socket.)
283 g_object_class_install_property (
284 object_class, PROP_REMOTE_ADDRESS,
285 g_param_spec_object (SOUP_SOCKET_REMOTE_ADDRESS,
287 "Address of remote end of socket",
289 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
291 * SoupSocket:non-blocking:
293 * Whether or not the socket uses non-blocking I/O.
295 * #SoupSocket's I/O methods are designed around the idea of
296 * using a single codepath for both synchronous and
297 * asynchronous I/O. If you want to read off a #SoupSocket,
298 * the "correct" way to do it is to call soup_socket_read() or
299 * soup_socket_read_until() repeatedly until you have read
300 * everything you want. If it returns %SOUP_SOCKET_WOULD_BLOCK
301 * at any point, stop reading and wait for it to emit the
302 * #SoupSocket::readable signal. Then go back to the
303 * reading-as-much-as-you-can loop. Likewise, for writing to a
304 * #SoupSocket, you should call soup_socket_write() either
305 * until you have written everything, or it returns
306 * %SOUP_SOCKET_WOULD_BLOCK (in which case you wait for
307 * #SoupSocket::writable and then go back into the loop).
309 * Code written this way will work correctly with both
310 * blocking and non-blocking sockets; blocking sockets will
311 * simply never return %SOUP_SOCKET_WOULD_BLOCK, and so the
312 * code that handles that case just won't get used for them.
315 * SOUP_SOCKET_FLAG_NONBLOCKING:
317 * Alias for the #SoupSocket:non-blocking property. (Whether
318 * or not the socket uses non-blocking I/O.)
320 g_object_class_install_property (
321 object_class, PROP_NON_BLOCKING,
322 g_param_spec_boolean (SOUP_SOCKET_FLAG_NONBLOCKING,
324 "Whether or not the socket uses non-blocking I/O",
328 * SOUP_SOCKET_IS_SERVER:
330 * Alias for the #SoupSocket:is-server property. (Whether or
331 * not the socket is a server socket.)
333 g_object_class_install_property (
334 object_class, PROP_IS_SERVER,
335 g_param_spec_boolean (SOUP_SOCKET_IS_SERVER,
337 "Whether or not the socket is a server socket",
341 * SOUP_SOCKET_SSL_CREDENTIALS:
343 * Alias for the #SoupSocket:ssl-credentials property.
344 * (SSL credential information.)
346 g_object_class_install_property (
347 object_class, PROP_SSL_CREDENTIALS,
348 g_param_spec_pointer (SOUP_SOCKET_SSL_CREDENTIALS,
350 "SSL credential information, passed from the session to the SSL implementation",
353 * SOUP_SOCKET_SSL_STRICT:
355 * Alias for the #SoupSocket:ignore-ssl-cert-errors property.
357 g_object_class_install_property (
358 object_class, PROP_SSL_STRICT,
359 g_param_spec_boolean (SOUP_SOCKET_SSL_STRICT,
360 "Strictly validate SSL certificates",
361 "Whether certificate errors should be considered a connection error",
363 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
365 * SOUP_SOCKET_TRUSTED_CERTIFICATE:
367 * Alias for the #SoupSocket:trusted-certificate
370 g_object_class_install_property (
371 object_class, PROP_TRUSTED_CERTIFICATE,
372 g_param_spec_boolean (SOUP_SOCKET_TRUSTED_CERTIFICATE,
373 "Trusted Certificate",
374 "Whether the server certificate is trusted, if this is an SSL socket",
378 * SOUP_SOCKET_ASYNC_CONTEXT:
380 * Alias for the #SoupSocket:async-context property. (The
381 * socket's #GMainContext.)
383 g_object_class_install_property (
384 object_class, PROP_ASYNC_CONTEXT,
385 g_param_spec_pointer (SOUP_SOCKET_ASYNC_CONTEXT,
386 "Async GMainContext",
387 "The GMainContext to dispatch this socket's async I/O in",
388 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
391 * SOUP_SOCKET_TIMEOUT:
393 * Alias for the #SoupSocket:timeout property. (The timeout
394 * in seconds for blocking socket I/O operations.)
396 g_object_class_install_property (
397 object_class, PROP_TIMEOUT,
398 g_param_spec_uint (SOUP_SOCKET_TIMEOUT,
400 "Value in seconds to timeout a blocking I/O",
404 g_object_class_install_property (
405 object_class, PROP_CLEAN_DISPOSE,
406 g_param_spec_boolean ("clean-dispose",
408 "Warn on unclean dispose",
410 G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
412 * SOUP_SOCKET_TLS_CERTIFICATE:
414 * Alias for the #SoupSocket:tls-certificate
415 * property. Note that this property's value is only useful
416 * if the socket is for a TLS connection, and only reliable
417 * after some data has been transferred to or from it.
421 g_object_class_install_property (
422 object_class, PROP_TLS_CERTIFICATE,
423 g_param_spec_object (SOUP_SOCKET_TLS_CERTIFICATE,
425 "The peer's TLS certificate",
426 G_TYPE_TLS_CERTIFICATE,
429 * SOUP_SOCKET_TLS_ERRORS:
431 * Alias for the #SoupSocket:tls-errors
432 * property. Note that this property's value is only useful
433 * if the socket is for a TLS connection, and only reliable
434 * after some data has been transferred to or from it.
438 g_object_class_install_property (
439 object_class, PROP_TLS_ERRORS,
440 g_param_spec_flags (SOUP_SOCKET_TLS_ERRORS,
442 "Errors with the peer's TLS certificate",
443 G_TYPE_TLS_CERTIFICATE_FLAGS, 0,
449 finish_socket_setup (SoupSocketPrivate *priv)
455 priv->conn = (GIOStream *)g_socket_connection_factory_create_connection (priv->gsock);
457 priv->istream = G_POLLABLE_INPUT_STREAM (g_io_stream_get_input_stream (priv->conn));
459 priv->ostream = G_POLLABLE_OUTPUT_STREAM (g_io_stream_get_output_stream (priv->conn));
461 g_socket_set_timeout (priv->gsock, priv->timeout);
465 set_property (GObject *object, guint prop_id,
466 const GValue *value, GParamSpec *pspec)
468 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (object);
471 case PROP_LOCAL_ADDRESS:
472 priv->local_addr = (SoupAddress *)g_value_dup_object (value);
474 case PROP_REMOTE_ADDRESS:
475 priv->remote_addr = (SoupAddress *)g_value_dup_object (value);
477 case PROP_NON_BLOCKING:
478 priv->non_blocking = g_value_get_boolean (value);
480 case PROP_SSL_CREDENTIALS:
481 priv->ssl_creds = g_value_get_pointer (value);
483 case PROP_SSL_STRICT:
484 priv->ssl_strict = g_value_get_boolean (value);
486 case PROP_ASYNC_CONTEXT:
487 priv->async_context = g_value_get_pointer (value);
488 if (priv->async_context)
489 g_main_context_ref (priv->async_context);
492 priv->timeout = g_value_get_uint (value);
494 g_socket_set_timeout (priv->gsock, priv->timeout);
496 case PROP_CLEAN_DISPOSE:
497 priv->clean_dispose = g_value_get_boolean (value);
500 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
506 get_property (GObject *object, guint prop_id,
507 GValue *value, GParamSpec *pspec)
509 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (object);
512 case PROP_LOCAL_ADDRESS:
513 g_value_set_object (value, soup_socket_get_local_address (SOUP_SOCKET (object)));
515 case PROP_REMOTE_ADDRESS:
516 g_value_set_object (value, soup_socket_get_remote_address (SOUP_SOCKET (object)));
518 case PROP_NON_BLOCKING:
519 g_value_set_boolean (value, priv->non_blocking);
522 g_value_set_boolean (value, priv->is_server);
524 case PROP_SSL_CREDENTIALS:
525 g_value_set_pointer (value, priv->ssl_creds);
527 case PROP_SSL_STRICT:
528 g_value_set_boolean (value, priv->ssl_strict);
530 case PROP_TRUSTED_CERTIFICATE:
531 g_value_set_boolean (value, priv->tls_errors == 0);
533 case PROP_ASYNC_CONTEXT:
534 g_value_set_pointer (value, priv->async_context ? g_main_context_ref (priv->async_context) : NULL);
537 g_value_set_uint (value, priv->timeout);
539 case PROP_TLS_CERTIFICATE:
540 if (G_IS_TLS_CONNECTION (priv->conn))
541 g_value_set_object (value, g_tls_connection_get_peer_certificate (G_TLS_CONNECTION (priv->conn)));
543 g_value_set_object (value, NULL);
545 case PROP_TLS_ERRORS:
546 g_value_set_flags (value, priv->tls_errors);
549 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
557 * @optname1: name of first property to set (or %NULL)
558 * @...: value of @optname1, followed by additional property/value pairs
560 * Creates a new (disconnected) socket
562 * Return value: the new socket
565 soup_socket_new (const char *optname1, ...)
570 va_start (ap, optname1);
571 sock = (SoupSocket *)g_object_new_valist (SOUP_TYPE_SOCKET,
579 socket_connected (SoupSocket *sock, GSocketConnection *conn, GError *error)
581 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
583 g_object_unref (priv->connect_cancel);
584 priv->connect_cancel = NULL;
587 if (error->domain == G_RESOLVER_ERROR) {
588 g_error_free (error);
589 return SOUP_STATUS_CANT_RESOLVE;
591 g_error_free (error);
592 return SOUP_STATUS_CANT_CONNECT;
596 priv->conn = (GIOStream *)conn;
597 priv->gsock = g_object_ref (g_socket_connection_get_socket (conn));
598 finish_socket_setup (priv);
600 return SOUP_STATUS_OK;
604 * SoupSocketCallback:
605 * @sock: the #SoupSocket
606 * @status: an HTTP status code indicating success or failure
607 * @user_data: the data passed to soup_socket_connect_async()
609 * The callback function passed to soup_socket_connect_async().
614 SoupSocketCallback callback;
616 } SoupSocketAsyncConnectData;
619 async_connected (GObject *client, GAsyncResult *result, gpointer data)
621 SoupSocketAsyncConnectData *sacd = data;
622 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sacd->sock);
623 GError *error = NULL;
624 GSocketConnection *conn;
627 if (priv->async_context)
628 g_main_context_pop_thread_default (priv->async_context);
630 conn = g_socket_client_connect_finish (G_SOCKET_CLIENT (client),
632 status = socket_connected (sacd->sock, conn, error);
634 sacd->callback (sacd->sock, status, sacd->user_data);
635 g_object_unref (sacd->sock);
636 g_slice_free (SoupSocketAsyncConnectData, sacd);
640 * soup_socket_connect_async:
641 * @sock: a client #SoupSocket (which must not already be connected)
642 * @cancellable: a #GCancellable, or %NULL
643 * @callback: (scope async): callback to call after connecting
644 * @user_data: data to pass to @callback
646 * Begins asynchronously connecting to @sock's remote address. The
647 * socket will call @callback when it succeeds or fails (but not
648 * before returning from this function).
650 * If @cancellable is non-%NULL, it can be used to cancel the
651 * connection. @callback will still be invoked in this case, with a
652 * status of %SOUP_STATUS_CANCELLED.
655 soup_socket_connect_async (SoupSocket *sock, GCancellable *cancellable,
656 SoupSocketCallback callback, gpointer user_data)
658 SoupSocketPrivate *priv;
659 SoupSocketAsyncConnectData *sacd;
660 GSocketClient *client;
662 g_return_if_fail (SOUP_IS_SOCKET (sock));
663 priv = SOUP_SOCKET_GET_PRIVATE (sock);
664 g_return_if_fail (priv->remote_addr != NULL);
666 sacd = g_slice_new0 (SoupSocketAsyncConnectData);
667 sacd->sock = g_object_ref (sock);
668 sacd->callback = callback;
669 sacd->user_data = user_data;
671 priv->connect_cancel = cancellable ? g_object_ref (cancellable) : g_cancellable_new ();
673 if (priv->async_context)
674 g_main_context_push_thread_default (priv->async_context);
676 client = g_socket_client_new ();
678 g_socket_client_set_timeout (client, priv->timeout);
679 g_socket_client_connect_async (client,
680 G_SOCKET_CONNECTABLE (priv->remote_addr),
681 priv->connect_cancel,
682 async_connected, sacd);
683 g_object_unref (client);
687 * soup_socket_connect_sync:
688 * @sock: a client #SoupSocket (which must not already be connected)
689 * @cancellable: a #GCancellable, or %NULL
691 * Attempt to synchronously connect @sock to its remote address.
693 * If @cancellable is non-%NULL, it can be used to cancel the
694 * connection, in which case soup_socket_connect_sync() will return
695 * %SOUP_STATUS_CANCELLED.
697 * Return value: a success or failure code.
700 soup_socket_connect_sync (SoupSocket *sock, GCancellable *cancellable)
702 SoupSocketPrivate *priv;
703 GSocketClient *client;
704 GSocketConnection *conn;
705 GError *error = NULL;
707 g_return_val_if_fail (SOUP_IS_SOCKET (sock), SOUP_STATUS_MALFORMED);
708 priv = SOUP_SOCKET_GET_PRIVATE (sock);
709 g_return_val_if_fail (!priv->is_server, SOUP_STATUS_MALFORMED);
710 g_return_val_if_fail (priv->gsock == NULL, SOUP_STATUS_MALFORMED);
711 g_return_val_if_fail (priv->remote_addr != NULL, SOUP_STATUS_MALFORMED);
714 g_object_ref (cancellable);
716 cancellable = g_cancellable_new ();
717 priv->connect_cancel = cancellable;
719 client = g_socket_client_new ();
721 g_socket_client_set_timeout (client, priv->timeout);
722 conn = g_socket_client_connect (client,
723 G_SOCKET_CONNECTABLE (priv->remote_addr),
724 priv->connect_cancel, &error);
725 g_object_unref (client);
727 return socket_connected (sock, conn, error);
731 soup_socket_get_fd (SoupSocket *sock)
733 g_return_val_if_fail (SOUP_IS_SOCKET (sock), -1);
735 return g_socket_get_fd (SOUP_SOCKET_GET_PRIVATE (sock)->gsock);
739 soup_socket_create_watch (SoupSocketPrivate *priv, GIOCondition cond,
740 GPollableSourceFunc callback, gpointer user_data,
741 GCancellable *cancellable)
746 watch = g_pollable_input_stream_create_source (priv->istream, cancellable);
748 watch = g_pollable_output_stream_create_source (priv->ostream, cancellable);
749 g_source_set_callback (watch, (GSourceFunc)callback, user_data, NULL);
750 g_source_attach (watch, priv->async_context);
751 g_source_unref (watch);
757 listen_watch (GObject *pollable, gpointer data)
759 SoupSocket *sock = data, *new;
760 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock), *new_priv;
763 new_gsock = g_socket_accept (priv->gsock, NULL, NULL);
767 new = g_object_new (SOUP_TYPE_SOCKET, NULL);
768 new_priv = SOUP_SOCKET_GET_PRIVATE (new);
769 new_priv->gsock = new_gsock;
770 if (priv->async_context)
771 new_priv->async_context = g_main_context_ref (priv->async_context);
772 new_priv->non_blocking = priv->non_blocking;
773 new_priv->is_server = TRUE;
775 new_priv->ssl_creds = priv->ssl_creds;
776 finish_socket_setup (new_priv);
778 if (new_priv->ssl_creds) {
779 if (!soup_socket_start_proxy_ssl (new, NULL, NULL)) {
780 g_object_unref (new);
785 g_signal_emit (sock, signals[NEW_CONNECTION], 0, new);
786 g_object_unref (new);
792 * soup_socket_listen:
793 * @sock: a server #SoupSocket (which must not already be connected or
796 * Makes @sock start listening on its local address. When connections
797 * come in, @sock will emit %new_connection.
799 * Return value: whether or not @sock is now listening.
802 soup_socket_listen (SoupSocket *sock)
805 SoupSocketPrivate *priv;
806 GSocketAddress *addr;
808 g_return_val_if_fail (SOUP_IS_SOCKET (sock), FALSE);
809 priv = SOUP_SOCKET_GET_PRIVATE (sock);
810 g_return_val_if_fail (priv->gsock == NULL, FALSE);
811 g_return_val_if_fail (priv->local_addr != NULL, FALSE);
813 priv->is_server = TRUE;
815 /* @local_addr may have its port set to 0. So we intentionally
816 * don't store it in priv->local_addr, so that if the
817 * caller calls soup_socket_get_local_address() later, we'll
818 * have to make a new addr by calling getsockname(), which
819 * will have the right port number.
821 addr = soup_address_get_gsockaddr (priv->local_addr);
822 g_return_val_if_fail (addr != NULL, FALSE);
824 priv->gsock = g_socket_new (g_socket_address_get_family (addr),
825 G_SOCKET_TYPE_STREAM,
826 G_SOCKET_PROTOCOL_DEFAULT,
830 finish_socket_setup (priv);
833 if (!g_socket_bind (priv->gsock, addr, TRUE, NULL))
835 /* Force local_addr to be re-resolved now */
836 g_object_unref (priv->local_addr);
837 priv->local_addr = NULL;
840 if (!g_socket_listen (priv->gsock, NULL))
843 priv->watch_src = soup_socket_create_watch (priv, G_IO_IN,
850 disconnect_internal (sock);
856 soup_socket_peer_certificate_changed (GObject *conn, GParamSpec *pspec,
859 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
861 priv->tls_errors = g_tls_connection_get_peer_certificate_errors (G_TLS_CONNECTION (priv->conn));
862 if (priv->ssl_ca_in_creds)
863 priv->tls_errors &= ~G_TLS_CERTIFICATE_UNKNOWN_CA;
865 g_object_notify (sock, "tls-certificate");
866 g_object_notify (sock, "tls-errors");
870 soup_socket_accept_certificate (GTlsConnection *conn, GTlsCertificate *cert,
871 GTlsCertificateFlags errors, gpointer sock)
873 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
875 if (soup_ssl_credentials_verify_certificate (priv->ssl_creds,
877 priv->ssl_ca_in_creds = TRUE;
881 return !priv->ssl_strict;
885 * soup_socket_start_ssl:
887 * @cancellable: a #GCancellable
889 * Starts using SSL on @socket.
891 * Return value: success or failure
894 soup_socket_start_ssl (SoupSocket *sock, GCancellable *cancellable)
896 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
898 return soup_socket_start_proxy_ssl (sock, soup_address_get_name (priv->remote_addr), cancellable);
902 * soup_socket_start_proxy_ssl:
904 * @ssl_host: hostname of the SSL server
905 * @cancellable: a #GCancellable
907 * Starts using SSL on @socket, expecting to find a host named
910 * Return value: success or failure
913 soup_socket_start_proxy_ssl (SoupSocket *sock, const char *ssl_host,
914 GCancellable *cancellable)
916 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
917 GTlsBackend *backend = g_tls_backend_get_default ();
919 if (G_IS_TLS_CONNECTION (priv->conn))
921 if (!priv->ssl_creds)
924 if (!priv->is_server) {
925 GTlsClientConnection *conn;
926 GSocketConnectable *identity;
928 identity = g_network_address_new (ssl_host, 0);
929 conn = g_initable_new (g_tls_backend_get_client_connection_type (backend),
931 "base-io-stream", priv->conn,
932 "server-identity", identity,
933 "use-system-certdb", FALSE,
934 "require-close-notify", FALSE,
937 g_object_unref (identity);
942 g_object_unref (priv->conn);
943 priv->conn = G_IO_STREAM (conn);
945 g_signal_connect (conn, "accept-certificate",
946 G_CALLBACK (soup_socket_accept_certificate),
949 GTlsServerConnection *conn;
951 conn = g_initable_new (g_tls_backend_get_server_connection_type (backend),
953 "base-io-stream", priv->conn,
954 "certificate", soup_ssl_credentials_get_certificate (priv->ssl_creds),
955 "use-system-certdb", FALSE,
956 "require-close-notify", FALSE,
961 g_object_unref (priv->conn);
962 priv->conn = G_IO_STREAM (conn);
965 priv->ssl_ca_in_creds = FALSE;
966 g_signal_connect (priv->conn, "notify::peer-certificate",
967 G_CALLBACK (soup_socket_peer_certificate_changed), sock);
969 priv->istream = G_POLLABLE_INPUT_STREAM (g_io_stream_get_input_stream (priv->conn));
970 priv->ostream = G_POLLABLE_OUTPUT_STREAM (g_io_stream_get_output_stream (priv->conn));
975 * soup_socket_is_ssl:
976 * @sock: a #SoupSocket
978 * Tests if @sock is set up to do SSL. Note that this simply means
979 * that the %SOUP_SOCKET_SSL_CREDENTIALS property has been set; it
980 * does not mean that soup_socket_start_ssl() has been called.
982 * Return value: %TRUE if @sock has SSL credentials set
985 soup_socket_is_ssl (SoupSocket *sock)
987 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
989 return priv->ssl_creds != NULL;
993 * soup_socket_disconnect:
994 * @sock: a #SoupSocket
996 * Disconnects @sock. Any further read or write attempts on it will
1000 soup_socket_disconnect (SoupSocket *sock)
1002 SoupSocketPrivate *priv;
1003 gboolean already_disconnected = FALSE;
1005 g_return_if_fail (SOUP_IS_SOCKET (sock));
1006 priv = SOUP_SOCKET_GET_PRIVATE (sock);
1008 if (priv->connect_cancel) {
1009 g_cancellable_cancel (priv->connect_cancel);
1011 } else if (g_mutex_trylock (priv->iolock)) {
1013 disconnect_internal (sock);
1015 already_disconnected = TRUE;
1016 g_mutex_unlock (priv->iolock);
1018 /* Another thread is currently doing IO, so
1019 * we can't close the socket. So just shutdown
1020 * the file descriptor to force the I/O to fail.
1021 * (It will actually be closed when the socket
1024 g_socket_shutdown (priv->gsock, TRUE, TRUE, NULL);
1027 if (already_disconnected)
1030 /* Keep ref around signals in case the object is unreferenced
1033 g_object_ref (sock);
1035 /* Give all readers a chance to notice the connection close */
1036 g_signal_emit (sock, signals[READABLE], 0);
1038 /* FIXME: can't disconnect until all data is read */
1040 /* Then let everyone know we're disconnected */
1041 g_signal_emit (sock, signals[DISCONNECTED], 0);
1043 g_object_unref (sock);
1047 * soup_socket_is_connected:
1048 * @sock: a #SoupSocket
1050 * Tests if @sock is connected to another host
1052 * Return value: %TRUE or %FALSE.
1055 soup_socket_is_connected (SoupSocket *sock)
1057 SoupSocketPrivate *priv;
1059 g_return_val_if_fail (SOUP_IS_SOCKET (sock), FALSE);
1060 priv = SOUP_SOCKET_GET_PRIVATE (sock);
1062 return priv->conn != NULL;
1066 * soup_socket_get_local_address:
1067 * @sock: a #SoupSocket
1069 * Returns the #SoupAddress corresponding to the local end of @sock.
1071 * Return value: (transfer none): the #SoupAddress
1074 soup_socket_get_local_address (SoupSocket *sock)
1076 SoupSocketPrivate *priv;
1078 g_return_val_if_fail (SOUP_IS_SOCKET (sock), NULL);
1079 priv = SOUP_SOCKET_GET_PRIVATE (sock);
1081 g_mutex_lock (priv->addrlock);
1082 if (!priv->local_addr) {
1083 GSocketAddress *addr;
1084 struct sockaddr_storage sa;
1087 addr = g_socket_get_local_address (priv->gsock, NULL);
1088 sa_len = g_socket_address_get_native_size (addr);
1089 g_socket_address_to_native (addr, &sa, sa_len, NULL);
1090 priv->local_addr = soup_address_new_from_sockaddr ((struct sockaddr *)&sa, sa_len);
1091 g_object_unref (addr);
1093 g_mutex_unlock (priv->addrlock);
1095 return priv->local_addr;
1099 * soup_socket_get_remote_address:
1100 * @sock: a #SoupSocket
1102 * Returns the #SoupAddress corresponding to the remote end of @sock.
1104 * Return value: (transfer none): the #SoupAddress
1107 soup_socket_get_remote_address (SoupSocket *sock)
1109 SoupSocketPrivate *priv;
1111 g_return_val_if_fail (SOUP_IS_SOCKET (sock), NULL);
1112 priv = SOUP_SOCKET_GET_PRIVATE (sock);
1114 g_mutex_lock (priv->addrlock);
1115 if (!priv->remote_addr) {
1116 GSocketAddress *addr;
1117 struct sockaddr_storage sa;
1120 addr = g_socket_get_remote_address (priv->gsock, NULL);
1121 sa_len = g_socket_address_get_native_size (addr);
1122 g_socket_address_to_native (addr, &sa, sa_len, NULL);
1123 priv->remote_addr = soup_address_new_from_sockaddr ((struct sockaddr *)&sa, sa_len);
1124 g_object_unref (addr);
1126 g_mutex_unlock (priv->addrlock);
1128 return priv->remote_addr;
1133 socket_read_watch (GObject *pollable, gpointer user_data)
1135 SoupSocket *sock = user_data;
1136 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
1138 priv->read_src = NULL;
1139 g_signal_emit (sock, signals[READABLE], 0);
1143 static SoupSocketIOStatus
1144 read_from_network (SoupSocket *sock, gpointer buffer, gsize len,
1145 gsize *nread, GCancellable *cancellable, GError **error)
1147 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
1148 GError *my_err = NULL;
1154 return SOUP_SOCKET_EOF;
1156 if (!priv->non_blocking) {
1157 my_nread = g_input_stream_read (G_INPUT_STREAM (priv->istream),
1159 cancellable, &my_err);
1161 my_nread = g_pollable_input_stream_read_nonblocking (
1162 priv->istream, buffer, len,
1163 cancellable, &my_err);
1167 g_clear_error (&my_err);
1169 return SOUP_SOCKET_OK;
1170 } else if (my_nread == 0) {
1171 g_clear_error (&my_err);
1173 return SOUP_SOCKET_EOF;
1174 } else if (g_error_matches (my_err, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) {
1175 g_clear_error (&my_err);
1176 if (!priv->read_src) {
1178 soup_socket_create_watch (priv, G_IO_IN,
1179 socket_read_watch, sock,
1182 return SOUP_SOCKET_WOULD_BLOCK;
1183 } else if (g_error_matches (my_err, G_TLS_ERROR, G_TLS_ERROR_HANDSHAKE)) {
1184 my_err->domain = SOUP_SSL_ERROR;
1185 my_err->code = SOUP_SSL_ERROR_CERTIFICATE;
1188 g_propagate_error (error, my_err);
1189 return SOUP_SOCKET_ERROR;
1192 static SoupSocketIOStatus
1193 read_from_buf (SoupSocket *sock, gpointer buffer, gsize len, gsize *nread)
1195 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
1196 GByteArray *read_buf = priv->read_buf;
1198 *nread = MIN (read_buf->len, len);
1199 memcpy (buffer, read_buf->data, *nread);
1201 if (*nread == read_buf->len) {
1202 g_byte_array_free (read_buf, TRUE);
1203 priv->read_buf = NULL;
1205 memmove (read_buf->data, read_buf->data + *nread,
1206 read_buf->len - *nread);
1207 g_byte_array_set_size (read_buf, read_buf->len - *nread);
1210 return SOUP_SOCKET_OK;
1214 * SoupSocketIOStatus:
1215 * @SOUP_SOCKET_OK: Success
1216 * @SOUP_SOCKET_WOULD_BLOCK: Cannot read/write any more at this time
1217 * @SOUP_SOCKET_EOF: End of file
1218 * @SOUP_SOCKET_ERROR: Other error
1220 * Return value from the #SoupSocket IO methods.
1226 * @buffer: buffer to read into
1227 * @len: size of @buffer in bytes
1228 * @nread: on return, the number of bytes read into @buffer
1229 * @cancellable: a #GCancellable, or %NULL
1230 * @error: error pointer
1232 * Attempts to read up to @len bytes from @sock into @buffer. If some
1233 * data is successfully read, soup_socket_read() will return
1234 * %SOUP_SOCKET_OK, and *@nread will contain the number of bytes
1235 * actually read (which may be less than @len).
1237 * If @sock is non-blocking, and no data is available, the return
1238 * value will be %SOUP_SOCKET_WOULD_BLOCK. In this case, the caller
1239 * can connect to the #SoupSocket::readable signal to know when there
1240 * is more data to read. (NB: You MUST read all available data off the
1241 * socket first. #SoupSocket::readable is only emitted after
1242 * soup_socket_read() returns %SOUP_SOCKET_WOULD_BLOCK, and it is only
1243 * emitted once. See the documentation for #SoupSocket:non-blocking.)
1245 * Return value: a #SoupSocketIOStatus, as described above (or
1246 * %SOUP_SOCKET_EOF if the socket is no longer connected, or
1247 * %SOUP_SOCKET_ERROR on any other error, in which case @error will
1251 soup_socket_read (SoupSocket *sock, gpointer buffer, gsize len,
1252 gsize *nread, GCancellable *cancellable, GError **error)
1254 SoupSocketPrivate *priv;
1255 SoupSocketIOStatus status;
1257 g_return_val_if_fail (SOUP_IS_SOCKET (sock), SOUP_SOCKET_ERROR);
1258 g_return_val_if_fail (nread != NULL, SOUP_SOCKET_ERROR);
1260 priv = SOUP_SOCKET_GET_PRIVATE (sock);
1262 g_mutex_lock (priv->iolock);
1264 status = read_from_buf (sock, buffer, len, nread);
1266 status = read_from_network (sock, buffer, len, nread, cancellable, error);
1267 g_mutex_unlock (priv->iolock);
1273 * soup_socket_read_until:
1275 * @buffer: buffer to read into
1276 * @len: size of @buffer in bytes
1277 * @boundary: boundary to read until
1278 * @boundary_len: length of @boundary in bytes
1279 * @nread: on return, the number of bytes read into @buffer
1280 * @got_boundary: on return, whether or not the data in @buffer
1281 * ends with the boundary string
1282 * @cancellable: a #GCancellable, or %NULL
1283 * @error: error pointer
1285 * Like soup_socket_read(), but reads no further than the first
1286 * occurrence of @boundary. (If the boundary is found, it will be
1287 * included in the returned data, and *@got_boundary will be set to
1288 * %TRUE.) Any data after the boundary will returned in future reads.
1290 * soup_socket_read_until() will almost always return fewer than @len
1291 * bytes: if the boundary is found, then it will only return the bytes
1292 * up until the end of the boundary, and if the boundary is not found,
1293 * then it will leave the last <literal>(boundary_len - 1)</literal>
1294 * bytes in its internal buffer, in case they form the start of the
1295 * boundary string. Thus, @len normally needs to be at least 1 byte
1296 * longer than @boundary_len if you want to make any progress at all.
1298 * Return value: as for soup_socket_read()
1301 soup_socket_read_until (SoupSocket *sock, gpointer buffer, gsize len,
1302 gconstpointer boundary, gsize boundary_len,
1303 gsize *nread, gboolean *got_boundary,
1304 GCancellable *cancellable, GError **error)
1306 SoupSocketPrivate *priv;
1307 SoupSocketIOStatus status;
1308 GByteArray *read_buf;
1309 guint match_len, prev_len;
1312 g_return_val_if_fail (SOUP_IS_SOCKET (sock), SOUP_SOCKET_ERROR);
1313 g_return_val_if_fail (nread != NULL, SOUP_SOCKET_ERROR);
1314 g_return_val_if_fail (len >= boundary_len, SOUP_SOCKET_ERROR);
1316 priv = SOUP_SOCKET_GET_PRIVATE (sock);
1318 g_mutex_lock (priv->iolock);
1320 *got_boundary = FALSE;
1322 if (!priv->read_buf)
1323 priv->read_buf = g_byte_array_new ();
1324 read_buf = priv->read_buf;
1326 if (read_buf->len < boundary_len) {
1327 prev_len = read_buf->len;
1328 g_byte_array_set_size (read_buf, len);
1329 status = read_from_network (sock,
1330 read_buf->data + prev_len,
1331 len - prev_len, nread, cancellable, error);
1332 read_buf->len = prev_len + *nread;
1334 if (status != SOUP_SOCKET_OK) {
1335 g_mutex_unlock (priv->iolock);
1340 /* Scan for the boundary */
1341 end = read_buf->data + read_buf->len;
1342 for (p = read_buf->data; p <= end - boundary_len; p++) {
1343 if (!memcmp (p, boundary, boundary_len)) {
1345 *got_boundary = TRUE;
1350 /* Return everything up to 'p' (which is either just after the
1351 * boundary, or @boundary_len - 1 bytes before the end of the
1354 match_len = p - read_buf->data;
1355 status = read_from_buf (sock, buffer, MIN (len, match_len), nread);
1357 g_mutex_unlock (priv->iolock);
1362 socket_write_watch (GObject *pollable, gpointer user_data)
1364 SoupSocket *sock = user_data;
1365 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
1367 priv->write_src = NULL;
1368 g_signal_emit (sock, signals[WRITABLE], 0);
1373 * soup_socket_write:
1375 * @buffer: data to write
1376 * @len: size of @buffer, in bytes
1377 * @nwrote: on return, number of bytes written
1378 * @cancellable: a #GCancellable, or %NULL
1379 * @error: error pointer
1381 * Attempts to write @len bytes from @buffer to @sock. If some data is
1382 * successfully written, the return status will be %SOUP_SOCKET_OK,
1383 * and *@nwrote will contain the number of bytes actually written
1384 * (which may be less than @len).
1386 * If @sock is non-blocking, and no data could be written right away,
1387 * the return value will be %SOUP_SOCKET_WOULD_BLOCK. In this case,
1388 * the caller can connect to the #SoupSocket::writable signal to know
1389 * when more data can be written. (NB: #SoupSocket::writable is only
1390 * emitted after soup_socket_write() returns %SOUP_SOCKET_WOULD_BLOCK,
1391 * and it is only emitted once. See the documentation for
1392 * #SoupSocket:non-blocking.)
1394 * Return value: a #SoupSocketIOStatus, as described above (or
1395 * %SOUP_SOCKET_EOF or %SOUP_SOCKET_ERROR. @error will be set if the
1396 * return value is %SOUP_SOCKET_ERROR.)
1399 soup_socket_write (SoupSocket *sock, gconstpointer buffer,
1400 gsize len, gsize *nwrote,
1401 GCancellable *cancellable, GError **error)
1403 SoupSocketPrivate *priv;
1404 GError *my_err = NULL;
1407 g_return_val_if_fail (SOUP_IS_SOCKET (sock), SOUP_SOCKET_ERROR);
1408 g_return_val_if_fail (nwrote != NULL, SOUP_SOCKET_ERROR);
1410 priv = SOUP_SOCKET_GET_PRIVATE (sock);
1412 g_mutex_lock (priv->iolock);
1415 g_mutex_unlock (priv->iolock);
1416 return SOUP_SOCKET_EOF;
1418 if (priv->write_src) {
1419 g_mutex_unlock (priv->iolock);
1420 return SOUP_SOCKET_WOULD_BLOCK;
1423 if (!priv->non_blocking) {
1424 my_nwrote = g_output_stream_write (G_OUTPUT_STREAM (priv->ostream),
1426 cancellable, &my_err);
1428 my_nwrote = g_pollable_output_stream_write_nonblocking (
1429 priv->ostream, buffer, len,
1430 cancellable, &my_err);
1433 if (my_nwrote > 0) {
1434 g_mutex_unlock (priv->iolock);
1435 g_clear_error (&my_err);
1436 *nwrote = my_nwrote;
1437 return SOUP_SOCKET_OK;
1440 if (g_error_matches (my_err, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) {
1441 g_mutex_unlock (priv->iolock);
1444 soup_socket_create_watch (priv,
1446 socket_write_watch, sock, cancellable);
1447 return SOUP_SOCKET_WOULD_BLOCK;
1448 } else if (g_error_matches (my_err, G_TLS_ERROR, G_TLS_ERROR_HANDSHAKE)) {
1449 my_err->domain = SOUP_SSL_ERROR;
1450 my_err->code = SOUP_SSL_ERROR_CERTIFICATE;
1453 g_mutex_unlock (priv->iolock);
1454 g_propagate_error (error, my_err);
1455 return SOUP_SOCKET_ERROR;