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,
65 SoupAddress *local_addr, *remote_addr;
68 GPollableInputStream *istream;
69 GPollableOutputStream *ostream;
74 guint trusted_certificate:1;
75 guint clean_dispose:1;
78 GMainContext *async_context;
80 GSource *read_src, *write_src;
83 GMutex *iolock, *addrlock;
86 GCancellable *connect_cancel;
88 #define SOUP_SOCKET_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SOUP_TYPE_SOCKET, SoupSocketPrivate))
90 static void set_property (GObject *object, guint prop_id,
91 const GValue *value, GParamSpec *pspec);
92 static void get_property (GObject *object, guint prop_id,
93 GValue *value, GParamSpec *pspec);
96 soup_socket_init (SoupSocket *sock)
98 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
100 priv->non_blocking = TRUE;
101 priv->addrlock = g_mutex_new ();
102 priv->iolock = g_mutex_new ();
106 disconnect_internal (SoupSocketPrivate *priv)
109 g_socket_close (priv->gsock, NULL);
110 g_object_unref (priv->gsock);
114 g_object_unref (priv->conn);
116 priv->istream = NULL;
117 priv->ostream = NULL;
120 if (priv->read_src) {
121 g_source_destroy (priv->read_src);
122 priv->read_src = NULL;
124 if (priv->write_src) {
125 g_source_destroy (priv->write_src);
126 priv->write_src = NULL;
131 finalize (GObject *object)
133 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (object);
135 if (priv->connect_cancel) {
136 if (priv->clean_dispose)
137 g_warning ("Disposing socket %p during connect", object);
138 g_object_unref (priv->connect_cancel);
141 if (priv->clean_dispose)
142 g_warning ("Disposing socket %p while still connected", object);
143 disconnect_internal (priv);
146 if (priv->local_addr)
147 g_object_unref (priv->local_addr);
148 if (priv->remote_addr)
149 g_object_unref (priv->remote_addr);
151 if (priv->watch_src) {
152 if (priv->clean_dispose && !priv->is_server)
153 g_warning ("Disposing socket %p during async op", object);
154 g_source_destroy (priv->watch_src);
156 if (priv->async_context)
157 g_main_context_unref (priv->async_context);
160 g_byte_array_free (priv->read_buf, TRUE);
162 g_mutex_free (priv->addrlock);
163 g_mutex_free (priv->iolock);
165 G_OBJECT_CLASS (soup_socket_parent_class)->finalize (object);
169 soup_socket_class_init (SoupSocketClass *socket_class)
171 GObjectClass *object_class = G_OBJECT_CLASS (socket_class);
173 g_type_class_add_private (socket_class, sizeof (SoupSocketPrivate));
175 /* virtual method override */
176 object_class->finalize = finalize;
177 object_class->set_property = set_property;
178 object_class->get_property = get_property;
183 * SoupSocket::readable:
186 * Emitted when an async socket is readable. See
187 * soup_socket_read(), soup_socket_read_until() and
188 * #SoupSocket:non-blocking.
191 g_signal_new ("readable",
192 G_OBJECT_CLASS_TYPE (object_class),
194 G_STRUCT_OFFSET (SoupSocketClass, readable),
196 soup_marshal_NONE__NONE,
200 * SoupSocket::writable:
203 * Emitted when an async socket is writable. See
204 * soup_socket_write() and #SoupSocket:non-blocking.
207 g_signal_new ("writable",
208 G_OBJECT_CLASS_TYPE (object_class),
210 G_STRUCT_OFFSET (SoupSocketClass, writable),
212 soup_marshal_NONE__NONE,
216 * SoupSocket::disconnected:
219 * Emitted when the socket is disconnected, for whatever
222 signals[DISCONNECTED] =
223 g_signal_new ("disconnected",
224 G_OBJECT_CLASS_TYPE (object_class),
226 G_STRUCT_OFFSET (SoupSocketClass, disconnected),
228 soup_marshal_NONE__NONE,
232 * SoupSocket::new-connection:
234 * @new: the new socket
236 * Emitted when a listening socket (set up with
237 * soup_socket_listen()) receives a new connection.
239 * You must ref the @new if you want to keep it; otherwise it
240 * will be destroyed after the signal is emitted.
242 signals[NEW_CONNECTION] =
243 g_signal_new ("new_connection",
244 G_OBJECT_CLASS_TYPE (object_class),
246 G_STRUCT_OFFSET (SoupSocketClass, new_connection),
248 soup_marshal_NONE__OBJECT,
254 * SOUP_SOCKET_LOCAL_ADDRESS:
256 * Alias for the #SoupSocket:local-address property. (Address
257 * of local end of socket.)
259 g_object_class_install_property (
260 object_class, PROP_LOCAL_ADDRESS,
261 g_param_spec_object (SOUP_SOCKET_LOCAL_ADDRESS,
263 "Address of local end of socket",
265 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
267 * SOUP_SOCKET_REMOTE_ADDRESS:
269 * Alias for the #SoupSocket:remote-address property. (Address
270 * of remote end of socket.)
272 g_object_class_install_property (
273 object_class, PROP_REMOTE_ADDRESS,
274 g_param_spec_object (SOUP_SOCKET_REMOTE_ADDRESS,
276 "Address of remote end of socket",
278 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
280 * SoupSocket:non-blocking:
282 * Whether or not the socket uses non-blocking I/O.
284 * #SoupSocket's I/O methods are designed around the idea of
285 * using a single codepath for both synchronous and
286 * asynchronous I/O. If you want to read off a #SoupSocket,
287 * the "correct" way to do it is to call soup_socket_read() or
288 * soup_socket_read_until() repeatedly until you have read
289 * everything you want. If it returns %SOUP_SOCKET_WOULD_BLOCK
290 * at any point, stop reading and wait for it to emit the
291 * #SoupSocket::readable signal. Then go back to the
292 * reading-as-much-as-you-can loop. Likewise, for writing to a
293 * #SoupSocket, you should call soup_socket_write() either
294 * until you have written everything, or it returns
295 * %SOUP_SOCKET_WOULD_BLOCK (in which case you wait for
296 * #SoupSocket::writable and then go back into the loop).
298 * Code written this way will work correctly with both
299 * blocking and non-blocking sockets; blocking sockets will
300 * simply never return %SOUP_SOCKET_WOULD_BLOCK, and so the
301 * code that handles that case just won't get used for them.
304 * SOUP_SOCKET_FLAG_NONBLOCKING:
306 * Alias for the #SoupSocket:non-blocking property. (Whether
307 * or not the socket uses non-blocking I/O.)
309 g_object_class_install_property (
310 object_class, PROP_NON_BLOCKING,
311 g_param_spec_boolean (SOUP_SOCKET_FLAG_NONBLOCKING,
313 "Whether or not the socket uses non-blocking I/O",
317 * SOUP_SOCKET_IS_SERVER:
319 * Alias for the #SoupSocket:is-server property. (Whether or
320 * not the socket is a server socket.)
322 g_object_class_install_property (
323 object_class, PROP_IS_SERVER,
324 g_param_spec_boolean (SOUP_SOCKET_IS_SERVER,
326 "Whether or not the socket is a server socket",
330 * SOUP_SOCKET_SSL_CREDENTIALS:
332 * Alias for the #SoupSocket:ssl-credentials property.
333 * (SSL credential information.)
335 g_object_class_install_property (
336 object_class, PROP_SSL_CREDENTIALS,
337 g_param_spec_pointer (SOUP_SOCKET_SSL_CREDENTIALS,
339 "SSL credential information, passed from the session to the SSL implementation",
342 * SOUP_SOCKET_SSL_STRICT:
344 * Alias for the #SoupSocket:ignore-ssl-cert-errors property.
346 g_object_class_install_property (
347 object_class, PROP_SSL_STRICT,
348 g_param_spec_boolean (SOUP_SOCKET_SSL_STRICT,
349 "Strictly validate SSL certificates",
350 "Whether certificate errors should be considered a connection error",
352 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
354 * SOUP_SOCKET_TRUSTED_CERTIFICATE:
356 * Alias for the #SoupSocket:trusted-certificate
357 * property. Notice that this property's value is only useful
358 * if the socket is for an SSL connection, and only reliable
359 * after some data has been transferred to or from it.
361 g_object_class_install_property (
362 object_class, PROP_TRUSTED_CERTIFICATE,
363 g_param_spec_boolean (SOUP_SOCKET_TRUSTED_CERTIFICATE,
364 "Trusted Certificate",
365 "Whether the server certificate is trusted, if this is an SSL socket",
367 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
369 * SOUP_SOCKET_ASYNC_CONTEXT:
371 * Alias for the #SoupSocket:async-context property. (The
372 * socket's #GMainContext.)
374 g_object_class_install_property (
375 object_class, PROP_ASYNC_CONTEXT,
376 g_param_spec_pointer (SOUP_SOCKET_ASYNC_CONTEXT,
377 "Async GMainContext",
378 "The GMainContext to dispatch this socket's async I/O in",
379 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
382 * SOUP_SOCKET_TIMEOUT:
384 * Alias for the #SoupSocket:timeout property. (The timeout
385 * in seconds for blocking socket I/O operations.)
387 g_object_class_install_property (
388 object_class, PROP_TIMEOUT,
389 g_param_spec_uint (SOUP_SOCKET_TIMEOUT,
391 "Value in seconds to timeout a blocking I/O",
395 g_object_class_install_property (
396 object_class, PROP_CLEAN_DISPOSE,
397 g_param_spec_boolean ("clean-dispose",
399 "Warn on unclean dispose",
401 G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
406 finish_socket_setup (SoupSocketPrivate *priv)
412 priv->conn = (GIOStream *)g_socket_connection_factory_create_connection (priv->gsock);
414 priv->istream = G_POLLABLE_INPUT_STREAM (g_io_stream_get_input_stream (priv->conn));
416 priv->ostream = G_POLLABLE_OUTPUT_STREAM (g_io_stream_get_output_stream (priv->conn));
418 g_socket_set_timeout (priv->gsock, priv->timeout);
422 set_property (GObject *object, guint prop_id,
423 const GValue *value, GParamSpec *pspec)
425 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (object);
428 case PROP_LOCAL_ADDRESS:
429 priv->local_addr = (SoupAddress *)g_value_dup_object (value);
431 case PROP_REMOTE_ADDRESS:
432 priv->remote_addr = (SoupAddress *)g_value_dup_object (value);
434 case PROP_NON_BLOCKING:
435 priv->non_blocking = g_value_get_boolean (value);
437 case PROP_SSL_CREDENTIALS:
438 priv->ssl_creds = g_value_get_pointer (value);
440 case PROP_SSL_STRICT:
441 priv->ssl_strict = g_value_get_boolean (value);
443 case PROP_TRUSTED_CERTIFICATE:
444 priv->trusted_certificate = g_value_get_boolean (value);
446 case PROP_ASYNC_CONTEXT:
447 priv->async_context = g_value_get_pointer (value);
448 if (priv->async_context)
449 g_main_context_ref (priv->async_context);
452 priv->timeout = g_value_get_uint (value);
454 g_socket_set_timeout (priv->gsock, priv->timeout);
456 case PROP_CLEAN_DISPOSE:
457 priv->clean_dispose = g_value_get_boolean (value);
460 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
466 get_property (GObject *object, guint prop_id,
467 GValue *value, GParamSpec *pspec)
469 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (object);
472 case PROP_LOCAL_ADDRESS:
473 g_value_set_object (value, soup_socket_get_local_address (SOUP_SOCKET (object)));
475 case PROP_REMOTE_ADDRESS:
476 g_value_set_object (value, soup_socket_get_remote_address (SOUP_SOCKET (object)));
478 case PROP_NON_BLOCKING:
479 g_value_set_boolean (value, priv->non_blocking);
482 g_value_set_boolean (value, priv->is_server);
484 case PROP_SSL_CREDENTIALS:
485 g_value_set_pointer (value, priv->ssl_creds);
487 case PROP_SSL_STRICT:
488 g_value_set_boolean (value, priv->ssl_strict);
490 case PROP_TRUSTED_CERTIFICATE:
491 g_value_set_boolean (value, priv->trusted_certificate);
493 case PROP_ASYNC_CONTEXT:
494 g_value_set_pointer (value, priv->async_context ? g_main_context_ref (priv->async_context) : NULL);
497 g_value_set_uint (value, priv->timeout);
500 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
508 * @optname1: name of first property to set (or %NULL)
509 * @...: value of @optname1, followed by additional property/value pairs
511 * Creates a new (disconnected) socket
513 * Return value: the new socket
516 soup_socket_new (const char *optname1, ...)
521 va_start (ap, optname1);
522 sock = (SoupSocket *)g_object_new_valist (SOUP_TYPE_SOCKET,
530 socket_connected (SoupSocket *sock, GSocketConnection *conn, GError *error)
532 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
534 g_object_unref (priv->connect_cancel);
535 priv->connect_cancel = NULL;
538 if (error->domain == G_RESOLVER_ERROR) {
539 g_error_free (error);
540 return SOUP_STATUS_CANT_RESOLVE;
542 g_error_free (error);
543 return SOUP_STATUS_CANT_CONNECT;
547 priv->conn = (GIOStream *)conn;
548 priv->gsock = g_object_ref (g_socket_connection_get_socket (conn));
549 finish_socket_setup (priv);
551 return SOUP_STATUS_OK;
555 * SoupSocketCallback:
556 * @sock: the #SoupSocket
557 * @status: an HTTP status code indicating success or failure
558 * @user_data: the data passed to soup_socket_connect_async()
560 * The callback function passed to soup_socket_connect_async().
565 SoupSocketCallback callback;
567 } SoupSocketAsyncConnectData;
570 async_connected (GObject *client, GAsyncResult *result, gpointer data)
572 SoupSocketAsyncConnectData *sacd = data;
573 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sacd->sock);
574 GError *error = NULL;
575 GSocketConnection *conn;
578 if (priv->async_context)
579 g_main_context_pop_thread_default (priv->async_context);
581 conn = g_socket_client_connect_finish (G_SOCKET_CLIENT (client),
583 status = socket_connected (sacd->sock, conn, error);
585 sacd->callback (sacd->sock, status, sacd->user_data);
586 g_object_unref (sacd->sock);
587 g_slice_free (SoupSocketAsyncConnectData, sacd);
591 * soup_socket_connect_async:
592 * @sock: a client #SoupSocket (which must not already be connected)
593 * @cancellable: a #GCancellable, or %NULL
594 * @callback: (scope async): callback to call after connecting
595 * @user_data: data to pass to @callback
597 * Begins asynchronously connecting to @sock's remote address. The
598 * socket will call @callback when it succeeds or fails (but not
599 * before returning from this function).
601 * If @cancellable is non-%NULL, it can be used to cancel the
602 * connection. @callback will still be invoked in this case, with a
603 * status of %SOUP_STATUS_CANCELLED.
606 soup_socket_connect_async (SoupSocket *sock, GCancellable *cancellable,
607 SoupSocketCallback callback, gpointer user_data)
609 SoupSocketPrivate *priv;
610 SoupSocketAsyncConnectData *sacd;
611 GSocketClient *client;
613 g_return_if_fail (SOUP_IS_SOCKET (sock));
614 priv = SOUP_SOCKET_GET_PRIVATE (sock);
615 g_return_if_fail (priv->remote_addr != NULL);
617 sacd = g_slice_new0 (SoupSocketAsyncConnectData);
618 sacd->sock = g_object_ref (sock);
619 sacd->callback = callback;
620 sacd->user_data = user_data;
622 priv->connect_cancel = cancellable ? g_object_ref (cancellable) : g_cancellable_new ();
624 if (priv->async_context)
625 g_main_context_push_thread_default (priv->async_context);
627 client = g_socket_client_new ();
629 g_socket_client_set_timeout (client, priv->timeout);
630 g_socket_client_connect_async (client,
631 G_SOCKET_CONNECTABLE (priv->remote_addr),
632 priv->connect_cancel,
633 async_connected, sacd);
634 g_object_unref (client);
638 * soup_socket_connect_sync:
639 * @sock: a client #SoupSocket (which must not already be connected)
640 * @cancellable: a #GCancellable, or %NULL
642 * Attempt to synchronously connect @sock to its remote address.
644 * If @cancellable is non-%NULL, it can be used to cancel the
645 * connection, in which case soup_socket_connect_sync() will return
646 * %SOUP_STATUS_CANCELLED.
648 * Return value: a success or failure code.
651 soup_socket_connect_sync (SoupSocket *sock, GCancellable *cancellable)
653 SoupSocketPrivate *priv;
654 GSocketClient *client;
655 GSocketConnection *conn;
656 GError *error = NULL;
658 g_return_val_if_fail (SOUP_IS_SOCKET (sock), SOUP_STATUS_MALFORMED);
659 priv = SOUP_SOCKET_GET_PRIVATE (sock);
660 g_return_val_if_fail (!priv->is_server, SOUP_STATUS_MALFORMED);
661 g_return_val_if_fail (priv->gsock == NULL, SOUP_STATUS_MALFORMED);
662 g_return_val_if_fail (priv->remote_addr != NULL, SOUP_STATUS_MALFORMED);
665 g_object_ref (cancellable);
667 cancellable = g_cancellable_new ();
668 priv->connect_cancel = cancellable;
670 client = g_socket_client_new ();
672 g_socket_client_set_timeout (client, priv->timeout);
673 conn = g_socket_client_connect (client,
674 G_SOCKET_CONNECTABLE (priv->remote_addr),
675 priv->connect_cancel, &error);
676 g_object_unref (client);
678 return socket_connected (sock, conn, error);
682 soup_socket_get_fd (SoupSocket *sock)
684 g_return_val_if_fail (SOUP_IS_SOCKET (sock), -1);
686 return g_socket_get_fd (SOUP_SOCKET_GET_PRIVATE (sock)->gsock);
690 soup_socket_create_watch (SoupSocketPrivate *priv, GIOCondition cond,
691 GPollableSourceFunc callback, gpointer user_data,
692 GCancellable *cancellable)
697 watch = g_pollable_input_stream_create_source (priv->istream, cancellable);
699 watch = g_pollable_output_stream_create_source (priv->ostream, cancellable);
700 g_source_set_callback (watch, (GSourceFunc)callback, user_data, NULL);
701 g_source_attach (watch, priv->async_context);
702 g_source_unref (watch);
708 listen_watch (GObject *pollable, gpointer data)
710 SoupSocket *sock = data, *new;
711 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock), *new_priv;
714 new_gsock = g_socket_accept (priv->gsock, NULL, NULL);
718 new = g_object_new (SOUP_TYPE_SOCKET, NULL);
719 new_priv = SOUP_SOCKET_GET_PRIVATE (new);
720 new_priv->gsock = new_gsock;
721 if (priv->async_context)
722 new_priv->async_context = g_main_context_ref (priv->async_context);
723 new_priv->non_blocking = priv->non_blocking;
724 new_priv->is_server = TRUE;
726 new_priv->ssl_creds = priv->ssl_creds;
727 finish_socket_setup (new_priv);
729 if (new_priv->ssl_creds) {
730 if (!soup_socket_start_proxy_ssl (new, NULL, NULL)) {
731 g_object_unref (new);
736 g_signal_emit (sock, signals[NEW_CONNECTION], 0, new);
737 g_object_unref (new);
743 * soup_socket_listen:
744 * @sock: a server #SoupSocket (which must not already be connected or
747 * Makes @sock start listening on its local address. When connections
748 * come in, @sock will emit %new_connection.
750 * Return value: whether or not @sock is now listening.
753 soup_socket_listen (SoupSocket *sock)
756 SoupSocketPrivate *priv;
757 GSocketAddress *addr;
759 g_return_val_if_fail (SOUP_IS_SOCKET (sock), FALSE);
760 priv = SOUP_SOCKET_GET_PRIVATE (sock);
761 g_return_val_if_fail (priv->gsock == NULL, FALSE);
762 g_return_val_if_fail (priv->local_addr != NULL, FALSE);
764 priv->is_server = TRUE;
766 /* @local_addr may have its port set to 0. So we intentionally
767 * don't store it in priv->local_addr, so that if the
768 * caller calls soup_socket_get_local_address() later, we'll
769 * have to make a new addr by calling getsockname(), which
770 * will have the right port number.
772 addr = soup_address_get_gsockaddr (priv->local_addr);
773 g_return_val_if_fail (addr != NULL, FALSE);
775 priv->gsock = g_socket_new (g_socket_address_get_family (addr),
776 G_SOCKET_TYPE_STREAM,
777 G_SOCKET_PROTOCOL_DEFAULT,
781 finish_socket_setup (priv);
784 if (!g_socket_bind (priv->gsock, addr, TRUE, NULL))
786 /* Force local_addr to be re-resolved now */
787 g_object_unref (priv->local_addr);
788 priv->local_addr = NULL;
791 if (!g_socket_listen (priv->gsock, NULL))
794 priv->watch_src = soup_socket_create_watch (priv, G_IO_IN,
801 disconnect_internal (priv);
807 soup_socket_accept_certificate (GTlsConnection *conn, GTlsCertificate *cert,
808 GTlsCertificateFlags errors, gpointer sock)
810 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
812 if (soup_ssl_credentials_verify_certificate (priv->ssl_creds,
816 if (!priv->ssl_strict) {
817 priv->trusted_certificate = FALSE;
824 * soup_socket_start_ssl:
826 * @cancellable: a #GCancellable
828 * Starts using SSL on @socket.
830 * Return value: success or failure
833 soup_socket_start_ssl (SoupSocket *sock, GCancellable *cancellable)
835 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
837 return soup_socket_start_proxy_ssl (sock, soup_address_get_name (priv->remote_addr), cancellable);
841 * soup_socket_start_proxy_ssl:
843 * @ssl_host: hostname of the SSL server
844 * @cancellable: a #GCancellable
846 * Starts using SSL on @socket, expecting to find a host named
849 * Return value: success or failure
852 soup_socket_start_proxy_ssl (SoupSocket *sock, const char *ssl_host,
853 GCancellable *cancellable)
855 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
856 GTlsBackend *backend = g_tls_backend_get_default ();
858 if (G_IS_TLS_CONNECTION (priv->conn))
860 if (!priv->ssl_creds)
863 if (!priv->is_server) {
864 GTlsClientConnection *conn;
865 GSocketConnectable *identity;
867 identity = g_network_address_new (ssl_host, 0);
868 conn = g_initable_new (g_tls_backend_get_client_connection_type (backend),
870 "base-io-stream", priv->conn,
871 "server-identity", identity,
872 "use-system-certdb", FALSE,
873 "require-close-notify", FALSE,
876 g_object_unref (identity);
881 g_object_unref (priv->conn);
882 priv->conn = G_IO_STREAM (conn);
884 priv->trusted_certificate = TRUE;
885 g_signal_connect (conn, "accept-certificate",
886 G_CALLBACK (soup_socket_accept_certificate),
889 GTlsServerConnection *conn;
891 conn = g_initable_new (g_tls_backend_get_server_connection_type (backend),
893 "base-io-stream", priv->conn,
894 "certificate", soup_ssl_credentials_get_certificate (priv->ssl_creds),
895 "use-system-certdb", FALSE,
896 "require-close-notify", FALSE,
901 g_object_unref (priv->conn);
902 priv->conn = G_IO_STREAM (conn);
905 priv->istream = G_POLLABLE_INPUT_STREAM (g_io_stream_get_input_stream (priv->conn));
906 priv->ostream = G_POLLABLE_OUTPUT_STREAM (g_io_stream_get_output_stream (priv->conn));
911 * soup_socket_is_ssl:
912 * @sock: a #SoupSocket
914 * Tests if @sock is set up to do SSL. Note that this simply means
915 * that the %SOUP_SOCKET_SSL_CREDENTIALS property has been set; it
916 * does not mean that soup_socket_start_ssl() has been called.
918 * Return value: %TRUE if @sock has SSL credentials set
921 soup_socket_is_ssl (SoupSocket *sock)
923 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
925 return priv->ssl_creds != NULL;
929 * soup_socket_disconnect:
930 * @sock: a #SoupSocket
932 * Disconnects @sock. Any further read or write attempts on it will
936 soup_socket_disconnect (SoupSocket *sock)
938 SoupSocketPrivate *priv;
939 gboolean already_disconnected = FALSE;
941 g_return_if_fail (SOUP_IS_SOCKET (sock));
942 priv = SOUP_SOCKET_GET_PRIVATE (sock);
944 if (priv->connect_cancel) {
945 g_cancellable_cancel (priv->connect_cancel);
947 } else if (g_mutex_trylock (priv->iolock)) {
949 disconnect_internal (priv);
951 already_disconnected = TRUE;
952 g_mutex_unlock (priv->iolock);
954 /* Another thread is currently doing IO, so
955 * we can't close the socket. So just shutdown
956 * the file descriptor to force the I/O to fail.
957 * (It will actually be closed when the socket
960 g_socket_shutdown (priv->gsock, TRUE, TRUE, NULL);
963 if (already_disconnected)
966 /* Keep ref around signals in case the object is unreferenced
971 /* Give all readers a chance to notice the connection close */
972 g_signal_emit (sock, signals[READABLE], 0);
974 /* FIXME: can't disconnect until all data is read */
976 /* Then let everyone know we're disconnected */
977 g_signal_emit (sock, signals[DISCONNECTED], 0);
979 g_object_unref (sock);
983 * soup_socket_is_connected:
984 * @sock: a #SoupSocket
986 * Tests if @sock is connected to another host
988 * Return value: %TRUE or %FALSE.
991 soup_socket_is_connected (SoupSocket *sock)
993 SoupSocketPrivate *priv;
995 g_return_val_if_fail (SOUP_IS_SOCKET (sock), FALSE);
996 priv = SOUP_SOCKET_GET_PRIVATE (sock);
998 return priv->conn != NULL;
1002 * soup_socket_get_local_address:
1003 * @sock: a #SoupSocket
1005 * Returns the #SoupAddress corresponding to the local end of @sock.
1007 * Return value: (transfer none): the #SoupAddress
1010 soup_socket_get_local_address (SoupSocket *sock)
1012 SoupSocketPrivate *priv;
1014 g_return_val_if_fail (SOUP_IS_SOCKET (sock), NULL);
1015 priv = SOUP_SOCKET_GET_PRIVATE (sock);
1017 g_mutex_lock (priv->addrlock);
1018 if (!priv->local_addr) {
1019 GSocketAddress *addr;
1020 struct sockaddr_storage sa;
1023 addr = g_socket_get_local_address (priv->gsock, NULL);
1024 sa_len = g_socket_address_get_native_size (addr);
1025 g_socket_address_to_native (addr, &sa, sa_len, NULL);
1026 priv->local_addr = soup_address_new_from_sockaddr ((struct sockaddr *)&sa, sa_len);
1027 g_object_unref (addr);
1029 g_mutex_unlock (priv->addrlock);
1031 return priv->local_addr;
1035 * soup_socket_get_remote_address:
1036 * @sock: a #SoupSocket
1038 * Returns the #SoupAddress corresponding to the remote end of @sock.
1040 * Return value: (transfer none): the #SoupAddress
1043 soup_socket_get_remote_address (SoupSocket *sock)
1045 SoupSocketPrivate *priv;
1047 g_return_val_if_fail (SOUP_IS_SOCKET (sock), NULL);
1048 priv = SOUP_SOCKET_GET_PRIVATE (sock);
1050 g_mutex_lock (priv->addrlock);
1051 if (!priv->remote_addr) {
1052 GSocketAddress *addr;
1053 struct sockaddr_storage sa;
1056 addr = g_socket_get_remote_address (priv->gsock, NULL);
1057 sa_len = g_socket_address_get_native_size (addr);
1058 g_socket_address_to_native (addr, &sa, sa_len, NULL);
1059 priv->local_addr = soup_address_new_from_sockaddr ((struct sockaddr *)&sa, sa_len);
1060 g_object_unref (addr);
1062 g_mutex_unlock (priv->addrlock);
1064 return priv->remote_addr;
1069 socket_read_watch (GObject *pollable, gpointer user_data)
1071 SoupSocket *sock = user_data;
1072 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
1074 priv->read_src = NULL;
1075 g_signal_emit (sock, signals[READABLE], 0);
1079 static SoupSocketIOStatus
1080 read_from_network (SoupSocket *sock, gpointer buffer, gsize len,
1081 gsize *nread, GCancellable *cancellable, GError **error)
1083 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
1084 GError *my_err = NULL;
1090 return SOUP_SOCKET_EOF;
1092 if (!priv->non_blocking) {
1093 my_nread = g_input_stream_read (G_INPUT_STREAM (priv->istream),
1095 cancellable, &my_err);
1097 my_nread = g_pollable_input_stream_read_nonblocking (
1098 priv->istream, buffer, len,
1099 cancellable, &my_err);
1103 g_clear_error (&my_err);
1105 return SOUP_SOCKET_OK;
1106 } else if (my_nread == 0) {
1107 g_clear_error (&my_err);
1109 return SOUP_SOCKET_EOF;
1110 } else if (g_error_matches (my_err, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) {
1111 g_clear_error (&my_err);
1112 if (!priv->read_src) {
1114 soup_socket_create_watch (priv, G_IO_IN,
1115 socket_read_watch, sock,
1118 return SOUP_SOCKET_WOULD_BLOCK;
1119 } else if (g_error_matches (my_err, G_TLS_ERROR, G_TLS_ERROR_HANDSHAKE)) {
1120 my_err->domain = SOUP_SSL_ERROR;
1121 my_err->code = SOUP_SSL_ERROR_CERTIFICATE;
1124 g_propagate_error (error, my_err);
1125 return SOUP_SOCKET_ERROR;
1128 static SoupSocketIOStatus
1129 read_from_buf (SoupSocket *sock, gpointer buffer, gsize len, gsize *nread)
1131 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
1132 GByteArray *read_buf = priv->read_buf;
1134 *nread = MIN (read_buf->len, len);
1135 memcpy (buffer, read_buf->data, *nread);
1137 if (*nread == read_buf->len) {
1138 g_byte_array_free (read_buf, TRUE);
1139 priv->read_buf = NULL;
1141 memmove (read_buf->data, read_buf->data + *nread,
1142 read_buf->len - *nread);
1143 g_byte_array_set_size (read_buf, read_buf->len - *nread);
1146 return SOUP_SOCKET_OK;
1150 * SoupSocketIOStatus:
1151 * @SOUP_SOCKET_OK: Success
1152 * @SOUP_SOCKET_WOULD_BLOCK: Cannot read/write any more at this time
1153 * @SOUP_SOCKET_EOF: End of file
1154 * @SOUP_SOCKET_ERROR: Other error
1156 * Return value from the #SoupSocket IO methods.
1162 * @buffer: buffer to read into
1163 * @len: size of @buffer in bytes
1164 * @nread: on return, the number of bytes read into @buffer
1165 * @cancellable: a #GCancellable, or %NULL
1166 * @error: error pointer
1168 * Attempts to read up to @len bytes from @sock into @buffer. If some
1169 * data is successfully read, soup_socket_read() will return
1170 * %SOUP_SOCKET_OK, and *@nread will contain the number of bytes
1171 * actually read (which may be less than @len).
1173 * If @sock is non-blocking, and no data is available, the return
1174 * value will be %SOUP_SOCKET_WOULD_BLOCK. In this case, the caller
1175 * can connect to the #SoupSocket::readable signal to know when there
1176 * is more data to read. (NB: You MUST read all available data off the
1177 * socket first. #SoupSocket::readable is only emitted after
1178 * soup_socket_read() returns %SOUP_SOCKET_WOULD_BLOCK, and it is only
1179 * emitted once. See the documentation for #SoupSocket:non-blocking.)
1181 * Return value: a #SoupSocketIOStatus, as described above (or
1182 * %SOUP_SOCKET_EOF if the socket is no longer connected, or
1183 * %SOUP_SOCKET_ERROR on any other error, in which case @error will
1187 soup_socket_read (SoupSocket *sock, gpointer buffer, gsize len,
1188 gsize *nread, GCancellable *cancellable, GError **error)
1190 SoupSocketPrivate *priv;
1191 SoupSocketIOStatus status;
1193 g_return_val_if_fail (SOUP_IS_SOCKET (sock), SOUP_SOCKET_ERROR);
1194 g_return_val_if_fail (nread != NULL, SOUP_SOCKET_ERROR);
1196 priv = SOUP_SOCKET_GET_PRIVATE (sock);
1198 g_mutex_lock (priv->iolock);
1200 status = read_from_buf (sock, buffer, len, nread);
1202 status = read_from_network (sock, buffer, len, nread, cancellable, error);
1203 g_mutex_unlock (priv->iolock);
1209 * soup_socket_read_until:
1211 * @buffer: buffer to read into
1212 * @len: size of @buffer in bytes
1213 * @boundary: boundary to read until
1214 * @boundary_len: length of @boundary in bytes
1215 * @nread: on return, the number of bytes read into @buffer
1216 * @got_boundary: on return, whether or not the data in @buffer
1217 * ends with the boundary string
1218 * @cancellable: a #GCancellable, or %NULL
1219 * @error: error pointer
1221 * Like soup_socket_read(), but reads no further than the first
1222 * occurrence of @boundary. (If the boundary is found, it will be
1223 * included in the returned data, and *@got_boundary will be set to
1224 * %TRUE.) Any data after the boundary will returned in future reads.
1226 * soup_socket_read_until() will almost always return fewer than @len
1227 * bytes: if the boundary is found, then it will only return the bytes
1228 * up until the end of the boundary, and if the boundary is not found,
1229 * then it will leave the last <literal>(boundary_len - 1)</literal>
1230 * bytes in its internal buffer, in case they form the start of the
1231 * boundary string. Thus, @len normally needs to be at least 1 byte
1232 * longer than @boundary_len if you want to make any progress at all.
1234 * Return value: as for soup_socket_read()
1237 soup_socket_read_until (SoupSocket *sock, gpointer buffer, gsize len,
1238 gconstpointer boundary, gsize boundary_len,
1239 gsize *nread, gboolean *got_boundary,
1240 GCancellable *cancellable, GError **error)
1242 SoupSocketPrivate *priv;
1243 SoupSocketIOStatus status;
1244 GByteArray *read_buf;
1245 guint match_len, prev_len;
1248 g_return_val_if_fail (SOUP_IS_SOCKET (sock), SOUP_SOCKET_ERROR);
1249 g_return_val_if_fail (nread != NULL, SOUP_SOCKET_ERROR);
1250 g_return_val_if_fail (len >= boundary_len, SOUP_SOCKET_ERROR);
1252 priv = SOUP_SOCKET_GET_PRIVATE (sock);
1254 g_mutex_lock (priv->iolock);
1256 *got_boundary = FALSE;
1258 if (!priv->read_buf)
1259 priv->read_buf = g_byte_array_new ();
1260 read_buf = priv->read_buf;
1262 if (read_buf->len < boundary_len) {
1263 prev_len = read_buf->len;
1264 g_byte_array_set_size (read_buf, len);
1265 status = read_from_network (sock,
1266 read_buf->data + prev_len,
1267 len - prev_len, nread, cancellable, error);
1268 read_buf->len = prev_len + *nread;
1270 if (status != SOUP_SOCKET_OK) {
1271 g_mutex_unlock (priv->iolock);
1276 /* Scan for the boundary */
1277 end = read_buf->data + read_buf->len;
1278 for (p = read_buf->data; p <= end - boundary_len; p++) {
1279 if (!memcmp (p, boundary, boundary_len)) {
1281 *got_boundary = TRUE;
1286 /* Return everything up to 'p' (which is either just after the
1287 * boundary, or @boundary_len - 1 bytes before the end of the
1290 match_len = p - read_buf->data;
1291 status = read_from_buf (sock, buffer, MIN (len, match_len), nread);
1293 g_mutex_unlock (priv->iolock);
1298 socket_write_watch (GObject *pollable, gpointer user_data)
1300 SoupSocket *sock = user_data;
1301 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
1303 priv->write_src = NULL;
1304 g_signal_emit (sock, signals[WRITABLE], 0);
1309 * soup_socket_write:
1311 * @buffer: data to write
1312 * @len: size of @buffer, in bytes
1313 * @nwrote: on return, number of bytes written
1314 * @cancellable: a #GCancellable, or %NULL
1315 * @error: error pointer
1317 * Attempts to write @len bytes from @buffer to @sock. If some data is
1318 * successfully written, the return status will be %SOUP_SOCKET_OK,
1319 * and *@nwrote will contain the number of bytes actually written
1320 * (which may be less than @len).
1322 * If @sock is non-blocking, and no data could be written right away,
1323 * the return value will be %SOUP_SOCKET_WOULD_BLOCK. In this case,
1324 * the caller can connect to the #SoupSocket::writable signal to know
1325 * when more data can be written. (NB: #SoupSocket::writable is only
1326 * emitted after soup_socket_write() returns %SOUP_SOCKET_WOULD_BLOCK,
1327 * and it is only emitted once. See the documentation for
1328 * #SoupSocket:non-blocking.)
1330 * Return value: a #SoupSocketIOStatus, as described above (or
1331 * %SOUP_SOCKET_EOF or %SOUP_SOCKET_ERROR. @error will be set if the
1332 * return value is %SOUP_SOCKET_ERROR.)
1335 soup_socket_write (SoupSocket *sock, gconstpointer buffer,
1336 gsize len, gsize *nwrote,
1337 GCancellable *cancellable, GError **error)
1339 SoupSocketPrivate *priv;
1340 GError *my_err = NULL;
1343 g_return_val_if_fail (SOUP_IS_SOCKET (sock), SOUP_SOCKET_ERROR);
1344 g_return_val_if_fail (nwrote != NULL, SOUP_SOCKET_ERROR);
1346 priv = SOUP_SOCKET_GET_PRIVATE (sock);
1348 g_mutex_lock (priv->iolock);
1351 g_mutex_unlock (priv->iolock);
1352 return SOUP_SOCKET_EOF;
1354 if (priv->write_src) {
1355 g_mutex_unlock (priv->iolock);
1356 return SOUP_SOCKET_WOULD_BLOCK;
1359 if (!priv->non_blocking) {
1360 my_nwrote = g_output_stream_write (G_OUTPUT_STREAM (priv->ostream),
1362 cancellable, &my_err);
1364 my_nwrote = g_pollable_output_stream_write_nonblocking (
1365 priv->ostream, buffer, len,
1366 cancellable, &my_err);
1369 if (my_nwrote > 0) {
1370 g_mutex_unlock (priv->iolock);
1371 g_clear_error (&my_err);
1372 *nwrote = my_nwrote;
1373 return SOUP_SOCKET_OK;
1376 if (g_error_matches (my_err, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) {
1377 g_mutex_unlock (priv->iolock);
1380 soup_socket_create_watch (priv,
1382 socket_write_watch, sock, cancellable);
1383 return SOUP_SOCKET_WOULD_BLOCK;
1384 } else if (g_error_matches (my_err, G_TLS_ERROR, G_TLS_ERROR_HANDSHAKE)) {
1385 my_err->domain = SOUP_SSL_ERROR;
1386 my_err->code = SOUP_SSL_ERROR_CERTIFICATE;
1389 g_mutex_unlock (priv->iolock);
1390 g_propagate_error (error, my_err);
1391 return SOUP_SOCKET_ERROR;