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