Allow autogening even without AM_PATH_LIBGCRYPT available
[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 <errno.h>
13 #include <fcntl.h>
14 #include <signal.h>
15 #include <string.h>
16 #include <unistd.h>
17
18 #include "soup-address.h"
19 #include "soup-socket.h"
20 #include "soup-marshal.h"
21 #include "soup-misc.h"
22 #include "soup-ssl.h"
23
24 #include <sys/time.h>
25 #include <sys/types.h>
26
27 /**
28  * SECTION:soup-socket
29  * @short_description: A network socket
30  *
31  **/
32
33 G_DEFINE_TYPE (SoupSocket, soup_socket, G_TYPE_OBJECT)
34
35 enum {
36         READABLE,
37         WRITABLE,
38         DISCONNECTED,
39         NEW_CONNECTION,
40         LAST_SIGNAL
41 };
42
43 static guint signals[LAST_SIGNAL] = { 0 };
44
45 enum {
46         PROP_0,
47
48         PROP_LOCAL_ADDRESS,
49         PROP_REMOTE_ADDRESS,
50         PROP_NON_BLOCKING,
51         PROP_IS_SERVER,
52         PROP_SSL_CREDENTIALS,
53         PROP_ASYNC_CONTEXT,
54         PROP_TIMEOUT,
55
56         LAST_PROP
57 };
58
59 typedef struct {
60         int sockfd;
61         SoupAddress *local_addr, *remote_addr;
62         GIOChannel *iochannel;
63
64         guint non_blocking:1;
65         guint is_server:1;
66         gpointer ssl_creds;
67
68         GMainContext   *async_context;
69         GSource        *watch_src;
70         GSource        *read_src, *write_src;
71         GByteArray     *read_buf;
72
73         GMutex *iolock, *addrlock;
74         guint timeout;
75 } SoupSocketPrivate;
76 #define SOUP_SOCKET_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SOUP_TYPE_SOCKET, SoupSocketPrivate))
77
78 #ifdef HAVE_IPV6
79 #define soup_sockaddr_max sockaddr_in6
80 #else
81 #define soup_sockaddr_max sockaddr_in
82 #endif
83
84 static void set_property (GObject *object, guint prop_id,
85                           const GValue *value, GParamSpec *pspec);
86 static void get_property (GObject *object, guint prop_id,
87                           GValue *value, GParamSpec *pspec);
88
89 #ifdef G_OS_WIN32
90 #define SOUP_IS_SOCKET_ERROR(status) ((status) == SOCKET_ERROR)
91 #define SOUP_IS_INVALID_SOCKET(socket) ((socket) == INVALID_SOCKET)
92 #define SOUP_IS_CONNECT_STATUS_INPROGRESS() (WSAGetLastError () == WSAEWOULDBLOCK)
93 #define SHUT_RDWR SD_BOTH
94 #else
95 #define SOUP_IS_SOCKET_ERROR(status) ((status) == -1)
96 #define SOUP_IS_INVALID_SOCKET(socket) ((socket) < 0)
97 #define SOUP_IS_CONNECT_STATUS_INPROGRESS() (errno == EINPROGRESS)
98 #endif
99
100 static void
101 soup_socket_init (SoupSocket *sock)
102 {
103         SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
104
105         priv->sockfd = -1;
106         priv->non_blocking = TRUE;
107         priv->addrlock = g_mutex_new ();
108         priv->iolock = g_mutex_new ();
109         priv->timeout = 0;
110 }
111
112 static void
113 disconnect_internal (SoupSocketPrivate *priv)
114 {
115         g_io_channel_unref (priv->iochannel);
116         priv->iochannel = NULL;
117         priv->sockfd = -1;
118
119         if (priv->read_src) {
120                 g_source_destroy (priv->read_src);
121                 priv->read_src = NULL;
122         }
123         if (priv->write_src) {
124                 g_source_destroy (priv->write_src);
125                 priv->write_src = NULL;
126         }
127 }
128
129 static void
130 finalize (GObject *object)
131 {
132         SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (object);
133
134         if (priv->iochannel)
135                 disconnect_internal (priv);
136
137         if (priv->local_addr)
138                 g_object_unref (priv->local_addr);
139         if (priv->remote_addr)
140                 g_object_unref (priv->remote_addr);
141
142         if (priv->watch_src)
143                 g_source_destroy (priv->watch_src);
144         if (priv->async_context)
145                 g_main_context_unref (priv->async_context);
146
147         if (priv->read_buf)
148                 g_byte_array_free (priv->read_buf, TRUE);
149
150         g_mutex_free (priv->addrlock);
151         g_mutex_free (priv->iolock);
152
153         G_OBJECT_CLASS (soup_socket_parent_class)->finalize (object);
154 }
155
156 static void
157 soup_socket_class_init (SoupSocketClass *socket_class)
158 {
159         GObjectClass *object_class = G_OBJECT_CLASS (socket_class);
160
161         g_type_class_add_private (socket_class, sizeof (SoupSocketPrivate));
162
163         /* virtual method override */
164         object_class->finalize = finalize;
165         object_class->set_property = set_property;
166         object_class->get_property = get_property;
167
168         /* signals */
169
170         /**
171          * SoupSocket::readable:
172          * @sock: the socket
173          *
174          * Emitted when an async socket is readable. See
175          * soup_socket_read() and soup_socket_read_until().
176          **/
177         signals[READABLE] =
178                 g_signal_new ("readable",
179                               G_OBJECT_CLASS_TYPE (object_class),
180                               G_SIGNAL_RUN_LAST,
181                               G_STRUCT_OFFSET (SoupSocketClass, readable),
182                               NULL, NULL,
183                               soup_marshal_NONE__NONE,
184                               G_TYPE_NONE, 0);
185
186         /**
187          * SoupSocket::writable:
188          * @sock: the socket
189          *
190          * Emitted when an async socket is writable. See
191          * soup_socket_write().
192          **/
193         signals[WRITABLE] =
194                 g_signal_new ("writable",
195                               G_OBJECT_CLASS_TYPE (object_class),
196                               G_SIGNAL_RUN_LAST,
197                               G_STRUCT_OFFSET (SoupSocketClass, writable),
198                               NULL, NULL,
199                               soup_marshal_NONE__NONE,
200                               G_TYPE_NONE, 0);
201
202         /**
203          * SoupSocket::disconnected:
204          * @sock: the socket
205          *
206          * Emitted when the socket is disconnected, for whatever
207          * reason.
208          **/
209         signals[DISCONNECTED] =
210                 g_signal_new ("disconnected",
211                               G_OBJECT_CLASS_TYPE (object_class),
212                               G_SIGNAL_RUN_LAST,
213                               G_STRUCT_OFFSET (SoupSocketClass, disconnected),
214                               NULL, NULL,
215                               soup_marshal_NONE__NONE,
216                               G_TYPE_NONE, 0);
217
218         /**
219          * SoupSocket::new-connection:
220          * @sock: the socket
221          * @new: the new socket
222          *
223          * Emitted when a listening socket (set up with
224          * soup_socket_listen()) receives a new connection.
225          *
226          * You must ref the @new if you want to keep it; otherwise it
227          * will be destroyed after the signal is emitted.
228          **/
229         signals[NEW_CONNECTION] =
230                 g_signal_new ("new_connection",
231                               G_OBJECT_CLASS_TYPE (object_class),
232                               G_SIGNAL_RUN_FIRST,
233                               G_STRUCT_OFFSET (SoupSocketClass, new_connection),
234                               NULL, NULL,
235                               soup_marshal_NONE__OBJECT,
236                               G_TYPE_NONE, 1,
237                               SOUP_TYPE_SOCKET);
238
239         /* properties */
240         g_object_class_install_property (
241                 object_class, PROP_LOCAL_ADDRESS,
242                 g_param_spec_object (SOUP_SOCKET_LOCAL_ADDRESS,
243                                      "Local address",
244                                      "Address of local end of socket",
245                                      SOUP_TYPE_ADDRESS,
246                                      G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
247         g_object_class_install_property (
248                 object_class, PROP_REMOTE_ADDRESS,
249                 g_param_spec_object (SOUP_SOCKET_REMOTE_ADDRESS,
250                                      "Remote address",
251                                      "Address of remote end of socket",
252                                      SOUP_TYPE_ADDRESS,
253                                      G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
254         g_object_class_install_property (
255                 object_class, PROP_NON_BLOCKING,
256                 g_param_spec_boolean (SOUP_SOCKET_FLAG_NONBLOCKING,
257                                       "Non-blocking",
258                                       "Whether or not the socket uses non-blocking I/O",
259                                       TRUE,
260                                       G_PARAM_READWRITE));
261         g_object_class_install_property (
262                 object_class, PROP_IS_SERVER,
263                 g_param_spec_boolean (SOUP_SOCKET_IS_SERVER,
264                                       "Server",
265                                       "Whether or not the socket is a server socket",
266                                       FALSE,
267                                       G_PARAM_READABLE));
268         g_object_class_install_property (
269                 object_class, PROP_SSL_CREDENTIALS,
270                 g_param_spec_pointer (SOUP_SOCKET_SSL_CREDENTIALS,
271                                       "SSL credentials",
272                                       "SSL credential information, passed from the session to the SSL implementation",
273                                       G_PARAM_READWRITE));
274         g_object_class_install_property (
275                 object_class, PROP_ASYNC_CONTEXT,
276                 g_param_spec_pointer (SOUP_SOCKET_ASYNC_CONTEXT,
277                                       "Async GMainContext",
278                                       "The GMainContext to dispatch this socket's async I/O in",
279                                       G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
280
281         g_object_class_install_property (
282                 object_class, PROP_TIMEOUT,
283                 g_param_spec_uint (SOUP_SOCKET_TIMEOUT,
284                                    "Timeout value",
285                                    "Value in seconds to timeout a blocking I/O",
286                                    0, G_MAXUINT, 0,
287                                    G_PARAM_READWRITE));
288
289 #ifdef G_OS_WIN32
290         /* Make sure WSAStartup() gets called. */
291         soup_address_get_type ();
292 #endif
293 }
294
295
296 static void
297 set_nonblocking (SoupSocketPrivate *priv)
298 {
299 #ifndef G_OS_WIN32
300         int flags;
301 #else
302         u_long val;
303 #endif
304
305         if (priv->sockfd == -1)
306                 return;
307
308 #ifndef G_OS_WIN32
309         flags = fcntl (priv->sockfd, F_GETFL, 0);
310         if (flags != -1) {
311                 if (priv->non_blocking)
312                         flags |= O_NONBLOCK;
313                 else
314                         flags &= ~O_NONBLOCK;
315                 fcntl (priv->sockfd, F_SETFL, flags);
316         }
317 #else
318         val = priv->non_blocking ? 1 : 0;
319         ioctlsocket (priv->sockfd, FIONBIO, &val);
320 #endif
321 }
322
323 static void
324 set_fdflags (SoupSocketPrivate *priv)
325 {
326         int opt;
327         struct timeval timeout;
328 #ifndef G_OS_WIN32
329         int flags;
330 #endif
331
332         if (priv->sockfd == -1)
333                 return;
334
335         set_nonblocking (priv);
336
337 #ifndef G_OS_WIN32
338         flags = fcntl (priv->sockfd, F_GETFD, 0);
339         if (flags != -1) {
340                 flags |= FD_CLOEXEC;
341                 fcntl (priv->sockfd, F_SETFD, flags);
342         }
343 #endif
344
345         opt = 1;
346         setsockopt (priv->sockfd, IPPROTO_TCP,
347                     TCP_NODELAY, (void *) &opt, sizeof (opt));
348         setsockopt (priv->sockfd, SOL_SOCKET,
349                     SO_REUSEADDR, (void *) &opt, sizeof (opt));
350
351         timeout.tv_sec = priv->timeout;
352         timeout.tv_usec = 0;
353         setsockopt (priv->sockfd, SOL_SOCKET,
354                     SO_RCVTIMEO, (void *) &timeout, sizeof (timeout));
355
356         timeout.tv_sec = priv->timeout;
357         timeout.tv_usec = 0;
358         setsockopt (priv->sockfd, SOL_SOCKET,
359                     SO_SNDTIMEO, (void *) &timeout, sizeof (timeout));
360
361 #ifndef G_OS_WIN32
362         priv->iochannel =
363                 g_io_channel_unix_new (priv->sockfd);
364 #else
365         priv->iochannel =
366                 g_io_channel_win32_new_socket (priv->sockfd);
367 #endif
368         g_io_channel_set_close_on_unref (priv->iochannel, TRUE);
369         g_io_channel_set_encoding (priv->iochannel, NULL, NULL);
370         g_io_channel_set_buffered (priv->iochannel, FALSE);
371 }
372
373 static void
374 set_property (GObject *object, guint prop_id,
375               const GValue *value, GParamSpec *pspec)
376 {
377         SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (object);
378
379         switch (prop_id) {
380         case PROP_LOCAL_ADDRESS:
381                 priv->local_addr = (SoupAddress *)g_value_dup_object (value);
382                 break;
383         case PROP_REMOTE_ADDRESS:
384                 priv->remote_addr = (SoupAddress *)g_value_dup_object (value);
385                 break;
386         case PROP_NON_BLOCKING:
387                 priv->non_blocking = g_value_get_boolean (value);
388                 set_nonblocking (priv);
389                 break;
390         case PROP_SSL_CREDENTIALS:
391                 priv->ssl_creds = g_value_get_pointer (value);
392                 break;
393         case PROP_ASYNC_CONTEXT:
394                 priv->async_context = g_value_get_pointer (value);
395                 if (priv->async_context)
396                         g_main_context_ref (priv->async_context);
397                 break;
398         case PROP_TIMEOUT:
399                 priv->timeout = g_value_get_uint (value);
400                 break;
401         default:
402                 break;
403         }
404 }
405
406 static void
407 get_property (GObject *object, guint prop_id,
408               GValue *value, GParamSpec *pspec)
409 {
410         SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (object);
411
412         switch (prop_id) {
413         case PROP_LOCAL_ADDRESS:
414                 g_value_set_object (value, soup_socket_get_local_address (SOUP_SOCKET (object)));
415                 break;
416         case PROP_REMOTE_ADDRESS:
417                 g_value_set_object (value, soup_socket_get_remote_address (SOUP_SOCKET (object)));
418                 break;
419         case PROP_NON_BLOCKING:
420                 g_value_set_boolean (value, priv->non_blocking);
421                 break;
422         case PROP_IS_SERVER:
423                 g_value_set_boolean (value, priv->is_server);
424                 break;
425         case PROP_SSL_CREDENTIALS:
426                 g_value_set_pointer (value, priv->ssl_creds);
427                 break;
428         case PROP_ASYNC_CONTEXT:
429                 g_value_set_pointer (value, priv->async_context ? g_main_context_ref (priv->async_context) : NULL);
430                 break;
431         case PROP_TIMEOUT:
432                 g_value_set_uint (value, priv->timeout);
433                 break;
434         default:
435                 break;
436         }
437 }
438
439
440 /**
441  * soup_socket_new:
442  * @optname1: name of first property to set (or %NULL)
443  * @...: value of @optname1, followed by additional property/value pairs
444  *
445  * Creates a new (disconnected) socket
446  *
447  * Return value: the new socket
448  **/
449 SoupSocket *
450 soup_socket_new (const char *optname1, ...)
451 {
452         SoupSocket *sock;
453         va_list ap;
454
455         va_start (ap, optname1);
456         sock = (SoupSocket *)g_object_new_valist (SOUP_TYPE_SOCKET,
457                                                   optname1, ap);
458         va_end (ap);
459
460         return sock;
461 }
462
463 typedef struct {
464         SoupSocket *sock;
465         GCancellable *cancellable;
466         guint cancel_id;
467         SoupSocketCallback callback;
468         gpointer user_data;
469 } SoupSocketAsyncConnectData;
470
471 static gboolean
472 idle_connect_result (gpointer user_data)
473 {
474         SoupSocketAsyncConnectData *sacd = user_data;
475         SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sacd->sock);
476         guint status;
477
478         priv->watch_src = NULL;
479         if (sacd->cancel_id)
480                 g_signal_handler_disconnect (sacd->cancellable, sacd->cancel_id);
481
482         if (priv->sockfd == -1) {
483                 if (g_cancellable_is_cancelled (sacd->cancellable))
484                         status = SOUP_STATUS_CANCELLED;
485                 else
486                         status = SOUP_STATUS_CANT_CONNECT;
487         } else
488                 status = SOUP_STATUS_OK;
489
490         sacd->callback (sacd->sock, status, sacd->user_data);
491         g_slice_free (SoupSocketAsyncConnectData, sacd);
492         return FALSE;
493 }
494
495 static gboolean
496 connect_watch (GIOChannel* iochannel, GIOCondition condition, gpointer data)
497 {
498         SoupSocketAsyncConnectData *sacd = data;
499         SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sacd->sock);
500         int error = 0;
501         int len = sizeof (error);
502
503         /* Remove the watch now in case we don't return immediately */
504         g_source_destroy (priv->watch_src);
505         priv->watch_src = NULL;
506
507         if ((condition & ~(G_IO_IN | G_IO_OUT)) ||
508             (getsockopt (priv->sockfd, SOL_SOCKET, SO_ERROR,
509                          (void *)&error, (void *)&len) != 0) ||
510             error)
511                 disconnect_internal (priv);
512
513         return idle_connect_result (sacd);
514 }
515
516 static void
517 got_address (SoupAddress *addr, guint status, gpointer user_data)
518 {
519         SoupSocketAsyncConnectData *sacd = user_data;
520
521         if (!SOUP_STATUS_IS_SUCCESSFUL (status)) {
522                 sacd->callback (sacd->sock, status, sacd->user_data);
523                 g_slice_free (SoupSocketAsyncConnectData, sacd);
524                 return;
525         }
526
527         soup_socket_connect_async (sacd->sock, sacd->cancellable,
528                                    sacd->callback, sacd->user_data);
529         g_slice_free (SoupSocketAsyncConnectData, sacd);
530 }
531
532 static void
533 async_cancel (GCancellable *cancellable, gpointer user_data)
534 {
535         SoupSocketAsyncConnectData *sacd = user_data;
536         SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sacd->sock);
537
538         if (priv->watch_src)
539                 g_source_destroy (priv->watch_src);
540         disconnect_internal (priv);
541         priv->watch_src = soup_add_idle (priv->async_context,
542                                          idle_connect_result, sacd);
543 }
544
545 static guint
546 socket_connect_internal (SoupSocket *sock)
547 {
548         SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
549         struct sockaddr *sa;
550         int len, status;
551
552         sa = soup_address_get_sockaddr (priv->remote_addr, &len);
553         if (!sa)
554                 return SOUP_STATUS_CANT_RESOLVE;
555
556         priv->sockfd = socket (sa->sa_family, SOCK_STREAM, 0);
557         if (SOUP_IS_INVALID_SOCKET (priv->sockfd))
558                 return SOUP_STATUS_CANT_CONNECT;
559         set_fdflags (priv);
560
561         status = connect (priv->sockfd, sa, len);
562
563         if (SOUP_IS_SOCKET_ERROR (status)) {
564                 if (SOUP_IS_CONNECT_STATUS_INPROGRESS ())
565                         return SOUP_STATUS_CONTINUE;
566
567                 disconnect_internal (priv);
568                 return SOUP_STATUS_CANT_CONNECT;
569         } else
570                 return SOUP_STATUS_OK;
571 }
572
573 /**
574  * SoupSocketCallback:
575  * @sock: the #SoupSocket
576  * @status: an HTTP status code indicating success or failure
577  * @user_data: the data passed to soup_socket_connect_async()
578  *
579  * The callback function passed to soup_socket_connect_async().
580  **/
581
582 /**
583  * soup_socket_connect_async:
584  * @sock: a client #SoupSocket (which must not already be connected)
585  * @cancellable: a #GCancellable, or %NULL
586  * @callback: callback to call after connecting
587  * @user_data: data to pass to @callback
588  *
589  * Begins asynchronously connecting to @sock's remote address. The
590  * socket will call @callback when it succeeds or fails (but not
591  * before returning from this function).
592  *
593  * If @cancellable is non-%NULL, it can be used to cancel the
594  * connection. @callback will still be invoked in this case, with a
595  * status of %SOUP_STATUS_CANCELLED.
596  **/
597 void
598 soup_socket_connect_async (SoupSocket *sock, GCancellable *cancellable,
599                            SoupSocketCallback callback, gpointer user_data)
600 {
601         SoupSocketPrivate *priv;
602         SoupSocketAsyncConnectData *sacd;
603         guint status;
604
605         g_return_if_fail (SOUP_IS_SOCKET (sock));
606         priv = SOUP_SOCKET_GET_PRIVATE (sock);
607         g_return_if_fail (priv->remote_addr != NULL);
608
609         sacd = g_slice_new0 (SoupSocketAsyncConnectData);
610         sacd->sock = sock;
611         sacd->cancellable = cancellable;
612         sacd->callback = callback;
613         sacd->user_data = user_data;
614
615         if (!soup_address_get_sockaddr (priv->remote_addr, NULL)) {
616                 soup_address_resolve_async (priv->remote_addr,
617                                             priv->async_context,
618                                             cancellable,
619                                             got_address, sacd);
620                 return;
621         }
622
623         status = socket_connect_internal (sock);
624         if (status == SOUP_STATUS_CONTINUE) {
625                 /* Wait for connect to succeed or fail */
626                 priv->watch_src =
627                         soup_add_io_watch (priv->async_context,
628                                            priv->iochannel,
629                                            G_IO_IN | G_IO_OUT |
630                                            G_IO_PRI | G_IO_ERR |
631                                            G_IO_HUP | G_IO_NVAL,
632                                            connect_watch, sacd);
633                 if (cancellable) {
634                         sacd->cancel_id =
635                                 g_signal_connect (cancellable, "cancelled",
636                                                   G_CALLBACK (async_cancel),
637                                                   sacd);
638                 }
639         } else {
640                 priv->watch_src = soup_add_idle (priv->async_context,
641                                                  idle_connect_result, sacd);
642         }
643 }
644
645 static void
646 sync_cancel (GCancellable *cancellable, gpointer sock)
647 {
648         SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
649
650         shutdown (priv->sockfd, SHUT_RDWR);
651 }
652
653 /**
654  * soup_socket_connect_sync:
655  * @sock: a client #SoupSocket (which must not already be connected)
656  * @cancellable: a #GCancellable, or %NULL
657  *
658  * Attempt to synchronously connect @sock to its remote address.
659  *
660  * If @cancellable is non-%NULL, it can be used to cancel the
661  * connection, in which case soup_socket_connect_sync() will return
662  * %SOUP_STATUS_CANCELLED.
663  *
664  * Return value: a success or failure code.
665  **/
666 guint
667 soup_socket_connect_sync (SoupSocket *sock, GCancellable *cancellable)
668 {
669         SoupSocketPrivate *priv;
670         guint status, cancel_id;
671
672         g_return_val_if_fail (SOUP_IS_SOCKET (sock), SOUP_STATUS_MALFORMED);
673         priv = SOUP_SOCKET_GET_PRIVATE (sock);
674         g_return_val_if_fail (!priv->is_server, SOUP_STATUS_MALFORMED);
675         g_return_val_if_fail (priv->sockfd == -1, SOUP_STATUS_MALFORMED);
676         g_return_val_if_fail (priv->remote_addr != NULL, SOUP_STATUS_MALFORMED);
677
678         if (!soup_address_get_sockaddr (priv->remote_addr, NULL)) {
679                 status = soup_address_resolve_sync (priv->remote_addr,
680                                                     cancellable);
681                 if (!SOUP_STATUS_IS_SUCCESSFUL (status))
682                         return status;
683         }
684
685         if (cancellable) {
686                 cancel_id = g_signal_connect (cancellable, "cancelled",
687                                               G_CALLBACK (sync_cancel), sock);
688         }
689
690         status = socket_connect_internal (sock);
691
692         if (cancellable) {
693                 if (status != SOUP_STATUS_OK &&
694                     g_cancellable_is_cancelled (cancellable)) {
695                         status = SOUP_STATUS_CANCELLED;
696                         disconnect_internal (priv);
697                 }
698                 g_signal_handler_disconnect (cancellable, cancel_id);
699         }
700
701         return status;
702 }
703
704 static gboolean
705 listen_watch (GIOChannel* iochannel, GIOCondition condition, gpointer data)
706 {
707         SoupSocket *sock = data, *new;
708         SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock), *new_priv;
709         struct soup_sockaddr_max sa;
710         int sa_len, sockfd;
711
712         if (condition & (G_IO_HUP | G_IO_ERR)) {
713                 g_source_destroy (priv->watch_src);
714                 priv->watch_src = NULL;
715                 return FALSE;
716         }
717
718         sa_len = sizeof (sa);
719         sockfd = accept (priv->sockfd, (struct sockaddr *)&sa, (void *)&sa_len);
720         if (SOUP_IS_INVALID_SOCKET (sockfd))
721                 return TRUE;
722
723         new = g_object_new (SOUP_TYPE_SOCKET, NULL);
724         new_priv = SOUP_SOCKET_GET_PRIVATE (new);
725         new_priv->sockfd = sockfd;
726         if (priv->async_context)
727                 new_priv->async_context = g_main_context_ref (priv->async_context);
728         new_priv->non_blocking = priv->non_blocking;
729         new_priv->is_server = TRUE;
730         new_priv->ssl_creds = priv->ssl_creds;
731         set_fdflags (new_priv);
732
733         new_priv->remote_addr = soup_address_new_from_sockaddr ((struct sockaddr *)&sa, sa_len);
734
735         if (new_priv->ssl_creds) {
736                 if (!soup_socket_start_ssl (new, NULL)) {
737                         g_object_unref (new);
738                         return TRUE;
739                 }
740         }
741
742         g_signal_emit (sock, signals[NEW_CONNECTION], 0, new);
743         g_object_unref (new);
744
745         return TRUE;
746 }
747
748 /**
749  * soup_socket_listen:
750  * @sock: a server #SoupSocket (which must not already be connected or
751  * listening)
752  *
753  * Makes @sock start listening on its local address. When connections
754  * come in, @sock will emit %new_connection.
755  *
756  * Return value: whether or not @sock is now listening.
757  **/
758 gboolean
759 soup_socket_listen (SoupSocket *sock)
760
761 {
762         SoupSocketPrivate *priv;
763         struct sockaddr *sa;
764         int sa_len;
765
766         g_return_val_if_fail (SOUP_IS_SOCKET (sock), FALSE);
767         priv = SOUP_SOCKET_GET_PRIVATE (sock);
768         g_return_val_if_fail (priv->sockfd == -1, FALSE);
769         g_return_val_if_fail (priv->local_addr != NULL, FALSE);
770
771         priv->is_server = TRUE;
772
773         /* @local_addr may have its port set to 0. So we intentionally
774          * don't store it in priv->local_addr, so that if the
775          * caller calls soup_socket_get_local_address() later, we'll
776          * have to make a new addr by calling getsockname(), which
777          * will have the right port number.
778          */
779         sa = soup_address_get_sockaddr (priv->local_addr, &sa_len);
780         g_return_val_if_fail (sa != NULL, FALSE);
781
782         priv->sockfd = socket (sa->sa_family, SOCK_STREAM, 0);
783         if (SOUP_IS_INVALID_SOCKET (priv->sockfd))
784                 goto cant_listen;
785         set_fdflags (priv);
786
787         /* Bind */
788         if (bind (priv->sockfd, sa, sa_len) != 0)
789                 goto cant_listen;
790         /* Force local_addr to be re-resolved now */
791         g_object_unref (priv->local_addr);
792         priv->local_addr = NULL;
793
794         /* Listen */
795         if (listen (priv->sockfd, 10) != 0)
796                 goto cant_listen;
797
798         priv->watch_src = soup_add_io_watch (priv->async_context,
799                                              priv->iochannel,
800                                              G_IO_IN | G_IO_ERR | G_IO_HUP,
801                                              listen_watch, sock);
802         return TRUE;
803
804  cant_listen:
805         if (priv->iochannel)
806                 disconnect_internal (priv);
807
808         return FALSE;
809 }
810
811 /**
812  * soup_socket_start_ssl:
813  * @sock: the socket
814  * @cancellable: a #GCancellable
815  *
816  * Starts using SSL on @socket.
817  *
818  * Return value: success or failure
819  **/
820 gboolean
821 soup_socket_start_ssl (SoupSocket *sock, GCancellable *cancellable)
822 {
823         SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
824
825         return soup_socket_start_proxy_ssl (sock, soup_address_get_name (priv->remote_addr), cancellable);
826 }
827         
828 /**
829  * soup_socket_start_proxy_ssl:
830  * @sock: the socket
831  * @ssl_host: hostname of the SSL server
832  * @cancellable: a #GCancellable
833  *
834  * Starts using SSL on @socket, expecting to find a host named
835  * @ssl_host.
836  *
837  * Return value: success or failure
838  **/
839 gboolean
840 soup_socket_start_proxy_ssl (SoupSocket *sock, const char *ssl_host,
841                              GCancellable *cancellable)
842 {
843         SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
844         GIOChannel *ssl_chan;
845         GIOChannel *real_chan;
846
847         real_chan = priv->iochannel;
848         ssl_chan = soup_ssl_wrap_iochannel (
849                 real_chan, priv->is_server ?
850                 SOUP_SSL_TYPE_SERVER : SOUP_SSL_TYPE_CLIENT,
851                 ssl_host, priv->ssl_creds);
852
853         if (!ssl_chan)
854                 return FALSE;
855
856         priv->iochannel = ssl_chan;
857         g_io_channel_unref (real_chan);
858
859         return TRUE;
860 }
861         
862 gboolean
863 soup_socket_is_ssl (SoupSocket *sock)
864 {
865         SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
866
867         return priv->ssl_creds != NULL;
868 }
869
870 /**
871  * soup_socket_disconnect:
872  * @sock: a #SoupSocket
873  *
874  * Disconnects @sock. Any further read or write attempts on it will
875  * fail.
876  **/
877 void
878 soup_socket_disconnect (SoupSocket *sock)
879 {
880         SoupSocketPrivate *priv;
881         gboolean already_disconnected = FALSE;
882
883         g_return_if_fail (SOUP_IS_SOCKET (sock));
884         priv = SOUP_SOCKET_GET_PRIVATE (sock);
885
886         if (g_mutex_trylock (priv->iolock)) {
887                 if (priv->iochannel)
888                         disconnect_internal (priv);
889                 else
890                         already_disconnected = TRUE;
891                 g_mutex_unlock (priv->iolock);
892         } else {
893                 int sockfd;
894
895                 /* Another thread is currently doing IO, so
896                  * we can't close the iochannel. So just shutdown
897                  * the file descriptor to force the I/O to fail.
898                  * (It will actually be closed when the socket is
899                  * destroyed.)
900                  */
901                 sockfd = priv->sockfd;
902                 priv->sockfd = -1;
903
904                 if (sockfd == -1)
905                         already_disconnected = TRUE;
906                 else
907                         shutdown (sockfd, SHUT_RDWR);
908         }
909
910         if (already_disconnected)
911                 return;
912
913         /* Give all readers a chance to notice the connection close */
914         g_signal_emit (sock, signals[READABLE], 0);
915
916         /* FIXME: can't disconnect until all data is read */
917
918         /* Then let everyone know we're disconnected */
919         g_signal_emit (sock, signals[DISCONNECTED], 0);
920 }
921
922 /**
923  * soup_socket_is_connected:
924  * @sock: a #SoupSocket
925  *
926  * Tests if @sock is connected to another host
927  *
928  * Return value: %TRUE or %FALSE.
929  **/
930 gboolean
931 soup_socket_is_connected (SoupSocket *sock)
932 {
933         SoupSocketPrivate *priv;
934
935         g_return_val_if_fail (SOUP_IS_SOCKET (sock), FALSE);
936         priv = SOUP_SOCKET_GET_PRIVATE (sock);
937
938         return priv->iochannel != NULL;
939 }
940
941 /**
942  * soup_socket_get_local_address:
943  * @sock: a #SoupSocket
944  *
945  * Returns the #SoupAddress corresponding to the local end of @sock.
946  *
947  * Return value: the #SoupAddress
948  **/
949 SoupAddress *
950 soup_socket_get_local_address (SoupSocket *sock)
951 {
952         SoupSocketPrivate *priv;
953
954         g_return_val_if_fail (SOUP_IS_SOCKET (sock), NULL);
955         priv = SOUP_SOCKET_GET_PRIVATE (sock);
956
957         g_mutex_lock (priv->addrlock);
958         if (!priv->local_addr) {
959                 struct soup_sockaddr_max bound_sa;
960                 int sa_len;
961
962                 sa_len = sizeof (bound_sa);
963                 getsockname (priv->sockfd, (struct sockaddr *)&bound_sa, (void *)&sa_len);
964                 priv->local_addr = soup_address_new_from_sockaddr ((struct sockaddr *)&bound_sa, sa_len);
965         }
966         g_mutex_unlock (priv->addrlock);
967
968         return priv->local_addr;
969 }
970
971 /**
972  * soup_socket_get_remote_address:
973  * @sock: a #SoupSocket
974  *
975  * Returns the #SoupAddress corresponding to the remote end of @sock.
976  *
977  * Return value: the #SoupAddress
978  **/
979 SoupAddress *
980 soup_socket_get_remote_address (SoupSocket *sock)
981 {
982         SoupSocketPrivate *priv;
983
984         g_return_val_if_fail (SOUP_IS_SOCKET (sock), NULL);
985         priv = SOUP_SOCKET_GET_PRIVATE (sock);
986
987         g_mutex_lock (priv->addrlock);
988         if (!priv->remote_addr) {
989                 struct soup_sockaddr_max bound_sa;
990                 int sa_len;
991
992                 sa_len = sizeof (bound_sa);
993                 getpeername (priv->sockfd, (struct sockaddr *)&bound_sa, (void *)&sa_len);
994                 priv->remote_addr = soup_address_new_from_sockaddr ((struct sockaddr *)&bound_sa, sa_len);
995         }
996         g_mutex_unlock (priv->addrlock);
997
998         return priv->remote_addr;
999 }
1000
1001
1002
1003
1004 static gboolean
1005 socket_read_watch (GIOChannel *chan, GIOCondition cond, gpointer user_data)
1006 {
1007         SoupSocket *sock = user_data;
1008         SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
1009
1010         priv->read_src = NULL;
1011
1012         if (cond & (G_IO_ERR | G_IO_HUP))
1013                 soup_socket_disconnect (sock);
1014         else
1015                 g_signal_emit (sock, signals[READABLE], 0);
1016
1017         return FALSE;
1018 }
1019
1020 static SoupSocketIOStatus
1021 read_from_network (SoupSocket *sock, gpointer buffer, gsize len,
1022                    gsize *nread, GError **error)
1023 {
1024         SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
1025         GIOStatus status;
1026         GIOCondition cond = G_IO_IN;
1027         GError *my_err = NULL;
1028
1029         if (!priv->iochannel) 
1030                 return SOUP_SOCKET_EOF;
1031
1032         status = g_io_channel_read_chars (priv->iochannel,
1033                                           buffer, len, nread, &my_err);
1034         if (my_err) {
1035                 if (my_err->domain == SOUP_SSL_ERROR &&
1036                     my_err->code == SOUP_SSL_ERROR_HANDSHAKE_NEEDS_WRITE)
1037                         cond = G_IO_OUT;
1038                 g_propagate_error (error, my_err);
1039         }
1040
1041         switch (status) {
1042         case G_IO_STATUS_NORMAL:
1043         case G_IO_STATUS_AGAIN:
1044                 if (*nread > 0) {
1045                         g_clear_error (error);
1046                         return SOUP_SOCKET_OK;
1047                 }
1048
1049                 /* If the socket is sync and we get EAGAIN, then it is
1050                  * a socket timeout and should be treated as an error
1051                  * condition.
1052                  */
1053                 if (!priv->non_blocking)
1054                         return SOUP_SOCKET_ERROR;
1055
1056                 if (!priv->read_src) {
1057                         priv->read_src =
1058                                 soup_add_io_watch (priv->async_context,
1059                                                    priv->iochannel,
1060                                                    cond | G_IO_HUP | G_IO_ERR,
1061                                                    socket_read_watch, sock);
1062                 }
1063                 g_clear_error (error);
1064                 return SOUP_SOCKET_WOULD_BLOCK;
1065
1066         case G_IO_STATUS_EOF:
1067                 g_clear_error (error);
1068                 return SOUP_SOCKET_EOF;
1069
1070         default:
1071                 return SOUP_SOCKET_ERROR;
1072         }
1073 }
1074
1075 static SoupSocketIOStatus
1076 read_from_buf (SoupSocket *sock, gpointer buffer, gsize len, gsize *nread)
1077 {
1078         SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
1079         GByteArray *read_buf = priv->read_buf;
1080
1081         *nread = MIN (read_buf->len, len);
1082         memcpy (buffer, read_buf->data, *nread);
1083
1084         if (*nread == read_buf->len) {
1085                 g_byte_array_free (read_buf, TRUE);
1086                 priv->read_buf = NULL;
1087         } else {
1088                 memmove (read_buf->data, read_buf->data + *nread, 
1089                          read_buf->len - *nread);
1090                 g_byte_array_set_size (read_buf, read_buf->len - *nread);
1091         }
1092
1093         return SOUP_SOCKET_OK;
1094 }
1095
1096 /**
1097  * SoupSocketIOStatus:
1098  * @SOUP_SOCKET_OK: Success
1099  * @SOUP_SOCKET_WOULD_BLOCK: Cannot read/write any more at this time
1100  * @SOUP_SOCKET_EOF: End of file
1101  * @SOUP_SOCKET_ERROR: Other error
1102  *
1103  * Return value from the #SoupSocket IO methods.
1104  **/
1105
1106 /**
1107  * soup_socket_read:
1108  * @sock: the socket
1109  * @buffer: buffer to read into
1110  * @len: size of @buffer in bytes
1111  * @nread: on return, the number of bytes read into @buffer
1112  * @cancellable: a #GCancellable, or %NULL
1113  * @error: error pointer
1114  *
1115  * Attempts to read up to @len bytes from @sock into @buffer. If some
1116  * data is successfully read, soup_socket_read() will return
1117  * %SOUP_SOCKET_OK, and *@nread will contain the number of bytes
1118  * actually read.
1119  *
1120  * If @sock is non-blocking, and no data is available, the return
1121  * value will be %SOUP_SOCKET_WOULD_BLOCK. In this case, the caller
1122  * can connect to the %readable signal to know when there is more data
1123  * to read. (NB: You MUST read all available data off the socket
1124  * first. The %readable signal will only be emitted after
1125  * soup_socket_read() has returned %SOUP_SOCKET_WOULD_BLOCK.)
1126  *
1127  * Return value: a #SoupSocketIOStatus, as described above (or
1128  * %SOUP_SOCKET_EOF if the socket is no longer connected, or
1129  * %SOUP_SOCKET_ERROR on any other error, in which case @error will
1130  * also be set).
1131  **/
1132 SoupSocketIOStatus
1133 soup_socket_read (SoupSocket *sock, gpointer buffer, gsize len,
1134                   gsize *nread, GCancellable *cancellable, GError **error)
1135 {
1136         SoupSocketPrivate *priv;
1137         SoupSocketIOStatus status;
1138
1139         g_return_val_if_fail (SOUP_IS_SOCKET (sock), SOUP_SOCKET_ERROR);
1140         priv = SOUP_SOCKET_GET_PRIVATE (sock);
1141
1142         g_mutex_lock (priv->iolock);
1143         if (priv->read_buf)
1144                 status = read_from_buf (sock, buffer, len, nread);
1145         else
1146                 status = read_from_network (sock, buffer, len, nread, error);
1147         g_mutex_unlock (priv->iolock);
1148
1149         return status;
1150 }
1151
1152 /**
1153  * soup_socket_read_until:
1154  * @sock: the socket
1155  * @buffer: buffer to read into
1156  * @len: size of @buffer in bytes
1157  * @boundary: boundary to read until
1158  * @boundary_len: length of @boundary in bytes
1159  * @nread: on return, the number of bytes read into @buffer
1160  * @got_boundary: on return, whether or not the data in @buffer
1161  * ends with the boundary string
1162  * @cancellable: a #GCancellable, or %NULL
1163  * @error: error pointer
1164  *
1165  * Like soup_socket_read(), but reads no further than the first
1166  * occurrence of @boundary. (If the boundary is found, it will be
1167  * included in the returned data, and *@got_boundary will be set to
1168  * %TRUE.) Any data after the boundary will returned in future reads.
1169  *
1170  * Return value: as for soup_socket_read()
1171  **/
1172 SoupSocketIOStatus
1173 soup_socket_read_until (SoupSocket *sock, gpointer buffer, gsize len,
1174                         gconstpointer boundary, gsize boundary_len,
1175                         gsize *nread, gboolean *got_boundary,
1176                         GCancellable *cancellable, GError **error)
1177 {
1178         SoupSocketPrivate *priv;
1179         SoupSocketIOStatus status;
1180         GByteArray *read_buf;
1181         guint match_len, prev_len;
1182         guint8 *p, *end;
1183
1184         g_return_val_if_fail (SOUP_IS_SOCKET (sock), SOUP_SOCKET_ERROR);
1185         priv = SOUP_SOCKET_GET_PRIVATE (sock);
1186         g_return_val_if_fail (len >= boundary_len, SOUP_SOCKET_ERROR);
1187
1188         g_mutex_lock (priv->iolock);
1189
1190         *got_boundary = FALSE;
1191
1192         if (!priv->read_buf)
1193                 priv->read_buf = g_byte_array_new ();
1194         read_buf = priv->read_buf;
1195
1196         if (read_buf->len < boundary_len) {
1197                 prev_len = read_buf->len;
1198                 g_byte_array_set_size (read_buf, len);
1199                 status = read_from_network (sock,
1200                                             read_buf->data + prev_len,
1201                                             len - prev_len, nread, error);
1202                 read_buf->len = prev_len + *nread;
1203
1204                 if (status != SOUP_SOCKET_OK) {
1205                         g_mutex_unlock (priv->iolock);
1206                         return status;
1207                 }
1208         }
1209
1210         /* Scan for the boundary */
1211         end = read_buf->data + read_buf->len;
1212         for (p = read_buf->data; p <= end - boundary_len; p++) {
1213                 if (!memcmp (p, boundary, boundary_len)) {
1214                         p += boundary_len;
1215                         *got_boundary = TRUE;
1216                         break;
1217                 }
1218         }
1219
1220         /* Return everything up to 'p' (which is either just after the
1221          * boundary, or @boundary_len - 1 bytes before the end of the
1222          * buffer).
1223          */
1224         match_len = p - read_buf->data;
1225         status = read_from_buf (sock, buffer, MIN (len, match_len), nread);
1226
1227         g_mutex_unlock (priv->iolock);
1228         return status;
1229 }
1230
1231 static gboolean
1232 socket_write_watch (GIOChannel *chan, GIOCondition cond, gpointer user_data)
1233 {
1234         SoupSocket *sock = user_data;
1235         SoupSocketPrivate *priv = SOUP_SOCKET_GET_PRIVATE (sock);
1236
1237         priv->write_src = NULL;
1238
1239         if (cond & (G_IO_ERR | G_IO_HUP))
1240                 soup_socket_disconnect (sock);
1241         else
1242                 g_signal_emit (sock, signals[WRITABLE], 0);
1243
1244         return FALSE;
1245 }
1246
1247 /**
1248  * soup_socket_write:
1249  * @sock: the socket
1250  * @buffer: data to write
1251  * @len: size of @buffer, in bytes
1252  * @nwrote: on return, number of bytes written
1253  * @cancellable: a #GCancellable, or %NULL
1254  * @error: error pointer
1255  *
1256  * Attempts to write @len bytes from @buffer to @sock. If some data is
1257  * successfully written, the resturn status will be
1258  * %SOUP_SOCKET_SUCCESS, and *@nwrote will contain the number of bytes
1259  * actually written.
1260  *
1261  * If @sock is non-blocking, and no data could be written right away,
1262  * the return value will be %SOUP_SOCKET_WOULD_BLOCK. In this case,
1263  * the caller can connect to the %writable signal to know when more
1264  * data can be written. (NB: %writable is only emitted after a
1265  * %SOUP_SOCKET_WOULD_BLOCK.)
1266  *
1267  * Return value: a #SoupSocketIOStatus, as described above (or
1268  * %SOUP_SOCKET_EOF or %SOUP_SOCKET_ERROR. @error will be set if the
1269  * return value is %SOUP_SOCKET_ERROR.)
1270  **/
1271 SoupSocketIOStatus
1272 soup_socket_write (SoupSocket *sock, gconstpointer buffer,
1273                    gsize len, gsize *nwrote,
1274                    GCancellable *cancellable, GError **error)
1275 {
1276         SoupSocketPrivate *priv;
1277         GIOStatus status;
1278 #ifdef SIGPIPE
1279         gpointer pipe_handler;
1280 #endif
1281         GIOCondition cond = G_IO_OUT;
1282         GError *my_err = NULL;
1283
1284         g_return_val_if_fail (SOUP_IS_SOCKET (sock), SOUP_SOCKET_ERROR);
1285         priv = SOUP_SOCKET_GET_PRIVATE (sock);
1286
1287         g_mutex_lock (priv->iolock);
1288
1289         if (!priv->iochannel) {
1290                 g_mutex_unlock (priv->iolock);
1291                 return SOUP_SOCKET_EOF;
1292         }
1293         if (priv->write_src) {
1294                 g_mutex_unlock (priv->iolock);
1295                 return SOUP_SOCKET_WOULD_BLOCK;
1296         }
1297
1298 #ifdef SIGPIPE
1299         pipe_handler = signal (SIGPIPE, SIG_IGN);
1300 #endif
1301         status = g_io_channel_write_chars (priv->iochannel,
1302                                            buffer, len, nwrote, &my_err);
1303 #ifdef SIGPIPE
1304         signal (SIGPIPE, pipe_handler);
1305 #endif
1306         if (my_err) {
1307                 if (my_err->domain == SOUP_SSL_ERROR &&
1308                     my_err->code == SOUP_SSL_ERROR_HANDSHAKE_NEEDS_READ)
1309                         cond = G_IO_IN;
1310                 g_propagate_error (error, my_err);
1311         }
1312
1313         /* If the socket is sync and we get EAGAIN, then it is a
1314          * socket timeout and should be treated as an error condition.
1315          */
1316         if (!priv->non_blocking && status == G_IO_STATUS_AGAIN) {
1317                 g_mutex_unlock (priv->iolock);
1318                 return SOUP_SOCKET_ERROR;
1319         }
1320
1321         if (status != G_IO_STATUS_NORMAL && status != G_IO_STATUS_AGAIN) {
1322                 g_mutex_unlock (priv->iolock);
1323                 return SOUP_SOCKET_ERROR;
1324         }
1325
1326         g_clear_error (error);
1327
1328         if (*nwrote) {
1329                 g_mutex_unlock (priv->iolock);
1330                 return SOUP_SOCKET_OK;
1331         }
1332
1333         priv->write_src =
1334                 soup_add_io_watch (priv->async_context,
1335                                    priv->iochannel,
1336                                    cond | G_IO_HUP | G_IO_ERR, 
1337                                    socket_write_watch, sock);
1338         g_mutex_unlock (priv->iolock);
1339         return SOUP_SOCKET_WOULD_BLOCK;
1340 }