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