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