SoupSocket: port to GSocketConnection/GTlsConnection
[platform/upstream/libsoup.git] / libsoup / soup-socket.c
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3  * soup-socket.c: Socket networking code.
4  *
5  * Copyright (C) 2000-2003, Ximian, Inc.
6  */
7
8 #ifdef HAVE_CONFIG_H
9 #include <config.h>
10 #endif
11
12 #include <stdio.h>
13 #include <errno.h>
14 #include <fcntl.h>
15 #include <signal.h>
16 #include <string.h>
17 #include <unistd.h>
18
19 #include "soup-address.h"
20 #include "soup-socket.h"
21 #include "soup-marshal.h"
22 #include "soup-misc.h"
23 #include "soup-ssl.h"
24
25 /**
26  * SECTION:soup-socket
27  * @short_description: A network socket
28  *
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.
33  **/
34
35 G_DEFINE_TYPE (SoupSocket, soup_socket, G_TYPE_OBJECT)
36
37 enum {
38         READABLE,
39         WRITABLE,
40         DISCONNECTED,
41         NEW_CONNECTION,
42         LAST_SIGNAL
43 };
44
45 static guint signals[LAST_SIGNAL] = { 0 };
46
47 enum {
48         PROP_0,
49
50         PROP_LOCAL_ADDRESS,
51         PROP_REMOTE_ADDRESS,
52         PROP_NON_BLOCKING,
53         PROP_IS_SERVER,
54         PROP_SSL_CREDENTIALS,
55         PROP_SSL_STRICT,
56         PROP_ASYNC_CONTEXT,
57         PROP_TIMEOUT,
58         PROP_TRUSTED_CERTIFICATE,
59         PROP_CLEAN_DISPOSE,
60
61         LAST_PROP
62 };
63
64 typedef struct {
65         SoupAddress *local_addr, *remote_addr;
66         GIOStream *conn;
67         GSocket *gsock;
68         GPollableInputStream *istream;
69         GPollableOutputStream *ostream;
70
71         guint non_blocking:1;
72         guint is_server:1;
73         guint ssl_strict:1;
74         guint trusted_certificate:1;
75         guint clean_dispose:1;
76         gpointer ssl_creds;
77
78         GMainContext   *async_context;
79         GSource        *watch_src;
80         GSource        *read_src, *write_src;
81         GByteArray     *read_buf;
82
83         GMutex *iolock, *addrlock;
84         guint timeout;
85
86         GCancellable *connect_cancel;
87 } SoupSocketPrivate;
88 #define SOUP_SOCKET_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SOUP_TYPE_SOCKET, SoupSocketPrivate))
89
90 static void set_property (GObject *object, guint prop_id,
91                           const GValue *value, GParamSpec *pspec);
92 static void get_property (GObject *object, guint prop_id,
93                           GValue *value, GParamSpec *pspec);
94
95 static void
96 soup_socket_init (SoupSocket *sock)
97 {
98         SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
99
100         priv->non_blocking = TRUE;
101         priv->addrlock = g_mutex_new ();
102         priv->iolock = g_mutex_new ();
103 }
104
105 static void
106 disconnect_internal (SoupSocketPrivate *priv)
107 {
108         if (priv->gsock) {
109                 g_socket_close (priv->gsock, NULL);
110                 g_object_unref (priv->gsock);
111                 priv->gsock = NULL;
112         }
113         if (priv->conn) {
114                 g_object_unref (priv->conn);
115                 priv->conn = NULL;
116                 priv->istream = NULL;
117                 priv->ostream = NULL;
118         }
119
120         if (priv->read_src) {
121                 g_source_destroy (priv->read_src);
122                 priv->read_src = NULL;
123         }
124         if (priv->write_src) {
125                 g_source_destroy (priv->write_src);
126                 priv->write_src = NULL;
127         }
128 }
129
130 static void
131 finalize (GObject *object)
132 {
133         SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (object);
134
135         if (priv->connect_cancel) {
136                 if (priv->clean_dispose)
137                         g_warning ("Disposing socket %p during connect", object);
138                 g_object_unref (priv->connect_cancel);
139         }
140         if (priv->conn) {
141                 if (priv->clean_dispose)
142                         g_warning ("Disposing socket %p while still connected", object);
143                 disconnect_internal (priv);
144         }
145
146         if (priv->local_addr)
147                 g_object_unref (priv->local_addr);
148         if (priv->remote_addr)
149                 g_object_unref (priv->remote_addr);
150
151         if (priv->watch_src) {
152                 if (priv->clean_dispose && !priv->is_server)
153                         g_warning ("Disposing socket %p during async op", object);
154                 g_source_destroy (priv->watch_src);
155         }
156         if (priv->async_context)
157                 g_main_context_unref (priv->async_context);
158
159         if (priv->read_buf)
160                 g_byte_array_free (priv->read_buf, TRUE);
161
162         g_mutex_free (priv->addrlock);
163         g_mutex_free (priv->iolock);
164
165         G_OBJECT_CLASS (soup_socket_parent_class)->finalize (object);
166 }
167
168 static void
169 soup_socket_class_init (SoupSocketClass *socket_class)
170 {
171         GObjectClass *object_class = G_OBJECT_CLASS (socket_class);
172
173         g_type_class_add_private (socket_class, sizeof (SoupSocketPrivate));
174
175         /* virtual method override */
176         object_class->finalize = finalize;
177         object_class->set_property = set_property;
178         object_class->get_property = get_property;
179
180         /* signals */
181
182         /**
183          * SoupSocket::readable:
184          * @sock: the socket
185          *
186          * Emitted when an async socket is readable. See
187          * soup_socket_read(), soup_socket_read_until() and
188          * #SoupSocket:non-blocking.
189          **/
190         signals[READABLE] =
191                 g_signal_new ("readable",
192                               G_OBJECT_CLASS_TYPE (object_class),
193                               G_SIGNAL_RUN_LAST,
194                               G_STRUCT_OFFSET (SoupSocketClass, readable),
195                               NULL, NULL,
196                               soup_marshal_NONE__NONE,
197                               G_TYPE_NONE, 0);
198
199         /**
200          * SoupSocket::writable:
201          * @sock: the socket
202          *
203          * Emitted when an async socket is writable. See
204          * soup_socket_write() and #SoupSocket:non-blocking.
205          **/
206         signals[WRITABLE] =
207                 g_signal_new ("writable",
208                               G_OBJECT_CLASS_TYPE (object_class),
209                               G_SIGNAL_RUN_LAST,
210                               G_STRUCT_OFFSET (SoupSocketClass, writable),
211                               NULL, NULL,
212                               soup_marshal_NONE__NONE,
213                               G_TYPE_NONE, 0);
214
215         /**
216          * SoupSocket::disconnected:
217          * @sock: the socket
218          *
219          * Emitted when the socket is disconnected, for whatever
220          * reason.
221          **/
222         signals[DISCONNECTED] =
223                 g_signal_new ("disconnected",
224                               G_OBJECT_CLASS_TYPE (object_class),
225                               G_SIGNAL_RUN_LAST,
226                               G_STRUCT_OFFSET (SoupSocketClass, disconnected),
227                               NULL, NULL,
228                               soup_marshal_NONE__NONE,
229                               G_TYPE_NONE, 0);
230
231         /**
232          * SoupSocket::new-connection:
233          * @sock: the socket
234          * @new: the new socket
235          *
236          * Emitted when a listening socket (set up with
237          * soup_socket_listen()) receives a new connection.
238          *
239          * You must ref the @new if you want to keep it; otherwise it
240          * will be destroyed after the signal is emitted.
241          **/
242         signals[NEW_CONNECTION] =
243                 g_signal_new ("new_connection",
244                               G_OBJECT_CLASS_TYPE (object_class),
245                               G_SIGNAL_RUN_FIRST,
246                               G_STRUCT_OFFSET (SoupSocketClass, new_connection),
247                               NULL, NULL,
248                               soup_marshal_NONE__OBJECT,
249                               G_TYPE_NONE, 1,
250                               SOUP_TYPE_SOCKET);
251
252         /* properties */
253         /**
254          * SOUP_SOCKET_LOCAL_ADDRESS:
255          *
256          * Alias for the #SoupSocket:local-address property. (Address
257          * of local end of socket.)
258          **/
259         g_object_class_install_property (
260                 object_class, PROP_LOCAL_ADDRESS,
261                 g_param_spec_object (SOUP_SOCKET_LOCAL_ADDRESS,
262                                      "Local address",
263                                      "Address of local end of socket",
264                                      SOUP_TYPE_ADDRESS,
265                                      G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
266         /**
267          * SOUP_SOCKET_REMOTE_ADDRESS:
268          *
269          * Alias for the #SoupSocket:remote-address property. (Address
270          * of remote end of socket.)
271          **/
272         g_object_class_install_property (
273                 object_class, PROP_REMOTE_ADDRESS,
274                 g_param_spec_object (SOUP_SOCKET_REMOTE_ADDRESS,
275                                      "Remote address",
276                                      "Address of remote end of socket",
277                                      SOUP_TYPE_ADDRESS,
278                                      G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
279         /**
280          * SoupSocket:non-blocking:
281          *
282          * Whether or not the socket uses non-blocking I/O.
283          *
284          * #SoupSocket's I/O methods are designed around the idea of
285          * using a single codepath for both synchronous and
286          * asynchronous I/O. If you want to read off a #SoupSocket,
287          * the "correct" way to do it is to call soup_socket_read() or
288          * soup_socket_read_until() repeatedly until you have read
289          * everything you want. If it returns %SOUP_SOCKET_WOULD_BLOCK
290          * at any point, stop reading and wait for it to emit the
291          * #SoupSocket::readable signal. Then go back to the
292          * reading-as-much-as-you-can loop. Likewise, for writing to a
293          * #SoupSocket, you should call soup_socket_write() either
294          * until you have written everything, or it returns
295          * %SOUP_SOCKET_WOULD_BLOCK (in which case you wait for
296          * #SoupSocket::writable and then go back into the loop).
297          *
298          * Code written this way will work correctly with both
299          * blocking and non-blocking sockets; blocking sockets will
300          * simply never return %SOUP_SOCKET_WOULD_BLOCK, and so the
301          * code that handles that case just won't get used for them.
302          **/
303         /**
304          * SOUP_SOCKET_FLAG_NONBLOCKING:
305          *
306          * Alias for the #SoupSocket:non-blocking property. (Whether
307          * or not the socket uses non-blocking I/O.)
308          **/
309         g_object_class_install_property (
310                 object_class, PROP_NON_BLOCKING,
311                 g_param_spec_boolean (SOUP_SOCKET_FLAG_NONBLOCKING,
312                                       "Non-blocking",
313                                       "Whether or not the socket uses non-blocking I/O",
314                                       TRUE,
315                                       G_PARAM_READWRITE));
316         /**
317          * SOUP_SOCKET_IS_SERVER:
318          *
319          * Alias for the #SoupSocket:is-server property. (Whether or
320          * not the socket is a server socket.)
321          **/
322         g_object_class_install_property (
323                 object_class, PROP_IS_SERVER,
324                 g_param_spec_boolean (SOUP_SOCKET_IS_SERVER,
325                                       "Server",
326                                       "Whether or not the socket is a server socket",
327                                       FALSE,
328                                       G_PARAM_READABLE));
329         /**
330          * SOUP_SOCKET_SSL_CREDENTIALS:
331          *
332          * Alias for the #SoupSocket:ssl-credentials property.
333          * (SSL credential information.)
334          **/
335         g_object_class_install_property (
336                 object_class, PROP_SSL_CREDENTIALS,
337                 g_param_spec_pointer (SOUP_SOCKET_SSL_CREDENTIALS,
338                                       "SSL credentials",
339                                       "SSL credential information, passed from the session to the SSL implementation",
340                                       G_PARAM_READWRITE));
341         /**
342          * SOUP_SOCKET_SSL_STRICT:
343          *
344          * Alias for the #SoupSocket:ignore-ssl-cert-errors property.
345          **/
346         g_object_class_install_property (
347                 object_class, PROP_SSL_STRICT,
348                 g_param_spec_boolean (SOUP_SOCKET_SSL_STRICT,
349                                       "Strictly validate SSL certificates",
350                                       "Whether certificate errors should be considered a connection error",
351                                       TRUE,
352                                       G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
353         /**
354          * SOUP_SOCKET_TRUSTED_CERTIFICATE:
355          *
356          * Alias for the #SoupSocket:trusted-certificate
357          * property. Notice that this property's value is only useful
358          * if the socket is for an SSL connection, and only reliable
359          * after some data has been transferred to or from it.
360          **/
361         g_object_class_install_property (
362                 object_class, PROP_TRUSTED_CERTIFICATE,
363                 g_param_spec_boolean (SOUP_SOCKET_TRUSTED_CERTIFICATE,
364                                      "Trusted Certificate",
365                                      "Whether the server certificate is trusted, if this is an SSL socket",
366                                      FALSE,
367                                      G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
368         /**
369          * SOUP_SOCKET_ASYNC_CONTEXT:
370          *
371          * Alias for the #SoupSocket:async-context property. (The
372          * socket's #GMainContext.)
373          **/
374         g_object_class_install_property (
375                 object_class, PROP_ASYNC_CONTEXT,
376                 g_param_spec_pointer (SOUP_SOCKET_ASYNC_CONTEXT,
377                                       "Async GMainContext",
378                                       "The GMainContext to dispatch this socket's async I/O in",
379                                       G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
380
381         /**
382          * SOUP_SOCKET_TIMEOUT:
383          *
384          * Alias for the #SoupSocket:timeout property. (The timeout
385          * in seconds for blocking socket I/O operations.)
386          **/
387         g_object_class_install_property (
388                 object_class, PROP_TIMEOUT,
389                 g_param_spec_uint (SOUP_SOCKET_TIMEOUT,
390                                    "Timeout value",
391                                    "Value in seconds to timeout a blocking I/O",
392                                    0, G_MAXUINT, 0,
393                                    G_PARAM_READWRITE));
394
395         g_object_class_install_property (
396                 object_class, PROP_CLEAN_DISPOSE,
397                 g_param_spec_boolean ("clean-dispose",
398                                       "Clean dispose",
399                                       "Warn on unclean dispose",
400                                       FALSE,
401                                       G_PARAM_WRITABLE | G_PARAM_CONSTRUCT_ONLY));
402 }
403
404
405 static void
406 finish_socket_setup (SoupSocketPrivate *priv)
407 {
408         if (!priv->gsock)
409                 return;
410
411         if (!priv->conn)
412                 priv->conn = (GIOStream *)g_socket_connection_factory_create_connection (priv->gsock);
413         if (!priv->istream)
414                 priv->istream = G_POLLABLE_INPUT_STREAM (g_io_stream_get_input_stream (priv->conn));
415         if (!priv->ostream)
416                 priv->ostream = G_POLLABLE_OUTPUT_STREAM (g_io_stream_get_output_stream (priv->conn));
417
418         g_socket_set_timeout (priv->gsock, priv->timeout);
419 }
420
421 static void
422 set_property (GObject *object, guint prop_id,
423               const GValue *value, GParamSpec *pspec)
424 {
425         SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (object);
426
427         switch (prop_id) {
428         case PROP_LOCAL_ADDRESS:
429                 priv->local_addr = (SoupAddress *)g_value_dup_object (value);
430                 break;
431         case PROP_REMOTE_ADDRESS:
432                 priv->remote_addr = (SoupAddress *)g_value_dup_object (value);
433                 break;
434         case PROP_NON_BLOCKING:
435                 priv->non_blocking = g_value_get_boolean (value);
436                 break;
437         case PROP_SSL_CREDENTIALS:
438                 priv->ssl_creds = g_value_get_pointer (value);
439                 break;
440         case PROP_SSL_STRICT:
441                 priv->ssl_strict = g_value_get_boolean (value);
442                 break;
443         case PROP_TRUSTED_CERTIFICATE:
444                 priv->trusted_certificate = g_value_get_boolean (value);
445                 break;
446         case PROP_ASYNC_CONTEXT:
447                 priv->async_context = g_value_get_pointer (value);
448                 if (priv->async_context)
449                         g_main_context_ref (priv->async_context);
450                 break;
451         case PROP_TIMEOUT:
452                 priv->timeout = g_value_get_uint (value);
453                 if (priv->conn)
454                         g_socket_set_timeout (priv->gsock, priv->timeout);
455                 break;
456         case PROP_CLEAN_DISPOSE:
457                 priv->clean_dispose = g_value_get_boolean (value);
458                 break;
459         default:
460                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
461                 break;
462         }
463 }
464
465 static void
466 get_property (GObject *object, guint prop_id,
467               GValue *value, GParamSpec *pspec)
468 {
469         SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (object);
470
471         switch (prop_id) {
472         case PROP_LOCAL_ADDRESS:
473                 g_value_set_object (value, soup_socket_get_local_address (SOUP_SOCKET (object)));
474                 break;
475         case PROP_REMOTE_ADDRESS:
476                 g_value_set_object (value, soup_socket_get_remote_address (SOUP_SOCKET (object)));
477                 break;
478         case PROP_NON_BLOCKING:
479                 g_value_set_boolean (value, priv->non_blocking);
480                 break;
481         case PROP_IS_SERVER:
482                 g_value_set_boolean (value, priv->is_server);
483                 break;
484         case PROP_SSL_CREDENTIALS:
485                 g_value_set_pointer (value, priv->ssl_creds);
486                 break;
487         case PROP_SSL_STRICT:
488                 g_value_set_boolean (value, priv->ssl_strict);
489                 break;
490         case PROP_TRUSTED_CERTIFICATE:
491                 g_value_set_boolean (value, priv->trusted_certificate);
492                 break;
493         case PROP_ASYNC_CONTEXT:
494                 g_value_set_pointer (value, priv->async_context ? g_main_context_ref (priv->async_context) : NULL);
495                 break;
496         case PROP_TIMEOUT:
497                 g_value_set_uint (value, priv->timeout);
498                 break;
499         default:
500                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
501                 break;
502         }
503 }
504
505
506 /**
507  * soup_socket_new:
508  * @optname1: name of first property to set (or %NULL)
509  * @...: value of @optname1, followed by additional property/value pairs
510  *
511  * Creates a new (disconnected) socket
512  *
513  * Return value: the new socket
514  **/
515 SoupSocket *
516 soup_socket_new (const char *optname1, ...)
517 {
518         SoupSocket *sock;
519         va_list ap;
520
521         va_start (ap, optname1);
522         sock = (SoupSocket *)g_object_new_valist (SOUP_TYPE_SOCKET,
523                                                   optname1, ap);
524         va_end (ap);
525
526         return sock;
527 }
528
529 static guint
530 socket_connected (SoupSocket *sock, GSocketConnection *conn, GError *error)
531 {
532         SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
533
534         g_object_unref (priv->connect_cancel);
535         priv->connect_cancel = NULL;
536
537         if (error) {
538                 if (error->domain == G_RESOLVER_ERROR) {
539                         g_error_free (error);
540                         return SOUP_STATUS_CANT_RESOLVE;
541                 } else {
542                         g_error_free (error);
543                         return SOUP_STATUS_CANT_CONNECT;
544                 }
545         }
546
547         priv->conn = (GIOStream *)conn;
548         priv->gsock = g_object_ref (g_socket_connection_get_socket (conn));
549         finish_socket_setup (priv);
550
551         return SOUP_STATUS_OK;
552 }
553
554 /**
555  * SoupSocketCallback:
556  * @sock: the #SoupSocket
557  * @status: an HTTP status code indicating success or failure
558  * @user_data: the data passed to soup_socket_connect_async()
559  *
560  * The callback function passed to soup_socket_connect_async().
561  **/
562
563 typedef struct {
564         SoupSocket *sock;
565         SoupSocketCallback callback;
566         gpointer user_data;
567 } SoupSocketAsyncConnectData;
568
569 static void
570 async_connected (GObject *client, GAsyncResult *result, gpointer data)
571 {
572         SoupSocketAsyncConnectData *sacd = data;
573         SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sacd->sock);
574         GError *error = NULL;
575         GSocketConnection *conn;
576         guint status;
577
578         if (priv->async_context)
579                 g_main_context_pop_thread_default (priv->async_context);
580
581         conn = g_socket_client_connect_finish (G_SOCKET_CLIENT (client),
582                                                result, &error);
583         status = socket_connected (sacd->sock, conn, error);
584
585         sacd->callback (sacd->sock, status, sacd->user_data);
586         g_object_unref (sacd->sock);
587         g_slice_free (SoupSocketAsyncConnectData, sacd);
588 }
589
590 /**
591  * soup_socket_connect_async:
592  * @sock: a client #SoupSocket (which must not already be connected)
593  * @cancellable: a #GCancellable, or %NULL
594  * @callback: (scope async): callback to call after connecting
595  * @user_data: data to pass to @callback
596  *
597  * Begins asynchronously connecting to @sock's remote address. The
598  * socket will call @callback when it succeeds or fails (but not
599  * before returning from this function).
600  *
601  * If @cancellable is non-%NULL, it can be used to cancel the
602  * connection. @callback will still be invoked in this case, with a
603  * status of %SOUP_STATUS_CANCELLED.
604  **/
605 void
606 soup_socket_connect_async (SoupSocket *sock, GCancellable *cancellable,
607                            SoupSocketCallback callback, gpointer user_data)
608 {
609         SoupSocketPrivate *priv;
610         SoupSocketAsyncConnectData *sacd;
611         GSocketClient *client;
612
613         g_return_if_fail (SOUP_IS_SOCKET (sock));
614         priv = SOUP_SOCKET_GET_PRIVATE (sock);
615         g_return_if_fail (priv->remote_addr != NULL);
616
617         sacd = g_slice_new0 (SoupSocketAsyncConnectData);
618         sacd->sock = g_object_ref (sock);
619         sacd->callback = callback;
620         sacd->user_data = user_data;
621
622         priv->connect_cancel = cancellable ? g_object_ref (cancellable) : g_cancellable_new ();
623
624         if (priv->async_context)
625                 g_main_context_push_thread_default (priv->async_context);
626
627         client = g_socket_client_new ();
628         if (priv->timeout)
629                 g_socket_client_set_timeout (client, priv->timeout);
630         g_socket_client_connect_async (client,
631                                        G_SOCKET_CONNECTABLE (priv->remote_addr),
632                                        priv->connect_cancel,
633                                        async_connected, sacd);
634         g_object_unref (client);
635 }
636
637 /**
638  * soup_socket_connect_sync:
639  * @sock: a client #SoupSocket (which must not already be connected)
640  * @cancellable: a #GCancellable, or %NULL
641  *
642  * Attempt to synchronously connect @sock to its remote address.
643  *
644  * If @cancellable is non-%NULL, it can be used to cancel the
645  * connection, in which case soup_socket_connect_sync() will return
646  * %SOUP_STATUS_CANCELLED.
647  *
648  * Return value: a success or failure code.
649  **/
650 guint
651 soup_socket_connect_sync (SoupSocket *sock, GCancellable *cancellable)
652 {
653         SoupSocketPrivate *priv;
654         GSocketClient *client;
655         GSocketConnection *conn;
656         GError *error = NULL;
657
658         g_return_val_if_fail (SOUP_IS_SOCKET (sock), SOUP_STATUS_MALFORMED);
659         priv = SOUP_SOCKET_GET_PRIVATE (sock);
660         g_return_val_if_fail (!priv->is_server, SOUP_STATUS_MALFORMED);
661         g_return_val_if_fail (priv->gsock == NULL, SOUP_STATUS_MALFORMED);
662         g_return_val_if_fail (priv->remote_addr != NULL, SOUP_STATUS_MALFORMED);
663
664         if (cancellable)
665                 g_object_ref (cancellable);
666         else
667                 cancellable = g_cancellable_new ();
668         priv->connect_cancel = cancellable;
669
670         client = g_socket_client_new ();
671         if (priv->timeout)
672                 g_socket_client_set_timeout (client, priv->timeout);
673         conn = g_socket_client_connect (client,
674                                         G_SOCKET_CONNECTABLE (priv->remote_addr),
675                                         priv->connect_cancel, &error);
676         g_object_unref (client);
677
678         return socket_connected (sock, conn, error);
679 }
680
681 int
682 soup_socket_get_fd (SoupSocket *sock)
683 {
684         g_return_val_if_fail (SOUP_IS_SOCKET (sock), -1);
685
686         return g_socket_get_fd (SOUP_SOCKET_GET_PRIVATE (sock)->gsock);
687 }
688
689 static GSource *
690 soup_socket_create_watch (SoupSocketPrivate *priv, GIOCondition cond,
691                           GPollableSourceFunc callback, gpointer user_data,
692                           GCancellable *cancellable)
693 {
694         GSource *watch;
695
696         if (cond == G_IO_IN)
697                 watch = g_pollable_input_stream_create_source (priv->istream, cancellable);
698         else
699                 watch = g_pollable_output_stream_create_source (priv->ostream, cancellable);
700         g_source_set_callback (watch, (GSourceFunc)callback, user_data, NULL);
701         g_source_attach (watch, priv->async_context);
702         g_source_unref (watch);
703
704         return watch;
705 }
706
707 static gboolean
708 listen_watch (GObject *pollable, gpointer data)
709 {
710         SoupSocket *sock = data, *new;
711         SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock), *new_priv;
712         GSocket *new_gsock;
713
714         new_gsock = g_socket_accept (priv->gsock, NULL, NULL);
715         if (!new_gsock)
716                 return FALSE;
717
718         new = g_object_new (SOUP_TYPE_SOCKET, NULL);
719         new_priv = SOUP_SOCKET_GET_PRIVATE (new);
720         new_priv->gsock = new_gsock;
721         if (priv->async_context)
722                 new_priv->async_context = g_main_context_ref (priv->async_context);
723         new_priv->non_blocking = priv->non_blocking;
724         new_priv->is_server = TRUE;
725         if (priv->ssl_creds)
726                 new_priv->ssl_creds = priv->ssl_creds;
727         finish_socket_setup (new_priv);
728
729         if (new_priv->ssl_creds) {
730                 if (!soup_socket_start_proxy_ssl (new, NULL, NULL)) {
731                         g_object_unref (new);
732                         return TRUE;
733                 }
734         }
735
736         g_signal_emit (sock, signals[NEW_CONNECTION], 0, new);
737         g_object_unref (new);
738
739         return TRUE;
740 }
741
742 /**
743  * soup_socket_listen:
744  * @sock: a server #SoupSocket (which must not already be connected or
745  * listening)
746  *
747  * Makes @sock start listening on its local address. When connections
748  * come in, @sock will emit %new_connection.
749  *
750  * Return value: whether or not @sock is now listening.
751  **/
752 gboolean
753 soup_socket_listen (SoupSocket *sock)
754
755 {
756         SoupSocketPrivate *priv;
757         GSocketAddress *addr;
758
759         g_return_val_if_fail (SOUP_IS_SOCKET (sock), FALSE);
760         priv = SOUP_SOCKET_GET_PRIVATE (sock);
761         g_return_val_if_fail (priv->gsock == NULL, FALSE);
762         g_return_val_if_fail (priv->local_addr != NULL, FALSE);
763
764         priv->is_server = TRUE;
765
766         /* @local_addr may have its port set to 0. So we intentionally
767          * don't store it in priv->local_addr, so that if the
768          * caller calls soup_socket_get_local_address() later, we'll
769          * have to make a new addr by calling getsockname(), which
770          * will have the right port number.
771          */
772         addr = soup_address_get_gsockaddr (priv->local_addr);
773         g_return_val_if_fail (addr != NULL, FALSE);
774
775         priv->gsock = g_socket_new (g_socket_address_get_family (addr),
776                                     G_SOCKET_TYPE_STREAM,
777                                     G_SOCKET_PROTOCOL_DEFAULT,
778                                     NULL);
779         if (!priv->gsock)
780                 goto cant_listen;
781         finish_socket_setup (priv);
782
783         /* Bind */
784         if (!g_socket_bind (priv->gsock, addr, TRUE, NULL))
785                 goto cant_listen;
786         /* Force local_addr to be re-resolved now */
787         g_object_unref (priv->local_addr);
788         priv->local_addr = NULL;
789
790         /* Listen */
791         if (!g_socket_listen (priv->gsock, NULL))
792                 goto cant_listen;
793
794         priv->watch_src = soup_socket_create_watch (priv, G_IO_IN,
795                                                     listen_watch, sock,
796                                                     NULL);
797         return TRUE;
798
799  cant_listen:
800         if (priv->conn)
801                 disconnect_internal (priv);
802
803         return FALSE;
804 }
805
806 static gboolean
807 soup_socket_accept_certificate (GTlsConnection *conn, GTlsCertificate *cert,
808                                 GTlsCertificateFlags errors, gpointer sock)
809 {
810         SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
811
812         if (soup_ssl_credentials_verify_certificate (priv->ssl_creds,
813                                                      cert, errors))
814                 return TRUE;
815
816         if (!priv->ssl_strict) {
817                 priv->trusted_certificate = FALSE;
818                 return TRUE;
819         }
820         return FALSE;
821 }
822
823 /**
824  * soup_socket_start_ssl:
825  * @sock: the socket
826  * @cancellable: a #GCancellable
827  *
828  * Starts using SSL on @socket.
829  *
830  * Return value: success or failure
831  **/
832 gboolean
833 soup_socket_start_ssl (SoupSocket *sock, GCancellable *cancellable)
834 {
835         SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
836
837         return soup_socket_start_proxy_ssl (sock, soup_address_get_name (priv->remote_addr), cancellable);
838 }
839         
840 /**
841  * soup_socket_start_proxy_ssl:
842  * @sock: the socket
843  * @ssl_host: hostname of the SSL server
844  * @cancellable: a #GCancellable
845  *
846  * Starts using SSL on @socket, expecting to find a host named
847  * @ssl_host.
848  *
849  * Return value: success or failure
850  **/
851 gboolean
852 soup_socket_start_proxy_ssl (SoupSocket *sock, const char *ssl_host,
853                              GCancellable *cancellable)
854 {
855         SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
856         GTlsBackend *backend = g_tls_backend_get_default ();
857
858         if (G_IS_TLS_CONNECTION (priv->conn))
859                 return TRUE;
860         if (!priv->ssl_creds)
861                 return FALSE;
862
863         if (!priv->is_server) {
864                 GTlsClientConnection *conn;
865                 GSocketConnectable *identity;
866
867                 identity = g_network_address_new (ssl_host, 0);
868                 conn = g_initable_new (g_tls_backend_get_client_connection_type (backend),
869                                        NULL, NULL,
870                                        "base-io-stream", priv->conn,
871                                        "server-identity", identity,
872                                        "use-system-certdb", FALSE,
873                                        "require-close-notify", FALSE,
874                                        "use-ssl3", TRUE,
875                                        NULL);
876                 g_object_unref (identity);
877
878                 if (!conn)
879                         return FALSE;
880
881                 g_object_unref (priv->conn);
882                 priv->conn = G_IO_STREAM (conn);
883
884                 priv->trusted_certificate = TRUE;
885                 g_signal_connect (conn, "accept-certificate",
886                                   G_CALLBACK (soup_socket_accept_certificate),
887                                   sock);
888         } else {
889                 GTlsServerConnection *conn;
890
891                 conn = g_initable_new (g_tls_backend_get_server_connection_type (backend),
892                                        NULL, NULL,
893                                        "base-io-stream", priv->conn,
894                                        "certificate", soup_ssl_credentials_get_certificate (priv->ssl_creds),
895                                        "use-system-certdb", FALSE,
896                                        "require-close-notify", FALSE,
897                                        NULL);
898                 if (!conn)
899                         return FALSE;
900
901                 g_object_unref (priv->conn);
902                 priv->conn = G_IO_STREAM (conn);
903         }
904
905         priv->istream = G_POLLABLE_INPUT_STREAM (g_io_stream_get_input_stream (priv->conn));
906         priv->ostream = G_POLLABLE_OUTPUT_STREAM (g_io_stream_get_output_stream (priv->conn));
907         return TRUE;
908 }
909         
910 /**
911  * soup_socket_is_ssl:
912  * @sock: a #SoupSocket
913  *
914  * Tests if @sock is set up to do SSL. Note that this simply means
915  * that the %SOUP_SOCKET_SSL_CREDENTIALS property has been set; it
916  * does not mean that soup_socket_start_ssl() has been called.
917  *
918  * Return value: %TRUE if @sock has SSL credentials set
919  **/
920 gboolean
921 soup_socket_is_ssl (SoupSocket *sock)
922 {
923         SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
924
925         return priv->ssl_creds != NULL;
926 }
927
928 /**
929  * soup_socket_disconnect:
930  * @sock: a #SoupSocket
931  *
932  * Disconnects @sock. Any further read or write attempts on it will
933  * fail.
934  **/
935 void
936 soup_socket_disconnect (SoupSocket *sock)
937 {
938         SoupSocketPrivate *priv;
939         gboolean already_disconnected = FALSE;
940
941         g_return_if_fail (SOUP_IS_SOCKET (sock));
942         priv = SOUP_SOCKET_GET_PRIVATE (sock);
943
944         if (priv->connect_cancel) {
945                 g_cancellable_cancel (priv->connect_cancel);
946                 return;
947         } else if (g_mutex_trylock (priv->iolock)) {
948                 if (priv->conn)
949                         disconnect_internal (priv);
950                 else
951                         already_disconnected = TRUE;
952                 g_mutex_unlock (priv->iolock);
953         } else {
954                 /* Another thread is currently doing IO, so
955                  * we can't close the socket. So just shutdown
956                  * the file descriptor to force the I/O to fail.
957                  * (It will actually be closed when the socket
958                  * is destroyed.)
959                  */
960                 g_socket_shutdown (priv->gsock, TRUE, TRUE, NULL);
961         }
962
963         if (already_disconnected)
964                 return;
965
966         /* Keep ref around signals in case the object is unreferenced
967          * in a handler
968          */
969         g_object_ref (sock);
970
971         /* Give all readers a chance to notice the connection close */
972         g_signal_emit (sock, signals[READABLE], 0);
973
974         /* FIXME: can't disconnect until all data is read */
975
976         /* Then let everyone know we're disconnected */
977         g_signal_emit (sock, signals[DISCONNECTED], 0);
978
979         g_object_unref (sock);
980 }
981
982 /**
983  * soup_socket_is_connected:
984  * @sock: a #SoupSocket
985  *
986  * Tests if @sock is connected to another host
987  *
988  * Return value: %TRUE or %FALSE.
989  **/
990 gboolean
991 soup_socket_is_connected (SoupSocket *sock)
992 {
993         SoupSocketPrivate *priv;
994
995         g_return_val_if_fail (SOUP_IS_SOCKET (sock), FALSE);
996         priv = SOUP_SOCKET_GET_PRIVATE (sock);
997
998         return priv->conn != NULL;
999 }
1000
1001 /**
1002  * soup_socket_get_local_address:
1003  * @sock: a #SoupSocket
1004  *
1005  * Returns the #SoupAddress corresponding to the local end of @sock.
1006  *
1007  * Return value: (transfer none): the #SoupAddress
1008  **/
1009 SoupAddress *
1010 soup_socket_get_local_address (SoupSocket *sock)
1011 {
1012         SoupSocketPrivate *priv;
1013
1014         g_return_val_if_fail (SOUP_IS_SOCKET (sock), NULL);
1015         priv = SOUP_SOCKET_GET_PRIVATE (sock);
1016
1017         g_mutex_lock (priv->addrlock);
1018         if (!priv->local_addr) {
1019                 GSocketAddress *addr;
1020                 struct sockaddr_storage sa;
1021                 gssize sa_len;
1022
1023                 addr = g_socket_get_local_address (priv->gsock, NULL);
1024                 sa_len = g_socket_address_get_native_size (addr);
1025                 g_socket_address_to_native (addr, &sa, sa_len, NULL);
1026                 priv->local_addr = soup_address_new_from_sockaddr ((struct sockaddr *)&sa, sa_len);
1027                 g_object_unref (addr);
1028         }
1029         g_mutex_unlock (priv->addrlock);
1030
1031         return priv->local_addr;
1032 }
1033
1034 /**
1035  * soup_socket_get_remote_address:
1036  * @sock: a #SoupSocket
1037  *
1038  * Returns the #SoupAddress corresponding to the remote end of @sock.
1039  *
1040  * Return value: (transfer none): the #SoupAddress
1041  **/
1042 SoupAddress *
1043 soup_socket_get_remote_address (SoupSocket *sock)
1044 {
1045         SoupSocketPrivate *priv;
1046
1047         g_return_val_if_fail (SOUP_IS_SOCKET (sock), NULL);
1048         priv = SOUP_SOCKET_GET_PRIVATE (sock);
1049
1050         g_mutex_lock (priv->addrlock);
1051         if (!priv->remote_addr) {
1052                 GSocketAddress *addr;
1053                 struct sockaddr_storage sa;
1054                 gssize sa_len;
1055
1056                 addr = g_socket_get_remote_address (priv->gsock, NULL);
1057                 sa_len = g_socket_address_get_native_size (addr);
1058                 g_socket_address_to_native (addr, &sa, sa_len, NULL);
1059                 priv->local_addr = soup_address_new_from_sockaddr ((struct sockaddr *)&sa, sa_len);
1060                 g_object_unref (addr);
1061         }
1062         g_mutex_unlock (priv->addrlock);
1063
1064         return priv->remote_addr;
1065 }
1066
1067
1068 static gboolean
1069 socket_read_watch (GObject *pollable, gpointer user_data)
1070 {
1071         SoupSocket *sock = user_data;
1072         SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
1073
1074         priv->read_src = NULL;
1075         g_signal_emit (sock, signals[READABLE], 0);
1076         return FALSE;
1077 }
1078
1079 static SoupSocketIOStatus
1080 read_from_network (SoupSocket *sock, gpointer buffer, gsize len,
1081                    gsize *nread, GCancellable *cancellable, GError **error)
1082 {
1083         SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
1084         GError *my_err = NULL;
1085         gssize my_nread;
1086
1087         *nread = 0;
1088
1089         if (!priv->conn)
1090                 return SOUP_SOCKET_EOF;
1091
1092         if (!priv->non_blocking) {
1093                 my_nread = g_input_stream_read (G_INPUT_STREAM (priv->istream),
1094                                                 buffer, len,
1095                                                 cancellable, &my_err);
1096         } else {
1097                 my_nread = g_pollable_input_stream_read_nonblocking (
1098                         priv->istream, buffer, len,
1099                         cancellable, &my_err);
1100         }
1101
1102         if (my_nread > 0) {
1103                 g_clear_error (&my_err);
1104                 *nread = my_nread;
1105                 return SOUP_SOCKET_OK;
1106         } else if (my_nread == 0) {
1107                 g_clear_error (&my_err);
1108                 *nread = my_nread;
1109                 return SOUP_SOCKET_EOF;
1110         } else if (g_error_matches (my_err, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) {
1111                 g_clear_error (&my_err);
1112                 if (!priv->read_src) {
1113                         priv->read_src =
1114                                 soup_socket_create_watch (priv, G_IO_IN,
1115                                                           socket_read_watch, sock,
1116                                                           cancellable);
1117                 }
1118                 return SOUP_SOCKET_WOULD_BLOCK;
1119         } else if (g_error_matches (my_err, G_TLS_ERROR, G_TLS_ERROR_HANDSHAKE)) {
1120                 my_err->domain = SOUP_SSL_ERROR;
1121                 my_err->code = SOUP_SSL_ERROR_CERTIFICATE;
1122         }
1123
1124         g_propagate_error (error, my_err);
1125         return SOUP_SOCKET_ERROR;
1126 }
1127
1128 static SoupSocketIOStatus
1129 read_from_buf (SoupSocket *sock, gpointer buffer, gsize len, gsize *nread)
1130 {
1131         SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
1132         GByteArray *read_buf = priv->read_buf;
1133
1134         *nread = MIN (read_buf->len, len);
1135         memcpy (buffer, read_buf->data, *nread);
1136
1137         if (*nread == read_buf->len) {
1138                 g_byte_array_free (read_buf, TRUE);
1139                 priv->read_buf = NULL;
1140         } else {
1141                 memmove (read_buf->data, read_buf->data + *nread, 
1142                          read_buf->len - *nread);
1143                 g_byte_array_set_size (read_buf, read_buf->len - *nread);
1144         }
1145
1146         return SOUP_SOCKET_OK;
1147 }
1148
1149 /**
1150  * SoupSocketIOStatus:
1151  * @SOUP_SOCKET_OK: Success
1152  * @SOUP_SOCKET_WOULD_BLOCK: Cannot read/write any more at this time
1153  * @SOUP_SOCKET_EOF: End of file
1154  * @SOUP_SOCKET_ERROR: Other error
1155  *
1156  * Return value from the #SoupSocket IO methods.
1157  **/
1158
1159 /**
1160  * soup_socket_read:
1161  * @sock: the socket
1162  * @buffer: buffer to read into
1163  * @len: size of @buffer in bytes
1164  * @nread: on return, the number of bytes read into @buffer
1165  * @cancellable: a #GCancellable, or %NULL
1166  * @error: error pointer
1167  *
1168  * Attempts to read up to @len bytes from @sock into @buffer. If some
1169  * data is successfully read, soup_socket_read() will return
1170  * %SOUP_SOCKET_OK, and *@nread will contain the number of bytes
1171  * actually read (which may be less than @len).
1172  *
1173  * If @sock is non-blocking, and no data is available, the return
1174  * value will be %SOUP_SOCKET_WOULD_BLOCK. In this case, the caller
1175  * can connect to the #SoupSocket::readable signal to know when there
1176  * is more data to read. (NB: You MUST read all available data off the
1177  * socket first. #SoupSocket::readable is only emitted after
1178  * soup_socket_read() returns %SOUP_SOCKET_WOULD_BLOCK, and it is only
1179  * emitted once. See the documentation for #SoupSocket:non-blocking.)
1180  *
1181  * Return value: a #SoupSocketIOStatus, as described above (or
1182  * %SOUP_SOCKET_EOF if the socket is no longer connected, or
1183  * %SOUP_SOCKET_ERROR on any other error, in which case @error will
1184  * also be set).
1185  **/
1186 SoupSocketIOStatus
1187 soup_socket_read (SoupSocket *sock, gpointer buffer, gsize len,
1188                   gsize *nread, GCancellable *cancellable, GError **error)
1189 {
1190         SoupSocketPrivate *priv;
1191         SoupSocketIOStatus status;
1192
1193         g_return_val_if_fail (SOUP_IS_SOCKET (sock), SOUP_SOCKET_ERROR);
1194         g_return_val_if_fail (nread != NULL, SOUP_SOCKET_ERROR);
1195
1196         priv = SOUP_SOCKET_GET_PRIVATE (sock);
1197
1198         g_mutex_lock (priv->iolock);
1199         if (priv->read_buf)
1200                 status = read_from_buf (sock, buffer, len, nread);
1201         else
1202                 status = read_from_network (sock, buffer, len, nread, cancellable, error);
1203         g_mutex_unlock (priv->iolock);
1204
1205         return status;
1206 }
1207
1208 /**
1209  * soup_socket_read_until:
1210  * @sock: the socket
1211  * @buffer: buffer to read into
1212  * @len: size of @buffer in bytes
1213  * @boundary: boundary to read until
1214  * @boundary_len: length of @boundary in bytes
1215  * @nread: on return, the number of bytes read into @buffer
1216  * @got_boundary: on return, whether or not the data in @buffer
1217  * ends with the boundary string
1218  * @cancellable: a #GCancellable, or %NULL
1219  * @error: error pointer
1220  *
1221  * Like soup_socket_read(), but reads no further than the first
1222  * occurrence of @boundary. (If the boundary is found, it will be
1223  * included in the returned data, and *@got_boundary will be set to
1224  * %TRUE.) Any data after the boundary will returned in future reads.
1225  *
1226  * soup_socket_read_until() will almost always return fewer than @len
1227  * bytes: if the boundary is found, then it will only return the bytes
1228  * up until the end of the boundary, and if the boundary is not found,
1229  * then it will leave the last <literal>(boundary_len - 1)</literal>
1230  * bytes in its internal buffer, in case they form the start of the
1231  * boundary string. Thus, @len normally needs to be at least 1 byte
1232  * longer than @boundary_len if you want to make any progress at all.
1233  *
1234  * Return value: as for soup_socket_read()
1235  **/
1236 SoupSocketIOStatus
1237 soup_socket_read_until (SoupSocket *sock, gpointer buffer, gsize len,
1238                         gconstpointer boundary, gsize boundary_len,
1239                         gsize *nread, gboolean *got_boundary,
1240                         GCancellable *cancellable, GError **error)
1241 {
1242         SoupSocketPrivate *priv;
1243         SoupSocketIOStatus status;
1244         GByteArray *read_buf;
1245         guint match_len, prev_len;
1246         guint8 *p, *end;
1247
1248         g_return_val_if_fail (SOUP_IS_SOCKET (sock), SOUP_SOCKET_ERROR);
1249         g_return_val_if_fail (nread != NULL, SOUP_SOCKET_ERROR);
1250         g_return_val_if_fail (len >= boundary_len, SOUP_SOCKET_ERROR);
1251
1252         priv = SOUP_SOCKET_GET_PRIVATE (sock);
1253
1254         g_mutex_lock (priv->iolock);
1255
1256         *got_boundary = FALSE;
1257
1258         if (!priv->read_buf)
1259                 priv->read_buf = g_byte_array_new ();
1260         read_buf = priv->read_buf;
1261
1262         if (read_buf->len < boundary_len) {
1263                 prev_len = read_buf->len;
1264                 g_byte_array_set_size (read_buf, len);
1265                 status = read_from_network (sock,
1266                                             read_buf->data + prev_len,
1267                                             len - prev_len, nread, cancellable, error);
1268                 read_buf->len = prev_len + *nread;
1269
1270                 if (status != SOUP_SOCKET_OK) {
1271                         g_mutex_unlock (priv->iolock);
1272                         return status;
1273                 }
1274         }
1275
1276         /* Scan for the boundary */
1277         end = read_buf->data + read_buf->len;
1278         for (p = read_buf->data; p <= end - boundary_len; p++) {
1279                 if (!memcmp (p, boundary, boundary_len)) {
1280                         p += boundary_len;
1281                         *got_boundary = TRUE;
1282                         break;
1283                 }
1284         }
1285
1286         /* Return everything up to 'p' (which is either just after the
1287          * boundary, or @boundary_len - 1 bytes before the end of the
1288          * buffer).
1289          */
1290         match_len = p - read_buf->data;
1291         status = read_from_buf (sock, buffer, MIN (len, match_len), nread);
1292
1293         g_mutex_unlock (priv->iolock);
1294         return status;
1295 }
1296
1297 static gboolean
1298 socket_write_watch (GObject *pollable, gpointer user_data)
1299 {
1300         SoupSocket *sock = user_data;
1301         SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
1302
1303         priv->write_src = NULL;
1304         g_signal_emit (sock, signals[WRITABLE], 0);
1305         return FALSE;
1306 }
1307
1308 /**
1309  * soup_socket_write:
1310  * @sock: the socket
1311  * @buffer: data to write
1312  * @len: size of @buffer, in bytes
1313  * @nwrote: on return, number of bytes written
1314  * @cancellable: a #GCancellable, or %NULL
1315  * @error: error pointer
1316  *
1317  * Attempts to write @len bytes from @buffer to @sock. If some data is
1318  * successfully written, the return status will be %SOUP_SOCKET_OK,
1319  * and *@nwrote will contain the number of bytes actually written
1320  * (which may be less than @len).
1321  *
1322  * If @sock is non-blocking, and no data could be written right away,
1323  * the return value will be %SOUP_SOCKET_WOULD_BLOCK. In this case,
1324  * the caller can connect to the #SoupSocket::writable signal to know
1325  * when more data can be written. (NB: #SoupSocket::writable is only
1326  * emitted after soup_socket_write() returns %SOUP_SOCKET_WOULD_BLOCK,
1327  * and it is only emitted once. See the documentation for
1328  * #SoupSocket:non-blocking.)
1329  *
1330  * Return value: a #SoupSocketIOStatus, as described above (or
1331  * %SOUP_SOCKET_EOF or %SOUP_SOCKET_ERROR. @error will be set if the
1332  * return value is %SOUP_SOCKET_ERROR.)
1333  **/
1334 SoupSocketIOStatus
1335 soup_socket_write (SoupSocket *sock, gconstpointer buffer,
1336                    gsize len, gsize *nwrote,
1337                    GCancellable *cancellable, GError **error)
1338 {
1339         SoupSocketPrivate *priv;
1340         GError *my_err = NULL;
1341         gssize my_nwrote;
1342
1343         g_return_val_if_fail (SOUP_IS_SOCKET (sock), SOUP_SOCKET_ERROR);
1344         g_return_val_if_fail (nwrote != NULL, SOUP_SOCKET_ERROR);
1345
1346         priv = SOUP_SOCKET_GET_PRIVATE (sock);
1347
1348         g_mutex_lock (priv->iolock);
1349
1350         if (!priv->conn) {
1351                 g_mutex_unlock (priv->iolock);
1352                 return SOUP_SOCKET_EOF;
1353         }
1354         if (priv->write_src) {
1355                 g_mutex_unlock (priv->iolock);
1356                 return SOUP_SOCKET_WOULD_BLOCK;
1357         }
1358
1359         if (!priv->non_blocking) {
1360                 my_nwrote = g_output_stream_write (G_OUTPUT_STREAM (priv->ostream),
1361                                                    buffer, len,
1362                                                    cancellable, &my_err);
1363         } else {
1364                 my_nwrote = g_pollable_output_stream_write_nonblocking (
1365                         priv->ostream, buffer, len,
1366                         cancellable, &my_err);
1367         }
1368
1369         if (my_nwrote > 0) {
1370                 g_mutex_unlock (priv->iolock);
1371                 g_clear_error (&my_err);
1372                 *nwrote = my_nwrote;
1373                 return SOUP_SOCKET_OK;
1374         }
1375
1376         if (g_error_matches (my_err, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) {
1377                 g_mutex_unlock (priv->iolock);
1378
1379                 priv->write_src =
1380                         soup_socket_create_watch (priv,
1381                                                   G_IO_OUT,
1382                                                   socket_write_watch, sock, cancellable);
1383                 return SOUP_SOCKET_WOULD_BLOCK;
1384         } else if (g_error_matches (my_err, G_TLS_ERROR, G_TLS_ERROR_HANDSHAKE)) {
1385                 my_err->domain = SOUP_SSL_ERROR;
1386                 my_err->code = SOUP_SSL_ERROR_CERTIFICATE;
1387         }
1388
1389         g_mutex_unlock (priv->iolock);
1390         g_propagate_error (error, my_err);
1391         return SOUP_SOCKET_ERROR;
1392 }