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