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