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