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