add/fix lots of gtk-doc comments
[platform/upstream/libsoup.git] / libsoup / soup-socket.c
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3  * soup-socket.c: Socket networking code.
4  *
5  * Copyright (C) 2000-2003, Ximian, Inc.
6  */
7
8 #ifdef HAVE_CONFIG_H
9 #include <config.h>
10 #endif
11
12 #include <errno.h>
13 #include <fcntl.h>
14 #include <signal.h>
15 #include <string.h>
16 #include <unistd.h>
17
18 #include "soup-address.h"
19 #include "soup-socket.h"
20 #include "soup-marshal.h"
21 #include "soup-misc.h"
22 #include "soup-ssl.h"
23
24 #include <sys/types.h>
25 #include <sys/socket.h>
26 #include <netinet/in.h>
27 #include <netinet/tcp.h>
28
29 #define PARENT_TYPE G_TYPE_OBJECT
30 static GObjectClass *parent_class;
31
32 enum {
33         CONNECT_RESULT,
34         READABLE,
35         WRITABLE,
36         DISCONNECTED,
37         NEW_CONNECTION,
38         LAST_SIGNAL
39 };
40
41 static guint signals[LAST_SIGNAL] = { 0 };
42
43 enum {
44         PROP_0,
45
46         PROP_NON_BLOCKING,
47         PROP_NODELAY,
48         PROP_REUSEADDR,
49         PROP_IS_SERVER,
50         PROP_SSL_CREDENTIALS,
51
52         LAST_PROP
53 };
54
55 struct SoupSocketPrivate {
56         int sockfd;
57         SoupAddress *local_addr, *remote_addr;
58         GIOChannel *iochannel;
59
60         guint non_blocking:1;
61         guint nodelay:1;
62         guint reuseaddr:1;
63         guint is_server:1;
64         gpointer ssl_creds;
65
66         guint           watch;
67         guint           read_tag, write_tag, error_tag;
68         GByteArray     *read_buf;
69
70         GMutex *iolock, *addrlock;
71 };
72
73 #ifdef HAVE_IPV6
74 #define soup_sockaddr_max sockaddr_in6
75 #else
76 #define soup_sockaddr_max sockaddr_in
77 #endif
78
79 static void set_property (GObject *object, guint prop_id,
80                           const GValue *value, GParamSpec *pspec);
81 static void get_property (GObject *object, guint prop_id,
82                           GValue *value, GParamSpec *pspec);
83
84 static void
85 init (GObject *object)
86 {
87         SoupSocket *sock = SOUP_SOCKET (object);
88
89         sock->priv = g_new0 (SoupSocketPrivate, 1);
90         sock->priv->sockfd = -1;
91         sock->priv->non_blocking = sock->priv->nodelay = TRUE;
92         sock->priv->reuseaddr = TRUE;
93         sock->priv->addrlock = g_mutex_new ();
94         sock->priv->iolock = g_mutex_new ();
95 }
96
97 static void
98 disconnect_internal (SoupSocket *sock)
99 {
100         g_io_channel_unref (sock->priv->iochannel);
101         sock->priv->iochannel = NULL;
102         sock->priv->sockfd = -1;
103
104         if (sock->priv->read_tag) {
105                 g_source_remove (sock->priv->read_tag);
106                 sock->priv->read_tag = 0;
107         }
108         if (sock->priv->write_tag) {
109                 g_source_remove (sock->priv->write_tag);
110                 sock->priv->write_tag = 0;
111         }
112         if (sock->priv->error_tag) {
113                 g_source_remove (sock->priv->error_tag);
114                 sock->priv->error_tag = 0;
115         }
116 }
117
118 static void
119 finalize (GObject *object)
120 {
121         SoupSocket *sock = SOUP_SOCKET (object);
122
123         if (sock->priv->iochannel)
124                 disconnect_internal (sock);
125
126         if (sock->priv->local_addr)
127                 g_object_unref (sock->priv->local_addr);
128         if (sock->priv->remote_addr)
129                 g_object_unref (sock->priv->remote_addr);
130
131         if (sock->priv->watch)
132                 g_source_remove (sock->priv->watch);
133
134         g_mutex_free (sock->priv->addrlock);
135         g_mutex_free (sock->priv->iolock);
136
137         g_free (sock->priv);
138
139         G_OBJECT_CLASS (parent_class)->finalize (object);
140 }
141
142 static void
143 class_init (GObjectClass *object_class)
144 {
145         parent_class = g_type_class_ref (PARENT_TYPE);
146
147         /* virtual method override */
148         object_class->finalize = finalize;
149         object_class->set_property = set_property;
150         object_class->get_property = get_property;
151
152         /* signals */
153         signals[CONNECT_RESULT] =
154                 g_signal_new ("connect_result",
155                               G_OBJECT_CLASS_TYPE (object_class),
156                               G_SIGNAL_RUN_FIRST,
157                               G_STRUCT_OFFSET (SoupSocketClass, connect_result),
158                               NULL, NULL,
159                               soup_marshal_NONE__INT,
160                               G_TYPE_NONE, 1,
161                               G_TYPE_INT);
162         signals[READABLE] =
163                 g_signal_new ("readable",
164                               G_OBJECT_CLASS_TYPE (object_class),
165                               G_SIGNAL_RUN_LAST,
166                               G_STRUCT_OFFSET (SoupSocketClass, readable),
167                               NULL, NULL,
168                               soup_marshal_NONE__NONE,
169                               G_TYPE_NONE, 0);
170         signals[WRITABLE] =
171                 g_signal_new ("writable",
172                               G_OBJECT_CLASS_TYPE (object_class),
173                               G_SIGNAL_RUN_LAST,
174                               G_STRUCT_OFFSET (SoupSocketClass, writable),
175                               NULL, NULL,
176                               soup_marshal_NONE__NONE,
177                               G_TYPE_NONE, 0);
178         signals[DISCONNECTED] =
179                 g_signal_new ("disconnected",
180                               G_OBJECT_CLASS_TYPE (object_class),
181                               G_SIGNAL_RUN_LAST,
182                               G_STRUCT_OFFSET (SoupSocketClass, disconnected),
183                               NULL, NULL,
184                               soup_marshal_NONE__NONE,
185                               G_TYPE_NONE, 0);
186         signals[NEW_CONNECTION] =
187                 g_signal_new ("new_connection",
188                               G_OBJECT_CLASS_TYPE (object_class),
189                               G_SIGNAL_RUN_FIRST,
190                               G_STRUCT_OFFSET (SoupSocketClass, new_connection),
191                               NULL, NULL,
192                               soup_marshal_NONE__OBJECT,
193                               G_TYPE_NONE, 1,
194                               SOUP_TYPE_SOCKET);
195
196         /* properties */
197         g_object_class_install_property (
198                 object_class, PROP_NON_BLOCKING,
199                 g_param_spec_boolean (SOUP_SOCKET_FLAG_NONBLOCKING,
200                                       "Non-blocking",
201                                       "Whether or not the socket uses non-blocking I/O",
202                                       TRUE,
203                                       G_PARAM_READWRITE));
204         g_object_class_install_property (
205                 object_class, PROP_NODELAY,
206                 g_param_spec_boolean (SOUP_SOCKET_FLAG_NODELAY,
207                                       "NODELAY",
208                                       "Whether or not the socket uses TCP NODELAY",
209                                       TRUE,
210                                       G_PARAM_READWRITE));
211         g_object_class_install_property (
212                 object_class, PROP_REUSEADDR,
213                 g_param_spec_boolean (SOUP_SOCKET_FLAG_REUSEADDR,
214                                       "REUSEADDR",
215                                       "Whether or not the socket uses the TCP REUSEADDR flag",
216                                       TRUE,
217                                       G_PARAM_READWRITE));
218         g_object_class_install_property (
219                 object_class, PROP_IS_SERVER,
220                 g_param_spec_boolean (SOUP_SOCKET_IS_SERVER,
221                                       "Server",
222                                       "Whether or not the socket is a server socket",
223                                       FALSE,
224                                       G_PARAM_READABLE));
225         g_object_class_install_property (
226                 object_class, PROP_SSL_CREDENTIALS,
227                 g_param_spec_pointer (SOUP_SOCKET_SSL_CREDENTIALS,
228                                       "SSL credentials",
229                                       "SSL credential information, passed from the session to the SSL implementation",
230                                       G_PARAM_READWRITE));
231 }
232
233 SOUP_MAKE_TYPE (soup_socket, SoupSocket, class_init, init, PARENT_TYPE)
234
235
236 static void
237 update_fdflags (SoupSocket *sock)
238 {
239         int flags, opt;
240
241         if (sock->priv->sockfd == -1)
242                 return;
243
244         flags = fcntl (sock->priv->sockfd, F_GETFL, 0);
245         if (flags != -1) {
246                 if (sock->priv->non_blocking)
247                         flags |= O_NONBLOCK;
248                 else
249                         flags &= ~O_NONBLOCK;
250                 fcntl (sock->priv->sockfd, F_SETFL, flags);
251         }
252
253         opt = (sock->priv->nodelay != 0);
254         setsockopt (sock->priv->sockfd, IPPROTO_TCP,
255                     TCP_NODELAY, &opt, sizeof (opt));
256
257         opt = (sock->priv->reuseaddr != 0);
258         setsockopt (sock->priv->sockfd, SOL_SOCKET,
259                     SO_REUSEADDR, &opt, sizeof (opt));
260 }
261
262 static void
263 set_property (GObject *object, guint prop_id,
264               const GValue *value, GParamSpec *pspec)
265 {
266         SoupSocket *sock = SOUP_SOCKET (object);
267
268         switch (prop_id) {
269         case PROP_NON_BLOCKING:
270                 sock->priv->non_blocking = g_value_get_boolean (value);
271                 update_fdflags (sock);
272                 break;
273         case PROP_NODELAY:
274                 sock->priv->nodelay = g_value_get_boolean (value);
275                 update_fdflags (sock);
276                 break;
277         case PROP_REUSEADDR:
278                 sock->priv->reuseaddr = g_value_get_boolean (value);
279                 update_fdflags (sock);
280                 break;
281         case PROP_SSL_CREDENTIALS:
282                 sock->priv->ssl_creds = g_value_get_pointer (value);
283                 break;
284         default:
285                 break;
286         }
287 }
288
289 static void
290 get_property (GObject *object, guint prop_id,
291               GValue *value, GParamSpec *pspec)
292 {
293         SoupSocket *sock = SOUP_SOCKET (object);
294
295         switch (prop_id) {
296         case PROP_NON_BLOCKING:
297                 g_value_set_boolean (value, sock->priv->non_blocking);
298                 break;
299         case PROP_NODELAY:
300                 g_value_set_boolean (value, sock->priv->nodelay);
301                 break;
302         case PROP_REUSEADDR:
303                 g_value_set_boolean (value, sock->priv->reuseaddr);
304                 break;
305         case PROP_IS_SERVER:
306                 g_value_set_boolean (value, sock->priv->is_server);
307                 break;
308         case PROP_SSL_CREDENTIALS:
309                 g_value_set_pointer (value, sock->priv->ssl_creds);
310                 break;
311         default:
312                 break;
313         }
314 }
315
316
317 /**
318  * soup_socket_new:
319  * @optname1: name of first property to set (or %NULL)
320  * @...: value of @optname1, followed by additional property/value pairs
321  *
322  * Creates a new (disconnected) socket
323  *
324  * Return value: the new socket
325  **/
326 SoupSocket *
327 soup_socket_new (const char *optname1, ...)
328 {
329         SoupSocket *sock;
330         va_list ap;
331
332         va_start (ap, optname1);
333         sock = (SoupSocket *)g_object_new_valist (SOUP_TYPE_SOCKET,
334                                                   optname1, ap);
335         va_end (ap);
336
337         return sock;
338 }
339
340 static GIOChannel *
341 get_iochannel (SoupSocket *sock)
342 {
343         g_mutex_lock (sock->priv->iolock);
344         if (!sock->priv->iochannel) {
345                 sock->priv->iochannel =
346                         g_io_channel_unix_new (sock->priv->sockfd);
347                 g_io_channel_set_close_on_unref (sock->priv->iochannel, TRUE);
348                 g_io_channel_set_encoding (sock->priv->iochannel, NULL, NULL);
349                 g_io_channel_set_buffered (sock->priv->iochannel, FALSE);
350         }
351         g_mutex_unlock (sock->priv->iolock);
352         return sock->priv->iochannel;
353 }
354
355 static gboolean
356 idle_connect_result (gpointer user_data)
357 {
358         SoupSocket *sock = user_data;
359
360         sock->priv->watch = 0;
361
362         g_signal_emit (sock, signals[CONNECT_RESULT], 0,
363                        sock->priv->sockfd != -1 ? SOUP_STATUS_OK : SOUP_STATUS_CANT_CONNECT);
364         return FALSE;
365 }
366
367 static gboolean
368 connect_watch (GIOChannel* iochannel, GIOCondition condition, gpointer data)
369 {
370         SoupSocket *sock = data;
371         int error = 0;
372         int len = sizeof (error);
373
374         /* Remove the watch now in case we don't return immediately */
375         g_source_remove (sock->priv->watch);
376         sock->priv->watch = 0;
377
378         if (condition & ~(G_IO_IN | G_IO_OUT))
379                 goto cant_connect;
380
381         if (getsockopt (sock->priv->sockfd, SOL_SOCKET, SO_ERROR,
382                         &error, &len) != 0)
383                 goto cant_connect;
384         if (error)
385                 goto cant_connect;
386
387         return idle_connect_result (sock);
388
389  cant_connect:
390         g_signal_emit (sock, signals[CONNECT_RESULT], 0, SOUP_STATUS_CANT_CONNECT);
391         return FALSE;
392 }
393
394 static void
395 got_address (SoupAddress *addr, guint status, gpointer user_data)
396 {
397         SoupSocket *sock = user_data;
398
399         if (!SOUP_STATUS_IS_SUCCESSFUL (status)) {
400                 g_signal_emit (sock, signals[CONNECT_RESULT], 0, status);
401                 g_object_unref (sock);
402                 return;
403         }
404
405         soup_socket_connect (sock, sock->priv->remote_addr);
406         /* soup_socket_connect re-reffed addr */
407         g_object_unref (addr);
408
409         g_object_unref (sock);
410 }
411
412 /**
413  * soup_socket_connect:
414  * @sock: a client #SoupSocket (which must not already be connected)
415  * @remote_addr: address to connect to
416  *
417  * If %SOUP_SOCKET_FLAG_NONBLOCKING has been set on the socket, this
418  * begins asynchronously connecting to the given address. The socket
419  * will emit %connect_result when it succeeds or fails (but not before
420  * returning from this function).
421  *
422  * If %SOUP_SOCKET_FLAG_NONBLOCKING has not been set, this will
423  * attempt to synchronously connect.
424  *
425  * Return value: %SOUP_STATUS_CONTINUE if connecting asynchronously,
426  * otherwise a success or failure code.
427  **/
428 guint
429 soup_socket_connect (SoupSocket *sock, SoupAddress *remote_addr)
430 {
431         struct sockaddr *sa;
432         int len, status;
433
434         g_return_val_if_fail (SOUP_IS_SOCKET (sock), SOUP_STATUS_MALFORMED);
435         g_return_val_if_fail (!sock->priv->is_server, SOUP_STATUS_MALFORMED);
436         g_return_val_if_fail (sock->priv->sockfd == -1, SOUP_STATUS_MALFORMED);
437         g_return_val_if_fail (SOUP_IS_ADDRESS (remote_addr), SOUP_STATUS_MALFORMED);
438
439         sock->priv->remote_addr = g_object_ref (remote_addr);
440         if (!sock->priv->non_blocking) {
441                 status = soup_address_resolve_sync (remote_addr);
442                 if (!SOUP_STATUS_IS_SUCCESSFUL (status))
443                         return status;
444         }
445
446         sa = soup_address_get_sockaddr (sock->priv->remote_addr, &len);
447         if (!sa) {
448                 if (!sock->priv->non_blocking)
449                         return SOUP_STATUS_CANT_RESOLVE;
450
451                 g_object_ref (sock);
452                 soup_address_resolve_async (remote_addr, got_address, sock);
453                 return SOUP_STATUS_CONTINUE;
454         }
455
456         sock->priv->sockfd = socket (sa->sa_family, SOCK_STREAM, 0);
457         if (sock->priv->sockfd == -1) {
458                 goto done;
459         }
460         update_fdflags (sock);
461
462         status = connect (sock->priv->sockfd, sa, len);
463
464         if (status == -1) {
465                 if (errno == EINPROGRESS) {
466                         /* Wait for connect to succeed or fail */
467                         sock->priv->watch =
468                                 g_io_add_watch (get_iochannel (sock),
469                                                 G_IO_IN | G_IO_OUT |
470                                                 G_IO_PRI | G_IO_ERR |
471                                                 G_IO_HUP | G_IO_NVAL,
472                                                 connect_watch, sock);
473                         return SOUP_STATUS_CONTINUE;
474                 } else {
475                         close (sock->priv->sockfd);
476                         sock->priv->sockfd = -1;
477                 }
478         }
479
480  done:
481         if (sock->priv->non_blocking) {
482                 sock->priv->watch = g_idle_add (idle_connect_result, sock);
483                 return SOUP_STATUS_CONTINUE;
484         } else if (sock->priv->sockfd == -1)
485                 return SOUP_STATUS_CANT_CONNECT;
486         else {
487                 get_iochannel (sock);
488                 return SOUP_STATUS_OK;
489         }
490 }
491
492 static gboolean
493 listen_watch (GIOChannel* iochannel, GIOCondition condition, gpointer data)
494 {
495         SoupSocket *sock = data, *new;
496         struct soup_sockaddr_max sa;
497         int sa_len, sockfd;
498
499         if (condition & (G_IO_HUP | G_IO_ERR)) {
500                 g_source_remove (sock->priv->watch);
501                 sock->priv->watch = 0;
502                 return FALSE;
503         }
504
505         sa_len = sizeof (sa);
506         sockfd = accept (sock->priv->sockfd, (struct sockaddr *)&sa, &sa_len);
507         if (sockfd == -1)
508                 return TRUE;
509
510         new = g_object_new (SOUP_TYPE_SOCKET, NULL);
511         new->priv->sockfd = sockfd;
512         new->priv->non_blocking = sock->priv->non_blocking;
513         new->priv->nodelay = sock->priv->nodelay;
514         new->priv->is_server = TRUE;
515         new->priv->ssl_creds = sock->priv->ssl_creds;
516         update_fdflags (new);
517
518         new->priv->remote_addr = soup_address_new_from_sockaddr ((struct sockaddr *)&sa, sa_len);
519
520         if (new->priv->ssl_creds) {
521                 if (!soup_socket_start_ssl (new)) {
522                         g_object_unref (new);
523                         return TRUE;
524                 }
525         } else
526                 get_iochannel (new);
527
528         g_signal_emit (sock, signals[NEW_CONNECTION], 0, new);
529         g_object_unref (new);
530
531         return TRUE;
532 }
533
534 /**
535  * soup_socket_listen:
536  * @sock: a server #SoupSocket (which must not already be connected or
537  * listening)
538  * @local_addr: Local address to bind to.
539  *
540  * Makes @sock start listening on the given interface and port. When
541  * connections come in, @sock will emit %new_connection.
542  *
543  * Return value: whether or not @sock is now listening.
544  **/
545 gboolean
546 soup_socket_listen (SoupSocket *sock, SoupAddress *local_addr)
547 {
548         struct sockaddr *sa;
549         int sa_len;
550
551         g_return_val_if_fail (SOUP_IS_SOCKET (sock), FALSE);
552         g_return_val_if_fail (sock->priv->is_server, FALSE);
553         g_return_val_if_fail (sock->priv->sockfd == -1, FALSE);
554         g_return_val_if_fail (SOUP_IS_ADDRESS (local_addr), FALSE);
555
556         /* @local_addr may have its port set to 0. So we intentionally
557          * don't store it in sock->priv->local_addr, so that if the
558          * caller calls soup_socket_get_local_address() later, we'll
559          * have to make a new addr by calling getsockname(), which
560          * will have the right port number.
561          */
562         sa = soup_address_get_sockaddr (local_addr, &sa_len);
563         g_return_val_if_fail (sa != NULL, FALSE);
564
565         sock->priv->sockfd = socket (sa->sa_family, SOCK_STREAM, 0);
566         if (sock->priv->sockfd < 0)
567                 goto cant_listen;
568         update_fdflags (sock);
569
570         /* Bind */
571         if (bind (sock->priv->sockfd, sa, sa_len) != 0)
572                 goto cant_listen;
573
574         /* Listen */
575         if (listen (sock->priv->sockfd, 10) != 0)
576                 goto cant_listen;
577
578         sock->priv->watch = g_io_add_watch (get_iochannel (sock),
579                                             G_IO_IN | G_IO_ERR | G_IO_HUP,
580                                             listen_watch, sock);
581         return TRUE;
582
583  cant_listen:
584         if (sock->priv->sockfd != -1) {
585                 close (sock->priv->sockfd);
586                 sock->priv->sockfd = -1;
587         }
588
589         return FALSE;
590 }
591
592 /**
593  * soup_socket_start_ssl:
594  * @sock: the socket
595  *
596  * Starts using SSL on @socket.
597  *
598  * Return value: success or failure
599  **/
600 gboolean
601 soup_socket_start_ssl (SoupSocket *sock)
602 {
603         GIOChannel *ssl_chan;
604
605         get_iochannel (sock);
606         ssl_chan = soup_ssl_wrap_iochannel (
607                 sock->priv->iochannel, sock->priv->is_server ?
608                 SOUP_SSL_TYPE_SERVER : SOUP_SSL_TYPE_CLIENT,
609                 soup_address_get_name (sock->priv->remote_addr),
610                 sock->priv->ssl_creds);
611
612         if (!ssl_chan)
613                 return FALSE;
614
615         sock->priv->iochannel = ssl_chan;
616         return TRUE;
617 }
618         
619
620 /**
621  * soup_socket_client_new_async:
622  * @hostname: remote machine to connect to
623  * @port: remote port to connect to
624  * @ssl_creds: SSL credentials structure, or %NULL if not SSL
625  * @callback: callback to call when the socket is connected
626  * @user_data: data for @callback
627  *
628  * Creates a connection to @hostname and @port. @callback will be
629  * called when the connection completes (or fails).
630  *
631  * Return value: the new socket (not yet ready for use).
632  **/
633 SoupSocket *
634 soup_socket_client_new_async (const char *hostname, guint port,
635                               gpointer ssl_creds,
636                               SoupSocketCallback callback, gpointer user_data)
637 {
638         SoupSocket *sock;
639
640         g_return_val_if_fail (hostname != NULL, NULL);
641
642         sock = g_object_new (SOUP_TYPE_SOCKET,
643                              SOUP_SOCKET_SSL_CREDENTIALS, ssl_creds,
644                              NULL);
645         soup_socket_connect (sock, soup_address_new (hostname, port));
646
647         if (callback) {
648                 soup_signal_connect_once (sock, "connect_result",
649                                           G_CALLBACK (callback), user_data);
650         }
651         return sock;
652 }
653
654 /**
655  * soup_socket_client_new_sync:
656  * @hostname: remote machine to connect to
657  * @port: remote port to connect to
658  * @ssl_creds: SSL credentials structure, or %NULL if not SSL
659  * @status_ret: pointer to return the soup status in
660  *
661  * Creates a connection to @hostname and @port. If @status_ret is not
662  * %NULL, it will contain a status code on return.
663  *
664  * Return value: the new socket, or %NULL if it could not connect.
665  **/
666 SoupSocket *
667 soup_socket_client_new_sync (const char *hostname, guint port,
668                              gpointer ssl_creds, guint *status_ret)
669 {
670         SoupSocket *sock;
671         guint status;
672
673         g_return_val_if_fail (hostname != NULL, NULL);
674
675         sock = g_object_new (SOUP_TYPE_SOCKET,
676                              SOUP_SOCKET_SSL_CREDENTIALS, ssl_creds,
677                              NULL);
678         sock->priv->non_blocking = FALSE;
679         status = soup_socket_connect (sock, soup_address_new (hostname, port));
680
681         if (!SOUP_STATUS_IS_SUCCESSFUL (status)) {
682                 g_object_unref (sock);
683                 sock = NULL;
684         }
685
686         if (status_ret)
687                 *status_ret = status;
688         return sock;
689 }
690
691 /**
692  * soup_socket_server_new:
693  * @local_addr: Local address to bind to. (Use soup_address_any_new() to
694  * accept connections on any local address)
695  * @ssl_creds: SSL credentials, or %NULL if this is not an SSL server
696  * @callback: Callback to call when a client connects
697  * @user_data: data to pass to @callback.
698  *
699  * Create and open a new #SoupSocket listening on the specified
700  * address. @callback will be called each time a client connects,
701  * with a new #SoupSocket.
702  *
703  * Returns: a new #SoupSocket, or NULL if there was a failure.
704  **/
705 SoupSocket *
706 soup_socket_server_new (SoupAddress *local_addr, gpointer ssl_creds,
707                         SoupSocketListenerCallback callback,
708                         gpointer user_data)
709 {
710         SoupSocket *sock;
711
712         g_return_val_if_fail (SOUP_IS_ADDRESS (local_addr), NULL);
713
714         sock = g_object_new (SOUP_TYPE_SOCKET,
715                              SOUP_SOCKET_SSL_CREDENTIALS, ssl_creds,
716                              NULL);
717         sock->priv->is_server = TRUE;
718         if (!soup_socket_listen (sock, local_addr)) {
719                 g_object_unref (sock);
720                 return NULL;
721         }
722
723         if (callback) {
724                 g_signal_connect (sock, "new_connection",
725                                   G_CALLBACK (callback), user_data);
726         }
727
728         return sock;
729 }
730
731
732 /**
733  * soup_socket_disconnect:
734  * @sock: a #SoupSocket
735  *
736  * Disconnects @sock. Any further read or write attempts on it will
737  * fail.
738  **/
739 void
740 soup_socket_disconnect (SoupSocket *sock)
741 {
742         gboolean already_disconnected = FALSE;
743
744         g_return_if_fail (SOUP_IS_SOCKET (sock));
745
746         if (g_mutex_trylock (sock->priv->iolock)) {
747                 if (sock->priv->iochannel)
748                         disconnect_internal (sock);
749                 else
750                         already_disconnected = TRUE;
751                 g_mutex_unlock (sock->priv->iolock);
752         } else {
753                 int sockfd;
754
755                 /* Another thread is currently doing IO, so
756                  * we can't close the iochannel. So just kick
757                  * the file descriptor out from under it.
758                  */
759
760                 sockfd = sock->priv->sockfd;
761                 sock->priv->sockfd = -1;
762                 if (sockfd == -1)
763                         already_disconnected = TRUE;
764                 else {
765                         g_io_channel_set_close_on_unref (sock->priv->iochannel,
766                                                          FALSE);
767                         close (sockfd);
768                 }
769         }
770
771         if (already_disconnected)
772                 return;
773
774         /* Give all readers a chance to notice the connection close */
775         g_signal_emit (sock, signals[READABLE], 0);
776
777         /* FIXME: can't disconnect until all data is read */
778
779         /* Then let everyone know we're disconnected */
780         g_signal_emit (sock, signals[DISCONNECTED], 0);
781 }
782
783 /**
784  * soup_socket_is_connected:
785  * @sock: a #SoupSocket
786  *
787  * Tests if @sock is connected to another host
788  *
789  * Return value: %TRUE or %FALSE.
790  **/
791 gboolean
792 soup_socket_is_connected (SoupSocket *sock)
793 {
794         g_return_val_if_fail (SOUP_IS_SOCKET (sock), FALSE);
795
796         return sock->priv->iochannel != NULL;
797 }
798
799 /**
800  * soup_socket_get_local_address:
801  * @sock: a #SoupSocket
802  *
803  * Returns the #SoupAddress corresponding to the local end of @sock.
804  *
805  * Return value: the #SoupAddress
806  **/
807 SoupAddress *
808 soup_socket_get_local_address (SoupSocket *sock)
809 {
810         g_return_val_if_fail (SOUP_IS_SOCKET (sock), NULL);
811
812         g_mutex_lock (sock->priv->addrlock);
813         if (!sock->priv->local_addr) {
814                 struct soup_sockaddr_max bound_sa;
815                 int sa_len;
816
817                 sa_len = sizeof (bound_sa);
818                 getsockname (sock->priv->sockfd, (struct sockaddr *)&bound_sa, &sa_len);
819                 sock->priv->local_addr = soup_address_new_from_sockaddr ((struct sockaddr *)&bound_sa, sa_len);
820         }
821         g_mutex_unlock (sock->priv->addrlock);
822
823         return sock->priv->local_addr;
824 }
825
826 /**
827  * soup_socket_get_remote_address:
828  * @sock: a #SoupSocket
829  *
830  * Returns the #SoupAddress corresponding to the remote end of @sock.
831  *
832  * Return value: the #SoupAddress
833  **/
834 SoupAddress *
835 soup_socket_get_remote_address (SoupSocket *sock)
836 {
837         g_return_val_if_fail (SOUP_IS_SOCKET (sock), NULL);
838
839         g_mutex_lock (sock->priv->addrlock);
840         if (!sock->priv->remote_addr) {
841                 struct soup_sockaddr_max bound_sa;
842                 int sa_len;
843
844                 sa_len = sizeof (bound_sa);
845                 getpeername (sock->priv->sockfd, (struct sockaddr *)&bound_sa, &sa_len);
846                 sock->priv->remote_addr = soup_address_new_from_sockaddr ((struct sockaddr *)&bound_sa, sa_len);
847         }
848         g_mutex_unlock (sock->priv->addrlock);
849
850         return sock->priv->remote_addr;
851 }
852
853
854
855
856 static gboolean
857 socket_read_watch (GIOChannel *chan, GIOCondition cond, gpointer user_data)
858 {
859         SoupSocket *sock = user_data;
860
861         sock->priv->read_tag = 0;
862         g_signal_emit (sock, signals[READABLE], 0);
863
864         return FALSE;
865 }
866
867 static SoupSocketIOStatus
868 read_from_network (SoupSocket *sock, gpointer buffer, gsize len, gsize *nread)
869 {
870         GIOStatus status;
871         GIOCondition cond = G_IO_IN;
872         GError *err = NULL;
873
874         if (!sock->priv->iochannel) 
875                 return SOUP_SOCKET_EOF;
876
877         status = g_io_channel_read_chars (sock->priv->iochannel,
878                                           buffer, len, nread, &err);
879         if (err) {
880                 if (err->domain == SOUP_SSL_ERROR &&
881                     err->code == SOUP_SSL_ERROR_HANDSHAKE_NEEDS_WRITE)
882                         cond = G_IO_OUT;
883                 g_error_free (err);
884         }
885
886         switch (status) {
887         case G_IO_STATUS_NORMAL:
888         case G_IO_STATUS_AGAIN:
889                 if (*nread > 0)
890                         return SOUP_SOCKET_OK;
891
892                 if (!sock->priv->read_tag) {
893                         sock->priv->read_tag =
894                                 g_io_add_watch (sock->priv->iochannel, cond,
895                                                 socket_read_watch, sock);
896                 }
897                 return SOUP_SOCKET_WOULD_BLOCK;
898
899         case G_IO_STATUS_EOF:
900                 return SOUP_SOCKET_EOF;
901
902         default:
903                 return SOUP_SOCKET_ERROR;
904         }
905 }
906
907 static SoupSocketIOStatus
908 read_from_buf (SoupSocket *sock, gpointer buffer, gsize len, gsize *nread)
909 {
910         GByteArray *read_buf = sock->priv->read_buf;
911
912         *nread = MIN (read_buf->len, len);
913         memcpy (buffer, read_buf->data, *nread);
914
915         if (*nread == read_buf->len) {
916                 g_byte_array_free (read_buf, TRUE);
917                 sock->priv->read_buf = NULL;
918         } else {
919                 memmove (read_buf->data, read_buf->data + *nread, 
920                          read_buf->len - *nread);
921                 g_byte_array_set_size (read_buf, read_buf->len - *nread);
922         }
923
924         return SOUP_SOCKET_OK;
925 }
926
927 /**
928  * soup_socket_read:
929  * @sock: the socket
930  * @buffer: buffer to read into
931  * @len: size of @buffer in bytes
932  * @nread: on return, the number of bytes read into @buffer
933  *
934  * Attempts to read up to @len bytes from @sock into @buffer. If some
935  * data is successfully read, soup_socket_read() will return
936  * %SOUP_SOCKET_OK, and *@nread will contain the number of bytes
937  * actually read.
938  *
939  * If @sock is non-blocking, and no data is available, the return
940  * value will be %SOUP_SOCKET_WOULD_BLOCK. In this case, the caller
941  * can connect to the %readable signal to know when there is more data
942  * to read. (NB: You MUST read all available data off the socket
943  * first. The %readable signal will only be emitted after
944  * soup_socket_read() has returned %SOUP_SOCKET_WOULD_BLOCK.)
945  *
946  * Return value: a #SoupSocketIOStatus, as described above (or
947  * %SOUP_SOCKET_EOF if the socket is no longer connected, or
948  * %SOUP_SOCKET_ERROR on any other error).
949  **/
950 SoupSocketIOStatus
951 soup_socket_read (SoupSocket *sock, gpointer buffer, gsize len, gsize *nread)
952 {
953         SoupSocketIOStatus status;
954
955         g_return_val_if_fail (SOUP_IS_SOCKET (sock), SOUP_SOCKET_ERROR);
956
957         g_mutex_lock (sock->priv->iolock);
958         if (sock->priv->read_buf)
959                 status = read_from_buf (sock, buffer, len, nread);
960         else
961                 status = read_from_network (sock, buffer, len, nread);
962         g_mutex_unlock (sock->priv->iolock);
963
964         return status;
965 }
966
967 /**
968  * soup_socket_read_until:
969  * @sock: the socket
970  * @buffer: buffer to read into
971  * @len: size of @buffer in bytes
972  * @boundary: boundary to read until
973  * @boundary_len: length of @boundary in bytes
974  * @nread: on return, the number of bytes read into @buffer
975  * @got_boundary: on return, whether or not the data in @buffer
976  * ends with the boundary string
977  *
978  * Like soup_socket_read(), but reads no further than the first
979  * occurrence of @boundary. (If the boundary is found, it will be
980  * included in the returned data, and *@got_boundary will be set to
981  * %TRUE.) Any data after the boundary will returned in future reads.
982  *
983  * Return value: as for soup_socket_read()
984  **/
985 SoupSocketIOStatus
986 soup_socket_read_until (SoupSocket *sock, gpointer buffer, gsize len,
987                         gconstpointer boundary, gsize boundary_len,
988                         gsize *nread, gboolean *got_boundary)
989 {
990         SoupSocketIOStatus status;
991         GByteArray *read_buf;
992         guint match_len, prev_len;
993         guint8 *p, *end;
994
995         g_return_val_if_fail (SOUP_IS_SOCKET (sock), SOUP_SOCKET_ERROR);
996         g_return_val_if_fail (len >= boundary_len, SOUP_SOCKET_ERROR);
997
998         g_mutex_lock (sock->priv->iolock);
999
1000         *got_boundary = FALSE;
1001
1002         if (!sock->priv->read_buf)
1003                 sock->priv->read_buf = g_byte_array_new ();
1004         read_buf = sock->priv->read_buf;
1005
1006         if (read_buf->len < boundary_len) {
1007                 prev_len = read_buf->len;
1008                 g_byte_array_set_size (read_buf, len);
1009                 status = read_from_network (sock,
1010                                             read_buf->data + prev_len,
1011                                             len - prev_len, nread);
1012                 read_buf->len = prev_len + *nread;
1013
1014                 if (status != SOUP_SOCKET_OK) {
1015                         g_mutex_unlock (sock->priv->iolock);
1016                         return status;
1017                 }
1018         }
1019
1020         /* Scan for the boundary */
1021         end = read_buf->data + read_buf->len;
1022         for (p = read_buf->data; p <= end - boundary_len; p++) {
1023                 if (!memcmp (p, boundary, boundary_len)) {
1024                         p += boundary_len;
1025                         *got_boundary = TRUE;
1026                         break;
1027                 }
1028         }
1029
1030         /* Return everything up to 'p' (which is either just after the
1031          * boundary, or @boundary_len - 1 bytes before the end of the
1032          * buffer).
1033          */
1034         match_len = p - read_buf->data;
1035         status = read_from_buf (sock, buffer, MIN (len, match_len), nread);
1036
1037         g_mutex_unlock (sock->priv->iolock);
1038         return status;
1039 }
1040
1041 static gboolean
1042 socket_write_watch (GIOChannel *chan, GIOCondition condition, gpointer user_data)
1043 {
1044         SoupSocket *sock = user_data;
1045
1046         sock->priv->write_tag = 0;
1047         g_signal_emit (sock, signals[WRITABLE], 0);
1048
1049         return FALSE;
1050 }
1051
1052 /**
1053  * soup_socket_write:
1054  * @sock: the socket
1055  * @buffer: data to write
1056  * @len: size of @buffer, in bytes
1057  * @nwrote: on return, number of bytes written
1058  *
1059  * Attempts to write @len bytes from @buffer to @sock. If some data is
1060  * successfully written, the resturn status will be
1061  * %SOUP_SOCKET_SUCCESS, and *@nwrote will contain the number of bytes
1062  * actually written.
1063  *
1064  * If @sock is non-blocking, and no data could be written right away,
1065  * the return value will be %SOUP_SOCKET_WOULD_BLOCK. In this case,
1066  * the caller can connect to the %writable signal to know when more
1067  * data can be written. (NB: %writable is only emitted after a
1068  * %SOUP_SOCKET_WOULD_BLOCK.)
1069  *
1070  * Return value: a #SoupSocketIOStatus, as described above (or
1071  * %SOUP_SOCKET_EOF or %SOUP_SOCKET_ERROR).
1072  **/
1073 SoupSocketIOStatus
1074 soup_socket_write (SoupSocket *sock, gconstpointer buffer,
1075                    gsize len, gsize *nwrote)
1076 {
1077         GIOStatus status;
1078         gpointer pipe_handler;
1079         GIOCondition cond = G_IO_OUT;
1080         GError *err = NULL;
1081
1082         g_return_val_if_fail (SOUP_IS_SOCKET (sock), SOUP_SOCKET_ERROR);
1083
1084         g_mutex_lock (sock->priv->iolock);
1085
1086         if (!sock->priv->iochannel) {
1087                 g_mutex_unlock (sock->priv->iolock);
1088                 return SOUP_SOCKET_EOF;
1089         }
1090         if (sock->priv->write_tag) {
1091                 g_mutex_unlock (sock->priv->iolock);
1092                 return SOUP_SOCKET_WOULD_BLOCK;
1093         }
1094
1095         pipe_handler = signal (SIGPIPE, SIG_IGN);
1096         status = g_io_channel_write_chars (sock->priv->iochannel,
1097                                            buffer, len, nwrote, &err);
1098         signal (SIGPIPE, pipe_handler);
1099         if (err) {
1100                 if (err->domain == SOUP_SSL_ERROR &&
1101                     err->code == SOUP_SSL_ERROR_HANDSHAKE_NEEDS_READ)
1102                         cond = G_IO_IN;
1103                 g_error_free (err);
1104         }
1105
1106         if (status != G_IO_STATUS_NORMAL && status != G_IO_STATUS_AGAIN) {
1107                 g_mutex_unlock (sock->priv->iolock);
1108                 return SOUP_SOCKET_ERROR;
1109         }
1110
1111         if (*nwrote) {
1112                 g_mutex_unlock (sock->priv->iolock);
1113                 return SOUP_SOCKET_OK;
1114         }
1115
1116         sock->priv->write_tag =
1117                 g_io_add_watch (sock->priv->iochannel, cond, 
1118                                 socket_write_watch, sock);
1119         g_mutex_unlock (sock->priv->iolock);
1120         return SOUP_SOCKET_WOULD_BLOCK;
1121 }