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