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