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