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