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-socket.h"
20 #include "soup-address.h"
21 #include "soup-filter-input-stream.h"
22 #include "soup-io-stream.h"
23 #include "soup-marshal.h"
24 #include "soup-misc.h"
25 #include "soup-misc-private.h"
30 * @short_description: A network socket
32 * #SoupSocket is libsoup's TCP socket type. While it is primarily
33 * intended for internal use, #SoupSocket<!-- -->s are exposed in the
34 * API in various places, and some of their methods (eg,
35 * soup_socket_get_remote_address()) may be useful to applications.
38 G_DEFINE_TYPE (SoupSocket, soup_socket, G_TYPE_OBJECT)
49 static guint signals[LAST_SIGNAL] = { 0 };
62 PROP_USE_THREAD_CONTEXT,
64 PROP_TRUSTED_CERTIFICATE,
74 SoupAddress *local_addr, *remote_addr;
75 GIOStream *conn, *iostream;
77 GInputStream *istream;
78 GOutputStream *ostream;
79 GTlsCertificateFlags tls_errors;
86 guint clean_dispose:1;
87 guint use_thread_context:1;
91 GMainContext *async_context;
93 GSource *read_src, *write_src;
95 GMutex iolock, addrlock;
98 GCancellable *connect_cancel;
100 #define SOUP_SOCKET_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SOUP_TYPE_SOCKET, SoupSocketPrivate))
102 static void set_property (GObject *object, guint prop_id,
103 const GValue *value, GParamSpec *pspec);
104 static void get_property (GObject *object, guint prop_id,
105 GValue *value, GParamSpec *pspec);
107 static void soup_socket_peer_certificate_changed (GObject *conn,
112 soup_socket_init (SoupSocket *sock)
114 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
116 priv->non_blocking = TRUE;
117 g_mutex_init (&priv->addrlock);
118 g_mutex_init (&priv->iolock);
122 disconnect_internal (SoupSocket *sock, gboolean close)
124 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
126 g_clear_object (&priv->gsock);
127 if (priv->conn && close)
128 g_io_stream_close (priv->conn, NULL, NULL);
130 if (priv->read_src) {
131 g_source_destroy (priv->read_src);
132 priv->read_src = NULL;
134 if (priv->write_src) {
135 g_source_destroy (priv->write_src);
136 priv->write_src = NULL;
141 finalize (GObject *object)
143 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (object);
145 if (priv->connect_cancel) {
146 if (priv->clean_dispose)
147 g_warning ("Disposing socket %p during connect", object);
148 g_object_unref (priv->connect_cancel);
151 if (priv->clean_dispose)
152 g_warning ("Disposing socket %p while still connected", object);
153 disconnect_internal (SOUP_SOCKET (object), TRUE);
156 g_clear_object (&priv->conn);
157 g_clear_object (&priv->iostream);
158 g_clear_object (&priv->istream);
159 g_clear_object (&priv->ostream);
161 if (priv->local_addr)
162 g_object_unref (priv->local_addr);
163 if (priv->remote_addr)
164 g_object_unref (priv->remote_addr);
166 if (priv->watch_src) {
167 if (priv->clean_dispose && !priv->is_server)
168 g_warning ("Disposing socket %p during async op", object);
169 g_source_destroy (priv->watch_src);
171 if (priv->async_context)
172 g_main_context_unref (priv->async_context);
174 g_mutex_clear (&priv->addrlock);
175 g_mutex_clear (&priv->iolock);
177 G_OBJECT_CLASS (soup_socket_parent_class)->finalize (object);
181 soup_socket_class_init (SoupSocketClass *socket_class)
183 GObjectClass *object_class = G_OBJECT_CLASS (socket_class);
185 g_type_class_add_private (socket_class, sizeof (SoupSocketPrivate));
187 /* virtual method override */
188 object_class->finalize = finalize;
189 object_class->set_property = set_property;
190 object_class->get_property = get_property;
195 * SoupSocket::readable:
198 * Emitted when an async socket is readable. See
199 * soup_socket_read(), soup_socket_read_until() and
200 * #SoupSocket:non-blocking.
203 g_signal_new ("readable",
204 G_OBJECT_CLASS_TYPE (object_class),
206 G_STRUCT_OFFSET (SoupSocketClass, readable),
208 _soup_marshal_NONE__NONE,
212 * SoupSocket::writable:
215 * Emitted when an async socket is writable. See
216 * soup_socket_write() and #SoupSocket:non-blocking.
219 g_signal_new ("writable",
220 G_OBJECT_CLASS_TYPE (object_class),
222 G_STRUCT_OFFSET (SoupSocketClass, writable),
224 _soup_marshal_NONE__NONE,
228 * SoupSocket::disconnected:
231 * Emitted when the socket is disconnected, for whatever
234 signals[DISCONNECTED] =
235 g_signal_new ("disconnected",
236 G_OBJECT_CLASS_TYPE (object_class),
238 G_STRUCT_OFFSET (SoupSocketClass, disconnected),
240 _soup_marshal_NONE__NONE,
244 * SoupSocket::new-connection:
246 * @new: the new socket
248 * Emitted when a listening socket (set up with
249 * soup_socket_listen()) receives a new connection.
251 * You must ref the @new if you want to keep it; otherwise it
252 * will be destroyed after the signal is emitted.
254 signals[NEW_CONNECTION] =
255 g_signal_new ("new_connection",
256 G_OBJECT_CLASS_TYPE (object_class),
258 G_STRUCT_OFFSET (SoupSocketClass, new_connection),
260 _soup_marshal_NONE__OBJECT,
266 * @event: the event that occurred
267 * @connection: the current connection state
269 * Emitted when a network-related event occurs. See
270 * #GSocketClient::event for more details.
275 g_signal_new ("event",
276 G_OBJECT_CLASS_TYPE (object_class),
282 G_TYPE_SOCKET_CLIENT_EVENT,
288 * SOUP_SOCKET_LOCAL_ADDRESS:
290 * Alias for the #SoupSocket:local-address property. (Address
291 * of local end of socket.)
293 g_object_class_install_property (
294 object_class, PROP_LOCAL_ADDRESS,
295 g_param_spec_object (SOUP_SOCKET_LOCAL_ADDRESS,
297 "Address of local end of socket",
299 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
301 * SOUP_SOCKET_REMOTE_ADDRESS:
303 * Alias for the #SoupSocket:remote-address property. (Address
304 * of remote end of socket.)
306 g_object_class_install_property (
307 object_class, PROP_REMOTE_ADDRESS,
308 g_param_spec_object (SOUP_SOCKET_REMOTE_ADDRESS,
310 "Address of remote end of socket",
312 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
314 * SoupSocket:non-blocking:
316 * Whether or not the socket uses non-blocking I/O.
318 * #SoupSocket's I/O methods are designed around the idea of
319 * using a single codepath for both synchronous and
320 * asynchronous I/O. If you want to read off a #SoupSocket,
321 * the "correct" way to do it is to call soup_socket_read() or
322 * soup_socket_read_until() repeatedly until you have read
323 * everything you want. If it returns %SOUP_SOCKET_WOULD_BLOCK
324 * at any point, stop reading and wait for it to emit the
325 * #SoupSocket::readable signal. Then go back to the
326 * reading-as-much-as-you-can loop. Likewise, for writing to a
327 * #SoupSocket, you should call soup_socket_write() either
328 * until you have written everything, or it returns
329 * %SOUP_SOCKET_WOULD_BLOCK (in which case you wait for
330 * #SoupSocket::writable and then go back into the loop).
332 * Code written this way will work correctly with both
333 * blocking and non-blocking sockets; blocking sockets will
334 * simply never return %SOUP_SOCKET_WOULD_BLOCK, and so the
335 * code that handles that case just won't get used for them.
338 * SOUP_SOCKET_FLAG_NONBLOCKING:
340 * Alias for the #SoupSocket:non-blocking property. (Whether
341 * or not the socket uses non-blocking I/O.)
343 g_object_class_install_property (
344 object_class, PROP_NON_BLOCKING,
345 g_param_spec_boolean (SOUP_SOCKET_FLAG_NONBLOCKING,
347 "Whether or not the socket uses non-blocking I/O",
351 * SOUP_SOCKET_IS_SERVER:
353 * Alias for the #SoupSocket:is-server property. (Whether or
354 * not the socket is a server socket.)
356 g_object_class_install_property (
357 object_class, PROP_IS_SERVER,
358 g_param_spec_boolean (SOUP_SOCKET_IS_SERVER,
360 "Whether or not the socket is a server socket",
364 * SOUP_SOCKET_SSL_CREDENTIALS:
366 * Alias for the #SoupSocket:ssl-creds property.
367 * (SSL credential information.)
369 /* For historical reasons, there's only a single property
370 * here, which is a GTlsDatabase for client sockets, and
371 * a GTlsCertificate for server sockets. Whee!
373 g_object_class_install_property (
374 object_class, PROP_SSL_CREDENTIALS,
375 g_param_spec_pointer (SOUP_SOCKET_SSL_CREDENTIALS,
377 "SSL credential information, passed from the session to the SSL implementation",
380 * SOUP_SOCKET_SSL_STRICT:
382 * Alias for the #SoupSocket:ssl-strict property.
384 g_object_class_install_property (
385 object_class, PROP_SSL_STRICT,
386 g_param_spec_boolean (SOUP_SOCKET_SSL_STRICT,
387 "Strictly validate SSL certificates",
388 "Whether certificate errors should be considered a connection error",
390 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
392 * SOUP_SOCKET_SSL_FALLBACK:
394 * Alias for the #SoupSocket:ssl-fallback property.
396 g_object_class_install_property (
397 object_class, PROP_SSL_FALLBACK,
398 g_param_spec_boolean (SOUP_SOCKET_SSL_FALLBACK,
400 "Use SSLv3 instead of TLS (client-side only)",
402 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
404 * SOUP_SOCKET_TRUSTED_CERTIFICATE:
406 * Alias for the #SoupSocket:trusted-certificate
409 g_object_class_install_property (
410 object_class, PROP_TRUSTED_CERTIFICATE,
411 g_param_spec_boolean (SOUP_SOCKET_TRUSTED_CERTIFICATE,
412 "Trusted Certificate",
413 "Whether the server certificate is trusted, if this is an SSL socket",
417 * SOUP_SOCKET_ASYNC_CONTEXT:
419 * Alias for the #SoupSocket:async-context property. (The
420 * socket's #GMainContext.)
422 g_object_class_install_property (
423 object_class, PROP_ASYNC_CONTEXT,
424 g_param_spec_pointer (SOUP_SOCKET_ASYNC_CONTEXT,
425 "Async GMainContext",
426 "The GMainContext to dispatch this socket's async I/O in",
427 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
430 * SOUP_SOCKET_USE_THREAD_CONTEXT:
432 * Alias for the #SoupSocket:use-thread-context property. (Use
433 * g_main_context_get_thread_default())
438 * SoupSocket:use-thread-context:
440 * Use g_main_context_get_thread_default().
444 g_object_class_install_property (
445 object_class, PROP_USE_THREAD_CONTEXT,
446 g_param_spec_boolean (SOUP_SOCKET_USE_THREAD_CONTEXT,
447 "Use thread context",
448 "Use g_main_context_get_thread_default",
450 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
453 * SOUP_SOCKET_TIMEOUT:
455 * Alias for the #SoupSocket:timeout property. (The timeout
456 * in seconds for blocking socket I/O operations.)
458 g_object_class_install_property (
459 object_class, PROP_TIMEOUT,
460 g_param_spec_uint (SOUP_SOCKET_TIMEOUT,
462 "Value in seconds to timeout a blocking I/O",
466 g_object_class_install_property (
467 object_class, PROP_CLEAN_DISPOSE,
468 g_param_spec_boolean ("clean-dispose",
470 "Warn on unclean dispose",
472 G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
474 * SOUP_SOCKET_TLS_CERTIFICATE:
476 * Alias for the #SoupSocket:tls-certificate
477 * property. Note that this property's value is only useful
478 * if the socket is for a TLS connection, and only reliable
479 * after some data has been transferred to or from it.
483 g_object_class_install_property (
484 object_class, PROP_TLS_CERTIFICATE,
485 g_param_spec_object (SOUP_SOCKET_TLS_CERTIFICATE,
487 "The peer's TLS certificate",
488 G_TYPE_TLS_CERTIFICATE,
491 * SOUP_SOCKET_TLS_ERRORS:
493 * Alias for the #SoupSocket:tls-errors
494 * property. Note that this property's value is only useful
495 * if the socket is for a TLS connection, and only reliable
496 * after some data has been transferred to or from it.
500 g_object_class_install_property (
501 object_class, PROP_TLS_ERRORS,
502 g_param_spec_flags (SOUP_SOCKET_TLS_ERRORS,
504 "Errors with the peer's TLS certificate",
505 G_TYPE_TLS_CERTIFICATE_FLAGS, 0,
508 g_object_class_install_property (
509 object_class, PROP_USE_PROXY,
510 g_param_spec_boolean (SOUP_SOCKET_USE_PROXY,
512 "Use #GProxyResolver",
514 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
519 finish_socket_setup (SoupSocketPrivate *priv)
525 priv->conn = (GIOStream *)g_socket_connection_factory_create_connection (priv->gsock);
527 priv->iostream = soup_io_stream_new (priv->conn, FALSE);
529 priv->istream = g_object_ref (g_io_stream_get_input_stream (priv->iostream));
531 priv->ostream = g_object_ref (g_io_stream_get_output_stream (priv->iostream));
533 g_socket_set_timeout (priv->gsock, priv->timeout);
537 set_property (GObject *object, guint prop_id,
538 const GValue *value, GParamSpec *pspec)
540 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (object);
543 case PROP_LOCAL_ADDRESS:
544 priv->local_addr = (SoupAddress *)g_value_dup_object (value);
546 case PROP_REMOTE_ADDRESS:
547 priv->remote_addr = (SoupAddress *)g_value_dup_object (value);
549 case PROP_NON_BLOCKING:
550 priv->non_blocking = g_value_get_boolean (value);
552 case PROP_SSL_CREDENTIALS:
553 priv->ssl_creds = g_value_get_pointer (value);
555 case PROP_SSL_STRICT:
556 priv->ssl_strict = g_value_get_boolean (value);
558 case PROP_SSL_FALLBACK:
559 priv->ssl_fallback = g_value_get_boolean (value);
561 case PROP_ASYNC_CONTEXT:
562 priv->async_context = g_value_get_pointer (value);
563 if (priv->async_context)
564 g_main_context_ref (priv->async_context);
566 case PROP_USE_THREAD_CONTEXT:
567 priv->use_thread_context = g_value_get_boolean (value);
570 priv->timeout = g_value_get_uint (value);
572 g_socket_set_timeout (priv->gsock, priv->timeout);
575 priv->use_proxy = g_value_get_boolean (value);
577 case PROP_CLEAN_DISPOSE:
578 priv->clean_dispose = g_value_get_boolean (value);
581 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
587 get_property (GObject *object, guint prop_id,
588 GValue *value, GParamSpec *pspec)
590 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (object);
593 case PROP_LOCAL_ADDRESS:
594 g_value_set_object (value, soup_socket_get_local_address (SOUP_SOCKET (object)));
596 case PROP_REMOTE_ADDRESS:
597 g_value_set_object (value, soup_socket_get_remote_address (SOUP_SOCKET (object)));
599 case PROP_NON_BLOCKING:
600 g_value_set_boolean (value, priv->non_blocking);
603 g_value_set_boolean (value, priv->is_server);
605 case PROP_SSL_CREDENTIALS:
606 g_value_set_pointer (value, priv->ssl_creds);
608 case PROP_SSL_STRICT:
609 g_value_set_boolean (value, priv->ssl_strict);
611 case PROP_SSL_FALLBACK:
612 g_value_set_boolean (value, priv->ssl_fallback);
614 case PROP_TRUSTED_CERTIFICATE:
615 g_value_set_boolean (value, priv->tls_errors == 0);
617 case PROP_ASYNC_CONTEXT:
618 g_value_set_pointer (value, priv->async_context ? g_main_context_ref (priv->async_context) : NULL);
620 case PROP_USE_THREAD_CONTEXT:
621 g_value_set_boolean (value, priv->use_thread_context);
624 g_value_set_uint (value, priv->timeout);
626 case PROP_TLS_CERTIFICATE:
627 if (G_IS_TLS_CONNECTION (priv->conn))
628 g_value_set_object (value, g_tls_connection_get_peer_certificate (G_TLS_CONNECTION (priv->conn)));
630 g_value_set_object (value, NULL);
632 case PROP_TLS_ERRORS:
633 g_value_set_flags (value, priv->tls_errors);
636 g_value_set_boolean (value, priv->use_proxy);
639 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
647 * @optname1: name of first property to set (or %NULL)
648 * @...: value of @optname1, followed by additional property/value pairs
650 * Creates a new (disconnected) socket
652 * Return value: the new socket
655 soup_socket_new (const char *optname1, ...)
660 va_start (ap, optname1);
661 sock = (SoupSocket *)g_object_new_valist (SOUP_TYPE_SOCKET,
669 proxy_socket_client_event (GSocketClient *client,
670 GSocketClientEvent event,
671 GSocketConnectable *connectable,
672 GIOStream *connection,
675 SoupSocket *sock = user_data;
677 g_signal_emit (sock, signals[EVENT], 0,
682 socket_connected (SoupSocket *sock, GSocketConnection *conn, GError *error)
684 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
686 if (priv->connect_cancel) {
687 GCancellable *cancellable = priv->connect_cancel;
689 g_object_unref (priv->connect_cancel);
690 priv->connect_cancel = NULL;
691 if (g_cancellable_is_cancelled (cancellable))
692 return SOUP_STATUS_CANCELLED;
696 if (error->domain == G_RESOLVER_ERROR) {
697 g_error_free (error);
698 return SOUP_STATUS_CANT_RESOLVE;
700 g_error_free (error);
701 return SOUP_STATUS_CANT_CONNECT;
705 priv->conn = (GIOStream *)conn;
706 priv->gsock = g_object_ref (g_socket_connection_get_socket (conn));
707 finish_socket_setup (priv);
709 return SOUP_STATUS_OK;
713 * SoupSocketCallback:
714 * @sock: the #SoupSocket
715 * @status: an HTTP status code indicating success or failure
716 * @user_data: the data passed to soup_socket_connect_async()
718 * The callback function passed to soup_socket_connect_async().
723 SoupSocketCallback callback;
725 } SoupSocketAsyncConnectData;
728 async_connected (GObject *client, GAsyncResult *result, gpointer data)
730 SoupSocketAsyncConnectData *sacd = data;
731 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sacd->sock);
732 GError *error = NULL;
733 GSocketConnection *conn;
736 if (priv->async_context && !priv->use_thread_context)
737 g_main_context_pop_thread_default (priv->async_context);
739 conn = g_socket_client_connect_finish (G_SOCKET_CLIENT (client),
741 status = socket_connected (sacd->sock, conn, error);
743 sacd->callback (sacd->sock, status, sacd->user_data);
744 g_object_unref (sacd->sock);
745 g_slice_free (SoupSocketAsyncConnectData, sacd);
749 * soup_socket_connect_async:
750 * @sock: a client #SoupSocket (which must not already be connected)
751 * @cancellable: a #GCancellable, or %NULL
752 * @callback: (scope async): callback to call after connecting
753 * @user_data: data to pass to @callback
755 * Begins asynchronously connecting to @sock's remote address. The
756 * socket will call @callback when it succeeds or fails (but not
757 * before returning from this function).
759 * If @cancellable is non-%NULL, it can be used to cancel the
760 * connection. @callback will still be invoked in this case, with a
761 * status of %SOUP_STATUS_CANCELLED.
764 soup_socket_connect_async (SoupSocket *sock, GCancellable *cancellable,
765 SoupSocketCallback callback, gpointer user_data)
767 SoupSocketPrivate *priv;
768 SoupSocketAsyncConnectData *sacd;
769 GSocketClient *client;
771 g_return_if_fail (SOUP_IS_SOCKET (sock));
772 priv = SOUP_SOCKET_GET_PRIVATE (sock);
773 g_return_if_fail (priv->remote_addr != NULL);
775 sacd = g_slice_new0 (SoupSocketAsyncConnectData);
776 sacd->sock = g_object_ref (sock);
777 sacd->callback = callback;
778 sacd->user_data = user_data;
780 priv->connect_cancel = cancellable ? g_object_ref (cancellable) : g_cancellable_new ();
782 if (priv->async_context && !priv->use_thread_context)
783 g_main_context_push_thread_default (priv->async_context);
785 client = g_socket_client_new ();
786 g_signal_connect (client, "event",
787 G_CALLBACK (proxy_socket_client_event), sock);
789 g_socket_client_add_application_proxy (client, "http");
791 g_socket_client_set_enable_proxy (client, FALSE);
793 g_socket_client_set_timeout (client, priv->timeout);
794 g_socket_client_connect_async (client,
795 G_SOCKET_CONNECTABLE (priv->remote_addr),
796 priv->connect_cancel,
797 async_connected, sacd);
798 g_object_unref (client);
802 * soup_socket_connect_sync:
803 * @sock: a client #SoupSocket (which must not already be connected)
804 * @cancellable: a #GCancellable, or %NULL
806 * Attempt to synchronously connect @sock to its remote address.
808 * If @cancellable is non-%NULL, it can be used to cancel the
809 * connection, in which case soup_socket_connect_sync() will return
810 * %SOUP_STATUS_CANCELLED.
812 * Return value: a success or failure code.
815 soup_socket_connect_sync (SoupSocket *sock, GCancellable *cancellable)
817 SoupSocketPrivate *priv;
818 GSocketClient *client;
819 GSocketConnection *conn;
820 GError *error = NULL;
822 g_return_val_if_fail (SOUP_IS_SOCKET (sock), SOUP_STATUS_MALFORMED);
823 priv = SOUP_SOCKET_GET_PRIVATE (sock);
824 g_return_val_if_fail (!priv->is_server, SOUP_STATUS_MALFORMED);
825 g_return_val_if_fail (priv->gsock == NULL, SOUP_STATUS_MALFORMED);
826 g_return_val_if_fail (priv->remote_addr != NULL, SOUP_STATUS_MALFORMED);
829 g_object_ref (cancellable);
831 cancellable = g_cancellable_new ();
832 priv->connect_cancel = cancellable;
834 client = g_socket_client_new ();
835 g_signal_connect (client, "event",
836 G_CALLBACK (proxy_socket_client_event), sock);
838 g_socket_client_add_application_proxy (client, "http");
840 g_socket_client_set_enable_proxy (client, FALSE);
842 g_socket_client_set_timeout (client, priv->timeout);
843 conn = g_socket_client_connect (client,
844 G_SOCKET_CONNECTABLE (priv->remote_addr),
845 priv->connect_cancel, &error);
846 g_object_unref (client);
848 return socket_connected (sock, conn, error);
852 soup_socket_get_fd (SoupSocket *sock)
854 g_return_val_if_fail (SOUP_IS_SOCKET (sock), -1);
856 return g_socket_get_fd (SOUP_SOCKET_GET_PRIVATE (sock)->gsock);
860 soup_socket_get_gsocket (SoupSocket *sock)
862 g_return_val_if_fail (SOUP_IS_SOCKET (sock), NULL);
864 return SOUP_SOCKET_GET_PRIVATE (sock)->gsock;
868 soup_socket_get_connection (SoupSocket *sock)
870 g_return_val_if_fail (SOUP_IS_SOCKET (sock), NULL);
872 return SOUP_SOCKET_GET_PRIVATE (sock)->conn;
876 soup_socket_get_iostream (SoupSocket *sock)
878 g_return_val_if_fail (SOUP_IS_SOCKET (sock), NULL);
880 return SOUP_SOCKET_GET_PRIVATE (sock)->iostream;
884 soup_socket_create_watch (SoupSocketPrivate *priv, GIOCondition cond,
885 GPollableSourceFunc callback, gpointer user_data,
886 GCancellable *cancellable)
889 GMainContext *async_context;
892 watch = g_pollable_input_stream_create_source (G_POLLABLE_INPUT_STREAM (priv->istream), cancellable);
894 watch = g_pollable_output_stream_create_source (G_POLLABLE_OUTPUT_STREAM (priv->ostream), cancellable);
895 g_source_set_callback (watch, (GSourceFunc)callback, user_data, NULL);
897 if (priv->use_thread_context)
898 async_context = g_main_context_get_thread_default ();
900 async_context = priv->async_context;
902 g_source_attach (watch, async_context);
903 g_source_unref (watch);
909 listen_watch (GObject *pollable, gpointer data)
911 SoupSocket *sock = data, *new;
912 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock), *new_priv;
915 new_gsock = g_socket_accept (priv->gsock, NULL, NULL);
919 new = g_object_new (SOUP_TYPE_SOCKET, NULL);
920 new_priv = SOUP_SOCKET_GET_PRIVATE (new);
921 new_priv->gsock = new_gsock;
922 if (priv->async_context)
923 new_priv->async_context = g_main_context_ref (priv->async_context);
924 new_priv->use_thread_context = priv->use_thread_context;
925 new_priv->non_blocking = priv->non_blocking;
926 new_priv->is_server = TRUE;
927 new_priv->ssl = priv->ssl;
929 new_priv->ssl_creds = priv->ssl_creds;
930 finish_socket_setup (new_priv);
932 if (new_priv->ssl_creds) {
933 if (!soup_socket_start_proxy_ssl (new, NULL, NULL)) {
934 g_object_unref (new);
939 g_signal_emit (sock, signals[NEW_CONNECTION], 0, new);
940 g_object_unref (new);
946 * soup_socket_listen:
947 * @sock: a server #SoupSocket (which must not already be connected or
950 * Makes @sock start listening on its local address. When connections
951 * come in, @sock will emit #SoupSocket::new_connection.
953 * Return value: whether or not @sock is now listening.
956 soup_socket_listen (SoupSocket *sock)
959 SoupSocketPrivate *priv;
960 GSocketAddress *addr;
962 g_return_val_if_fail (SOUP_IS_SOCKET (sock), FALSE);
963 priv = SOUP_SOCKET_GET_PRIVATE (sock);
964 g_return_val_if_fail (priv->gsock == NULL, FALSE);
965 g_return_val_if_fail (priv->local_addr != NULL, FALSE);
967 priv->is_server = TRUE;
969 /* @local_addr may have its port set to 0. So we intentionally
970 * don't store it in priv->local_addr, so that if the
971 * caller calls soup_socket_get_local_address() later, we'll
972 * have to make a new addr by calling getsockname(), which
973 * will have the right port number.
975 addr = soup_address_get_gsockaddr (priv->local_addr);
976 g_return_val_if_fail (addr != NULL, FALSE);
978 priv->gsock = g_socket_new (g_socket_address_get_family (addr),
979 G_SOCKET_TYPE_STREAM,
980 G_SOCKET_PROTOCOL_DEFAULT,
984 finish_socket_setup (priv);
987 if (!g_socket_bind (priv->gsock, addr, TRUE, NULL))
989 /* Force local_addr to be re-resolved now */
990 g_object_unref (priv->local_addr);
991 priv->local_addr = NULL;
994 if (!g_socket_listen (priv->gsock, NULL))
997 priv->watch_src = soup_socket_create_watch (priv, G_IO_IN,
1000 g_object_unref (addr);
1005 disconnect_internal (sock, TRUE);
1006 g_object_unref (addr);
1012 soup_socket_peer_certificate_changed (GObject *conn, GParamSpec *pspec,
1015 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
1017 priv->tls_errors = g_tls_connection_get_peer_certificate_errors (G_TLS_CONNECTION (priv->conn));
1019 g_object_notify (sock, "tls-certificate");
1020 g_object_notify (sock, "tls-errors");
1024 soup_socket_accept_certificate (GTlsConnection *conn, GTlsCertificate *cert,
1025 GTlsCertificateFlags errors, gpointer sock)
1031 * soup_socket_start_ssl:
1033 * @cancellable: a #GCancellable
1035 * Starts using SSL on @socket.
1037 * Return value: success or failure
1040 soup_socket_start_ssl (SoupSocket *sock, GCancellable *cancellable)
1042 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
1044 return soup_socket_start_proxy_ssl (sock, soup_address_get_name (priv->remote_addr), cancellable);
1048 * soup_socket_start_proxy_ssl:
1050 * @ssl_host: hostname of the SSL server
1051 * @cancellable: a #GCancellable
1053 * Starts using SSL on @socket, expecting to find a host named
1056 * Return value: success or failure
1059 soup_socket_start_proxy_ssl (SoupSocket *sock, const char *ssl_host,
1060 GCancellable *cancellable)
1062 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
1063 GTlsBackend *backend = g_tls_backend_get_default ();
1065 if (G_IS_TLS_CONNECTION (priv->conn))
1068 if (g_cancellable_is_cancelled (cancellable))
1073 if (!priv->is_server) {
1074 GTlsClientConnection *conn;
1075 GSocketConnectable *identity;
1077 identity = g_network_address_new (ssl_host, 0);
1078 conn = g_initable_new (g_tls_backend_get_client_connection_type (backend),
1080 "base-io-stream", priv->conn,
1081 "server-identity", identity,
1082 "database", priv->ssl_creds,
1083 "require-close-notify", FALSE,
1084 "use-ssl3", priv->ssl_fallback,
1086 g_object_unref (identity);
1091 g_object_unref (priv->conn);
1092 priv->conn = G_IO_STREAM (conn);
1094 if (!priv->ssl_strict) {
1095 g_signal_connect (conn, "accept-certificate",
1096 G_CALLBACK (soup_socket_accept_certificate),
1100 GTlsServerConnection *conn;
1102 conn = g_initable_new (g_tls_backend_get_server_connection_type (backend),
1104 "base-io-stream", priv->conn,
1105 "certificate", priv->ssl_creds,
1106 "use-system-certdb", FALSE,
1107 "require-close-notify", FALSE,
1112 g_object_unref (priv->conn);
1113 priv->conn = G_IO_STREAM (conn);
1116 g_signal_connect (priv->conn, "notify::peer-certificate",
1117 G_CALLBACK (soup_socket_peer_certificate_changed), sock);
1119 g_clear_object (&priv->istream);
1120 g_clear_object (&priv->ostream);
1121 g_clear_object (&priv->iostream);
1122 priv->iostream = soup_io_stream_new (priv->conn, FALSE);
1123 priv->istream = g_object_ref (g_io_stream_get_input_stream (priv->iostream));
1124 priv->ostream = g_object_ref (g_io_stream_get_output_stream (priv->iostream));
1130 soup_socket_handshake_sync (SoupSocket *sock,
1131 GCancellable *cancellable)
1133 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
1134 GError *error = NULL;
1137 if (g_tls_connection_handshake (G_TLS_CONNECTION (priv->conn),
1138 cancellable, &error))
1139 return SOUP_STATUS_OK;
1140 else if (!priv->ssl_fallback &&
1141 g_error_matches (error, G_TLS_ERROR, G_TLS_ERROR_NOT_TLS)) {
1142 g_error_free (error);
1143 return SOUP_STATUS_TLS_FAILED;
1145 g_error_free (error);
1146 return SOUP_STATUS_SSL_FAILED;
1151 handshake_async_ready (GObject *source, GAsyncResult *result, gpointer user_data)
1153 SoupSocketAsyncConnectData *data = user_data;
1154 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (data->sock);
1155 GError *error = NULL;
1158 if (priv->async_context && !priv->use_thread_context)
1159 g_main_context_pop_thread_default (priv->async_context);
1161 if (g_tls_connection_handshake_finish (G_TLS_CONNECTION (source),
1163 status = SOUP_STATUS_OK;
1164 else if (!priv->ssl_fallback &&
1165 g_error_matches (error, G_TLS_ERROR, G_TLS_ERROR_NOT_TLS))
1166 status = SOUP_STATUS_TLS_FAILED;
1168 status = SOUP_STATUS_SSL_FAILED;
1169 g_clear_error (&error);
1171 data->callback (data->sock, status, data->user_data);
1172 g_object_unref (data->sock);
1173 g_slice_free (SoupSocketAsyncConnectData, data);
1177 soup_socket_handshake_async (SoupSocket *sock,
1178 GCancellable *cancellable,
1179 SoupSocketCallback callback,
1182 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
1183 SoupSocketAsyncConnectData *data;
1187 data = g_slice_new (SoupSocketAsyncConnectData);
1188 data->sock = g_object_ref (sock);
1189 data->callback = callback;
1190 data->user_data = user_data;
1192 if (priv->async_context && !priv->use_thread_context)
1193 g_main_context_push_thread_default (priv->async_context);
1194 g_tls_connection_handshake_async (G_TLS_CONNECTION (priv->conn),
1196 cancellable, handshake_async_ready,
1201 * soup_socket_is_ssl:
1202 * @sock: a #SoupSocket
1204 * Tests if @sock is doing (or has attempted to do) SSL.
1206 * Return value: %TRUE if @sock has SSL credentials set
1209 soup_socket_is_ssl (SoupSocket *sock)
1211 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
1217 * soup_socket_disconnect:
1218 * @sock: a #SoupSocket
1220 * Disconnects @sock. Any further read or write attempts on it will
1224 soup_socket_disconnect (SoupSocket *sock)
1226 SoupSocketPrivate *priv;
1227 gboolean already_disconnected = FALSE;
1229 g_return_if_fail (SOUP_IS_SOCKET (sock));
1230 priv = SOUP_SOCKET_GET_PRIVATE (sock);
1232 if (priv->connect_cancel) {
1233 disconnect_internal (sock, FALSE);
1234 g_cancellable_cancel (priv->connect_cancel);
1236 } else if (g_mutex_trylock (&priv->iolock)) {
1238 disconnect_internal (sock, TRUE);
1240 already_disconnected = TRUE;
1241 g_mutex_unlock (&priv->iolock);
1243 /* Another thread is currently doing IO, so
1244 * we can't close the socket. So just shutdown
1245 * the file descriptor to force the I/O to fail.
1246 * (It will actually be closed when the socket
1249 g_socket_shutdown (priv->gsock, TRUE, TRUE, NULL);
1252 if (already_disconnected)
1255 /* Keep ref around signals in case the object is unreferenced
1258 g_object_ref (sock);
1260 /* Give all readers a chance to notice the connection close */
1261 g_signal_emit (sock, signals[READABLE], 0);
1263 /* FIXME: can't disconnect until all data is read */
1265 /* Then let everyone know we're disconnected */
1266 g_signal_emit (sock, signals[DISCONNECTED], 0);
1268 g_object_unref (sock);
1272 * soup_socket_is_connected:
1273 * @sock: a #SoupSocket
1275 * Tests if @sock is connected to another host
1277 * Return value: %TRUE or %FALSE.
1280 soup_socket_is_connected (SoupSocket *sock)
1282 SoupSocketPrivate *priv;
1284 g_return_val_if_fail (SOUP_IS_SOCKET (sock), FALSE);
1285 priv = SOUP_SOCKET_GET_PRIVATE (sock);
1287 return priv->conn && !g_io_stream_is_closed (priv->conn);
1291 * soup_socket_get_local_address:
1292 * @sock: a #SoupSocket
1294 * Returns the #SoupAddress corresponding to the local end of @sock.
1296 * Return value: (transfer none): the #SoupAddress
1299 soup_socket_get_local_address (SoupSocket *sock)
1301 SoupSocketPrivate *priv;
1303 g_return_val_if_fail (SOUP_IS_SOCKET (sock), NULL);
1304 priv = SOUP_SOCKET_GET_PRIVATE (sock);
1306 g_mutex_lock (&priv->addrlock);
1307 if (!priv->local_addr) {
1308 GSocketAddress *addr;
1309 struct sockaddr_storage sa;
1312 addr = g_socket_get_local_address (priv->gsock, NULL);
1313 sa_len = g_socket_address_get_native_size (addr);
1314 g_socket_address_to_native (addr, &sa, sa_len, NULL);
1315 priv->local_addr = soup_address_new_from_sockaddr ((struct sockaddr *)&sa, sa_len);
1316 g_object_unref (addr);
1318 g_mutex_unlock (&priv->addrlock);
1320 return priv->local_addr;
1324 * soup_socket_get_remote_address:
1325 * @sock: a #SoupSocket
1327 * Returns the #SoupAddress corresponding to the remote end of @sock.
1329 * Return value: (transfer none): the #SoupAddress
1332 soup_socket_get_remote_address (SoupSocket *sock)
1334 SoupSocketPrivate *priv;
1336 g_return_val_if_fail (SOUP_IS_SOCKET (sock), NULL);
1337 priv = SOUP_SOCKET_GET_PRIVATE (sock);
1339 g_mutex_lock (&priv->addrlock);
1340 if (!priv->remote_addr) {
1341 GSocketAddress *addr;
1342 struct sockaddr_storage sa;
1345 addr = g_socket_get_remote_address (priv->gsock, NULL);
1346 sa_len = g_socket_address_get_native_size (addr);
1347 g_socket_address_to_native (addr, &sa, sa_len, NULL);
1348 priv->remote_addr = soup_address_new_from_sockaddr ((struct sockaddr *)&sa, sa_len);
1349 g_object_unref (addr);
1351 g_mutex_unlock (&priv->addrlock);
1353 return priv->remote_addr;
1357 soup_socket_get_http_proxy_uri (SoupSocket *sock)
1359 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
1360 GSocketAddress *addr;
1361 GProxyAddress *paddr;
1365 addr = g_socket_get_remote_address (priv->gsock, NULL);
1366 if (!addr || !G_IS_PROXY_ADDRESS (addr))
1369 paddr = G_PROXY_ADDRESS (addr);
1370 if (strcmp (g_proxy_address_get_protocol (paddr), "http") != 0)
1373 return soup_uri_new (g_proxy_address_get_uri (paddr));
1377 socket_read_watch (GObject *pollable, gpointer user_data)
1379 SoupSocket *sock = user_data;
1380 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
1382 priv->read_src = NULL;
1383 g_signal_emit (sock, signals[READABLE], 0);
1387 static SoupSocketIOStatus
1388 translate_read_status (SoupSocket *sock, GCancellable *cancellable,
1389 gssize my_nread, gsize *nread,
1390 GError *my_err, GError **error)
1392 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
1395 g_assert_no_error (my_err);
1397 return SOUP_SOCKET_OK;
1398 } else if (my_nread == 0) {
1399 g_assert_no_error (my_err);
1401 return SOUP_SOCKET_EOF;
1402 } else if (g_error_matches (my_err, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) {
1403 g_clear_error (&my_err);
1404 if (!priv->read_src) {
1406 soup_socket_create_watch (priv, G_IO_IN,
1407 socket_read_watch, sock,
1410 return SOUP_SOCKET_WOULD_BLOCK;
1413 g_propagate_error (error, my_err);
1414 return SOUP_SOCKET_ERROR;
1418 * SoupSocketIOStatus:
1419 * @SOUP_SOCKET_OK: Success
1420 * @SOUP_SOCKET_WOULD_BLOCK: Cannot read/write any more at this time
1421 * @SOUP_SOCKET_EOF: End of file
1422 * @SOUP_SOCKET_ERROR: Other error
1424 * Return value from the #SoupSocket IO methods.
1430 * @buffer: buffer to read into
1431 * @len: size of @buffer in bytes
1432 * @nread: (out): on return, the number of bytes read into @buffer
1433 * @cancellable: a #GCancellable, or %NULL
1434 * @error: error pointer
1436 * Attempts to read up to @len bytes from @sock into @buffer. If some
1437 * data is successfully read, soup_socket_read() will return
1438 * %SOUP_SOCKET_OK, and *@nread will contain the number of bytes
1439 * actually read (which may be less than @len).
1441 * If @sock is non-blocking, and no data is available, the return
1442 * value will be %SOUP_SOCKET_WOULD_BLOCK. In this case, the caller
1443 * can connect to the #SoupSocket::readable signal to know when there
1444 * is more data to read. (NB: You MUST read all available data off the
1445 * socket first. #SoupSocket::readable is only emitted after
1446 * soup_socket_read() returns %SOUP_SOCKET_WOULD_BLOCK, and it is only
1447 * emitted once. See the documentation for #SoupSocket:non-blocking.)
1449 * Return value: a #SoupSocketIOStatus, as described above (or
1450 * %SOUP_SOCKET_EOF if the socket is no longer connected, or
1451 * %SOUP_SOCKET_ERROR on any other error, in which case @error will
1455 soup_socket_read (SoupSocket *sock, gpointer buffer, gsize len,
1456 gsize *nread, GCancellable *cancellable, GError **error)
1458 SoupSocketPrivate *priv;
1459 SoupSocketIOStatus status;
1461 GError *my_err = NULL;
1463 g_return_val_if_fail (SOUP_IS_SOCKET (sock), SOUP_SOCKET_ERROR);
1464 g_return_val_if_fail (nread != NULL, SOUP_SOCKET_ERROR);
1466 priv = SOUP_SOCKET_GET_PRIVATE (sock);
1468 g_mutex_lock (&priv->iolock);
1470 if (!priv->istream) {
1471 status = SOUP_SOCKET_EOF;
1475 if (!priv->non_blocking) {
1476 my_nread = g_input_stream_read (priv->istream, buffer, len,
1477 cancellable, &my_err);
1479 my_nread = g_pollable_input_stream_read_nonblocking (G_POLLABLE_INPUT_STREAM (priv->istream),
1481 cancellable, &my_err);
1483 status = translate_read_status (sock, cancellable,
1484 my_nread, nread, my_err, error);
1487 g_mutex_unlock (&priv->iolock);
1493 * soup_socket_read_until:
1495 * @buffer: buffer to read into
1496 * @len: size of @buffer in bytes
1497 * @boundary: boundary to read until
1498 * @boundary_len: length of @boundary in bytes
1499 * @nread: (out): on return, the number of bytes read into @buffer
1500 * @got_boundary: on return, whether or not the data in @buffer
1501 * ends with the boundary string
1502 * @cancellable: a #GCancellable, or %NULL
1503 * @error: error pointer
1505 * Like soup_socket_read(), but reads no further than the first
1506 * occurrence of @boundary. (If the boundary is found, it will be
1507 * included in the returned data, and *@got_boundary will be set to
1508 * %TRUE.) Any data after the boundary will returned in future reads.
1510 * soup_socket_read_until() will almost always return fewer than @len
1511 * bytes: if the boundary is found, then it will only return the bytes
1512 * up until the end of the boundary, and if the boundary is not found,
1513 * then it will leave the last <literal>(boundary_len - 1)</literal>
1514 * bytes in its internal buffer, in case they form the start of the
1515 * boundary string. Thus, @len normally needs to be at least 1 byte
1516 * longer than @boundary_len if you want to make any progress at all.
1518 * Return value: as for soup_socket_read()
1521 soup_socket_read_until (SoupSocket *sock, gpointer buffer, gsize len,
1522 gconstpointer boundary, gsize boundary_len,
1523 gsize *nread, gboolean *got_boundary,
1524 GCancellable *cancellable, GError **error)
1526 SoupSocketPrivate *priv;
1527 SoupSocketIOStatus status;
1529 GError *my_err = NULL;
1531 g_return_val_if_fail (SOUP_IS_SOCKET (sock), SOUP_SOCKET_ERROR);
1532 g_return_val_if_fail (nread != NULL, SOUP_SOCKET_ERROR);
1533 g_return_val_if_fail (len >= boundary_len, SOUP_SOCKET_ERROR);
1535 priv = SOUP_SOCKET_GET_PRIVATE (sock);
1537 g_mutex_lock (&priv->iolock);
1539 *got_boundary = FALSE;
1542 status = SOUP_SOCKET_EOF;
1544 my_nread = soup_filter_input_stream_read_until (
1545 SOUP_FILTER_INPUT_STREAM (priv->istream),
1546 buffer, len, boundary, boundary_len,
1547 !priv->non_blocking,
1548 got_boundary, cancellable, &my_err);
1549 status = translate_read_status (sock, cancellable,
1550 my_nread, nread, my_err, error);
1553 g_mutex_unlock (&priv->iolock);
1558 socket_write_watch (GObject *pollable, gpointer user_data)
1560 SoupSocket *sock = user_data;
1561 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
1563 priv->write_src = NULL;
1564 g_signal_emit (sock, signals[WRITABLE], 0);
1569 * soup_socket_write:
1571 * @buffer: data to write
1572 * @len: size of @buffer, in bytes
1573 * @nwrote: (out): on return, number of bytes written
1574 * @cancellable: a #GCancellable, or %NULL
1575 * @error: error pointer
1577 * Attempts to write @len bytes from @buffer to @sock. If some data is
1578 * successfully written, the return status will be %SOUP_SOCKET_OK,
1579 * and *@nwrote will contain the number of bytes actually written
1580 * (which may be less than @len).
1582 * If @sock is non-blocking, and no data could be written right away,
1583 * the return value will be %SOUP_SOCKET_WOULD_BLOCK. In this case,
1584 * the caller can connect to the #SoupSocket::writable signal to know
1585 * when more data can be written. (NB: #SoupSocket::writable is only
1586 * emitted after soup_socket_write() returns %SOUP_SOCKET_WOULD_BLOCK,
1587 * and it is only emitted once. See the documentation for
1588 * #SoupSocket:non-blocking.)
1590 * Return value: a #SoupSocketIOStatus, as described above (or
1591 * %SOUP_SOCKET_EOF or %SOUP_SOCKET_ERROR. @error will be set if the
1592 * return value is %SOUP_SOCKET_ERROR.)
1595 soup_socket_write (SoupSocket *sock, gconstpointer buffer,
1596 gsize len, gsize *nwrote,
1597 GCancellable *cancellable, GError **error)
1599 SoupSocketPrivate *priv;
1600 GError *my_err = NULL;
1603 g_return_val_if_fail (SOUP_IS_SOCKET (sock), SOUP_SOCKET_ERROR);
1604 g_return_val_if_fail (nwrote != NULL, SOUP_SOCKET_ERROR);
1606 priv = SOUP_SOCKET_GET_PRIVATE (sock);
1608 g_mutex_lock (&priv->iolock);
1611 g_mutex_unlock (&priv->iolock);
1612 return SOUP_SOCKET_EOF;
1614 if (priv->write_src) {
1615 g_mutex_unlock (&priv->iolock);
1616 return SOUP_SOCKET_WOULD_BLOCK;
1619 if (!priv->non_blocking) {
1620 my_nwrote = g_output_stream_write (priv->ostream,
1622 cancellable, &my_err);
1624 my_nwrote = g_pollable_output_stream_write_nonblocking (
1625 G_POLLABLE_OUTPUT_STREAM (priv->ostream),
1626 buffer, len, cancellable, &my_err);
1629 if (my_nwrote > 0) {
1630 g_mutex_unlock (&priv->iolock);
1631 g_clear_error (&my_err);
1632 *nwrote = my_nwrote;
1633 return SOUP_SOCKET_OK;
1636 if (g_error_matches (my_err, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) {
1637 g_mutex_unlock (&priv->iolock);
1638 g_clear_error (&my_err);
1641 soup_socket_create_watch (priv,
1643 socket_write_watch, sock, cancellable);
1644 return SOUP_SOCKET_WOULD_BLOCK;
1647 g_mutex_unlock (&priv->iolock);
1648 g_propagate_error (error, my_err);
1649 return SOUP_SOCKET_ERROR;