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