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, gboolean close)
120 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
124 g_socket_close (priv->gsock, NULL);
125 g_object_unref (priv->gsock);
129 if (G_IS_TLS_CONNECTION (priv->conn))
130 g_signal_handlers_disconnect_by_func (priv->conn, soup_socket_peer_certificate_changed, sock);
131 g_object_unref (priv->conn);
133 priv->istream = NULL;
134 priv->ostream = NULL;
137 if (priv->read_src) {
138 g_source_destroy (priv->read_src);
139 priv->read_src = NULL;
141 if (priv->write_src) {
142 g_source_destroy (priv->write_src);
143 priv->write_src = NULL;
148 finalize (GObject *object)
150 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (object);
152 if (priv->connect_cancel) {
153 if (priv->clean_dispose)
154 g_warning ("Disposing socket %p during connect", object);
155 g_object_unref (priv->connect_cancel);
158 if (priv->clean_dispose)
159 g_warning ("Disposing socket %p while still connected", object);
160 disconnect_internal (SOUP_SOCKET (object), TRUE);
163 if (priv->local_addr)
164 g_object_unref (priv->local_addr);
165 if (priv->remote_addr)
166 g_object_unref (priv->remote_addr);
168 if (priv->watch_src) {
169 if (priv->clean_dispose && !priv->is_server)
170 g_warning ("Disposing socket %p during async op", object);
171 g_source_destroy (priv->watch_src);
173 if (priv->async_context)
174 g_main_context_unref (priv->async_context);
177 g_byte_array_free (priv->read_buf, TRUE);
179 g_mutex_clear (&priv->addrlock);
180 g_mutex_clear (&priv->iolock);
182 G_OBJECT_CLASS (soup_socket_parent_class)->finalize (object);
186 soup_socket_class_init (SoupSocketClass *socket_class)
188 GObjectClass *object_class = G_OBJECT_CLASS (socket_class);
190 g_type_class_add_private (socket_class, sizeof (SoupSocketPrivate));
192 /* virtual method override */
193 object_class->finalize = finalize;
194 object_class->set_property = set_property;
195 object_class->get_property = get_property;
200 * SoupSocket::readable:
203 * Emitted when an async socket is readable. See
204 * soup_socket_read(), soup_socket_read_until() and
205 * #SoupSocket:non-blocking.
208 g_signal_new ("readable",
209 G_OBJECT_CLASS_TYPE (object_class),
211 G_STRUCT_OFFSET (SoupSocketClass, readable),
213 _soup_marshal_NONE__NONE,
217 * SoupSocket::writable:
220 * Emitted when an async socket is writable. See
221 * soup_socket_write() and #SoupSocket:non-blocking.
224 g_signal_new ("writable",
225 G_OBJECT_CLASS_TYPE (object_class),
227 G_STRUCT_OFFSET (SoupSocketClass, writable),
229 _soup_marshal_NONE__NONE,
233 * SoupSocket::disconnected:
236 * Emitted when the socket is disconnected, for whatever
239 signals[DISCONNECTED] =
240 g_signal_new ("disconnected",
241 G_OBJECT_CLASS_TYPE (object_class),
243 G_STRUCT_OFFSET (SoupSocketClass, disconnected),
245 _soup_marshal_NONE__NONE,
249 * SoupSocket::new-connection:
251 * @new: the new socket
253 * Emitted when a listening socket (set up with
254 * soup_socket_listen()) receives a new connection.
256 * You must ref the @new if you want to keep it; otherwise it
257 * will be destroyed after the signal is emitted.
259 signals[NEW_CONNECTION] =
260 g_signal_new ("new_connection",
261 G_OBJECT_CLASS_TYPE (object_class),
263 G_STRUCT_OFFSET (SoupSocketClass, new_connection),
265 _soup_marshal_NONE__OBJECT,
271 * @event: the event that occurred
272 * @connection: the current connection state
274 * Emitted when a network-related event occurs. See
275 * #GSocketClient::event for more details.
280 g_signal_new ("event",
281 G_OBJECT_CLASS_TYPE (object_class),
287 G_TYPE_SOCKET_CLIENT_EVENT,
293 * SOUP_SOCKET_LOCAL_ADDRESS:
295 * Alias for the #SoupSocket:local-address property. (Address
296 * of local end of socket.)
298 g_object_class_install_property (
299 object_class, PROP_LOCAL_ADDRESS,
300 g_param_spec_object (SOUP_SOCKET_LOCAL_ADDRESS,
302 "Address of local end of socket",
304 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
306 * SOUP_SOCKET_REMOTE_ADDRESS:
308 * Alias for the #SoupSocket:remote-address property. (Address
309 * of remote end of socket.)
311 g_object_class_install_property (
312 object_class, PROP_REMOTE_ADDRESS,
313 g_param_spec_object (SOUP_SOCKET_REMOTE_ADDRESS,
315 "Address of remote end of socket",
317 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
319 * SoupSocket:non-blocking:
321 * Whether or not the socket uses non-blocking I/O.
323 * #SoupSocket's I/O methods are designed around the idea of
324 * using a single codepath for both synchronous and
325 * asynchronous I/O. If you want to read off a #SoupSocket,
326 * the "correct" way to do it is to call soup_socket_read() or
327 * soup_socket_read_until() repeatedly until you have read
328 * everything you want. If it returns %SOUP_SOCKET_WOULD_BLOCK
329 * at any point, stop reading and wait for it to emit the
330 * #SoupSocket::readable signal. Then go back to the
331 * reading-as-much-as-you-can loop. Likewise, for writing to a
332 * #SoupSocket, you should call soup_socket_write() either
333 * until you have written everything, or it returns
334 * %SOUP_SOCKET_WOULD_BLOCK (in which case you wait for
335 * #SoupSocket::writable and then go back into the loop).
337 * Code written this way will work correctly with both
338 * blocking and non-blocking sockets; blocking sockets will
339 * simply never return %SOUP_SOCKET_WOULD_BLOCK, and so the
340 * code that handles that case just won't get used for them.
343 * SOUP_SOCKET_FLAG_NONBLOCKING:
345 * Alias for the #SoupSocket:non-blocking property. (Whether
346 * or not the socket uses non-blocking I/O.)
348 g_object_class_install_property (
349 object_class, PROP_NON_BLOCKING,
350 g_param_spec_boolean (SOUP_SOCKET_FLAG_NONBLOCKING,
352 "Whether or not the socket uses non-blocking I/O",
356 * SOUP_SOCKET_IS_SERVER:
358 * Alias for the #SoupSocket:is-server property. (Whether or
359 * not the socket is a server socket.)
361 g_object_class_install_property (
362 object_class, PROP_IS_SERVER,
363 g_param_spec_boolean (SOUP_SOCKET_IS_SERVER,
365 "Whether or not the socket is a server socket",
369 * SOUP_SOCKET_SSL_CREDENTIALS:
371 * Alias for the #SoupSocket:ssl-creds property.
372 * (SSL credential information.)
374 /* For historical reasons, there's only a single property
375 * here, which is a GTlsDatabase for client sockets, and
376 * a GTlsCertificate for server sockets. Whee!
378 g_object_class_install_property (
379 object_class, PROP_SSL_CREDENTIALS,
380 g_param_spec_pointer (SOUP_SOCKET_SSL_CREDENTIALS,
382 "SSL credential information, passed from the session to the SSL implementation",
385 * SOUP_SOCKET_SSL_STRICT:
387 * Alias for the #SoupSocket:ssl-strict property.
389 g_object_class_install_property (
390 object_class, PROP_SSL_STRICT,
391 g_param_spec_boolean (SOUP_SOCKET_SSL_STRICT,
392 "Strictly validate SSL certificates",
393 "Whether certificate errors should be considered a connection error",
395 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
397 * SOUP_SOCKET_SSL_FALLBACK:
399 * Alias for the #SoupSocket:ssl-fallback property.
401 g_object_class_install_property (
402 object_class, PROP_SSL_FALLBACK,
403 g_param_spec_boolean (SOUP_SOCKET_SSL_FALLBACK,
405 "Use SSLv3 instead of TLS (client-side only)",
407 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
409 * SOUP_SOCKET_TRUSTED_CERTIFICATE:
411 * Alias for the #SoupSocket:trusted-certificate
414 g_object_class_install_property (
415 object_class, PROP_TRUSTED_CERTIFICATE,
416 g_param_spec_boolean (SOUP_SOCKET_TRUSTED_CERTIFICATE,
417 "Trusted Certificate",
418 "Whether the server certificate is trusted, if this is an SSL socket",
422 * SOUP_SOCKET_ASYNC_CONTEXT:
424 * Alias for the #SoupSocket:async-context property. (The
425 * socket's #GMainContext.)
427 g_object_class_install_property (
428 object_class, PROP_ASYNC_CONTEXT,
429 g_param_spec_pointer (SOUP_SOCKET_ASYNC_CONTEXT,
430 "Async GMainContext",
431 "The GMainContext to dispatch this socket's async I/O in",
432 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
435 * SOUP_SOCKET_USE_THREAD_CONTEXT:
437 * Alias for the #SoupSocket:use-thread-context property. (Use
438 * g_main_context_get_thread_default())
443 * SoupSocket:use-thread-context:
445 * Use g_main_context_get_thread_default().
449 g_object_class_install_property (
450 object_class, PROP_USE_THREAD_CONTEXT,
451 g_param_spec_boolean (SOUP_SOCKET_USE_THREAD_CONTEXT,
452 "Use thread context",
453 "Use g_main_context_get_thread_default",
455 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
458 * SOUP_SOCKET_TIMEOUT:
460 * Alias for the #SoupSocket:timeout property. (The timeout
461 * in seconds for blocking socket I/O operations.)
463 g_object_class_install_property (
464 object_class, PROP_TIMEOUT,
465 g_param_spec_uint (SOUP_SOCKET_TIMEOUT,
467 "Value in seconds to timeout a blocking I/O",
471 g_object_class_install_property (
472 object_class, PROP_CLEAN_DISPOSE,
473 g_param_spec_boolean ("clean-dispose",
475 "Warn on unclean dispose",
477 G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
479 * SOUP_SOCKET_TLS_CERTIFICATE:
481 * Alias for the #SoupSocket:tls-certificate
482 * property. Note that this property's value is only useful
483 * if the socket is for a TLS connection, and only reliable
484 * after some data has been transferred to or from it.
488 g_object_class_install_property (
489 object_class, PROP_TLS_CERTIFICATE,
490 g_param_spec_object (SOUP_SOCKET_TLS_CERTIFICATE,
492 "The peer's TLS certificate",
493 G_TYPE_TLS_CERTIFICATE,
496 * SOUP_SOCKET_TLS_ERRORS:
498 * Alias for the #SoupSocket:tls-errors
499 * property. Note that this property's value is only useful
500 * if the socket is for a TLS connection, and only reliable
501 * after some data has been transferred to or from it.
505 g_object_class_install_property (
506 object_class, PROP_TLS_ERRORS,
507 g_param_spec_flags (SOUP_SOCKET_TLS_ERRORS,
509 "Errors with the peer's TLS certificate",
510 G_TYPE_TLS_CERTIFICATE_FLAGS, 0,
516 finish_socket_setup (SoupSocketPrivate *priv)
522 priv->conn = (GIOStream *)g_socket_connection_factory_create_connection (priv->gsock);
524 priv->istream = G_POLLABLE_INPUT_STREAM (g_io_stream_get_input_stream (priv->conn));
526 priv->ostream = G_POLLABLE_OUTPUT_STREAM (g_io_stream_get_output_stream (priv->conn));
528 g_socket_set_timeout (priv->gsock, priv->timeout);
532 set_property (GObject *object, guint prop_id,
533 const GValue *value, GParamSpec *pspec)
535 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (object);
538 case PROP_LOCAL_ADDRESS:
539 priv->local_addr = (SoupAddress *)g_value_dup_object (value);
541 case PROP_REMOTE_ADDRESS:
542 priv->remote_addr = (SoupAddress *)g_value_dup_object (value);
544 case PROP_NON_BLOCKING:
545 priv->non_blocking = g_value_get_boolean (value);
547 case PROP_SSL_CREDENTIALS:
548 priv->ssl_creds = g_value_get_pointer (value);
550 case PROP_SSL_STRICT:
551 priv->ssl_strict = g_value_get_boolean (value);
553 case PROP_SSL_FALLBACK:
554 priv->ssl_fallback = g_value_get_boolean (value);
556 case PROP_ASYNC_CONTEXT:
557 priv->async_context = g_value_get_pointer (value);
558 if (priv->async_context)
559 g_main_context_ref (priv->async_context);
561 case PROP_USE_THREAD_CONTEXT:
562 priv->use_thread_context = g_value_get_boolean (value);
565 priv->timeout = g_value_get_uint (value);
567 g_socket_set_timeout (priv->gsock, priv->timeout);
569 case PROP_CLEAN_DISPOSE:
570 priv->clean_dispose = g_value_get_boolean (value);
573 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
579 get_property (GObject *object, guint prop_id,
580 GValue *value, GParamSpec *pspec)
582 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (object);
585 case PROP_LOCAL_ADDRESS:
586 g_value_set_object (value, soup_socket_get_local_address (SOUP_SOCKET (object)));
588 case PROP_REMOTE_ADDRESS:
589 g_value_set_object (value, soup_socket_get_remote_address (SOUP_SOCKET (object)));
591 case PROP_NON_BLOCKING:
592 g_value_set_boolean (value, priv->non_blocking);
595 g_value_set_boolean (value, priv->is_server);
597 case PROP_SSL_CREDENTIALS:
598 g_value_set_pointer (value, priv->ssl_creds);
600 case PROP_SSL_STRICT:
601 g_value_set_boolean (value, priv->ssl_strict);
603 case PROP_SSL_FALLBACK:
604 g_value_set_boolean (value, priv->ssl_fallback);
606 case PROP_TRUSTED_CERTIFICATE:
607 g_value_set_boolean (value, priv->tls_errors == 0);
609 case PROP_ASYNC_CONTEXT:
610 g_value_set_pointer (value, priv->async_context ? g_main_context_ref (priv->async_context) : NULL);
612 case PROP_USE_THREAD_CONTEXT:
613 g_value_set_boolean (value, priv->use_thread_context);
616 g_value_set_uint (value, priv->timeout);
618 case PROP_TLS_CERTIFICATE:
619 if (G_IS_TLS_CONNECTION (priv->conn))
620 g_value_set_object (value, g_tls_connection_get_peer_certificate (G_TLS_CONNECTION (priv->conn)));
622 g_value_set_object (value, NULL);
624 case PROP_TLS_ERRORS:
625 g_value_set_flags (value, priv->tls_errors);
628 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
636 * @optname1: name of first property to set (or %NULL)
637 * @...: value of @optname1, followed by additional property/value pairs
639 * Creates a new (disconnected) socket
641 * Return value: the new socket
644 soup_socket_new (const char *optname1, ...)
649 va_start (ap, optname1);
650 sock = (SoupSocket *)g_object_new_valist (SOUP_TYPE_SOCKET,
658 proxy_socket_client_event (GSocketClient *client,
659 GSocketClientEvent event,
660 GSocketConnectable *connectable,
661 GIOStream *connection,
664 SoupSocket *sock = user_data;
666 g_signal_emit (sock, signals[EVENT], 0,
671 socket_connected (SoupSocket *sock, GSocketConnection *conn, GError *error)
673 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
675 if (priv->connect_cancel) {
676 GCancellable *cancellable = priv->connect_cancel;
678 g_object_unref (priv->connect_cancel);
679 priv->connect_cancel = NULL;
680 if (g_cancellable_is_cancelled (cancellable))
681 return SOUP_STATUS_CANCELLED;
685 if (error->domain == G_RESOLVER_ERROR) {
686 g_error_free (error);
687 return SOUP_STATUS_CANT_RESOLVE;
689 g_error_free (error);
690 return SOUP_STATUS_CANT_CONNECT;
694 priv->conn = (GIOStream *)conn;
695 priv->gsock = g_object_ref (g_socket_connection_get_socket (conn));
696 finish_socket_setup (priv);
698 return SOUP_STATUS_OK;
702 * SoupSocketCallback:
703 * @sock: the #SoupSocket
704 * @status: an HTTP status code indicating success or failure
705 * @user_data: the data passed to soup_socket_connect_async()
707 * The callback function passed to soup_socket_connect_async().
712 SoupSocketCallback callback;
714 } SoupSocketAsyncConnectData;
717 async_connected (GObject *client, GAsyncResult *result, gpointer data)
719 SoupSocketAsyncConnectData *sacd = data;
720 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sacd->sock);
721 GError *error = NULL;
722 GSocketConnection *conn;
725 if (priv->async_context && !priv->use_thread_context)
726 g_main_context_pop_thread_default (priv->async_context);
728 conn = g_socket_client_connect_finish (G_SOCKET_CLIENT (client),
730 status = socket_connected (sacd->sock, conn, error);
732 sacd->callback (sacd->sock, status, sacd->user_data);
733 g_object_unref (sacd->sock);
734 g_slice_free (SoupSocketAsyncConnectData, sacd);
738 * soup_socket_connect_async:
739 * @sock: a client #SoupSocket (which must not already be connected)
740 * @cancellable: a #GCancellable, or %NULL
741 * @callback: (scope async): callback to call after connecting
742 * @user_data: data to pass to @callback
744 * Begins asynchronously connecting to @sock's remote address. The
745 * socket will call @callback when it succeeds or fails (but not
746 * before returning from this function).
748 * If @cancellable is non-%NULL, it can be used to cancel the
749 * connection. @callback will still be invoked in this case, with a
750 * status of %SOUP_STATUS_CANCELLED.
753 soup_socket_connect_async (SoupSocket *sock, GCancellable *cancellable,
754 SoupSocketCallback callback, gpointer user_data)
756 SoupSocketPrivate *priv;
757 SoupSocketAsyncConnectData *sacd;
758 GSocketClient *client;
760 g_return_if_fail (SOUP_IS_SOCKET (sock));
761 priv = SOUP_SOCKET_GET_PRIVATE (sock);
762 g_return_if_fail (priv->remote_addr != NULL);
764 sacd = g_slice_new0 (SoupSocketAsyncConnectData);
765 sacd->sock = g_object_ref (sock);
766 sacd->callback = callback;
767 sacd->user_data = user_data;
769 priv->connect_cancel = cancellable ? g_object_ref (cancellable) : g_cancellable_new ();
771 if (priv->async_context && !priv->use_thread_context)
772 g_main_context_push_thread_default (priv->async_context);
774 client = g_socket_client_new ();
775 g_signal_connect (client, "event",
776 G_CALLBACK (proxy_socket_client_event), sock);
778 g_socket_client_set_timeout (client, priv->timeout);
779 g_socket_client_connect_async (client,
780 G_SOCKET_CONNECTABLE (priv->remote_addr),
781 priv->connect_cancel,
782 async_connected, sacd);
783 g_object_unref (client);
787 * soup_socket_connect_sync:
788 * @sock: a client #SoupSocket (which must not already be connected)
789 * @cancellable: a #GCancellable, or %NULL
791 * Attempt to synchronously connect @sock to its remote address.
793 * If @cancellable is non-%NULL, it can be used to cancel the
794 * connection, in which case soup_socket_connect_sync() will return
795 * %SOUP_STATUS_CANCELLED.
797 * Return value: a success or failure code.
800 soup_socket_connect_sync (SoupSocket *sock, GCancellable *cancellable)
802 SoupSocketPrivate *priv;
803 GSocketClient *client;
804 GSocketConnection *conn;
805 GError *error = NULL;
807 g_return_val_if_fail (SOUP_IS_SOCKET (sock), SOUP_STATUS_MALFORMED);
808 priv = SOUP_SOCKET_GET_PRIVATE (sock);
809 g_return_val_if_fail (!priv->is_server, SOUP_STATUS_MALFORMED);
810 g_return_val_if_fail (priv->gsock == NULL, SOUP_STATUS_MALFORMED);
811 g_return_val_if_fail (priv->remote_addr != NULL, SOUP_STATUS_MALFORMED);
814 g_object_ref (cancellable);
816 cancellable = g_cancellable_new ();
817 priv->connect_cancel = cancellable;
819 client = g_socket_client_new ();
820 g_signal_connect (client, "event",
821 G_CALLBACK (proxy_socket_client_event), sock);
823 g_socket_client_set_timeout (client, priv->timeout);
824 conn = g_socket_client_connect (client,
825 G_SOCKET_CONNECTABLE (priv->remote_addr),
826 priv->connect_cancel, &error);
827 g_object_unref (client);
829 return socket_connected (sock, conn, error);
833 soup_socket_get_fd (SoupSocket *sock)
835 g_return_val_if_fail (SOUP_IS_SOCKET (sock), -1);
837 return g_socket_get_fd (SOUP_SOCKET_GET_PRIVATE (sock)->gsock);
841 soup_socket_get_gsocket (SoupSocket *sock)
843 g_return_val_if_fail (SOUP_IS_SOCKET (sock), NULL);
845 return SOUP_SOCKET_GET_PRIVATE (sock)->gsock;
849 soup_socket_get_iostream (SoupSocket *sock)
851 g_return_val_if_fail (SOUP_IS_SOCKET (sock), NULL);
853 return SOUP_SOCKET_GET_PRIVATE (sock)->conn;
857 soup_socket_create_watch (SoupSocketPrivate *priv, GIOCondition cond,
858 GPollableSourceFunc callback, gpointer user_data,
859 GCancellable *cancellable)
862 GMainContext *async_context;
865 watch = g_pollable_input_stream_create_source (priv->istream, cancellable);
867 watch = g_pollable_output_stream_create_source (priv->ostream, cancellable);
868 g_source_set_callback (watch, (GSourceFunc)callback, user_data, NULL);
870 if (priv->use_thread_context)
871 async_context = g_main_context_get_thread_default ();
873 async_context = priv->async_context;
875 g_source_attach (watch, async_context);
876 g_source_unref (watch);
882 listen_watch (GObject *pollable, gpointer data)
884 SoupSocket *sock = data, *new;
885 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock), *new_priv;
888 new_gsock = g_socket_accept (priv->gsock, NULL, NULL);
892 new = g_object_new (SOUP_TYPE_SOCKET, NULL);
893 new_priv = SOUP_SOCKET_GET_PRIVATE (new);
894 new_priv->gsock = new_gsock;
895 if (priv->async_context)
896 new_priv->async_context = g_main_context_ref (priv->async_context);
897 new_priv->use_thread_context = priv->use_thread_context;
898 new_priv->non_blocking = priv->non_blocking;
899 new_priv->is_server = TRUE;
900 new_priv->ssl = priv->ssl;
902 new_priv->ssl_creds = priv->ssl_creds;
903 finish_socket_setup (new_priv);
905 if (new_priv->ssl_creds) {
906 if (!soup_socket_start_proxy_ssl (new, NULL, NULL)) {
907 g_object_unref (new);
912 g_signal_emit (sock, signals[NEW_CONNECTION], 0, new);
913 g_object_unref (new);
919 * soup_socket_listen:
920 * @sock: a server #SoupSocket (which must not already be connected or
923 * Makes @sock start listening on its local address. When connections
924 * come in, @sock will emit #SoupSocket::new_connection.
926 * Return value: whether or not @sock is now listening.
929 soup_socket_listen (SoupSocket *sock)
932 SoupSocketPrivate *priv;
933 GSocketAddress *addr;
935 g_return_val_if_fail (SOUP_IS_SOCKET (sock), FALSE);
936 priv = SOUP_SOCKET_GET_PRIVATE (sock);
937 g_return_val_if_fail (priv->gsock == NULL, FALSE);
938 g_return_val_if_fail (priv->local_addr != NULL, FALSE);
940 priv->is_server = TRUE;
942 /* @local_addr may have its port set to 0. So we intentionally
943 * don't store it in priv->local_addr, so that if the
944 * caller calls soup_socket_get_local_address() later, we'll
945 * have to make a new addr by calling getsockname(), which
946 * will have the right port number.
948 addr = soup_address_get_gsockaddr (priv->local_addr);
949 g_return_val_if_fail (addr != NULL, FALSE);
951 priv->gsock = g_socket_new (g_socket_address_get_family (addr),
952 G_SOCKET_TYPE_STREAM,
953 G_SOCKET_PROTOCOL_DEFAULT,
957 finish_socket_setup (priv);
960 if (!g_socket_bind (priv->gsock, addr, TRUE, NULL))
962 /* Force local_addr to be re-resolved now */
963 g_object_unref (priv->local_addr);
964 priv->local_addr = NULL;
967 if (!g_socket_listen (priv->gsock, NULL))
970 priv->watch_src = soup_socket_create_watch (priv, G_IO_IN,
973 g_object_unref (addr);
978 disconnect_internal (sock, TRUE);
979 g_object_unref (addr);
985 soup_socket_peer_certificate_changed (GObject *conn, GParamSpec *pspec,
988 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
990 priv->tls_errors = g_tls_connection_get_peer_certificate_errors (G_TLS_CONNECTION (priv->conn));
992 g_object_notify (sock, "tls-certificate");
993 g_object_notify (sock, "tls-errors");
997 soup_socket_accept_certificate (GTlsConnection *conn, GTlsCertificate *cert,
998 GTlsCertificateFlags errors, gpointer sock)
1004 * soup_socket_start_ssl:
1006 * @cancellable: a #GCancellable
1008 * Starts using SSL on @socket.
1010 * Return value: success or failure
1013 soup_socket_start_ssl (SoupSocket *sock, GCancellable *cancellable)
1015 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
1017 return soup_socket_start_proxy_ssl (sock, soup_address_get_name (priv->remote_addr), cancellable);
1021 * soup_socket_start_proxy_ssl:
1023 * @ssl_host: hostname of the SSL server
1024 * @cancellable: a #GCancellable
1026 * Starts using SSL on @socket, expecting to find a host named
1029 * Return value: success or failure
1032 soup_socket_start_proxy_ssl (SoupSocket *sock, const char *ssl_host,
1033 GCancellable *cancellable)
1035 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
1036 GTlsBackend *backend = g_tls_backend_get_default ();
1038 if (G_IS_TLS_CONNECTION (priv->conn))
1041 if (g_cancellable_is_cancelled (cancellable))
1046 if (!priv->is_server) {
1047 GTlsClientConnection *conn;
1048 GSocketConnectable *identity;
1050 identity = g_network_address_new (ssl_host, 0);
1051 conn = g_initable_new (g_tls_backend_get_client_connection_type (backend),
1053 "base-io-stream", priv->conn,
1054 "server-identity", identity,
1055 "database", priv->ssl_creds,
1056 "require-close-notify", FALSE,
1057 "use-ssl3", priv->ssl_fallback,
1059 g_object_unref (identity);
1064 g_object_unref (priv->conn);
1065 priv->conn = G_IO_STREAM (conn);
1067 if (!priv->ssl_strict) {
1068 g_signal_connect (conn, "accept-certificate",
1069 G_CALLBACK (soup_socket_accept_certificate),
1073 GTlsServerConnection *conn;
1075 conn = g_initable_new (g_tls_backend_get_server_connection_type (backend),
1077 "base-io-stream", priv->conn,
1078 "certificate", priv->ssl_creds,
1079 "use-system-certdb", FALSE,
1080 "require-close-notify", FALSE,
1085 g_object_unref (priv->conn);
1086 priv->conn = G_IO_STREAM (conn);
1089 g_signal_connect (priv->conn, "notify::peer-certificate",
1090 G_CALLBACK (soup_socket_peer_certificate_changed), sock);
1092 priv->istream = G_POLLABLE_INPUT_STREAM (g_io_stream_get_input_stream (priv->conn));
1093 priv->ostream = G_POLLABLE_OUTPUT_STREAM (g_io_stream_get_output_stream (priv->conn));
1098 soup_socket_handshake_sync (SoupSocket *sock,
1099 GCancellable *cancellable)
1101 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
1102 GError *error = NULL;
1105 if (g_tls_connection_handshake (G_TLS_CONNECTION (priv->conn),
1106 cancellable, &error))
1107 return SOUP_STATUS_OK;
1108 else if (!priv->ssl_fallback &&
1109 g_error_matches (error, G_TLS_ERROR, G_TLS_ERROR_NOT_TLS)) {
1110 g_error_free (error);
1111 return SOUP_STATUS_TLS_FAILED;
1113 g_error_free (error);
1114 return SOUP_STATUS_SSL_FAILED;
1119 handshake_async_ready (GObject *source, GAsyncResult *result, gpointer user_data)
1121 SoupSocketAsyncConnectData *data = user_data;
1122 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (data->sock);
1123 GError *error = NULL;
1126 if (priv->async_context && !priv->use_thread_context)
1127 g_main_context_pop_thread_default (priv->async_context);
1129 if (g_tls_connection_handshake_finish (G_TLS_CONNECTION (source),
1131 status = SOUP_STATUS_OK;
1132 else if (!priv->ssl_fallback &&
1133 g_error_matches (error, G_TLS_ERROR, G_TLS_ERROR_NOT_TLS))
1134 status = SOUP_STATUS_TLS_FAILED;
1136 status = SOUP_STATUS_SSL_FAILED;
1137 g_clear_error (&error);
1139 data->callback (data->sock, status, data->user_data);
1140 g_object_unref (data->sock);
1141 g_slice_free (SoupSocketAsyncConnectData, data);
1145 soup_socket_handshake_async (SoupSocket *sock,
1146 GCancellable *cancellable,
1147 SoupSocketCallback callback,
1150 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
1151 SoupSocketAsyncConnectData *data;
1155 data = g_slice_new (SoupSocketAsyncConnectData);
1156 data->sock = g_object_ref (sock);
1157 data->callback = callback;
1158 data->user_data = user_data;
1160 if (priv->async_context && !priv->use_thread_context)
1161 g_main_context_push_thread_default (priv->async_context);
1162 g_tls_connection_handshake_async (G_TLS_CONNECTION (priv->conn),
1164 cancellable, handshake_async_ready,
1169 * soup_socket_is_ssl:
1170 * @sock: a #SoupSocket
1172 * Tests if @sock is doing (or has attempted to do) SSL.
1174 * Return value: %TRUE if @sock has SSL credentials set
1177 soup_socket_is_ssl (SoupSocket *sock)
1179 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
1185 * soup_socket_disconnect:
1186 * @sock: a #SoupSocket
1188 * Disconnects @sock. Any further read or write attempts on it will
1192 soup_socket_disconnect (SoupSocket *sock)
1194 SoupSocketPrivate *priv;
1195 gboolean already_disconnected = FALSE;
1197 g_return_if_fail (SOUP_IS_SOCKET (sock));
1198 priv = SOUP_SOCKET_GET_PRIVATE (sock);
1200 if (priv->connect_cancel) {
1201 disconnect_internal (sock, FALSE);
1202 g_cancellable_cancel (priv->connect_cancel);
1204 } else if (g_mutex_trylock (&priv->iolock)) {
1206 disconnect_internal (sock, TRUE);
1208 already_disconnected = TRUE;
1209 g_mutex_unlock (&priv->iolock);
1211 /* Another thread is currently doing IO, so
1212 * we can't close the socket. So just shutdown
1213 * the file descriptor to force the I/O to fail.
1214 * (It will actually be closed when the socket
1217 g_socket_shutdown (priv->gsock, TRUE, TRUE, NULL);
1220 if (already_disconnected)
1223 /* Keep ref around signals in case the object is unreferenced
1226 g_object_ref (sock);
1228 /* Give all readers a chance to notice the connection close */
1229 g_signal_emit (sock, signals[READABLE], 0);
1231 /* FIXME: can't disconnect until all data is read */
1233 /* Then let everyone know we're disconnected */
1234 g_signal_emit (sock, signals[DISCONNECTED], 0);
1236 g_object_unref (sock);
1240 * soup_socket_is_connected:
1241 * @sock: a #SoupSocket
1243 * Tests if @sock is connected to another host
1245 * Return value: %TRUE or %FALSE.
1248 soup_socket_is_connected (SoupSocket *sock)
1250 SoupSocketPrivate *priv;
1252 g_return_val_if_fail (SOUP_IS_SOCKET (sock), FALSE);
1253 priv = SOUP_SOCKET_GET_PRIVATE (sock);
1255 return priv->conn != NULL;
1259 * soup_socket_get_local_address:
1260 * @sock: a #SoupSocket
1262 * Returns the #SoupAddress corresponding to the local end of @sock.
1264 * Return value: (transfer none): the #SoupAddress
1267 soup_socket_get_local_address (SoupSocket *sock)
1269 SoupSocketPrivate *priv;
1271 g_return_val_if_fail (SOUP_IS_SOCKET (sock), NULL);
1272 priv = SOUP_SOCKET_GET_PRIVATE (sock);
1274 g_mutex_lock (&priv->addrlock);
1275 if (!priv->local_addr) {
1276 GSocketAddress *addr;
1277 struct sockaddr_storage sa;
1280 addr = g_socket_get_local_address (priv->gsock, NULL);
1281 sa_len = g_socket_address_get_native_size (addr);
1282 g_socket_address_to_native (addr, &sa, sa_len, NULL);
1283 priv->local_addr = soup_address_new_from_sockaddr ((struct sockaddr *)&sa, sa_len);
1284 g_object_unref (addr);
1286 g_mutex_unlock (&priv->addrlock);
1288 return priv->local_addr;
1292 * soup_socket_get_remote_address:
1293 * @sock: a #SoupSocket
1295 * Returns the #SoupAddress corresponding to the remote end of @sock.
1297 * Return value: (transfer none): the #SoupAddress
1300 soup_socket_get_remote_address (SoupSocket *sock)
1302 SoupSocketPrivate *priv;
1304 g_return_val_if_fail (SOUP_IS_SOCKET (sock), NULL);
1305 priv = SOUP_SOCKET_GET_PRIVATE (sock);
1307 g_mutex_lock (&priv->addrlock);
1308 if (!priv->remote_addr) {
1309 GSocketAddress *addr;
1310 struct sockaddr_storage sa;
1313 addr = g_socket_get_remote_address (priv->gsock, NULL);
1314 sa_len = g_socket_address_get_native_size (addr);
1315 g_socket_address_to_native (addr, &sa, sa_len, NULL);
1316 priv->remote_addr = soup_address_new_from_sockaddr ((struct sockaddr *)&sa, sa_len);
1317 g_object_unref (addr);
1319 g_mutex_unlock (&priv->addrlock);
1321 return priv->remote_addr;
1326 socket_read_watch (GObject *pollable, gpointer user_data)
1328 SoupSocket *sock = user_data;
1329 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
1331 priv->read_src = NULL;
1332 g_signal_emit (sock, signals[READABLE], 0);
1336 static SoupSocketIOStatus
1337 read_from_network (SoupSocket *sock, gpointer buffer, gsize len,
1338 gsize *nread, GCancellable *cancellable, GError **error)
1340 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
1341 GError *my_err = NULL;
1347 return SOUP_SOCKET_EOF;
1349 if (!priv->non_blocking) {
1350 my_nread = g_input_stream_read (G_INPUT_STREAM (priv->istream),
1352 cancellable, &my_err);
1354 my_nread = g_pollable_input_stream_read_nonblocking (
1355 priv->istream, buffer, len,
1356 cancellable, &my_err);
1360 g_clear_error (&my_err);
1362 return SOUP_SOCKET_OK;
1363 } else if (my_nread == 0) {
1364 g_clear_error (&my_err);
1366 return SOUP_SOCKET_EOF;
1367 } else if (g_error_matches (my_err, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) {
1368 g_clear_error (&my_err);
1369 if (!priv->read_src) {
1371 soup_socket_create_watch (priv, G_IO_IN,
1372 socket_read_watch, sock,
1375 return SOUP_SOCKET_WOULD_BLOCK;
1378 g_propagate_error (error, my_err);
1379 return SOUP_SOCKET_ERROR;
1382 static SoupSocketIOStatus
1383 read_from_buf (SoupSocket *sock, gpointer buffer, gsize len, gsize *nread)
1385 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
1386 GByteArray *read_buf = priv->read_buf;
1388 *nread = MIN (read_buf->len, len);
1389 memcpy (buffer, read_buf->data, *nread);
1391 if (*nread == read_buf->len) {
1392 g_byte_array_free (read_buf, TRUE);
1393 priv->read_buf = NULL;
1395 memmove (read_buf->data, read_buf->data + *nread,
1396 read_buf->len - *nread);
1397 g_byte_array_set_size (read_buf, read_buf->len - *nread);
1400 return SOUP_SOCKET_OK;
1404 * SoupSocketIOStatus:
1405 * @SOUP_SOCKET_OK: Success
1406 * @SOUP_SOCKET_WOULD_BLOCK: Cannot read/write any more at this time
1407 * @SOUP_SOCKET_EOF: End of file
1408 * @SOUP_SOCKET_ERROR: Other error
1410 * Return value from the #SoupSocket IO methods.
1416 * @buffer: buffer to read into
1417 * @len: size of @buffer in bytes
1418 * @nread: (out): on return, the number of bytes read into @buffer
1419 * @cancellable: a #GCancellable, or %NULL
1420 * @error: error pointer
1422 * Attempts to read up to @len bytes from @sock into @buffer. If some
1423 * data is successfully read, soup_socket_read() will return
1424 * %SOUP_SOCKET_OK, and *@nread will contain the number of bytes
1425 * actually read (which may be less than @len).
1427 * If @sock is non-blocking, and no data is available, the return
1428 * value will be %SOUP_SOCKET_WOULD_BLOCK. In this case, the caller
1429 * can connect to the #SoupSocket::readable signal to know when there
1430 * is more data to read. (NB: You MUST read all available data off the
1431 * socket first. #SoupSocket::readable is only emitted after
1432 * soup_socket_read() returns %SOUP_SOCKET_WOULD_BLOCK, and it is only
1433 * emitted once. See the documentation for #SoupSocket:non-blocking.)
1435 * Return value: a #SoupSocketIOStatus, as described above (or
1436 * %SOUP_SOCKET_EOF if the socket is no longer connected, or
1437 * %SOUP_SOCKET_ERROR on any other error, in which case @error will
1441 soup_socket_read (SoupSocket *sock, gpointer buffer, gsize len,
1442 gsize *nread, GCancellable *cancellable, GError **error)
1444 SoupSocketPrivate *priv;
1445 SoupSocketIOStatus status;
1447 g_return_val_if_fail (SOUP_IS_SOCKET (sock), SOUP_SOCKET_ERROR);
1448 g_return_val_if_fail (nread != NULL, SOUP_SOCKET_ERROR);
1450 priv = SOUP_SOCKET_GET_PRIVATE (sock);
1452 g_mutex_lock (&priv->iolock);
1454 status = read_from_buf (sock, buffer, len, nread);
1456 status = read_from_network (sock, buffer, len, nread, cancellable, error);
1457 g_mutex_unlock (&priv->iolock);
1463 * soup_socket_read_until:
1465 * @buffer: buffer to read into
1466 * @len: size of @buffer in bytes
1467 * @boundary: boundary to read until
1468 * @boundary_len: length of @boundary in bytes
1469 * @nread: (out): on return, the number of bytes read into @buffer
1470 * @got_boundary: on return, whether or not the data in @buffer
1471 * ends with the boundary string
1472 * @cancellable: a #GCancellable, or %NULL
1473 * @error: error pointer
1475 * Like soup_socket_read(), but reads no further than the first
1476 * occurrence of @boundary. (If the boundary is found, it will be
1477 * included in the returned data, and *@got_boundary will be set to
1478 * %TRUE.) Any data after the boundary will returned in future reads.
1480 * soup_socket_read_until() will almost always return fewer than @len
1481 * bytes: if the boundary is found, then it will only return the bytes
1482 * up until the end of the boundary, and if the boundary is not found,
1483 * then it will leave the last <literal>(boundary_len - 1)</literal>
1484 * bytes in its internal buffer, in case they form the start of the
1485 * boundary string. Thus, @len normally needs to be at least 1 byte
1486 * longer than @boundary_len if you want to make any progress at all.
1488 * Return value: as for soup_socket_read()
1491 soup_socket_read_until (SoupSocket *sock, gpointer buffer, gsize len,
1492 gconstpointer boundary, gsize boundary_len,
1493 gsize *nread, gboolean *got_boundary,
1494 GCancellable *cancellable, GError **error)
1496 SoupSocketPrivate *priv;
1497 SoupSocketIOStatus status;
1498 GByteArray *read_buf;
1499 guint match_len, prev_len;
1502 g_return_val_if_fail (SOUP_IS_SOCKET (sock), SOUP_SOCKET_ERROR);
1503 g_return_val_if_fail (nread != NULL, SOUP_SOCKET_ERROR);
1504 g_return_val_if_fail (len >= boundary_len, SOUP_SOCKET_ERROR);
1506 priv = SOUP_SOCKET_GET_PRIVATE (sock);
1508 g_mutex_lock (&priv->iolock);
1510 *got_boundary = FALSE;
1512 if (!priv->read_buf)
1513 priv->read_buf = g_byte_array_new ();
1514 read_buf = priv->read_buf;
1516 if (read_buf->len < boundary_len) {
1517 prev_len = read_buf->len;
1518 g_byte_array_set_size (read_buf, len);
1519 status = read_from_network (sock,
1520 read_buf->data + prev_len,
1521 len - prev_len, nread, cancellable, error);
1522 read_buf->len = prev_len + *nread;
1524 if (status != SOUP_SOCKET_OK) {
1525 g_mutex_unlock (&priv->iolock);
1530 /* Scan for the boundary */
1531 end = read_buf->data + read_buf->len;
1532 for (p = read_buf->data; p <= end - boundary_len; p++) {
1533 if (!memcmp (p, boundary, boundary_len)) {
1535 *got_boundary = TRUE;
1540 /* Return everything up to 'p' (which is either just after the
1541 * boundary, or @boundary_len - 1 bytes before the end of the
1544 match_len = p - read_buf->data;
1545 status = read_from_buf (sock, buffer, MIN (len, match_len), nread);
1547 g_mutex_unlock (&priv->iolock);
1552 socket_write_watch (GObject *pollable, gpointer user_data)
1554 SoupSocket *sock = user_data;
1555 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
1557 priv->write_src = NULL;
1558 g_signal_emit (sock, signals[WRITABLE], 0);
1563 * soup_socket_write:
1565 * @buffer: data to write
1566 * @len: size of @buffer, in bytes
1567 * @nwrote: (out): on return, number of bytes written
1568 * @cancellable: a #GCancellable, or %NULL
1569 * @error: error pointer
1571 * Attempts to write @len bytes from @buffer to @sock. If some data is
1572 * successfully written, the return status will be %SOUP_SOCKET_OK,
1573 * and *@nwrote will contain the number of bytes actually written
1574 * (which may be less than @len).
1576 * If @sock is non-blocking, and no data could be written right away,
1577 * the return value will be %SOUP_SOCKET_WOULD_BLOCK. In this case,
1578 * the caller can connect to the #SoupSocket::writable signal to know
1579 * when more data can be written. (NB: #SoupSocket::writable is only
1580 * emitted after soup_socket_write() returns %SOUP_SOCKET_WOULD_BLOCK,
1581 * and it is only emitted once. See the documentation for
1582 * #SoupSocket:non-blocking.)
1584 * Return value: a #SoupSocketIOStatus, as described above (or
1585 * %SOUP_SOCKET_EOF or %SOUP_SOCKET_ERROR. @error will be set if the
1586 * return value is %SOUP_SOCKET_ERROR.)
1589 soup_socket_write (SoupSocket *sock, gconstpointer buffer,
1590 gsize len, gsize *nwrote,
1591 GCancellable *cancellable, GError **error)
1593 SoupSocketPrivate *priv;
1594 GError *my_err = NULL;
1597 g_return_val_if_fail (SOUP_IS_SOCKET (sock), SOUP_SOCKET_ERROR);
1598 g_return_val_if_fail (nwrote != NULL, SOUP_SOCKET_ERROR);
1600 priv = SOUP_SOCKET_GET_PRIVATE (sock);
1602 g_mutex_lock (&priv->iolock);
1605 g_mutex_unlock (&priv->iolock);
1606 return SOUP_SOCKET_EOF;
1608 if (priv->write_src) {
1609 g_mutex_unlock (&priv->iolock);
1610 return SOUP_SOCKET_WOULD_BLOCK;
1613 if (!priv->non_blocking) {
1614 my_nwrote = g_output_stream_write (G_OUTPUT_STREAM (priv->ostream),
1616 cancellable, &my_err);
1618 my_nwrote = g_pollable_output_stream_write_nonblocking (
1619 priv->ostream, buffer, len,
1620 cancellable, &my_err);
1623 if (my_nwrote > 0) {
1624 g_mutex_unlock (&priv->iolock);
1625 g_clear_error (&my_err);
1626 *nwrote = my_nwrote;
1627 return SOUP_SOCKET_OK;
1630 if (g_error_matches (my_err, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) {
1631 g_mutex_unlock (&priv->iolock);
1632 g_clear_error (&my_err);
1635 soup_socket_create_watch (priv,
1637 socket_write_watch, sock, cancellable);
1638 return SOUP_SOCKET_WOULD_BLOCK;
1641 g_mutex_unlock (&priv->iolock);
1642 g_propagate_error (error, my_err);
1643 return SOUP_SOCKET_ERROR;