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.
14 #include "soup-socket.h"
16 #include "soup-filter-input-stream.h"
17 #include "soup-io-stream.h"
18 #include "soup-marshal.h"
19 #include "soup-misc-private.h"
23 * @short_description: A network socket
25 * #SoupSocket is libsoup's TCP socket type. While it is primarily
26 * intended for internal use, #SoupSocket<!-- -->s are exposed in the
27 * API in various places, and some of their methods (eg,
28 * soup_socket_get_remote_address()) may be useful to applications.
31 G_DEFINE_TYPE (SoupSocket, soup_socket, G_TYPE_OBJECT)
42 static guint signals[LAST_SIGNAL] = { 0 };
55 PROP_USE_THREAD_CONTEXT,
57 PROP_TRUSTED_CERTIFICATE,
67 SoupAddress *local_addr, *remote_addr;
68 GIOStream *conn, *iostream;
70 GInputStream *istream;
71 GOutputStream *ostream;
72 GTlsCertificateFlags tls_errors;
79 guint clean_dispose:1;
80 guint use_thread_context:1;
84 GMainContext *async_context;
86 GSource *read_src, *write_src;
88 GMutex iolock, addrlock;
91 GCancellable *connect_cancel;
93 #define SOUP_SOCKET_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SOUP_TYPE_SOCKET, SoupSocketPrivate))
95 static void soup_socket_peer_certificate_changed (GObject *conn,
100 soup_socket_init (SoupSocket *sock)
102 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
104 priv->non_blocking = TRUE;
105 g_mutex_init (&priv->addrlock);
106 g_mutex_init (&priv->iolock);
110 disconnect_internal (SoupSocket *sock, gboolean close)
112 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
114 g_clear_object (&priv->gsock);
115 if (priv->conn && close)
116 g_io_stream_close (priv->conn, NULL, NULL);
118 if (priv->read_src) {
119 g_source_destroy (priv->read_src);
120 priv->read_src = NULL;
122 if (priv->write_src) {
123 g_source_destroy (priv->write_src);
124 priv->write_src = NULL;
129 soup_socket_finalize (GObject *object)
131 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (object);
133 if (priv->connect_cancel) {
134 if (priv->clean_dispose)
135 g_warning ("Disposing socket %p during connect", object);
136 g_object_unref (priv->connect_cancel);
139 if (priv->clean_dispose)
140 g_warning ("Disposing socket %p while still connected", object);
141 disconnect_internal (SOUP_SOCKET (object), TRUE);
144 g_clear_object (&priv->conn);
145 g_clear_object (&priv->iostream);
146 g_clear_object (&priv->istream);
147 g_clear_object (&priv->ostream);
149 g_clear_object (&priv->local_addr);
150 g_clear_object (&priv->remote_addr);
152 if (priv->watch_src) {
153 if (priv->clean_dispose && !priv->is_server)
154 g_warning ("Disposing socket %p during async op", object);
155 g_source_destroy (priv->watch_src);
157 g_clear_pointer (&priv->async_context, g_main_context_unref);
159 g_mutex_clear (&priv->addrlock);
160 g_mutex_clear (&priv->iolock);
162 G_OBJECT_CLASS (soup_socket_parent_class)->finalize (object);
167 finish_socket_setup (SoupSocketPrivate *priv)
173 priv->conn = (GIOStream *)g_socket_connection_factory_create_connection (priv->gsock);
175 priv->iostream = soup_io_stream_new (priv->conn, FALSE);
177 priv->istream = g_object_ref (g_io_stream_get_input_stream (priv->iostream));
179 priv->ostream = g_object_ref (g_io_stream_get_output_stream (priv->iostream));
181 g_socket_set_timeout (priv->gsock, priv->timeout);
185 soup_socket_set_property (GObject *object, guint prop_id,
186 const GValue *value, GParamSpec *pspec)
188 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (object);
191 case PROP_LOCAL_ADDRESS:
192 priv->local_addr = (SoupAddress *)g_value_dup_object (value);
194 case PROP_REMOTE_ADDRESS:
195 priv->remote_addr = (SoupAddress *)g_value_dup_object (value);
197 case PROP_NON_BLOCKING:
198 priv->non_blocking = g_value_get_boolean (value);
200 case PROP_SSL_CREDENTIALS:
201 priv->ssl_creds = g_value_get_pointer (value);
203 case PROP_SSL_STRICT:
204 priv->ssl_strict = g_value_get_boolean (value);
206 case PROP_SSL_FALLBACK:
207 priv->ssl_fallback = g_value_get_boolean (value);
209 case PROP_ASYNC_CONTEXT:
210 priv->async_context = g_value_get_pointer (value);
211 if (priv->async_context)
212 g_main_context_ref (priv->async_context);
214 case PROP_USE_THREAD_CONTEXT:
215 priv->use_thread_context = g_value_get_boolean (value);
218 priv->timeout = g_value_get_uint (value);
220 g_socket_set_timeout (priv->gsock, priv->timeout);
223 priv->use_proxy = g_value_get_boolean (value);
225 case PROP_CLEAN_DISPOSE:
226 priv->clean_dispose = g_value_get_boolean (value);
229 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
235 soup_socket_get_property (GObject *object, guint prop_id,
236 GValue *value, GParamSpec *pspec)
238 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (object);
241 case PROP_LOCAL_ADDRESS:
242 g_value_set_object (value, soup_socket_get_local_address (SOUP_SOCKET (object)));
244 case PROP_REMOTE_ADDRESS:
245 g_value_set_object (value, soup_socket_get_remote_address (SOUP_SOCKET (object)));
247 case PROP_NON_BLOCKING:
248 g_value_set_boolean (value, priv->non_blocking);
251 g_value_set_boolean (value, priv->is_server);
253 case PROP_SSL_CREDENTIALS:
254 g_value_set_pointer (value, priv->ssl_creds);
256 case PROP_SSL_STRICT:
257 g_value_set_boolean (value, priv->ssl_strict);
259 case PROP_SSL_FALLBACK:
260 g_value_set_boolean (value, priv->ssl_fallback);
262 case PROP_TRUSTED_CERTIFICATE:
263 g_value_set_boolean (value, priv->tls_errors == 0);
265 case PROP_ASYNC_CONTEXT:
266 g_value_set_pointer (value, priv->async_context ? g_main_context_ref (priv->async_context) : NULL);
268 case PROP_USE_THREAD_CONTEXT:
269 g_value_set_boolean (value, priv->use_thread_context);
272 g_value_set_uint (value, priv->timeout);
274 case PROP_TLS_CERTIFICATE:
275 if (G_IS_TLS_CONNECTION (priv->conn))
276 g_value_set_object (value, g_tls_connection_get_peer_certificate (G_TLS_CONNECTION (priv->conn)));
278 g_value_set_object (value, NULL);
280 case PROP_TLS_ERRORS:
281 g_value_set_flags (value, priv->tls_errors);
284 g_value_set_boolean (value, priv->use_proxy);
287 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
293 soup_socket_class_init (SoupSocketClass *socket_class)
295 GObjectClass *object_class = G_OBJECT_CLASS (socket_class);
297 g_type_class_add_private (socket_class, sizeof (SoupSocketPrivate));
299 /* virtual method override */
300 object_class->finalize = soup_socket_finalize;
301 object_class->set_property = soup_socket_set_property;
302 object_class->get_property = soup_socket_get_property;
307 * SoupSocket::readable:
310 * Emitted when an async socket is readable. See
311 * soup_socket_read(), soup_socket_read_until() and
312 * #SoupSocket:non-blocking.
315 g_signal_new ("readable",
316 G_OBJECT_CLASS_TYPE (object_class),
318 G_STRUCT_OFFSET (SoupSocketClass, readable),
320 _soup_marshal_NONE__NONE,
324 * SoupSocket::writable:
327 * Emitted when an async socket is writable. See
328 * soup_socket_write() and #SoupSocket:non-blocking.
331 g_signal_new ("writable",
332 G_OBJECT_CLASS_TYPE (object_class),
334 G_STRUCT_OFFSET (SoupSocketClass, writable),
336 _soup_marshal_NONE__NONE,
340 * SoupSocket::disconnected:
343 * Emitted when the socket is disconnected, for whatever
346 signals[DISCONNECTED] =
347 g_signal_new ("disconnected",
348 G_OBJECT_CLASS_TYPE (object_class),
350 G_STRUCT_OFFSET (SoupSocketClass, disconnected),
352 _soup_marshal_NONE__NONE,
356 * SoupSocket::new-connection:
358 * @new: the new socket
360 * Emitted when a listening socket (set up with
361 * soup_socket_listen()) receives a new connection.
363 * You must ref the @new if you want to keep it; otherwise it
364 * will be destroyed after the signal is emitted.
366 signals[NEW_CONNECTION] =
367 g_signal_new ("new_connection",
368 G_OBJECT_CLASS_TYPE (object_class),
370 G_STRUCT_OFFSET (SoupSocketClass, new_connection),
372 _soup_marshal_NONE__OBJECT,
378 * @event: the event that occurred
379 * @connection: the current connection state
381 * Emitted when a network-related event occurs. See
382 * #GSocketClient::event for more details.
387 g_signal_new ("event",
388 G_OBJECT_CLASS_TYPE (object_class),
394 G_TYPE_SOCKET_CLIENT_EVENT,
400 * SOUP_SOCKET_LOCAL_ADDRESS:
402 * Alias for the #SoupSocket:local-address property. (Address
403 * of local end of socket.)
405 g_object_class_install_property (
406 object_class, PROP_LOCAL_ADDRESS,
407 g_param_spec_object (SOUP_SOCKET_LOCAL_ADDRESS,
409 "Address of local end of socket",
411 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
413 * SOUP_SOCKET_REMOTE_ADDRESS:
415 * Alias for the #SoupSocket:remote-address property. (Address
416 * of remote end of socket.)
418 g_object_class_install_property (
419 object_class, PROP_REMOTE_ADDRESS,
420 g_param_spec_object (SOUP_SOCKET_REMOTE_ADDRESS,
422 "Address of remote end of socket",
424 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
426 * SoupSocket:non-blocking:
428 * Whether or not the socket uses non-blocking I/O.
430 * #SoupSocket's I/O methods are designed around the idea of
431 * using a single codepath for both synchronous and
432 * asynchronous I/O. If you want to read off a #SoupSocket,
433 * the "correct" way to do it is to call soup_socket_read() or
434 * soup_socket_read_until() repeatedly until you have read
435 * everything you want. If it returns %SOUP_SOCKET_WOULD_BLOCK
436 * at any point, stop reading and wait for it to emit the
437 * #SoupSocket::readable signal. Then go back to the
438 * reading-as-much-as-you-can loop. Likewise, for writing to a
439 * #SoupSocket, you should call soup_socket_write() either
440 * until you have written everything, or it returns
441 * %SOUP_SOCKET_WOULD_BLOCK (in which case you wait for
442 * #SoupSocket::writable and then go back into the loop).
444 * Code written this way will work correctly with both
445 * blocking and non-blocking sockets; blocking sockets will
446 * simply never return %SOUP_SOCKET_WOULD_BLOCK, and so the
447 * code that handles that case just won't get used for them.
450 * SOUP_SOCKET_FLAG_NONBLOCKING:
452 * Alias for the #SoupSocket:non-blocking property. (Whether
453 * or not the socket uses non-blocking I/O.)
455 g_object_class_install_property (
456 object_class, PROP_NON_BLOCKING,
457 g_param_spec_boolean (SOUP_SOCKET_FLAG_NONBLOCKING,
459 "Whether or not the socket uses non-blocking I/O",
463 * SOUP_SOCKET_IS_SERVER:
465 * Alias for the #SoupSocket:is-server property. (Whether or
466 * not the socket is a server socket.)
468 g_object_class_install_property (
469 object_class, PROP_IS_SERVER,
470 g_param_spec_boolean (SOUP_SOCKET_IS_SERVER,
472 "Whether or not the socket is a server socket",
476 * SOUP_SOCKET_SSL_CREDENTIALS:
478 * Alias for the #SoupSocket:ssl-creds property.
479 * (SSL credential information.)
481 /* For historical reasons, there's only a single property
482 * here, which is a GTlsDatabase for client sockets, and
483 * a GTlsCertificate for server sockets. Whee!
485 g_object_class_install_property (
486 object_class, PROP_SSL_CREDENTIALS,
487 g_param_spec_pointer (SOUP_SOCKET_SSL_CREDENTIALS,
489 "SSL credential information, passed from the session to the SSL implementation",
492 * SOUP_SOCKET_SSL_STRICT:
494 * Alias for the #SoupSocket:ssl-strict property.
496 g_object_class_install_property (
497 object_class, PROP_SSL_STRICT,
498 g_param_spec_boolean (SOUP_SOCKET_SSL_STRICT,
499 "Strictly validate SSL certificates",
500 "Whether certificate errors should be considered a connection error",
502 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
504 * SOUP_SOCKET_SSL_FALLBACK:
506 * Alias for the #SoupSocket:ssl-fallback property.
508 g_object_class_install_property (
509 object_class, PROP_SSL_FALLBACK,
510 g_param_spec_boolean (SOUP_SOCKET_SSL_FALLBACK,
512 "Use SSLv3 instead of TLS (client-side only)",
514 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
516 * SOUP_SOCKET_TRUSTED_CERTIFICATE:
518 * Alias for the #SoupSocket:trusted-certificate
521 g_object_class_install_property (
522 object_class, PROP_TRUSTED_CERTIFICATE,
523 g_param_spec_boolean (SOUP_SOCKET_TRUSTED_CERTIFICATE,
524 "Trusted Certificate",
525 "Whether the server certificate is trusted, if this is an SSL socket",
529 * SOUP_SOCKET_ASYNC_CONTEXT:
531 * Alias for the #SoupSocket:async-context property. (The
532 * socket's #GMainContext.)
534 g_object_class_install_property (
535 object_class, PROP_ASYNC_CONTEXT,
536 g_param_spec_pointer (SOUP_SOCKET_ASYNC_CONTEXT,
537 "Async GMainContext",
538 "The GMainContext to dispatch this socket's async I/O in",
539 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
542 * SOUP_SOCKET_USE_THREAD_CONTEXT:
544 * Alias for the #SoupSocket:use-thread-context property. (Use
545 * g_main_context_get_thread_default())
550 * SoupSocket:use-thread-context:
552 * Use g_main_context_get_thread_default().
556 g_object_class_install_property (
557 object_class, PROP_USE_THREAD_CONTEXT,
558 g_param_spec_boolean (SOUP_SOCKET_USE_THREAD_CONTEXT,
559 "Use thread context",
560 "Use g_main_context_get_thread_default",
562 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
565 * SOUP_SOCKET_TIMEOUT:
567 * Alias for the #SoupSocket:timeout property. (The timeout
568 * in seconds for blocking socket I/O operations.)
570 g_object_class_install_property (
571 object_class, PROP_TIMEOUT,
572 g_param_spec_uint (SOUP_SOCKET_TIMEOUT,
574 "Value in seconds to timeout a blocking I/O",
578 g_object_class_install_property (
579 object_class, PROP_CLEAN_DISPOSE,
580 g_param_spec_boolean ("clean-dispose",
582 "Warn on unclean dispose",
584 G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
586 * SOUP_SOCKET_TLS_CERTIFICATE:
588 * Alias for the #SoupSocket:tls-certificate
589 * property. Note that this property's value is only useful
590 * if the socket is for a TLS connection, and only reliable
591 * after some data has been transferred to or from it.
595 g_object_class_install_property (
596 object_class, PROP_TLS_CERTIFICATE,
597 g_param_spec_object (SOUP_SOCKET_TLS_CERTIFICATE,
599 "The peer's TLS certificate",
600 G_TYPE_TLS_CERTIFICATE,
603 * SOUP_SOCKET_TLS_ERRORS:
605 * Alias for the #SoupSocket:tls-errors
606 * property. Note that this property's value is only useful
607 * if the socket is for a TLS connection, and only reliable
608 * after some data has been transferred to or from it.
612 g_object_class_install_property (
613 object_class, PROP_TLS_ERRORS,
614 g_param_spec_flags (SOUP_SOCKET_TLS_ERRORS,
616 "Errors with the peer's TLS certificate",
617 G_TYPE_TLS_CERTIFICATE_FLAGS, 0,
620 g_object_class_install_property (
621 object_class, PROP_USE_PROXY,
622 g_param_spec_boolean (SOUP_SOCKET_USE_PROXY,
624 "Use #GProxyResolver",
626 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
632 * @optname1: name of first property to set (or %NULL)
633 * @...: value of @optname1, followed by additional property/value pairs
635 * Creates a new (disconnected) socket
637 * Return value: the new socket
640 soup_socket_new (const char *optname1, ...)
645 va_start (ap, optname1);
646 sock = (SoupSocket *)g_object_new_valist (SOUP_TYPE_SOCKET,
654 proxy_socket_client_event (GSocketClient *client,
655 GSocketClientEvent event,
656 GSocketConnectable *connectable,
657 GIOStream *connection,
660 SoupSocket *sock = user_data;
662 g_signal_emit (sock, signals[EVENT], 0,
667 socket_connected (SoupSocket *sock, GSocketConnection *conn, GError *error)
669 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
671 if (priv->connect_cancel) {
672 GCancellable *cancellable = priv->connect_cancel;
673 gboolean cancelled = g_cancellable_is_cancelled (cancellable);
675 g_object_unref (priv->connect_cancel);
676 priv->connect_cancel = NULL;
678 g_clear_error (&error);
679 return SOUP_STATUS_CANCELLED;
684 if (error->domain == G_RESOLVER_ERROR) {
685 g_error_free (error);
686 return SOUP_STATUS_CANT_RESOLVE;
688 g_error_free (error);
689 return SOUP_STATUS_CANT_CONNECT;
693 priv->conn = (GIOStream *)conn;
694 priv->gsock = g_object_ref (g_socket_connection_get_socket (conn));
695 finish_socket_setup (priv);
697 return SOUP_STATUS_OK;
701 * SoupSocketCallback:
702 * @sock: the #SoupSocket
703 * @status: an HTTP status code indicating success or failure
704 * @user_data: the data passed to soup_socket_connect_async()
706 * The callback function passed to soup_socket_connect_async().
711 SoupSocketCallback callback;
713 } SoupSocketAsyncConnectData;
716 async_connected (GObject *client, GAsyncResult *result, gpointer data)
718 SoupSocketAsyncConnectData *sacd = data;
719 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sacd->sock);
720 GError *error = NULL;
721 GSocketConnection *conn;
724 if (priv->async_context && !priv->use_thread_context)
725 g_main_context_pop_thread_default (priv->async_context);
727 conn = g_socket_client_connect_finish (G_SOCKET_CLIENT (client),
729 status = socket_connected (sacd->sock, conn, error);
731 sacd->callback (sacd->sock, status, sacd->user_data);
732 g_object_unref (sacd->sock);
733 g_slice_free (SoupSocketAsyncConnectData, sacd);
737 * soup_socket_connect_async:
738 * @sock: a client #SoupSocket (which must not already be connected)
739 * @cancellable: a #GCancellable, or %NULL
740 * @callback: (scope async): callback to call after connecting
741 * @user_data: data to pass to @callback
743 * Begins asynchronously connecting to @sock's remote address. The
744 * socket will call @callback when it succeeds or fails (but not
745 * before returning from this function).
747 * If @cancellable is non-%NULL, it can be used to cancel the
748 * connection. @callback will still be invoked in this case, with a
749 * status of %SOUP_STATUS_CANCELLED.
752 soup_socket_connect_async (SoupSocket *sock, GCancellable *cancellable,
753 SoupSocketCallback callback, gpointer user_data)
755 SoupSocketPrivate *priv;
756 SoupSocketAsyncConnectData *sacd;
757 GSocketClient *client;
759 g_return_if_fail (SOUP_IS_SOCKET (sock));
760 priv = SOUP_SOCKET_GET_PRIVATE (sock);
761 g_return_if_fail (priv->remote_addr != NULL);
763 sacd = g_slice_new0 (SoupSocketAsyncConnectData);
764 sacd->sock = g_object_ref (sock);
765 sacd->callback = callback;
766 sacd->user_data = user_data;
768 priv->connect_cancel = cancellable ? g_object_ref (cancellable) : g_cancellable_new ();
770 if (priv->async_context && !priv->use_thread_context)
771 g_main_context_push_thread_default (priv->async_context);
773 client = g_socket_client_new ();
774 g_signal_connect (client, "event",
775 G_CALLBACK (proxy_socket_client_event), sock);
777 g_socket_client_add_application_proxy (client, "http");
779 g_socket_client_set_enable_proxy (client, FALSE);
781 g_socket_client_set_timeout (client, priv->timeout);
782 g_socket_client_connect_async (client,
783 G_SOCKET_CONNECTABLE (priv->remote_addr),
784 priv->connect_cancel,
785 async_connected, sacd);
786 g_object_unref (client);
790 * soup_socket_connect_sync:
791 * @sock: a client #SoupSocket (which must not already be connected)
792 * @cancellable: a #GCancellable, or %NULL
794 * Attempt to synchronously connect @sock to its remote address.
796 * If @cancellable is non-%NULL, it can be used to cancel the
797 * connection, in which case soup_socket_connect_sync() will return
798 * %SOUP_STATUS_CANCELLED.
800 * Return value: a success or failure code.
803 soup_socket_connect_sync (SoupSocket *sock, GCancellable *cancellable)
805 SoupSocketPrivate *priv;
806 GSocketClient *client;
807 GSocketConnection *conn;
808 GError *error = NULL;
810 g_return_val_if_fail (SOUP_IS_SOCKET (sock), SOUP_STATUS_MALFORMED);
811 priv = SOUP_SOCKET_GET_PRIVATE (sock);
812 g_return_val_if_fail (!priv->is_server, SOUP_STATUS_MALFORMED);
813 g_return_val_if_fail (priv->gsock == NULL, SOUP_STATUS_MALFORMED);
814 g_return_val_if_fail (priv->remote_addr != NULL, SOUP_STATUS_MALFORMED);
817 g_object_ref (cancellable);
819 cancellable = g_cancellable_new ();
820 priv->connect_cancel = cancellable;
822 client = g_socket_client_new ();
823 g_signal_connect (client, "event",
824 G_CALLBACK (proxy_socket_client_event), sock);
826 g_socket_client_add_application_proxy (client, "http");
828 g_socket_client_set_enable_proxy (client, FALSE);
830 g_socket_client_set_timeout (client, priv->timeout);
831 conn = g_socket_client_connect (client,
832 G_SOCKET_CONNECTABLE (priv->remote_addr),
833 priv->connect_cancel, &error);
834 g_object_unref (client);
836 return socket_connected (sock, conn, error);
840 * soup_socket_get_fd:
841 * @sock: a #SoupSocket
843 * Gets @sock's underlying file descriptor.
845 * Note that fiddling with the file descriptor may break the
848 * Return value: @sock's file descriptor.
851 soup_socket_get_fd (SoupSocket *sock)
853 g_return_val_if_fail (SOUP_IS_SOCKET (sock), -1);
855 return g_socket_get_fd (SOUP_SOCKET_GET_PRIVATE (sock)->gsock);
859 soup_socket_get_gsocket (SoupSocket *sock)
861 g_return_val_if_fail (SOUP_IS_SOCKET (sock), NULL);
863 return SOUP_SOCKET_GET_PRIVATE (sock)->gsock;
867 soup_socket_get_connection (SoupSocket *sock)
869 g_return_val_if_fail (SOUP_IS_SOCKET (sock), NULL);
871 return SOUP_SOCKET_GET_PRIVATE (sock)->conn;
875 soup_socket_get_iostream (SoupSocket *sock)
877 g_return_val_if_fail (SOUP_IS_SOCKET (sock), NULL);
879 return SOUP_SOCKET_GET_PRIVATE (sock)->iostream;
883 soup_socket_create_watch (SoupSocketPrivate *priv, GIOCondition cond,
884 GPollableSourceFunc callback, gpointer user_data,
885 GCancellable *cancellable)
888 GMainContext *async_context;
891 watch = g_pollable_input_stream_create_source (G_POLLABLE_INPUT_STREAM (priv->istream), cancellable);
893 watch = g_pollable_output_stream_create_source (G_POLLABLE_OUTPUT_STREAM (priv->ostream), cancellable);
894 g_source_set_callback (watch, (GSourceFunc)callback, user_data, NULL);
896 if (priv->use_thread_context)
897 async_context = g_main_context_get_thread_default ();
899 async_context = priv->async_context;
901 g_source_attach (watch, async_context);
902 g_source_unref (watch);
908 listen_watch (GObject *pollable, gpointer data)
910 SoupSocket *sock = data, *new;
911 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock), *new_priv;
914 new_gsock = g_socket_accept (priv->gsock, NULL, NULL);
918 new = g_object_new (SOUP_TYPE_SOCKET, NULL);
919 new_priv = SOUP_SOCKET_GET_PRIVATE (new);
920 new_priv->gsock = new_gsock;
921 if (priv->async_context)
922 new_priv->async_context = g_main_context_ref (priv->async_context);
923 new_priv->use_thread_context = priv->use_thread_context;
924 new_priv->non_blocking = priv->non_blocking;
925 new_priv->is_server = TRUE;
926 new_priv->ssl = priv->ssl;
928 new_priv->ssl_creds = priv->ssl_creds;
929 finish_socket_setup (new_priv);
931 if (new_priv->ssl_creds) {
932 if (!soup_socket_start_proxy_ssl (new, NULL, NULL)) {
933 g_object_unref (new);
938 g_signal_emit (sock, signals[NEW_CONNECTION], 0, new);
939 g_object_unref (new);
945 * soup_socket_listen:
946 * @sock: a server #SoupSocket (which must not already be connected or
949 * Makes @sock start listening on its local address. When connections
950 * come in, @sock will emit #SoupSocket::new_connection.
952 * Return value: whether or not @sock is now listening.
955 soup_socket_listen (SoupSocket *sock)
958 SoupSocketPrivate *priv;
959 GSocketAddress *addr;
961 g_return_val_if_fail (SOUP_IS_SOCKET (sock), FALSE);
962 priv = SOUP_SOCKET_GET_PRIVATE (sock);
963 g_return_val_if_fail (priv->gsock == NULL, FALSE);
964 g_return_val_if_fail (priv->local_addr != NULL, FALSE);
966 priv->is_server = TRUE;
968 /* @local_addr may have its port set to 0. So we intentionally
969 * don't store it in priv->local_addr, so that if the
970 * caller calls soup_socket_get_local_address() later, we'll
971 * have to make a new addr by calling getsockname(), which
972 * will have the right port number.
974 addr = soup_address_get_gsockaddr (priv->local_addr);
975 g_return_val_if_fail (addr != NULL, FALSE);
977 priv->gsock = g_socket_new (g_socket_address_get_family (addr),
978 G_SOCKET_TYPE_STREAM,
979 G_SOCKET_PROTOCOL_DEFAULT,
983 finish_socket_setup (priv);
986 if (!g_socket_bind (priv->gsock, addr, TRUE, NULL))
988 /* Force local_addr to be re-resolved now */
989 g_object_unref (priv->local_addr);
990 priv->local_addr = NULL;
993 if (!g_socket_listen (priv->gsock, NULL))
996 priv->watch_src = soup_socket_create_watch (priv, G_IO_IN,
999 g_object_unref (addr);
1004 disconnect_internal (sock, TRUE);
1005 g_object_unref (addr);
1011 soup_socket_peer_certificate_changed (GObject *conn, GParamSpec *pspec,
1014 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
1016 priv->tls_errors = g_tls_connection_get_peer_certificate_errors (G_TLS_CONNECTION (priv->conn));
1018 g_object_notify (sock, "tls-certificate");
1019 g_object_notify (sock, "tls-errors");
1023 soup_socket_accept_certificate (GTlsConnection *conn, GTlsCertificate *cert,
1024 GTlsCertificateFlags errors, gpointer sock)
1030 * soup_socket_start_ssl:
1032 * @cancellable: a #GCancellable
1034 * Starts using SSL on @socket.
1036 * Return value: success or failure
1039 soup_socket_start_ssl (SoupSocket *sock, GCancellable *cancellable)
1041 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
1043 return soup_socket_start_proxy_ssl (sock, soup_address_get_name (priv->remote_addr), cancellable);
1047 * soup_socket_start_proxy_ssl:
1049 * @ssl_host: hostname of the SSL server
1050 * @cancellable: a #GCancellable
1052 * Starts using SSL on @socket, expecting to find a host named
1055 * Return value: success or failure
1058 soup_socket_start_proxy_ssl (SoupSocket *sock, const char *ssl_host,
1059 GCancellable *cancellable)
1061 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
1062 GTlsBackend *backend = g_tls_backend_get_default ();
1064 if (G_IS_TLS_CONNECTION (priv->conn))
1067 if (g_cancellable_is_cancelled (cancellable))
1072 if (!priv->is_server) {
1073 GTlsClientConnection *conn;
1074 GSocketConnectable *identity;
1076 identity = g_network_address_new (ssl_host, 0);
1077 conn = g_initable_new (g_tls_backend_get_client_connection_type (backend),
1079 "base-io-stream", priv->conn,
1080 "server-identity", identity,
1081 "database", priv->ssl_creds,
1082 "require-close-notify", FALSE,
1083 "use-ssl3", priv->ssl_fallback,
1085 g_object_unref (identity);
1090 g_object_unref (priv->conn);
1091 priv->conn = G_IO_STREAM (conn);
1093 if (!priv->ssl_strict) {
1094 g_signal_connect (conn, "accept-certificate",
1095 G_CALLBACK (soup_socket_accept_certificate),
1099 GTlsServerConnection *conn;
1101 conn = g_initable_new (g_tls_backend_get_server_connection_type (backend),
1103 "base-io-stream", priv->conn,
1104 "certificate", priv->ssl_creds,
1105 "use-system-certdb", FALSE,
1106 "require-close-notify", FALSE,
1111 g_object_unref (priv->conn);
1112 priv->conn = G_IO_STREAM (conn);
1115 g_signal_connect (priv->conn, "notify::peer-certificate",
1116 G_CALLBACK (soup_socket_peer_certificate_changed), sock);
1118 g_clear_object (&priv->istream);
1119 g_clear_object (&priv->ostream);
1120 g_clear_object (&priv->iostream);
1121 priv->iostream = soup_io_stream_new (priv->conn, FALSE);
1122 priv->istream = g_object_ref (g_io_stream_get_input_stream (priv->iostream));
1123 priv->ostream = g_object_ref (g_io_stream_get_output_stream (priv->iostream));
1129 soup_socket_handshake_sync (SoupSocket *sock,
1130 GCancellable *cancellable)
1132 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
1133 GError *error = NULL;
1136 if (g_tls_connection_handshake (G_TLS_CONNECTION (priv->conn),
1137 cancellable, &error))
1138 return SOUP_STATUS_OK;
1139 else if (!priv->ssl_fallback &&
1140 g_error_matches (error, G_TLS_ERROR, G_TLS_ERROR_NOT_TLS)) {
1141 g_error_free (error);
1142 return SOUP_STATUS_TLS_FAILED;
1144 g_error_free (error);
1145 return SOUP_STATUS_SSL_FAILED;
1150 handshake_async_ready (GObject *source, GAsyncResult *result, gpointer user_data)
1152 SoupSocketAsyncConnectData *data = user_data;
1153 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (data->sock);
1154 GError *error = NULL;
1157 if (priv->async_context && !priv->use_thread_context)
1158 g_main_context_pop_thread_default (priv->async_context);
1160 if (g_tls_connection_handshake_finish (G_TLS_CONNECTION (source),
1162 status = SOUP_STATUS_OK;
1163 else if (!priv->ssl_fallback &&
1164 g_error_matches (error, G_TLS_ERROR, G_TLS_ERROR_NOT_TLS))
1165 status = SOUP_STATUS_TLS_FAILED;
1167 status = SOUP_STATUS_SSL_FAILED;
1168 g_clear_error (&error);
1170 data->callback (data->sock, status, data->user_data);
1171 g_object_unref (data->sock);
1172 g_slice_free (SoupSocketAsyncConnectData, data);
1176 soup_socket_handshake_async (SoupSocket *sock,
1177 GCancellable *cancellable,
1178 SoupSocketCallback callback,
1181 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
1182 SoupSocketAsyncConnectData *data;
1186 data = g_slice_new (SoupSocketAsyncConnectData);
1187 data->sock = g_object_ref (sock);
1188 data->callback = callback;
1189 data->user_data = user_data;
1191 if (priv->async_context && !priv->use_thread_context)
1192 g_main_context_push_thread_default (priv->async_context);
1193 g_tls_connection_handshake_async (G_TLS_CONNECTION (priv->conn),
1195 cancellable, handshake_async_ready,
1200 * soup_socket_is_ssl:
1201 * @sock: a #SoupSocket
1203 * Tests if @sock is doing (or has attempted to do) SSL.
1205 * Return value: %TRUE if @sock has SSL credentials set
1208 soup_socket_is_ssl (SoupSocket *sock)
1210 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
1216 * soup_socket_disconnect:
1217 * @sock: a #SoupSocket
1219 * Disconnects @sock. Any further read or write attempts on it will
1223 soup_socket_disconnect (SoupSocket *sock)
1225 SoupSocketPrivate *priv;
1226 gboolean already_disconnected = FALSE;
1228 g_return_if_fail (SOUP_IS_SOCKET (sock));
1229 priv = SOUP_SOCKET_GET_PRIVATE (sock);
1231 if (priv->connect_cancel) {
1232 disconnect_internal (sock, FALSE);
1233 g_cancellable_cancel (priv->connect_cancel);
1235 } else if (g_mutex_trylock (&priv->iolock)) {
1237 disconnect_internal (sock, TRUE);
1239 already_disconnected = TRUE;
1240 g_mutex_unlock (&priv->iolock);
1242 /* Another thread is currently doing IO, so
1243 * we can't close the socket. So just shutdown
1244 * the file descriptor to force the I/O to fail.
1245 * (It will actually be closed when the socket
1248 g_socket_shutdown (priv->gsock, TRUE, TRUE, NULL);
1251 if (already_disconnected)
1254 /* Keep ref around signals in case the object is unreferenced
1257 g_object_ref (sock);
1259 if (priv->non_blocking) {
1260 /* Give all readers a chance to notice the connection close */
1261 g_signal_emit (sock, signals[READABLE], 0);
1264 /* FIXME: can't disconnect until all data is read */
1266 /* Then let everyone know we're disconnected */
1267 g_signal_emit (sock, signals[DISCONNECTED], 0);
1269 g_object_unref (sock);
1273 * soup_socket_is_connected:
1274 * @sock: a #SoupSocket
1276 * Tests if @sock is connected to another host
1278 * Return value: %TRUE or %FALSE.
1281 soup_socket_is_connected (SoupSocket *sock)
1283 SoupSocketPrivate *priv;
1285 g_return_val_if_fail (SOUP_IS_SOCKET (sock), FALSE);
1286 priv = SOUP_SOCKET_GET_PRIVATE (sock);
1288 return priv->conn && !g_io_stream_is_closed (priv->conn);
1292 * soup_socket_get_local_address:
1293 * @sock: a #SoupSocket
1295 * Returns the #SoupAddress corresponding to the local end of @sock.
1297 * Calling this method on an unconnected socket is considered to be
1298 * an error, and produces undefined results.
1300 * Return value: (transfer none): the #SoupAddress
1303 soup_socket_get_local_address (SoupSocket *sock)
1305 SoupSocketPrivate *priv;
1307 g_return_val_if_fail (SOUP_IS_SOCKET (sock), NULL);
1308 priv = SOUP_SOCKET_GET_PRIVATE (sock);
1310 g_mutex_lock (&priv->addrlock);
1311 if (!priv->local_addr) {
1312 GSocketAddress *addr;
1313 struct sockaddr_storage sa;
1315 GError *error = NULL;
1317 if (priv->gsock == NULL) {
1318 g_warning ("%s: socket not connected", G_STRLOC);
1322 addr = g_socket_get_local_address (priv->gsock, &error);
1324 g_warning ("%s: %s", G_STRLOC, error->message);
1325 g_error_free (error);
1328 sa_len = g_socket_address_get_native_size (addr);
1329 g_socket_address_to_native (addr, &sa, sa_len, NULL);
1330 priv->local_addr = soup_address_new_from_sockaddr ((struct sockaddr *)&sa, sa_len);
1331 g_object_unref (addr);
1334 g_mutex_unlock (&priv->addrlock);
1336 return priv->local_addr;
1340 * soup_socket_get_remote_address:
1341 * @sock: a #SoupSocket
1343 * Returns the #SoupAddress corresponding to the remote end of @sock.
1345 * Calling this method on an unconnected socket is considered to be
1346 * an error, and produces undefined results.
1348 * Return value: (transfer none): the #SoupAddress
1351 soup_socket_get_remote_address (SoupSocket *sock)
1353 SoupSocketPrivate *priv;
1355 g_return_val_if_fail (SOUP_IS_SOCKET (sock), NULL);
1356 priv = SOUP_SOCKET_GET_PRIVATE (sock);
1358 g_mutex_lock (&priv->addrlock);
1359 if (!priv->remote_addr) {
1360 GSocketAddress *addr;
1361 struct sockaddr_storage sa;
1363 GError *error = NULL;
1365 if (priv->gsock == NULL) {
1366 g_warning ("%s: socket not connected", G_STRLOC);
1370 addr = g_socket_get_remote_address (priv->gsock, &error);
1372 g_warning ("%s: %s", G_STRLOC, error->message);
1373 g_error_free (error);
1376 sa_len = g_socket_address_get_native_size (addr);
1377 g_socket_address_to_native (addr, &sa, sa_len, NULL);
1378 priv->remote_addr = soup_address_new_from_sockaddr ((struct sockaddr *)&sa, sa_len);
1379 g_object_unref (addr);
1382 g_mutex_unlock (&priv->addrlock);
1384 return priv->remote_addr;
1388 soup_socket_get_http_proxy_uri (SoupSocket *sock)
1390 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
1391 GSocketAddress *addr;
1392 GProxyAddress *paddr;
1396 addr = g_socket_get_remote_address (priv->gsock, NULL);
1397 if (!addr || !G_IS_PROXY_ADDRESS (addr))
1400 paddr = G_PROXY_ADDRESS (addr);
1401 if (strcmp (g_proxy_address_get_protocol (paddr), "http") != 0)
1404 return soup_uri_new (g_proxy_address_get_uri (paddr));
1408 socket_read_watch (GObject *pollable, gpointer user_data)
1410 SoupSocket *sock = user_data;
1411 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
1413 priv->read_src = NULL;
1414 g_signal_emit (sock, signals[READABLE], 0);
1418 static SoupSocketIOStatus
1419 translate_read_status (SoupSocket *sock, GCancellable *cancellable,
1420 gssize my_nread, gsize *nread,
1421 GError *my_err, GError **error)
1423 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
1426 g_assert_no_error (my_err);
1428 return SOUP_SOCKET_OK;
1429 } else if (my_nread == 0) {
1430 g_assert_no_error (my_err);
1432 return SOUP_SOCKET_EOF;
1433 } else if (g_error_matches (my_err, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) {
1434 g_clear_error (&my_err);
1435 if (!priv->read_src) {
1437 soup_socket_create_watch (priv, G_IO_IN,
1438 socket_read_watch, sock,
1441 return SOUP_SOCKET_WOULD_BLOCK;
1444 g_propagate_error (error, my_err);
1445 return SOUP_SOCKET_ERROR;
1449 * SoupSocketIOStatus:
1450 * @SOUP_SOCKET_OK: Success
1451 * @SOUP_SOCKET_WOULD_BLOCK: Cannot read/write any more at this time
1452 * @SOUP_SOCKET_EOF: End of file
1453 * @SOUP_SOCKET_ERROR: Other error
1455 * Return value from the #SoupSocket IO methods.
1461 * @buffer: buffer to read into
1462 * @len: size of @buffer in bytes
1463 * @nread: (out): on return, the number of bytes read into @buffer
1464 * @cancellable: a #GCancellable, or %NULL
1465 * @error: error pointer
1467 * Attempts to read up to @len bytes from @sock into @buffer. If some
1468 * data is successfully read, soup_socket_read() will return
1469 * %SOUP_SOCKET_OK, and *@nread will contain the number of bytes
1470 * actually read (which may be less than @len).
1472 * If @sock is non-blocking, and no data is available, the return
1473 * value will be %SOUP_SOCKET_WOULD_BLOCK. In this case, the caller
1474 * can connect to the #SoupSocket::readable signal to know when there
1475 * is more data to read. (NB: You MUST read all available data off the
1476 * socket first. #SoupSocket::readable is only emitted after
1477 * soup_socket_read() returns %SOUP_SOCKET_WOULD_BLOCK, and it is only
1478 * emitted once. See the documentation for #SoupSocket:non-blocking.)
1480 * Return value: a #SoupSocketIOStatus, as described above (or
1481 * %SOUP_SOCKET_EOF if the socket is no longer connected, or
1482 * %SOUP_SOCKET_ERROR on any other error, in which case @error will
1486 soup_socket_read (SoupSocket *sock, gpointer buffer, gsize len,
1487 gsize *nread, GCancellable *cancellable, GError **error)
1489 SoupSocketPrivate *priv;
1490 SoupSocketIOStatus status;
1492 GError *my_err = NULL;
1494 g_return_val_if_fail (SOUP_IS_SOCKET (sock), SOUP_SOCKET_ERROR);
1495 g_return_val_if_fail (nread != NULL, SOUP_SOCKET_ERROR);
1497 priv = SOUP_SOCKET_GET_PRIVATE (sock);
1499 g_mutex_lock (&priv->iolock);
1501 if (!priv->istream) {
1502 status = SOUP_SOCKET_EOF;
1506 if (!priv->non_blocking) {
1507 my_nread = g_input_stream_read (priv->istream, buffer, len,
1508 cancellable, &my_err);
1510 my_nread = g_pollable_input_stream_read_nonblocking (G_POLLABLE_INPUT_STREAM (priv->istream),
1512 cancellable, &my_err);
1514 status = translate_read_status (sock, cancellable,
1515 my_nread, nread, my_err, error);
1518 g_mutex_unlock (&priv->iolock);
1524 * soup_socket_read_until:
1526 * @buffer: buffer to read into
1527 * @len: size of @buffer in bytes
1528 * @boundary: boundary to read until
1529 * @boundary_len: length of @boundary in bytes
1530 * @nread: (out): on return, the number of bytes read into @buffer
1531 * @got_boundary: on return, whether or not the data in @buffer
1532 * ends with the boundary string
1533 * @cancellable: a #GCancellable, or %NULL
1534 * @error: error pointer
1536 * Like soup_socket_read(), but reads no further than the first
1537 * occurrence of @boundary. (If the boundary is found, it will be
1538 * included in the returned data, and *@got_boundary will be set to
1539 * %TRUE.) Any data after the boundary will returned in future reads.
1541 * soup_socket_read_until() will almost always return fewer than @len
1542 * bytes: if the boundary is found, then it will only return the bytes
1543 * up until the end of the boundary, and if the boundary is not found,
1544 * then it will leave the last <literal>(boundary_len - 1)</literal>
1545 * bytes in its internal buffer, in case they form the start of the
1546 * boundary string. Thus, @len normally needs to be at least 1 byte
1547 * longer than @boundary_len if you want to make any progress at all.
1549 * Return value: as for soup_socket_read()
1552 soup_socket_read_until (SoupSocket *sock, gpointer buffer, gsize len,
1553 gconstpointer boundary, gsize boundary_len,
1554 gsize *nread, gboolean *got_boundary,
1555 GCancellable *cancellable, GError **error)
1557 SoupSocketPrivate *priv;
1558 SoupSocketIOStatus status;
1560 GError *my_err = NULL;
1562 g_return_val_if_fail (SOUP_IS_SOCKET (sock), SOUP_SOCKET_ERROR);
1563 g_return_val_if_fail (nread != NULL, SOUP_SOCKET_ERROR);
1564 g_return_val_if_fail (len >= boundary_len, SOUP_SOCKET_ERROR);
1566 priv = SOUP_SOCKET_GET_PRIVATE (sock);
1568 g_mutex_lock (&priv->iolock);
1570 *got_boundary = FALSE;
1573 status = SOUP_SOCKET_EOF;
1575 my_nread = soup_filter_input_stream_read_until (
1576 SOUP_FILTER_INPUT_STREAM (priv->istream),
1577 buffer, len, boundary, boundary_len,
1578 !priv->non_blocking,
1579 TRUE, got_boundary, cancellable, &my_err);
1580 status = translate_read_status (sock, cancellable,
1581 my_nread, nread, my_err, error);
1584 g_mutex_unlock (&priv->iolock);
1589 socket_write_watch (GObject *pollable, gpointer user_data)
1591 SoupSocket *sock = user_data;
1592 SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
1594 priv->write_src = NULL;
1595 g_signal_emit (sock, signals[WRITABLE], 0);
1600 * soup_socket_write:
1602 * @buffer: data to write
1603 * @len: size of @buffer, in bytes
1604 * @nwrote: (out): on return, number of bytes written
1605 * @cancellable: a #GCancellable, or %NULL
1606 * @error: error pointer
1608 * Attempts to write @len bytes from @buffer to @sock. If some data is
1609 * successfully written, the return status will be %SOUP_SOCKET_OK,
1610 * and *@nwrote will contain the number of bytes actually written
1611 * (which may be less than @len).
1613 * If @sock is non-blocking, and no data could be written right away,
1614 * the return value will be %SOUP_SOCKET_WOULD_BLOCK. In this case,
1615 * the caller can connect to the #SoupSocket::writable signal to know
1616 * when more data can be written. (NB: #SoupSocket::writable is only
1617 * emitted after soup_socket_write() returns %SOUP_SOCKET_WOULD_BLOCK,
1618 * and it is only emitted once. See the documentation for
1619 * #SoupSocket:non-blocking.)
1621 * Return value: a #SoupSocketIOStatus, as described above (or
1622 * %SOUP_SOCKET_EOF or %SOUP_SOCKET_ERROR. @error will be set if the
1623 * return value is %SOUP_SOCKET_ERROR.)
1626 soup_socket_write (SoupSocket *sock, gconstpointer buffer,
1627 gsize len, gsize *nwrote,
1628 GCancellable *cancellable, GError **error)
1630 SoupSocketPrivate *priv;
1631 GError *my_err = NULL;
1634 g_return_val_if_fail (SOUP_IS_SOCKET (sock), SOUP_SOCKET_ERROR);
1635 g_return_val_if_fail (nwrote != NULL, SOUP_SOCKET_ERROR);
1637 priv = SOUP_SOCKET_GET_PRIVATE (sock);
1639 g_mutex_lock (&priv->iolock);
1642 g_mutex_unlock (&priv->iolock);
1643 return SOUP_SOCKET_EOF;
1645 if (priv->write_src) {
1646 g_mutex_unlock (&priv->iolock);
1647 return SOUP_SOCKET_WOULD_BLOCK;
1650 if (!priv->non_blocking) {
1651 my_nwrote = g_output_stream_write (priv->ostream,
1653 cancellable, &my_err);
1655 my_nwrote = g_pollable_output_stream_write_nonblocking (
1656 G_POLLABLE_OUTPUT_STREAM (priv->ostream),
1657 buffer, len, cancellable, &my_err);
1660 if (my_nwrote > 0) {
1661 g_mutex_unlock (&priv->iolock);
1662 g_clear_error (&my_err);
1663 *nwrote = my_nwrote;
1664 return SOUP_SOCKET_OK;
1667 if (g_error_matches (my_err, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) {
1668 g_mutex_unlock (&priv->iolock);
1669 g_clear_error (&my_err);
1672 soup_socket_create_watch (priv,
1674 socket_write_watch, sock, cancellable);
1675 return SOUP_SOCKET_WOULD_BLOCK;
1678 g_mutex_unlock (&priv->iolock);
1679 g_propagate_error (error, my_err);
1680 return SOUP_SOCKET_ERROR;