Remove extern "C" wrapping other includes
[platform/upstream/libsoup.git] / libsoup / soup-server.c
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3  * soup-server.c: Asynchronous HTTP server
4  *
5  * Copyright (C) 2001-2003, Ximian, Inc.
6  */
7
8 #ifdef HAVE_CONFIG_H
9 #include <config.h>
10 #endif
11
12 #include <string.h>
13
14 #include <glib/gi18n-lib.h>
15
16 #include "soup-server.h"
17 #include "soup.h"
18 #include "soup-message-private.h"
19 #include "soup-misc-private.h"
20 #include "soup-path-map.h" 
21 #include "soup-socket-private.h"
22 #include "soup-websocket.h"
23 #include "soup-websocket-connection.h"
24 #include "soup-websocket-extension-deflate.h"
25
26 /**
27  * SECTION:soup-server
28  * @short_description: HTTP server
29  * @see_also: #SoupAuthDomain
30  *
31  * #SoupServer implements a simple HTTP server.
32  *
33  * (The following documentation describes the current #SoupServer API,
34  * available in <application>libsoup</application> 2.48 and later. See
35  * the section "<link linkend="soup-server-old-api">The Old SoupServer
36  * Listening API</link>" in the server how-to documentation for
37  * details on the older #SoupServer API.)
38  * 
39  * To begin, create a server using soup_server_new(). Add at least one
40  * handler by calling soup_server_add_handler() or
41  * soup_server_add_early_handler(); the handler will be called to
42  * process any requests underneath the path you pass. (If you want all
43  * requests to go to the same handler, just pass "/" (or %NULL) for
44  * the path.)
45  *
46  * When a new connection is accepted (or a new request is started on
47  * an existing persistent connection), the #SoupServer will emit
48  * #SoupServer::request-started and then begin processing the request
49  * as described below, but note that once the message is assigned a
50  * #SoupMessage:status-code, then callbacks after that point will be
51  * skipped. Note also that it is not defined when the callbacks happen
52  * relative to various #SoupMessage signals.
53  *
54  * Once the headers have been read, #SoupServer will check if there is
55  * a #SoupAuthDomain (qv) covering the Request-URI; if so, and if the
56  * message does not contain suitable authorization, then the
57  * #SoupAuthDomain will set a status of %SOUP_STATUS_UNAUTHORIZED on
58  * the message.
59  *
60  * After checking for authorization, #SoupServer will look for "early"
61  * handlers (added with soup_server_add_early_handler()) matching the
62  * Request-URI. If one is found, it will be run; in particular, this
63  * can be used to connect to signals to do a streaming read of the
64  * request body.
65  *
66  * (At this point, if the request headers contain "<literal>Expect:
67  * 100-continue</literal>", and a status code has been set, then
68  * #SoupServer will skip the remaining steps and return the response.
69  * If the request headers contain "<literal>Expect:
70  * 100-continue</literal>" and no status code has been set,
71  * #SoupServer will return a %SOUP_STATUS_CONTINUE status before
72  * continuing.)
73  *
74  * The server will then read in the response body (if present). At
75  * this point, if there are no handlers at all defined for the
76  * Request-URI, then the server will return %SOUP_STATUS_NOT_FOUND to
77  * the client.
78  *
79  * Otherwise (assuming no previous step assigned a status to the
80  * message) any "normal" handlers (added with
81  * soup_server_add_handler()) for the message's Request-URI will be
82  * run.
83  *
84  * Then, if the path has a WebSocket handler registered (and has
85  * not yet been assigned a status), #SoupServer will attempt to
86  * validate the WebSocket handshake, filling in the response and
87  * setting a status of %SOUP_STATUS_SWITCHING_PROTOCOLS or
88  * %SOUP_STATUS_BAD_REQUEST accordingly.
89  *
90  * If the message still has no status code at this point (and has not
91  * been paused with soup_server_pause_message()), then it will be
92  * given a status of %SOUP_STATUS_INTERNAL_SERVER_ERROR (because at
93  * least one handler ran, but returned without assigning a status).
94  *
95  * Finally, the server will emit #SoupServer::request-finished (or
96  * #SoupServer::request-aborted if an I/O error occurred before
97  * handling was completed).
98  *
99  * If you want to handle the special "*" URI (eg, "OPTIONS *"), you
100  * must explicitly register a handler for "*"; the default handler
101  * will not be used for that case.
102  * 
103  * If you want to process https connections in addition to (or instead
104  * of) http connections, you can either set the
105  * %SOUP_SERVER_TLS_CERTIFICATE property when creating the server, or
106  * else call soup_server_set_ssl_certificate() after creating it.
107  *
108  * Once the server is set up, make one or more calls to
109  * soup_server_listen(), soup_server_listen_local(), or
110  * soup_server_listen_all() to tell it where to listen for
111  * connections. (All ports on a #SoupServer use the same handlers; if
112  * you need to handle some ports differently, such as returning
113  * different data for http and https, you'll need to create multiple
114  * #SoupServers, or else check the passed-in URI in the handler
115  * function.).
116  *
117  * #SoupServer will begin processing connections as soon as you return
118  * to (or start) the main loop for the current thread-default
119  * #GMainContext.
120  */
121
122 enum {
123         REQUEST_STARTED,
124         REQUEST_READ,
125         REQUEST_FINISHED,
126         REQUEST_ABORTED,
127         LAST_SIGNAL
128 };
129
130 static guint signals[LAST_SIGNAL] = { 0 };
131
132 struct SoupClientContext {
133         SoupServer     *server;
134         SoupSocket     *sock;
135         GSocket        *gsock;
136         SoupMessage    *msg;
137         SoupAuthDomain *auth_domain;
138         char           *auth_user;
139
140         GSocketAddress *remote_addr;
141         char           *remote_ip;
142         GSocketAddress *local_addr;
143
144         int             ref_count;
145 };
146
147 typedef struct {
148         char               *path;
149
150         SoupServerCallback  early_callback;
151         GDestroyNotify      early_destroy;
152         gpointer            early_user_data;
153
154         SoupServerCallback  callback;
155         GDestroyNotify      destroy;
156         gpointer            user_data;
157
158         char                         *websocket_origin;
159         char                        **websocket_protocols;
160         GList                        *websocket_extensions;
161         SoupServerWebsocketCallback   websocket_callback;
162         GDestroyNotify                websocket_destroy;
163         gpointer                      websocket_user_data;
164 } SoupServerHandler;
165
166 typedef struct {
167         GSList            *listeners;
168         GSList            *clients;
169
170         char              *ssl_cert_file, *ssl_key_file;
171         GTlsCertificate   *tls_cert;
172
173         char              *server_header;
174
175         GMainContext      *async_context;
176         GMainLoop         *loop;
177
178         gboolean           raw_paths;
179         SoupPathMap       *handlers;
180
181         GSList            *auth_domains;
182
183         char             **http_aliases, **https_aliases;
184
185         SoupAddress       *legacy_iface;
186         int                legacy_port;
187
188         GPtrArray         *websocket_extension_types;
189
190         gboolean           disposed;
191
192 } SoupServerPrivate;
193
194 #define SOUP_SERVER_SERVER_HEADER_BASE "libsoup/" PACKAGE_VERSION
195
196 enum {
197         PROP_0,
198
199         PROP_PORT,
200         PROP_INTERFACE,
201         PROP_SSL_CERT_FILE,
202         PROP_SSL_KEY_FILE,
203         PROP_TLS_CERT_FILE,
204         PROP_TLS_KEY_FILE,
205         PROP_TLS_CERTIFICATE,
206         PROP_ASYNC_CONTEXT,
207         PROP_RAW_PATHS,
208         PROP_SERVER_HEADER,
209         PROP_HTTP_ALIASES,
210         PROP_HTTPS_ALIASES,
211         PROP_ADD_WEBSOCKET_EXTENSION,
212         PROP_REMOVE_WEBSOCKET_EXTENSION,
213
214         LAST_PROP
215 };
216
217 G_DEFINE_TYPE_WITH_PRIVATE (SoupServer, soup_server, G_TYPE_OBJECT)
218
219 static SoupClientContext *soup_client_context_ref (SoupClientContext *client);
220 static void soup_client_context_unref (SoupClientContext *client);
221
222 static void
223 free_handler (SoupServerHandler *handler)
224 {
225         g_free (handler->path);
226         g_free (handler->websocket_origin);
227         g_strfreev (handler->websocket_protocols);
228         g_list_free_full (handler->websocket_extensions, g_object_unref);
229         if (handler->early_destroy)
230                 handler->early_destroy (handler->early_user_data);
231         if (handler->destroy)
232                 handler->destroy (handler->user_data);
233         if (handler->websocket_destroy)
234                 handler->websocket_destroy (handler->websocket_user_data);
235         g_slice_free (SoupServerHandler, handler);
236 }
237
238 static void
239 soup_server_init (SoupServer *server)
240 {
241         SoupServerPrivate *priv = soup_server_get_instance_private (server);
242
243         priv->handlers = soup_path_map_new ((GDestroyNotify)free_handler);
244
245         priv->http_aliases = g_new (char *, 2);
246         priv->http_aliases[0] = (char *)g_intern_string ("*");
247         priv->http_aliases[1] = NULL;
248
249         priv->legacy_port = -1;
250
251         priv->websocket_extension_types = g_ptr_array_new_with_free_func ((GDestroyNotify)g_type_class_unref);
252
253         /* Use permessage-deflate extension by default */
254         g_ptr_array_add (priv->websocket_extension_types, g_type_class_ref (SOUP_TYPE_WEBSOCKET_EXTENSION_DEFLATE));
255 }
256
257 static void
258 soup_server_dispose (GObject *object)
259 {
260         SoupServer *server = SOUP_SERVER (object);
261         SoupServerPrivate *priv = soup_server_get_instance_private (server);
262
263         priv->disposed = TRUE;
264         soup_server_disconnect (server);
265
266         G_OBJECT_CLASS (soup_server_parent_class)->dispose (object);
267 }
268
269 static void
270 soup_server_finalize (GObject *object)
271 {
272         SoupServer *server = SOUP_SERVER (object);
273         SoupServerPrivate *priv = soup_server_get_instance_private (server);
274
275         g_clear_object (&priv->legacy_iface);
276
277         g_free (priv->ssl_cert_file);
278         g_free (priv->ssl_key_file);
279         g_clear_object (&priv->tls_cert);
280
281         g_free (priv->server_header);
282
283         soup_path_map_free (priv->handlers);
284
285         g_slist_free_full (priv->auth_domains, g_object_unref);
286
287         g_clear_pointer (&priv->loop, g_main_loop_unref);
288         g_clear_pointer (&priv->async_context, g_main_context_unref);
289
290         g_free (priv->http_aliases);
291         g_free (priv->https_aliases);
292
293         g_ptr_array_free (priv->websocket_extension_types, TRUE);
294
295         G_OBJECT_CLASS (soup_server_parent_class)->finalize (object);
296 }
297
298 static gboolean
299 soup_server_ensure_listening (SoupServer *server)
300 {
301         SoupServerPrivate *priv = soup_server_get_instance_private (server);
302         SoupSocket *listener;
303
304         if (priv->listeners)
305                 return TRUE;
306
307         if (!priv->legacy_iface) {
308                 priv->legacy_iface =
309                         soup_address_new_any (SOUP_ADDRESS_FAMILY_IPV4,
310                                               priv->legacy_port);
311         }
312
313         listener = soup_socket_new (SOUP_SOCKET_LOCAL_ADDRESS, priv->legacy_iface,
314                                     SOUP_SOCKET_SSL_CREDENTIALS, priv->tls_cert,
315                                     SOUP_SOCKET_ASYNC_CONTEXT, priv->async_context,
316                                     NULL);
317         if (!soup_socket_listen (listener)) {
318                 g_object_unref (listener);
319                 return FALSE;
320         }
321
322         /* Re-resolve the interface address, in particular in case
323          * the passed-in address had SOUP_ADDRESS_ANY_PORT.
324          */
325         g_object_unref (priv->legacy_iface);
326         priv->legacy_iface = soup_socket_get_local_address (listener);
327         g_object_ref (priv->legacy_iface);
328         priv->legacy_port = soup_address_get_port (priv->legacy_iface);
329
330         priv->listeners = g_slist_prepend (priv->listeners, listener);
331         return TRUE;
332 }
333
334 static GObject *
335 soup_server_constructor (GType                  type,
336                          guint                  n_construct_properties,
337                          GObjectConstructParam *construct_properties)
338 {
339         GObject *server;
340         SoupServerPrivate *priv;
341         gboolean legacy_port_set;
342
343         server = G_OBJECT_CLASS (soup_server_parent_class)->
344                 constructor (type, n_construct_properties, construct_properties);
345         priv = soup_server_get_instance_private (SOUP_SERVER (server));
346
347         /* For backward compatibility, we have to process the
348          * :ssl-cert-file, :ssl-key-file, :interface, and :port
349          * properties now, and return NULL if they are
350          * invalid/unsatisfiable.
351          */
352         if (priv->ssl_cert_file && priv->ssl_key_file) {
353                 GError *error = NULL;
354
355                 if (priv->tls_cert)
356                         g_object_unref (priv->tls_cert);
357                 priv->tls_cert = g_tls_certificate_new_from_files (priv->ssl_cert_file, priv->ssl_key_file, &error);
358                 if (!priv->tls_cert) {
359                         g_warning ("Could not read TLS certificate from '%s': %s",
360                                    priv->ssl_cert_file, error->message);
361                         g_error_free (error);
362                         g_object_unref (server);
363                         return NULL;
364                 }
365         }
366
367         if (priv->legacy_port != -1)
368                 legacy_port_set = TRUE;
369         else {
370                 legacy_port_set = FALSE;
371                 priv->legacy_port = 0;
372         }
373
374         if (legacy_port_set || priv->legacy_iface) {
375                 if (!soup_server_ensure_listening (SOUP_SERVER (server))) {
376                         g_object_unref (server);
377                         return NULL;
378                 }
379         } else {
380                 /* If neither port nor iface was specified, then
381                  * either: (a) the caller is planning to use the new
382                  * listen APIs, so we don't have to do anything now,
383                  * or (b) the caller is using the legacy APIs but
384                  * wants the default values for interface and port
385                  * (address 0.0.0.0, port 0), in which case a later
386                  * call to soup_server_ensure_listening() will set it
387                  * up just-in-time; we don't have to worry about it
388                  * failing in that case, because it can't (unless you
389                  * have no IPv4 addresses configured [even localhost],
390                  * or there are already listeners on all 65,535 ports.
391                  * We assume neither of these will happen.)
392                  */
393         }
394
395         return server;
396 }
397
398 /* priv->http_aliases and priv->https_aliases are stored as arrays of
399  * *interned* strings, so we can't just use g_strdupv() to set them.
400  */
401 static void
402 set_aliases (char ***variable, char **value)
403 {
404         int len, i;
405
406         if (*variable)
407                 g_free (*variable);
408
409         if (!value) {
410                 *variable = NULL;
411                 return;
412         }
413
414         len = g_strv_length (value);
415         *variable = g_new (char *, len + 1);
416         for (i = 0; i < len; i++)
417                 (*variable)[i] = (char *)g_intern_string (value[i]);
418         (*variable)[i] = NULL;
419 }
420
421 static void
422 soup_server_set_property (GObject *object, guint prop_id,
423                           const GValue *value, GParamSpec *pspec)
424 {
425         SoupServer *server = SOUP_SERVER (object);
426         SoupServerPrivate *priv = soup_server_get_instance_private (server);
427         const char *header;
428
429         switch (prop_id) {
430         case PROP_PORT:
431                 if (g_value_get_uint (value) != 0)
432                         priv->legacy_port = g_value_get_uint (value);
433                 break;
434         case PROP_INTERFACE:
435                 if (priv->legacy_iface)
436                         g_object_unref (priv->legacy_iface);
437                 priv->legacy_iface = g_value_get_object (value);
438                 if (priv->legacy_iface)
439                         g_object_ref (priv->legacy_iface);
440                 break;
441         case PROP_SSL_CERT_FILE:
442                 g_free (priv->ssl_cert_file);
443                 priv->ssl_cert_file = g_value_dup_string (value);
444                 break;
445         case PROP_SSL_KEY_FILE:
446                 g_free (priv->ssl_key_file);
447                 priv->ssl_key_file = g_value_dup_string (value);
448                 break;
449         case PROP_TLS_CERTIFICATE:
450                 if (priv->tls_cert)
451                         g_object_unref (priv->tls_cert);
452                 priv->tls_cert = g_value_dup_object (value);
453                 break;
454         case PROP_ASYNC_CONTEXT:
455                 priv->async_context = g_value_get_pointer (value);
456                 if (priv->async_context)
457                         g_main_context_ref (priv->async_context);
458                 break;
459         case PROP_RAW_PATHS:
460                 priv->raw_paths = g_value_get_boolean (value);
461                 break;
462         case PROP_SERVER_HEADER:
463                 g_free (priv->server_header);
464                 header = g_value_get_string (value);
465                 if (!header)
466                         priv->server_header = NULL;
467                 else if (!*header) {
468                         priv->server_header =
469                                 g_strdup (SOUP_SERVER_SERVER_HEADER_BASE);
470                 } else if (g_str_has_suffix (header, " ")) {
471                         priv->server_header =
472                                 g_strdup_printf ("%s%s", header,
473                                                  SOUP_SERVER_SERVER_HEADER_BASE);
474                 } else
475                         priv->server_header = g_strdup (header);
476                 break;
477         case PROP_HTTP_ALIASES:
478                 set_aliases (&priv->http_aliases, g_value_get_boxed (value));
479                 break;
480         case PROP_HTTPS_ALIASES:
481                 set_aliases (&priv->https_aliases, g_value_get_boxed (value));
482                 break;
483         case PROP_ADD_WEBSOCKET_EXTENSION:
484                 soup_server_add_websocket_extension (server, g_value_get_gtype (value));
485                 break;
486         case PROP_REMOVE_WEBSOCKET_EXTENSION:
487                 soup_server_remove_websocket_extension (server, g_value_get_gtype (value));
488                 break;
489         default:
490                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
491                 break;
492         }
493 }
494
495 static void
496 soup_server_get_property (GObject *object, guint prop_id,
497                           GValue *value, GParamSpec *pspec)
498 {
499         SoupServer *server = SOUP_SERVER (object);
500         SoupServerPrivate *priv = soup_server_get_instance_private (server);
501
502         switch (prop_id) {
503         case PROP_PORT:
504                 soup_server_ensure_listening (server);
505                 g_value_set_uint (value, priv->legacy_port > 0 ? priv->legacy_port : 0);
506                 break;
507         case PROP_INTERFACE:
508                 soup_server_ensure_listening (server);
509                 g_value_set_object (value, priv->legacy_iface);
510                 break;
511         case PROP_SSL_CERT_FILE:
512                 g_value_set_string (value, priv->ssl_cert_file);
513                 break;
514         case PROP_SSL_KEY_FILE:
515                 g_value_set_string (value, priv->ssl_key_file);
516                 break;
517         case PROP_TLS_CERTIFICATE:
518                 g_value_set_object (value, priv->tls_cert);
519                 break;
520         case PROP_ASYNC_CONTEXT:
521                 g_value_set_pointer (value, priv->async_context ? g_main_context_ref (priv->async_context) : NULL);
522                 break;
523         case PROP_RAW_PATHS:
524                 g_value_set_boolean (value, priv->raw_paths);
525                 break;
526         case PROP_SERVER_HEADER:
527                 g_value_set_string (value, priv->server_header);
528                 break;
529         case PROP_HTTP_ALIASES:
530                 g_value_set_boxed (value, priv->http_aliases);
531                 break;
532         case PROP_HTTPS_ALIASES:
533                 g_value_set_boxed (value, priv->https_aliases);
534                 break;
535         default:
536                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
537                 break;
538         }
539 }
540
541 static void
542 soup_server_class_init (SoupServerClass *server_class)
543 {
544         GObjectClass *object_class = G_OBJECT_CLASS (server_class);
545
546         /* virtual method override */
547         object_class->constructor = soup_server_constructor;
548         object_class->dispose = soup_server_dispose;
549         object_class->finalize = soup_server_finalize;
550         object_class->set_property = soup_server_set_property;
551         object_class->get_property = soup_server_get_property;
552
553         /* signals */
554
555         /**
556          * SoupServer::request-started:
557          * @server: the server
558          * @message: the new message
559          * @client: the client context
560          *
561          * Emitted when the server has started reading a new request.
562          * @message will be completely blank; not even the
563          * Request-Line will have been read yet. About the only thing
564          * you can usefully do with it is connect to its signals.
565          *
566          * If the request is read successfully, this will eventually
567          * be followed by a #SoupServer::request_read signal. If a
568          * response is then sent, the request processing will end with
569          * a #SoupServer::request_finished signal. If a network error
570          * occurs, the processing will instead end with
571          * #SoupServer::request_aborted.
572          **/
573         signals[REQUEST_STARTED] =
574                 g_signal_new ("request-started",
575                               G_OBJECT_CLASS_TYPE (object_class),
576                               G_SIGNAL_RUN_FIRST,
577                               G_STRUCT_OFFSET (SoupServerClass, request_started),
578                               NULL, NULL,
579                               NULL,
580                               G_TYPE_NONE, 2, 
581                               SOUP_TYPE_MESSAGE,
582                               SOUP_TYPE_CLIENT_CONTEXT);
583
584         /**
585          * SoupServer::request-read:
586          * @server: the server
587          * @message: the message
588          * @client: the client context
589          *
590          * Emitted when the server has successfully read a request.
591          * @message will have all of its request-side information
592          * filled in, and if the message was authenticated, @client
593          * will have information about that. This signal is emitted
594          * before any (non-early) handlers are called for the message,
595          * and if it sets the message's #status_code, then normal
596          * handler processing will be skipped.
597          **/
598         signals[REQUEST_READ] =
599                 g_signal_new ("request-read",
600                               G_OBJECT_CLASS_TYPE (object_class),
601                               G_SIGNAL_RUN_FIRST,
602                               G_STRUCT_OFFSET (SoupServerClass, request_read),
603                               NULL, NULL,
604                               NULL,
605                               G_TYPE_NONE, 2,
606                               SOUP_TYPE_MESSAGE,
607                               SOUP_TYPE_CLIENT_CONTEXT);
608
609         /**
610          * SoupServer::request-finished:
611          * @server: the server
612          * @message: the message
613          * @client: the client context
614          *
615          * Emitted when the server has finished writing a response to
616          * a request.
617          **/
618         signals[REQUEST_FINISHED] =
619                 g_signal_new ("request-finished",
620                               G_OBJECT_CLASS_TYPE (object_class),
621                               G_SIGNAL_RUN_FIRST,
622                               G_STRUCT_OFFSET (SoupServerClass, request_finished),
623                               NULL, NULL,
624                               NULL,
625                               G_TYPE_NONE, 2,
626                               SOUP_TYPE_MESSAGE,
627                               SOUP_TYPE_CLIENT_CONTEXT);
628
629         /**
630          * SoupServer::request-aborted:
631          * @server: the server
632          * @message: the message
633          * @client: the client context
634          *
635          * Emitted when processing has failed for a message; this
636          * could mean either that it could not be read (if
637          * #SoupServer::request_read has not been emitted for it yet),
638          * or that the response could not be written back (if
639          * #SoupServer::request_read has been emitted but
640          * #SoupServer::request_finished has not been).
641          *
642          * @message is in an undefined state when this signal is
643          * emitted; the signal exists primarily to allow the server to
644          * free any state that it may have allocated in
645          * #SoupServer::request_started.
646          **/
647         signals[REQUEST_ABORTED] =
648                 g_signal_new ("request-aborted",
649                               G_OBJECT_CLASS_TYPE (object_class),
650                               G_SIGNAL_RUN_FIRST,
651                               G_STRUCT_OFFSET (SoupServerClass, request_aborted),
652                               NULL, NULL,
653                               NULL,
654                               G_TYPE_NONE, 2,
655                               SOUP_TYPE_MESSAGE,
656                               SOUP_TYPE_CLIENT_CONTEXT);
657
658         /* properties */
659         /**
660          * SoupServer:port:
661          *
662          * The port the server is listening on, if you are using the
663          * old #SoupServer API. (This will not be set if you use
664          * soup_server_listen(), etc.)
665          *
666          * Deprecated: #SoupServers can listen on multiple interfaces
667          * at once now. Use soup_server_listen(), etc, to listen on a
668          * port, and soup_server_get_uris() to see what ports are
669          * being listened on.
670          */
671         /**
672          * SOUP_SERVER_PORT:
673          *
674          * Alias for the deprecated #SoupServer:port property, qv.
675          *
676          * Deprecated: #SoupServers can listen on multiple interfaces
677          * at once now. Use soup_server_listen(), etc, to listen on a
678          * port, and soup_server_get_uris() to see what ports are
679          * being listened on.
680          **/
681         g_object_class_install_property (
682                 object_class, PROP_PORT,
683                 g_param_spec_uint (SOUP_SERVER_PORT,
684                                    "Port",
685                                    "Port to listen on (Deprecated)",
686                                    0, 65536, 0,
687                                    G_PARAM_READWRITE |
688                                    G_PARAM_CONSTRUCT_ONLY |
689                                    G_PARAM_STATIC_STRINGS |
690                                    G_PARAM_DEPRECATED));
691         /**
692          * SoupServer:interface:
693          *
694          * The address of the network interface the server is
695          * listening on, if you are using the old #SoupServer API.
696          * (This will not be set if you use soup_server_listen(),
697          * etc.)
698          *
699          * Deprecated: #SoupServers can listen on multiple interfaces
700          * at once now. Use soup_server_listen(), etc, to listen on an
701          * interface, and soup_server_get_uris() to see what addresses
702          * are being listened on.
703          */
704         /**
705          * SOUP_SERVER_INTERFACE:
706          *
707          * Alias for the #SoupServer:interface property, qv.
708          *
709          * Deprecated: #SoupServers can listen on multiple interfaces
710          * at once now. Use soup_server_listen(), etc, to listen on an
711          * interface, and soup_server_get_uris() to see what addresses
712          * are being listened on.
713          **/
714         g_object_class_install_property (
715                 object_class, PROP_INTERFACE,
716                 g_param_spec_object (SOUP_SERVER_INTERFACE,
717                                      "Interface",
718                                      "Address of interface to listen on (Deprecated)",
719                                      SOUP_TYPE_ADDRESS,
720                                      G_PARAM_READWRITE |
721                                      G_PARAM_CONSTRUCT_ONLY |
722                                      G_PARAM_STATIC_STRINGS |
723                                      G_PARAM_DEPRECATED));
724         /**
725          * SOUP_SERVER_SSL_CERT_FILE:
726          *
727          * Alias for the #SoupServer:ssl-cert-file property, qv.
728          *
729          * Deprecated: use #SoupServer:tls-certificate or
730          * soup_server_set_ssl_certificate().
731          */
732         /**
733          * SoupServer:ssl-cert-file:
734          *
735          * Path to a file containing a PEM-encoded certificate.
736          *
737          * If you set this property and #SoupServer:ssl-key-file at
738          * construct time, then soup_server_new() will try to read the
739          * files; if it cannot, it will return %NULL, with no explicit
740          * indication of what went wrong (and logging a warning with
741          * newer versions of glib, since returning %NULL from a
742          * constructor is illegal).
743          *
744          * Deprecated: use #SoupServer:tls-certificate or
745          * soup_server_set_ssl_certificate().
746          */
747         g_object_class_install_property (
748                 object_class, PROP_SSL_CERT_FILE,
749                 g_param_spec_string (SOUP_SERVER_SSL_CERT_FILE,
750                                      "TLS (aka SSL) certificate file",
751                                      "File containing server TLS (aka SSL) certificate",
752                                      NULL,
753                                      G_PARAM_READWRITE |
754                                      G_PARAM_CONSTRUCT_ONLY |
755                                      G_PARAM_STATIC_STRINGS));
756         /**
757          * SOUP_SERVER_SSL_KEY_FILE:
758          *
759          * Alias for the #SoupServer:ssl-key-file property, qv.
760          *
761          * Deprecated: use #SoupServer:tls-certificate or
762          * soup_server_set_ssl_certificate().
763          */
764         /**
765          * SoupServer:ssl-key-file:
766          *
767          * Path to a file containing a PEM-encoded private key. See
768          * #SoupServer:ssl-cert-file for more information about how this
769          * is used.
770          *
771          * Deprecated: use #SoupServer:tls-certificate or
772          * soup_server_set_ssl_certificate().
773          */
774         g_object_class_install_property (
775                 object_class, PROP_SSL_KEY_FILE,
776                 g_param_spec_string (SOUP_SERVER_SSL_KEY_FILE,
777                                      "TLS (aka SSL) key file",
778                                      "File containing server TLS (aka SSL) key",
779                                      NULL,
780                                      G_PARAM_READWRITE |
781                                      G_PARAM_CONSTRUCT_ONLY |
782                                      G_PARAM_STATIC_STRINGS));
783         /**
784          * SOUP_SERVER_TLS_CERTIFICATE:
785          *
786          * Alias for the #SoupServer:tls-certificate property, qv.
787          *
788          * Since: 2.38
789          */
790         /**
791          * SoupServer:tls-certificate:
792          *
793          * A #GTlsCertificate that has a #GTlsCertificate:private-key
794          * set. If this is set, then the server will be able to speak
795          * https in addition to (or instead of) plain http.
796          *
797          * Alternatively, you can call soup_server_set_ssl_cert_file()
798          * to have #SoupServer read in a a certificate from a file.
799          *
800          * Since: 2.38
801          */
802         g_object_class_install_property (
803                 object_class, PROP_TLS_CERTIFICATE,
804                 g_param_spec_object (SOUP_SERVER_TLS_CERTIFICATE,
805                                      "TLS certificate",
806                                      "GTlsCertificate to use for https",
807                                      G_TYPE_TLS_CERTIFICATE,
808                                      G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
809         /**
810          * SoupServer:async-context:
811          *
812          * The server's #GMainContext, if you are using the old API.
813          * Servers created using soup_server_listen() will listen on
814          * the #GMainContext that was the thread-default context at
815          * the time soup_server_listen() was called.
816          *
817          * Deprecated: The new API uses the thread-default #GMainContext
818          * rather than having an explicitly-specified one.
819          */
820         /**
821          * SOUP_SERVER_ASYNC_CONTEXT:
822          *
823          * Alias for the deprecated #SoupServer:async-context
824          * property, qv.
825          *
826          * Deprecated: The new API uses the thread-default #GMainContext
827          * rather than having an explicitly-specified one.
828          **/
829         g_object_class_install_property (
830                 object_class, PROP_ASYNC_CONTEXT,
831                 g_param_spec_pointer (SOUP_SERVER_ASYNC_CONTEXT,
832                                       "Async GMainContext",
833                                       "The GMainContext to dispatch async I/O in",
834                                       G_PARAM_READWRITE |
835                                       G_PARAM_CONSTRUCT_ONLY |
836                                       G_PARAM_STATIC_STRINGS |
837                                       G_PARAM_DEPRECATED));
838         /**
839          * SOUP_SERVER_RAW_PATHS:
840          *
841          * Alias for the #SoupServer:raw-paths property. (If %TRUE,
842          * percent-encoding in the Request-URI path will not be
843          * automatically decoded.)
844          **/
845         g_object_class_install_property (
846                 object_class, PROP_RAW_PATHS,
847                 g_param_spec_boolean (SOUP_SERVER_RAW_PATHS,
848                                       "Raw paths",
849                                       "If %TRUE, percent-encoding in the Request-URI path will not be automatically decoded.",
850                                       FALSE,
851                                       G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY | G_PARAM_STATIC_STRINGS));
852
853         /**
854          * SoupServer:server-header:
855          *
856          * If non-%NULL, the value to use for the "Server" header on
857          * #SoupMessage<!-- -->s processed by this server.
858          *
859          * The Server header is the server equivalent of the
860          * User-Agent header, and provides information about the
861          * server and its components. It contains a list of one or
862          * more product tokens, separated by whitespace, with the most
863          * significant product token coming first. The tokens must be
864          * brief, ASCII, and mostly alphanumeric (although "-", "_",
865          * and "." are also allowed), and may optionally include a "/"
866          * followed by a version string. You may also put comments,
867          * enclosed in parentheses, between or after the tokens.
868          *
869          * Some HTTP server implementations intentionally do not use
870          * version numbers in their Server header, so that
871          * installations running older versions of the server don't
872          * end up advertising their vulnerability to specific security
873          * holes.
874          *
875          * As with #SoupSession:user_agent, if you set a
876          * #SoupServer:server_header property that has trailing whitespace,
877          * #SoupServer will append its own product token (eg,
878          * "<literal>libsoup/2.3.2</literal>") to the end of the
879          * header for you.
880          **/
881         /**
882          * SOUP_SERVER_SERVER_HEADER:
883          *
884          * Alias for the #SoupServer:server-header property, qv.
885          **/
886         g_object_class_install_property (
887                 object_class, PROP_SERVER_HEADER,
888                 g_param_spec_string (SOUP_SERVER_SERVER_HEADER,
889                                      "Server header",
890                                      "Server header",
891                                      NULL,
892                                      G_PARAM_READWRITE | G_PARAM_CONSTRUCT | G_PARAM_STATIC_STRINGS));
893
894         /**
895          * SoupServer:http-aliases:
896          *
897          * A %NULL-terminated array of URI schemes that should be
898          * considered to be aliases for "http". Eg, if this included
899          * <literal>"dav"</literal>, than a URI of
900          * <literal>dav://example.com/path</literal> would be treated
901          * identically to <literal>http://example.com/path</literal>.
902          * In particular, this is needed in cases where a client
903          * sends requests with absolute URIs, where those URIs do
904          * not use "http:".
905          *
906          * The default value is an array containing the single element
907          * <literal>"*"</literal>, a special value which means that
908          * any scheme except "https" is considered to be an alias for
909          * "http".
910          *
911          * See also #SoupServer:https-aliases.
912          *
913          * Since: 2.44
914          */
915         /**
916          * SOUP_SERVER_HTTP_ALIASES:
917          *
918          * Alias for the #SoupServer:http-aliases property, qv.
919          *
920          * Since: 2.44
921          */
922         g_object_class_install_property (
923                 object_class, PROP_HTTP_ALIASES,
924                 g_param_spec_boxed (SOUP_SERVER_HTTP_ALIASES,
925                                     "http aliases",
926                                     "URI schemes that are considered aliases for 'http'",
927                                     G_TYPE_STRV,
928                                     G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
929         /**
930          * SoupServer:https-aliases:
931          *
932          * A comma-delimited list of URI schemes that should be
933          * considered to be aliases for "https". See
934          * #SoupServer:http-aliases for more information.
935          *
936          * The default value is %NULL, meaning that no URI schemes
937          * are considered aliases for "https".
938          *
939          * Since: 2.44
940          */
941         /**
942          * SOUP_SERVER_HTTPS_ALIASES:
943          *
944          * Alias for the #SoupServer:https-aliases property, qv.
945          *
946          * Since: 2.44
947          **/
948         g_object_class_install_property (
949                 object_class, PROP_HTTPS_ALIASES,
950                 g_param_spec_boxed (SOUP_SERVER_HTTPS_ALIASES,
951                                     "https aliases",
952                                     "URI schemes that are considered aliases for 'https'",
953                                     G_TYPE_STRV,
954                                     G_PARAM_READWRITE | G_PARAM_STATIC_STRINGS));
955
956         /**
957          * SoupServer:add-websocket-extension: (skip)
958          *
959          * Add support for #SoupWebsocketExtension of the given type.
960          * (Shortcut for calling soup_server_add_websocket_extension().)
961          *
962          * Since: 2.68
963          **/
964         /**
965          * SOUP_SERVER_ADD_WEBSOCKET_EXTENSION: (skip)
966          *
967          * Alias for the #SoupServer:add-websocket-extension property, qv.
968          *
969          * Since: 2.68
970          **/
971         g_object_class_install_property (
972                 object_class, PROP_ADD_WEBSOCKET_EXTENSION,
973                 g_param_spec_gtype (SOUP_SERVER_ADD_WEBSOCKET_EXTENSION,
974                                     "Add support for a WebSocket extension",
975                                     "Add support for a WebSocket extension of the given type",
976                                     SOUP_TYPE_WEBSOCKET_EXTENSION,
977                                     G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS));
978         /**
979          * SoupServer:remove-websocket-extension: (skip)
980          *
981          * Remove support for #SoupWebsocketExtension of the given type. (Shortcut for
982          * calling soup_server_remove_websocket_extension().)
983          *
984          * Since: 2.68
985          **/
986         /**
987          * SOUP_SERVER_REMOVE_WEBSOCKET_EXTENSION: (skip)
988          *
989          * Alias for the #SoupServer:remove-websocket-extension property, qv.
990          *
991          * Since: 2.68
992          **/
993         g_object_class_install_property (
994                 object_class, PROP_REMOVE_WEBSOCKET_EXTENSION,
995                 g_param_spec_gtype (SOUP_SERVER_REMOVE_WEBSOCKET_EXTENSION,
996                                     "Remove support for a WebSocket extension",
997                                     "Remove support for a WebSocket extension of the given type",
998                                     SOUP_TYPE_WEBSOCKET_EXTENSION,
999                                     G_PARAM_WRITABLE | G_PARAM_STATIC_STRINGS));
1000 }
1001
1002 /**
1003  * soup_server_new:
1004  * @optname1: name of first property to set
1005  * @...: value of @optname1, followed by additional property/value pairs
1006  *
1007  * Creates a new #SoupServer. This is exactly equivalent to calling
1008  * g_object_new() and specifying %SOUP_TYPE_SERVER as the type.
1009  *
1010  * Return value: (nullable): a new #SoupServer. If you are using
1011  * certain legacy properties, this may also return %NULL if an error
1012  * occurs.
1013  **/
1014 SoupServer *
1015 soup_server_new (const char *optname1, ...)
1016 {
1017         SoupServer *server;
1018         va_list ap;
1019
1020         va_start (ap, optname1);
1021         server = (SoupServer *)g_object_new_valist (SOUP_TYPE_SERVER,
1022                                                     optname1, ap);
1023         va_end (ap);
1024
1025         return server;
1026 }
1027
1028 /**
1029  * soup_server_get_port:
1030  * @server: a #SoupServer
1031  *
1032  * Gets the TCP port that @server is listening on, if you are using
1033  * the old API.
1034  *
1035  * Return value: the port @server is listening on.
1036  *
1037  * Deprecated: If you are using soup_server_listen(), etc, then use
1038  * soup_server_get_uris() to get a list of all listening addresses.
1039  **/
1040 guint
1041 soup_server_get_port (SoupServer *server)
1042 {
1043         SoupServerPrivate *priv;
1044
1045         g_return_val_if_fail (SOUP_IS_SERVER (server), 0);
1046         priv = soup_server_get_instance_private (server);
1047
1048         soup_server_ensure_listening (server);
1049         g_return_val_if_fail (priv->legacy_iface != NULL, 0);
1050
1051         return priv->legacy_port;
1052 }
1053
1054 /**
1055  * soup_server_set_ssl_cert_file:
1056  * @server: a #SoupServer
1057  * @ssl_cert_file: path to a file containing a PEM-encoded SSL/TLS
1058  *   certificate.
1059  * @ssl_key_file: path to a file containing a PEM-encoded private key.
1060  * @error: return location for a #GError
1061  *
1062  * Sets @server up to do https, using the SSL/TLS certificate
1063  * specified by @ssl_cert_file and @ssl_key_file (which may point to
1064  * the same file).
1065  *
1066  * Alternatively, you can set the #SoupServer:tls-certificate property
1067  * at construction time, if you already have a #GTlsCertificate.
1068  *
1069  * Return value: success or failure.
1070  *
1071  * Since: 2.48
1072  */
1073 gboolean
1074 soup_server_set_ssl_cert_file  (SoupServer  *server,
1075                                 const char  *ssl_cert_file,
1076                                 const char  *ssl_key_file,
1077                                 GError     **error)
1078 {
1079         SoupServerPrivate *priv;
1080
1081         g_return_val_if_fail (SOUP_IS_SERVER (server), FALSE);
1082         priv = soup_server_get_instance_private (server);
1083
1084         if (priv->tls_cert)
1085                 g_object_unref (priv->tls_cert);
1086
1087         g_free (priv->ssl_cert_file);
1088         priv->ssl_cert_file = g_strdup (ssl_cert_file);
1089
1090         g_free (priv->ssl_key_file);
1091         priv->ssl_key_file = g_strdup (ssl_key_file);
1092
1093         priv->tls_cert = g_tls_certificate_new_from_files (priv->ssl_cert_file,
1094                                                            priv->ssl_key_file,
1095                                                            error);
1096         return priv->tls_cert != NULL;
1097 }
1098
1099 /**
1100  * soup_server_is_https:
1101  * @server: a #SoupServer
1102  *
1103  * Checks whether @server is capable of https.
1104  *
1105  * In order for a server to run https, you must call
1106  * soup_server_set_ssl_cert_file(), or set the
1107  * #SoupServer:tls-certificate property, to provide it with a
1108  * certificate to use.
1109  *
1110  * If you are using the deprecated single-listener APIs, then a return
1111  * value of %TRUE indicates that the #SoupServer serves https
1112  * exclusively. If you are using soup_server_listen(), etc, then a
1113  * %TRUE return value merely indicates that the server is
1114  * <emphasis>able</emphasis> to do https, regardless of whether it
1115  * actually currently is or not. Use soup_server_get_uris() to see if
1116  * it currently has any https listeners.
1117  *
1118  * Return value: %TRUE if @server is configured to serve https.
1119  **/
1120 gboolean
1121 soup_server_is_https (SoupServer *server)
1122 {
1123         SoupServerPrivate *priv;
1124
1125         g_return_val_if_fail (SOUP_IS_SERVER (server), 0);
1126         priv = soup_server_get_instance_private (server);
1127
1128         return priv->tls_cert != NULL;
1129 }
1130
1131 /**
1132  * soup_server_get_listener:
1133  * @server: a #SoupServer
1134  *
1135  * Gets @server's listening socket, if you are using the old API.
1136  *
1137  * You should treat this socket as read-only; writing to it or
1138  * modifiying it may cause @server to malfunction.
1139  *
1140  * Return value: (transfer none): the listening socket.
1141  *
1142  * Deprecated: If you are using soup_server_listen(), etc, then use
1143  * soup_server_get_listeners() to get a list of all listening sockets,
1144  * but note that that function returns #GSockets, not #SoupSockets.
1145  **/
1146 SoupSocket *
1147 soup_server_get_listener (SoupServer *server)
1148 {
1149         SoupServerPrivate *priv;
1150
1151         g_return_val_if_fail (SOUP_IS_SERVER (server), NULL);
1152         priv = soup_server_get_instance_private (server);
1153
1154         soup_server_ensure_listening (server);
1155         g_return_val_if_fail (priv->legacy_iface != NULL, NULL);
1156
1157         return priv->listeners ? priv->listeners->data : NULL;
1158 }
1159
1160 /**
1161  * soup_server_get_listeners:
1162  * @server: a #SoupServer
1163  *
1164  * Gets @server's list of listening sockets.
1165  *
1166  * You should treat these sockets as read-only; writing to or
1167  * modifiying any of these sockets may cause @server to malfunction.
1168  *
1169  * (Beware that in contrast to the old soup_server_get_listener(), this
1170  * function returns #GSockets, not #SoupSockets.)
1171  *
1172  * Return value: (transfer container) (element-type Gio.Socket): a
1173  * list of listening sockets.
1174  **/
1175 GSList *
1176 soup_server_get_listeners (SoupServer *server)
1177 {
1178         SoupServerPrivate *priv;
1179         GSList *listeners, *iter;
1180
1181         g_return_val_if_fail (SOUP_IS_SERVER (server), NULL);
1182         priv = soup_server_get_instance_private (server);
1183
1184         listeners = NULL;
1185         for (iter = priv->listeners; iter; iter = iter->next)
1186                 listeners = g_slist_prepend (listeners, soup_socket_get_gsocket (iter->data));
1187
1188         /* priv->listeners has the sockets in reverse order from how
1189          * they were added, so listeners now has them back in the
1190          * original order.
1191          */
1192         return listeners;
1193 }
1194
1195 static void start_request (SoupServer *, SoupClientContext *);
1196 static void socket_disconnected (SoupSocket *sock, SoupClientContext *client);
1197
1198 static SoupClientContext *
1199 soup_client_context_new (SoupServer *server, SoupSocket *sock)
1200 {
1201         SoupClientContext *client = g_slice_new0 (SoupClientContext);
1202
1203         client->server = server;
1204         client->sock = g_object_ref (sock);
1205         client->gsock = soup_socket_get_gsocket (sock);
1206         if (client->gsock)
1207                 g_object_ref (client->gsock);
1208         g_signal_connect (sock, "disconnected",
1209                           G_CALLBACK (socket_disconnected), client);
1210         client->ref_count = 1;
1211
1212         return client;
1213 }
1214
1215 static void
1216 soup_client_context_cleanup (SoupClientContext *client)
1217 {
1218         g_clear_object (&client->auth_domain);
1219         g_clear_pointer (&client->auth_user, g_free);
1220         g_clear_object (&client->remote_addr);
1221         g_clear_object (&client->local_addr);
1222
1223         client->msg = NULL;
1224 }
1225
1226 static SoupClientContext *
1227 soup_client_context_ref (SoupClientContext *client)
1228 {
1229         g_atomic_int_inc (&client->ref_count);
1230         return client;
1231 }
1232
1233 static void
1234 soup_client_context_unref (SoupClientContext *client)
1235 {
1236         if (!g_atomic_int_dec_and_test (&client->ref_count))
1237                 return;
1238
1239         soup_client_context_cleanup (client);
1240
1241         g_signal_handlers_disconnect_by_func (client->sock, socket_disconnected, client);
1242         g_object_unref (client->sock);
1243         g_clear_object (&client->gsock);
1244         g_clear_pointer (&client->remote_ip, g_free);
1245         g_slice_free (SoupClientContext, client);
1246 }
1247
1248 static void
1249 request_finished (SoupMessage *msg, SoupMessageIOCompletion completion, gpointer user_data)
1250 {
1251         SoupClientContext *client = user_data;
1252         SoupServer *server = client->server;
1253         SoupServerPrivate *priv = soup_server_get_instance_private (server);
1254         SoupSocket *sock = client->sock;
1255         gboolean failed;
1256
1257         if (completion == SOUP_MESSAGE_IO_STOLEN) {
1258                 soup_client_context_unref (client);
1259                 g_object_unref (msg);
1260                 return;
1261         }
1262
1263         /* Complete the message, assuming it actually really started. */
1264         if (msg->method) {
1265                 soup_message_finished (msg);
1266
1267                 failed = (completion == SOUP_MESSAGE_IO_INTERRUPTED ||
1268                           msg->status_code == SOUP_STATUS_IO_ERROR);
1269                 g_signal_emit (server,
1270                                failed ? signals[REQUEST_ABORTED] : signals[REQUEST_FINISHED],
1271                                0, msg, client);
1272         }
1273
1274         if (completion == SOUP_MESSAGE_IO_COMPLETE &&
1275             soup_socket_is_connected (sock) &&
1276             soup_message_is_keepalive (msg) &&
1277             priv->listeners) {
1278                 start_request (server, client);
1279         } else {
1280                 soup_socket_disconnect (client->sock);
1281                 soup_client_context_unref (client);
1282         }
1283         g_object_unref (msg);
1284 }
1285
1286 /* "" was never documented as meaning the same thing as "/", but it
1287  * effectively was. We have to special case it now or otherwise it
1288  * would match "*" too.
1289  */
1290 #define NORMALIZED_PATH(path) ((path) && *(path) ? (path) : "/")
1291
1292 static SoupServerHandler *
1293 get_handler (SoupServer *server, SoupMessage *msg)
1294 {
1295         SoupServerPrivate *priv = soup_server_get_instance_private (server);
1296         SoupURI *uri;
1297
1298         uri = soup_message_get_uri (msg);
1299         return soup_path_map_lookup (priv->handlers, NORMALIZED_PATH (uri->path));
1300 }
1301
1302 static void
1303 call_handler (SoupServer *server, SoupServerHandler *handler,
1304               SoupClientContext *client, SoupMessage *msg,
1305               gboolean early)
1306 {
1307         GHashTable *form_data_set;
1308         SoupURI *uri;
1309
1310         if (early && !handler->early_callback)
1311                 return;
1312         else if (!early && !handler->callback)
1313                 return;
1314
1315         if (msg->status_code != 0)
1316                 return;
1317
1318         uri = soup_message_get_uri (msg);
1319         if (uri->query)
1320                 form_data_set = soup_form_decode (uri->query);
1321         else
1322                 form_data_set = NULL;
1323
1324         if (early) {
1325                 (*handler->early_callback) (server, msg,
1326                                             uri->path, form_data_set,
1327                                             client, handler->early_user_data);
1328         } else {
1329                 (*handler->callback) (server, msg,
1330                                       uri->path, form_data_set,
1331                                       client, handler->user_data);
1332         }
1333
1334         if (form_data_set)
1335                 g_hash_table_unref (form_data_set);
1336 }
1337
1338 static void
1339 got_headers (SoupMessage *msg, SoupClientContext *client)
1340 {
1341         SoupServer *server = client->server;
1342         SoupServerPrivate *priv = soup_server_get_instance_private (server);
1343         SoupServerHandler *handler;
1344         SoupURI *uri;
1345         SoupDate *date;
1346         char *date_string;
1347         SoupAuthDomain *domain;
1348         GSList *iter;
1349         gboolean rejected = FALSE;
1350         char *auth_user;
1351
1352         /* Add required response headers */
1353         date = soup_date_new_from_now (0);
1354         date_string = soup_date_to_string (date, SOUP_DATE_HTTP);
1355         soup_message_headers_replace (msg->response_headers, "Date",
1356                                       date_string);
1357         g_free (date_string);
1358         soup_date_free (date);
1359
1360         if (msg->status_code != 0)
1361                 return;
1362
1363         uri = soup_message_get_uri (msg);
1364         if ((soup_socket_is_ssl (client->sock) && !soup_uri_is_https (uri, priv->https_aliases)) ||
1365             (!soup_socket_is_ssl (client->sock) && !soup_uri_is_http (uri, priv->http_aliases))) {
1366                 soup_message_set_status (msg, SOUP_STATUS_BAD_REQUEST);
1367                 return;
1368         }
1369
1370         if (!priv->raw_paths) {
1371                 char *decoded_path;
1372
1373                 decoded_path = soup_uri_decode (uri->path);
1374
1375                 if (strstr (decoded_path, "/../") ||
1376                     g_str_has_suffix (decoded_path, "/..")
1377 #ifdef G_OS_WIN32
1378                     ||
1379                     strstr (decoded_path, "\\..\\") ||
1380                     strstr (decoded_path, "/..\\") ||
1381                     strstr (decoded_path, "\\../") ||
1382                     g_str_has_suffix (decoded_path, "\\..")
1383 #endif
1384                     ) {
1385                         /* Introducing new ".." segments is not allowed */
1386                         g_free (decoded_path);
1387                         soup_message_set_status (msg, SOUP_STATUS_BAD_REQUEST);
1388                         return;
1389                 }
1390
1391                 soup_uri_set_path (uri, decoded_path);
1392                 g_free (decoded_path);
1393         }
1394
1395         /* Now handle authentication. (We do this here so that if
1396          * the request uses "Expect: 100-continue", we can reject it
1397          * immediately rather than waiting for the request body to
1398          * be sent.
1399          */
1400         for (iter = priv->auth_domains; iter; iter = iter->next) {
1401                 domain = iter->data;
1402
1403                 if (soup_auth_domain_covers (domain, msg)) {
1404                         auth_user = soup_auth_domain_accepts (domain, msg);
1405                         if (auth_user) {
1406                                 client->auth_domain = g_object_ref (domain);
1407                                 client->auth_user = auth_user;
1408                                 return;
1409                         }
1410
1411                         rejected = TRUE;
1412                 }
1413         }
1414
1415         /* If any auth domain rejected it, then it will need authentication. */
1416         if (rejected) {
1417                 for (iter = priv->auth_domains; iter; iter = iter->next) {
1418                         domain = iter->data;
1419
1420                         if (soup_auth_domain_covers (domain, msg))
1421                                 soup_auth_domain_challenge (domain, msg);
1422                 }
1423                 return;
1424         }
1425
1426         /* Otherwise, call the early handlers. */
1427         handler = get_handler (server, msg);
1428         if (handler)
1429                 call_handler (server, handler, client, msg, TRUE);
1430 }
1431
1432 static void
1433 complete_websocket_upgrade (SoupMessage *msg, gpointer user_data)
1434 {
1435         SoupClientContext *client = user_data;
1436         SoupServer *server = client->server;
1437         SoupURI *uri = soup_message_get_uri (msg);
1438         SoupServerHandler *handler;
1439         GIOStream *stream;
1440         SoupWebsocketConnection *conn;
1441
1442         handler = get_handler (server, msg);
1443         if (!handler || !handler->websocket_callback)
1444                 return;
1445
1446         soup_client_context_ref (client);
1447         stream = soup_client_context_steal_connection (client);
1448         conn = soup_websocket_connection_new_with_extensions (stream, uri,
1449                                                               SOUP_WEBSOCKET_CONNECTION_SERVER,
1450                                                               soup_message_headers_get_one (msg->request_headers, "Origin"),
1451                                                               soup_message_headers_get_one (msg->response_headers, "Sec-WebSocket-Protocol"),
1452                                                               handler->websocket_extensions);
1453         handler->websocket_extensions = NULL;
1454         g_object_unref (stream);
1455         soup_client_context_unref (client);
1456
1457         (*handler->websocket_callback) (server, conn, uri->path, client,
1458                                         handler->websocket_user_data);
1459         g_object_unref (conn);
1460         soup_client_context_unref (client);
1461 }
1462
1463 static void
1464 got_body (SoupMessage *msg, SoupClientContext *client)
1465 {
1466         SoupServer *server = client->server;
1467         SoupServerHandler *handler;
1468
1469         g_signal_emit (server, signals[REQUEST_READ], 0, msg, client);
1470
1471         if (msg->status_code != 0)
1472                 return;
1473
1474         handler = get_handler (server, msg);
1475         if (!handler) {
1476                 soup_message_set_status (msg, SOUP_STATUS_NOT_FOUND);
1477                 return;
1478         }
1479
1480         call_handler (server, handler, client, msg, FALSE);
1481         if (msg->status_code != 0)
1482                 return;
1483
1484         if (handler->websocket_callback) {
1485                 SoupServerPrivate *priv;
1486
1487                 priv = soup_server_get_instance_private (server);
1488                 if (soup_websocket_server_process_handshake_with_extensions (msg,
1489                                                                              handler->websocket_origin,
1490                                                                              handler->websocket_protocols,
1491                                                                              priv->websocket_extension_types,
1492                                                                              &handler->websocket_extensions)) {
1493                         g_signal_connect (msg, "wrote-informational",
1494                                           G_CALLBACK (complete_websocket_upgrade),
1495                                           soup_client_context_ref (client));
1496                 }
1497         }
1498 }
1499
1500 static void
1501 start_request (SoupServer *server, SoupClientContext *client)
1502 {
1503         SoupServerPrivate *priv = soup_server_get_instance_private (server);
1504         SoupMessage *msg;
1505
1506         soup_client_context_cleanup (client);
1507
1508         /* Listen for another request on this connection */
1509         msg = g_object_new (SOUP_TYPE_MESSAGE,
1510                             SOUP_MESSAGE_SERVER_SIDE, TRUE,
1511                             NULL);
1512         client->msg = msg;
1513
1514         if (priv->server_header) {
1515                 soup_message_headers_append (msg->response_headers, "Server",
1516                                              priv->server_header);
1517         }
1518
1519         g_signal_connect (msg, "got_headers", G_CALLBACK (got_headers), client);
1520         g_signal_connect (msg, "got_body", G_CALLBACK (got_body), client);
1521
1522         g_signal_emit (server, signals[REQUEST_STARTED], 0,
1523                        msg, client);
1524
1525         soup_message_read_request (msg, client->sock,
1526                                    priv->legacy_iface == NULL,
1527                                    request_finished, client);
1528 }
1529
1530 static void
1531 socket_disconnected (SoupSocket *sock, SoupClientContext *client)
1532 {
1533         SoupServerPrivate *priv = soup_server_get_instance_private (client->server);
1534
1535         priv->clients = g_slist_remove (priv->clients, client);
1536
1537         if (client->msg) {
1538                 soup_message_set_status (client->msg, SOUP_STATUS_IO_ERROR);
1539                 soup_message_io_finished (client->msg);
1540         }
1541 }
1542
1543 static void
1544 soup_server_accept_socket (SoupServer *server,
1545                            SoupSocket *sock)
1546 {
1547         SoupServerPrivate *priv = soup_server_get_instance_private (server);
1548         SoupClientContext *client;
1549
1550         client = soup_client_context_new (server, sock);
1551         priv->clients = g_slist_prepend (priv->clients, client);
1552         start_request (server, client);
1553 }
1554
1555 /**
1556  * soup_server_accept_iostream:
1557  * @server: a #SoupServer
1558  * @stream: a #GIOStream
1559  * @local_addr: (allow-none): the local #GSocketAddress associated with the @stream
1560  * @remote_addr: (allow-none): the remote #GSocketAddress associated with the @stream
1561  * @error: return location for a #GError
1562  *
1563  * Add a new client stream to the @server.
1564  *
1565  * Return value: %TRUE on success, %FALSE if the stream could not be
1566  * accepted or any other error occurred (in which case @error will be
1567  * set).
1568  *
1569  * Since: 2.50
1570  **/
1571 gboolean
1572 soup_server_accept_iostream   (SoupServer     *server,
1573                                GIOStream      *stream,
1574                                GSocketAddress *local_addr,
1575                                GSocketAddress *remote_addr,
1576                                GError        **error)
1577 {
1578         SoupSocket *sock;
1579         SoupAddress *local = NULL, *remote = NULL;
1580
1581         if (local_addr)
1582                 local = soup_address_new_from_gsockaddr (local_addr);
1583         if (remote_addr)
1584                 remote = soup_address_new_from_gsockaddr (remote_addr);
1585
1586         sock = g_initable_new (SOUP_TYPE_SOCKET, NULL, error,
1587                                "iostream", stream,
1588                                "local-address", local,
1589                                "remote-address", remote,
1590                                NULL);
1591
1592         g_clear_object (&local);
1593         g_clear_object (&remote);
1594
1595         if (!sock)
1596                 return FALSE;
1597
1598         soup_server_accept_socket (server, sock);
1599         g_object_unref (sock);
1600
1601         return TRUE;
1602 }
1603
1604 static void
1605 new_connection (SoupSocket *listener, SoupSocket *sock, gpointer user_data)
1606 {
1607         SoupServer *server = user_data;
1608
1609         soup_server_accept_socket (server, sock);
1610 }
1611
1612 /**
1613  * soup_server_run_async:
1614  * @server: a #SoupServer
1615  *
1616  * Starts @server, if you are using the old API, causing it to listen
1617  * for and process incoming connections.
1618  *
1619  * The server runs in @server's #GMainContext. It will not actually
1620  * perform any processing unless the appropriate main loop is running.
1621  * In the simple case where you did not set the server's
1622  * %SOUP_SERVER_ASYNC_CONTEXT property, this means the server will run
1623  * whenever the glib main loop is running.
1624  *
1625  * Deprecated: When using soup_server_listen(), etc, the server will
1626  * always listen for connections, and will process them whenever the
1627  * thread-default #GMainContext is running.
1628  **/
1629 void
1630 soup_server_run_async (SoupServer *server)
1631 {
1632         SoupServerPrivate *priv;
1633         SoupSocket *listener;
1634
1635         g_return_if_fail (SOUP_IS_SERVER (server));
1636         priv = soup_server_get_instance_private (server);
1637
1638         soup_server_ensure_listening (server);
1639
1640         g_return_if_fail (priv->legacy_iface != NULL);
1641
1642         if (!priv->listeners) {
1643                 if (priv->loop) {
1644                         g_main_loop_unref (priv->loop);
1645                         priv->loop = NULL;
1646                 }
1647                 return;
1648         }
1649
1650         listener = priv->listeners->data;
1651         g_signal_connect (listener, "new_connection",
1652                           G_CALLBACK (new_connection), server);
1653
1654         return;
1655 }
1656
1657 /**
1658  * soup_server_run:
1659  * @server: a #SoupServer
1660  *
1661  * Starts @server, if you are using the old API, causing it to listen
1662  * for and process incoming connections. Unlike
1663  * soup_server_run_async(), this creates a #GMainLoop and runs it, and
1664  * it will not return until someone calls soup_server_quit() to stop
1665  * the server.
1666  *
1667  * Deprecated: When using soup_server_listen(), etc, the server will
1668  * always listen for connections, and will process them whenever the
1669  * thread-default #GMainContext is running.
1670  **/
1671 void
1672 soup_server_run (SoupServer *server)
1673 {
1674         SoupServerPrivate *priv;
1675
1676         g_return_if_fail (SOUP_IS_SERVER (server));
1677         priv = soup_server_get_instance_private (server);
1678
1679         if (!priv->loop) {
1680                 priv->loop = g_main_loop_new (priv->async_context, TRUE);
1681                 G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
1682                 soup_server_run_async (server);
1683                 G_GNUC_END_IGNORE_DEPRECATIONS;
1684         }
1685
1686         if (priv->loop)
1687                 g_main_loop_run (priv->loop);
1688 }
1689
1690 /**
1691  * soup_server_quit:
1692  * @server: a #SoupServer
1693  *
1694  * Stops processing for @server, if you are using the old API. Call
1695  * this to clean up after soup_server_run_async(), or to terminate a
1696  * call to soup_server_run().
1697  *
1698  * Note that messages currently in progress will continue to be
1699  * handled, if the main loop associated with the server is resumed or
1700  * kept running.
1701  *
1702  * @server is still in a working state after this call; you can start
1703  * and stop a server as many times as you want.
1704  *
1705  * Deprecated: When using soup_server_listen(), etc, the server will
1706  * always listen for connections, and will process them whenever the
1707  * thread-default #GMainContext is running.
1708  **/
1709 void
1710 soup_server_quit (SoupServer *server)
1711 {
1712         SoupServerPrivate *priv;
1713         SoupSocket *listener;
1714
1715         g_return_if_fail (SOUP_IS_SERVER (server));
1716         priv = soup_server_get_instance_private (server);
1717         g_return_if_fail (priv->legacy_iface != NULL);
1718         g_return_if_fail (priv->listeners != NULL);
1719
1720         listener = priv->listeners->data;
1721         g_signal_handlers_disconnect_by_func (listener,
1722                                               G_CALLBACK (new_connection),
1723                                               server);
1724         if (priv->loop)
1725                 g_main_loop_quit (priv->loop);
1726 }
1727
1728 /**
1729  * soup_server_disconnect:
1730  * @server: a #SoupServer
1731  *
1732  * Closes and frees @server's listening sockets. If you are using the
1733  * old #SoupServer APIs, this also includes the effect of
1734  * soup_server_quit().
1735  *
1736  * Note that if there are currently requests in progress on @server,
1737  * that they will continue to be processed if @server's #GMainContext
1738  * is still running.
1739  *
1740  * You can call soup_server_listen(), etc, after calling this function
1741  * if you want to start listening again.
1742  **/
1743 void
1744 soup_server_disconnect (SoupServer *server)
1745 {
1746         SoupServerPrivate *priv;
1747         GSList *listeners, *clients, *iter;
1748         SoupSocket *listener;
1749         SoupClientContext *client;
1750
1751         g_return_if_fail (SOUP_IS_SERVER (server));
1752         priv = soup_server_get_instance_private (server);
1753
1754         if (priv->legacy_iface) {
1755                 G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
1756                 soup_server_quit (server);
1757                 G_GNUC_END_IGNORE_DEPRECATIONS;
1758         }
1759
1760         clients = priv->clients;
1761         priv->clients = NULL;
1762         listeners = priv->listeners;
1763         priv->listeners = NULL;
1764
1765         for (iter = clients; iter; iter = iter->next) {
1766                 client = iter->data;
1767                 soup_socket_disconnect (client->sock);
1768         }
1769         g_slist_free (clients);
1770
1771         for (iter = listeners; iter; iter = iter->next) {
1772                 listener = iter->data;
1773                 soup_socket_disconnect (listener);
1774                 g_object_unref (listener);
1775         }
1776         g_slist_free (listeners);
1777 }
1778
1779 /**
1780  * SoupServerListenOptions:
1781  * @SOUP_SERVER_LISTEN_HTTPS: Listen for https connections rather
1782  *   than plain http.
1783  * @SOUP_SERVER_LISTEN_IPV4_ONLY: Only listen on IPv4 interfaces.
1784  * @SOUP_SERVER_LISTEN_IPV6_ONLY: Only listen on IPv6 interfaces.
1785  *
1786  * Options to pass to soup_server_listen(), etc.
1787  *
1788  * %SOUP_SERVER_LISTEN_IPV4_ONLY and %SOUP_SERVER_LISTEN_IPV6_ONLY
1789  * only make sense with soup_server_listen_all() and
1790  * soup_server_listen_local(), not plain soup_server_listen() (which
1791  * simply listens on whatever kind of socket you give it). And you
1792  * cannot specify both of them in a single call.
1793  *
1794  * Since: 2.48
1795  */
1796
1797 static gboolean
1798 soup_server_listen_internal (SoupServer *server, SoupSocket *listener,
1799                              SoupServerListenOptions options,
1800                              GError **error)
1801 {
1802         SoupServerPrivate *priv = soup_server_get_instance_private (server);
1803         gboolean is_listening;
1804
1805         if (options & SOUP_SERVER_LISTEN_HTTPS) {
1806                 if (!priv->tls_cert) {
1807                         g_set_error_literal (error,
1808                                              G_IO_ERROR,
1809                                              G_IO_ERROR_INVALID_ARGUMENT,
1810                                              _("Can’t create a TLS server without a TLS certificate"));
1811                         return FALSE;
1812                 }
1813
1814                 g_object_set (G_OBJECT (listener),
1815                               SOUP_SOCKET_SSL_CREDENTIALS, priv->tls_cert,
1816                               NULL);
1817         }
1818
1819         g_object_get (G_OBJECT (listener),
1820                       SOUP_SOCKET_IS_SERVER, &is_listening,
1821                       NULL);
1822         if (!is_listening) {
1823                 if (!soup_socket_listen_full (listener, error)) {
1824                         SoupAddress *saddr = soup_socket_get_local_address (listener);
1825
1826                         g_prefix_error (error,
1827                                         _("Could not listen on address %s, port %d: "),
1828                                         soup_address_get_physical (saddr),
1829                                         soup_address_get_port (saddr));
1830                         return FALSE;
1831                 }
1832         }
1833
1834         g_signal_connect (listener, "new_connection",
1835                           G_CALLBACK (new_connection), server);
1836
1837         /* Note: soup_server_listen_ipv4_ipv6() below relies on the
1838          * fact that this does g_slist_prepend().
1839          */
1840         priv->listeners = g_slist_prepend (priv->listeners, g_object_ref (listener));
1841         return TRUE;
1842 }
1843
1844 /**
1845  * soup_server_listen:
1846  * @server: a #SoupServer
1847  * @address: the address of the interface to listen on
1848  * @options: listening options for this server
1849  * @error: return location for a #GError
1850  *
1851  * This attempts to set up @server to listen for connections on
1852  * @address.
1853  *
1854  * If @options includes %SOUP_SERVER_LISTEN_HTTPS, and @server has
1855  * been configured for TLS, then @server will listen for https
1856  * connections on this port. Otherwise it will listen for plain http.
1857  *
1858  * You may call this method (along with the other "listen" methods)
1859  * any number of times on a server, if you want to listen on multiple
1860  * ports, or set up both http and https service.
1861  *
1862  * After calling this method, @server will begin accepting and
1863  * processing connections as soon as the appropriate #GMainContext is
1864  * run.
1865  *
1866  * Note that #SoupServer never makes use of dual IPv4/IPv6 sockets; if
1867  * @address is an IPv6 address, it will only accept IPv6 connections.
1868  * You must configure IPv4 listening separately.
1869  *
1870  * Return value: %TRUE on success, %FALSE if @address could not be
1871  * bound or any other error occurred (in which case @error will be
1872  * set).
1873  *
1874  * Since: 2.48
1875  **/
1876 gboolean
1877 soup_server_listen (SoupServer *server, GSocketAddress *address,
1878                     SoupServerListenOptions options,
1879                     GError **error)
1880 {
1881         SoupServerPrivate *priv;
1882         SoupSocket *listener;
1883         SoupAddress *saddr;
1884         gboolean success;
1885
1886         g_return_val_if_fail (SOUP_IS_SERVER (server), FALSE);
1887         g_return_val_if_fail (!(options & SOUP_SERVER_LISTEN_IPV4_ONLY) &&
1888                               !(options & SOUP_SERVER_LISTEN_IPV6_ONLY), FALSE);
1889
1890         priv = soup_server_get_instance_private (server);
1891         g_return_val_if_fail (priv->disposed == FALSE, FALSE);
1892
1893         saddr = soup_address_new_from_gsockaddr (address);
1894         listener = soup_socket_new (SOUP_SOCKET_LOCAL_ADDRESS, saddr,
1895                                     SOUP_SOCKET_USE_THREAD_CONTEXT, TRUE,
1896                                     SOUP_SOCKET_IPV6_ONLY, TRUE,
1897                                     NULL);
1898
1899         success = soup_server_listen_internal (server, listener, options, error);
1900         g_object_unref (listener);
1901         g_object_unref (saddr);
1902
1903         return success;
1904 }
1905
1906 static gboolean
1907 soup_server_listen_ipv4_ipv6 (SoupServer *server,
1908                               GInetAddress *iaddr4,
1909                               GInetAddress *iaddr6,
1910                               guint port,
1911                               SoupServerListenOptions options,
1912                               GError **error)
1913 {
1914         SoupServerPrivate *priv = soup_server_get_instance_private (server);
1915         GSocketAddress *addr4, *addr6;
1916         GError *my_error = NULL;
1917         SoupSocket *v4sock;
1918         guint v4port;
1919
1920         g_return_val_if_fail (iaddr4 != NULL || iaddr6 != NULL, FALSE);
1921
1922         options &= ~(SOUP_SERVER_LISTEN_IPV4_ONLY | SOUP_SERVER_LISTEN_IPV6_ONLY);
1923
1924  try_again:
1925         if (iaddr4) {
1926                 addr4 = g_inet_socket_address_new (iaddr4, port);
1927                 if (!soup_server_listen (server, addr4, options, error)) {
1928                         g_object_unref (addr4);
1929                         return FALSE;
1930                 }
1931                 g_object_unref (addr4);
1932
1933                 v4sock = priv->listeners->data;
1934                 v4port = soup_address_get_port (soup_socket_get_local_address (v4sock));
1935         } else {
1936                 v4sock = NULL;
1937                 v4port = port;
1938         }
1939
1940         if (!iaddr6)
1941                 return TRUE;
1942
1943         addr6 = g_inet_socket_address_new (iaddr6, v4port);
1944         if (soup_server_listen (server, addr6, options, &my_error)) {
1945                 g_object_unref (addr6);
1946                 return TRUE;
1947         }
1948         g_object_unref (addr6);
1949
1950         if (v4sock && g_error_matches (my_error, G_IO_ERROR,
1951 #if GLIB_CHECK_VERSION (2, 41, 0)
1952                                        G_IO_ERROR_NOT_SUPPORTED
1953 #else
1954                                        G_IO_ERROR_FAILED
1955 #endif
1956                                        )) {
1957                 /* No IPv6 support, but IPV6_ONLY wasn't specified, so just
1958                  * ignore the failure.
1959                  */
1960                 g_error_free (my_error);
1961                 return TRUE;
1962         }
1963
1964         if (v4sock) {
1965                 priv->listeners = g_slist_remove (priv->listeners, v4sock);
1966                 soup_socket_disconnect (v4sock);
1967                 g_object_unref (v4sock);
1968         }
1969
1970         if (port == 0 && g_error_matches (my_error, G_IO_ERROR, G_IO_ERROR_ADDRESS_IN_USE)) {
1971                 /* The randomly-assigned IPv4 port was in use on the IPv6 side... Try again */
1972                 g_clear_error (&my_error);
1973                 goto try_again;
1974         }
1975
1976         g_propagate_error (error, my_error);
1977         return FALSE;
1978 }
1979
1980 /**
1981  * soup_server_listen_all:
1982  * @server: a #SoupServer
1983  * @port: the port to listen on, or 0
1984  * @options: listening options for this server
1985  * @error: return location for a #GError
1986  *
1987  * This attempts to set up @server to listen for connections on all
1988  * interfaces on the system. (That is, it listens on the addresses
1989  * <literal>0.0.0.0</literal> and/or <literal>::</literal>, depending
1990  * on whether @options includes %SOUP_SERVER_LISTEN_IPV4_ONLY,
1991  * %SOUP_SERVER_LISTEN_IPV6_ONLY, or neither.) If @port is specified,
1992  * @server will listen on that port. If it is 0, @server will find an
1993  * unused port to listen on. (In that case, you can use
1994  * soup_server_get_uris() to find out what port it ended up choosing.)
1995  *
1996  * See soup_server_listen() for more details.
1997  *
1998  * Return value: %TRUE on success, %FALSE if @port could not be bound
1999  * or any other error occurred (in which case @error will be set).
2000  *
2001  * Since: 2.48
2002  **/
2003 gboolean 
2004 soup_server_listen_all (SoupServer *server, guint port,
2005                         SoupServerListenOptions options,
2006                         GError **error)
2007 {
2008         GInetAddress *iaddr4, *iaddr6;
2009         gboolean success;
2010
2011         g_return_val_if_fail (SOUP_IS_SERVER (server), FALSE);
2012         g_return_val_if_fail (!(options & SOUP_SERVER_LISTEN_IPV4_ONLY) ||
2013                               !(options & SOUP_SERVER_LISTEN_IPV6_ONLY), FALSE);
2014
2015         if (options & SOUP_SERVER_LISTEN_IPV6_ONLY)
2016                 iaddr4 = NULL;
2017         else
2018                 iaddr4 = g_inet_address_new_any (G_SOCKET_FAMILY_IPV4);
2019
2020         if (options & SOUP_SERVER_LISTEN_IPV4_ONLY)
2021                 iaddr6 = NULL;
2022         else
2023                 iaddr6 = g_inet_address_new_any (G_SOCKET_FAMILY_IPV6);
2024
2025         success = soup_server_listen_ipv4_ipv6 (server, iaddr4, iaddr6,
2026                                                 port, options, error);
2027
2028         g_clear_object (&iaddr4);
2029         g_clear_object (&iaddr6);
2030
2031         return success;
2032 }
2033
2034 /**
2035  * soup_server_listen_local:
2036  * @server: a #SoupServer
2037  * @port: the port to listen on, or 0
2038  * @options: listening options for this server
2039  * @error: return location for a #GError
2040  *
2041  * This attempts to set up @server to listen for connections on
2042  * "localhost" (that is, <literal>127.0.0.1</literal> and/or
2043  * <literal>::1</literal>, depending on whether @options includes
2044  * %SOUP_SERVER_LISTEN_IPV4_ONLY, %SOUP_SERVER_LISTEN_IPV6_ONLY, or
2045  * neither). If @port is specified, @server will listen on that port.
2046  * If it is 0, @server will find an unused port to listen on. (In that
2047  * case, you can use soup_server_get_uris() to find out what port it
2048  * ended up choosing.)
2049  *
2050  * See soup_server_listen() for more details.
2051  *
2052  * Return value: %TRUE on success, %FALSE if @port could not be bound
2053  * or any other error occurred (in which case @error will be set).
2054  *
2055  * Since: 2.48
2056  **/
2057 gboolean
2058 soup_server_listen_local (SoupServer *server, guint port,
2059                           SoupServerListenOptions options,
2060                           GError **error)
2061 {
2062         GInetAddress *iaddr4, *iaddr6;
2063         gboolean success;
2064
2065         g_return_val_if_fail (SOUP_IS_SERVER (server), FALSE);
2066         g_return_val_if_fail (!(options & SOUP_SERVER_LISTEN_IPV4_ONLY) ||
2067                               !(options & SOUP_SERVER_LISTEN_IPV6_ONLY), FALSE);
2068
2069         if (options & SOUP_SERVER_LISTEN_IPV6_ONLY)
2070                 iaddr4 = NULL;
2071         else
2072                 iaddr4 = g_inet_address_new_loopback (G_SOCKET_FAMILY_IPV4);
2073
2074         if (options & SOUP_SERVER_LISTEN_IPV4_ONLY)
2075                 iaddr6 = NULL;
2076         else
2077                 iaddr6 = g_inet_address_new_loopback (G_SOCKET_FAMILY_IPV6);
2078
2079         success = soup_server_listen_ipv4_ipv6 (server, iaddr4, iaddr6,
2080                                                 port, options, error);
2081
2082         g_clear_object (&iaddr4);
2083         g_clear_object (&iaddr6);
2084
2085         return success;
2086 }
2087
2088 /**
2089  * soup_server_listen_socket:
2090  * @server: a #SoupServer
2091  * @socket: a listening #GSocket
2092  * @options: listening options for this server
2093  * @error: return location for a #GError
2094  *
2095  * This attempts to set up @server to listen for connections on
2096  * @socket.
2097  *
2098  * See soup_server_listen() for more details.
2099  *
2100  * Return value: %TRUE on success, %FALSE if an error occurred (in
2101  * which case @error will be set).
2102  *
2103  * Since: 2.48
2104  **/
2105 gboolean
2106 soup_server_listen_socket (SoupServer *server, GSocket *socket,
2107                            SoupServerListenOptions options,
2108                            GError **error)
2109 {
2110         SoupServerPrivate *priv;
2111         SoupSocket *listener;
2112         gboolean success;
2113
2114         g_return_val_if_fail (SOUP_IS_SERVER (server), FALSE);
2115         g_return_val_if_fail (G_IS_SOCKET (socket), FALSE);
2116         g_return_val_if_fail (!(options & SOUP_SERVER_LISTEN_IPV4_ONLY) &&
2117                               !(options & SOUP_SERVER_LISTEN_IPV6_ONLY), FALSE);
2118
2119         priv = soup_server_get_instance_private (server);
2120         g_return_val_if_fail (priv->disposed == FALSE, FALSE);
2121
2122         listener = g_initable_new (SOUP_TYPE_SOCKET, NULL, error,
2123                                    SOUP_SOCKET_GSOCKET, socket,
2124                                    SOUP_SOCKET_USE_THREAD_CONTEXT, TRUE,
2125                                    SOUP_SOCKET_IPV6_ONLY, TRUE,
2126                                    NULL);
2127         if (!listener)
2128                 return FALSE;
2129
2130         success = soup_server_listen_internal (server, listener, options, error);
2131         g_object_unref (listener);
2132
2133         return success;
2134 }
2135
2136 /**
2137  * soup_server_listen_fd:
2138  * @server: a #SoupServer
2139  * @fd: the file descriptor of a listening socket
2140  * @options: listening options for this server
2141  * @error: return location for a #GError
2142  *
2143  * This attempts to set up @server to listen for connections on
2144  * @fd.
2145  *
2146  * See soup_server_listen() for more details.
2147  *
2148  * Note that @server will close @fd when you free it or call
2149  * soup_server_disconnect().
2150  *
2151  * Return value: %TRUE on success, %FALSE if an error occurred (in
2152  * which case @error will be set).
2153  *
2154  * Since: 2.48
2155  **/
2156 gboolean
2157 soup_server_listen_fd (SoupServer *server, int fd,
2158                        SoupServerListenOptions options,
2159                        GError **error)
2160 {
2161         SoupServerPrivate *priv;
2162         SoupSocket *listener;
2163         gboolean success;
2164
2165         g_return_val_if_fail (SOUP_IS_SERVER (server), FALSE);
2166         g_return_val_if_fail (!(options & SOUP_SERVER_LISTEN_IPV4_ONLY) &&
2167                               !(options & SOUP_SERVER_LISTEN_IPV6_ONLY), FALSE);
2168
2169         priv = soup_server_get_instance_private (server);
2170         g_return_val_if_fail (priv->disposed == FALSE, FALSE);
2171
2172         listener = g_initable_new (SOUP_TYPE_SOCKET, NULL, error,
2173                                    SOUP_SOCKET_FD, fd,
2174                                    SOUP_SOCKET_USE_THREAD_CONTEXT, TRUE,
2175                                    SOUP_SOCKET_IPV6_ONLY, TRUE,
2176                                    NULL);
2177         if (!listener)
2178                 return FALSE;
2179
2180         success = soup_server_listen_internal (server, listener, options, error);
2181         g_object_unref (listener);
2182
2183         return success;
2184 }
2185
2186 /**
2187  * soup_server_get_uris:
2188  * @server: a #SoupServer
2189  *
2190  * Gets a list of URIs corresponding to the interfaces @server is
2191  * listening on. These will contain IP addresses, not hostnames, and
2192  * will also indicate whether the given listener is http or https.
2193  *
2194  * Note that if you used soup_server_listen_all(), the returned URIs
2195  * will use the addresses <literal>0.0.0.0</literal> and
2196  * <literal>::</literal>, rather than actually returning separate URIs
2197  * for each interface on the system.
2198  *
2199  * Return value: (transfer full) (element-type Soup.URI): a list of
2200  * #SoupURIs, which you must free when you are done with it.
2201  *
2202  * Since: 2.48
2203  */
2204 GSList *
2205 soup_server_get_uris (SoupServer *server)
2206 {
2207         SoupServerPrivate *priv;
2208         GSList *uris, *l;
2209         SoupSocket *listener;
2210         SoupAddress *addr;
2211         SoupURI *uri;
2212         gpointer creds;
2213
2214         g_return_val_if_fail (SOUP_IS_SERVER (server), NULL);
2215         priv = soup_server_get_instance_private (server);
2216
2217         for (l = priv->listeners, uris = NULL; l; l = l->next) {
2218                 listener = l->data;
2219                 addr = soup_socket_get_local_address (listener);
2220                 g_object_get (G_OBJECT (listener), SOUP_SOCKET_SSL_CREDENTIALS, &creds, NULL);
2221
2222                 uri = soup_uri_new (NULL);
2223                 soup_uri_set_scheme (uri, creds ? "https" : "http");
2224                 soup_uri_set_host (uri, soup_address_get_physical (addr));
2225                 soup_uri_set_port (uri, soup_address_get_port (addr));
2226                 soup_uri_set_path (uri, "/");
2227
2228                 uris = g_slist_prepend (uris, uri);
2229         }
2230
2231         return uris;
2232 }
2233
2234 /**
2235  * soup_server_get_async_context:
2236  * @server: a #SoupServer
2237  *
2238  * Gets @server's async_context, if you are using the old API. (With
2239  * the new API, the server runs in the thread's thread-default
2240  * #GMainContext, regardless of what this method returns.)
2241  *
2242  * This does not add a ref to the context, so you will need to ref it
2243  * yourself if you want it to outlive its server.
2244  *
2245  * Return value: (nullable) (transfer none): @server's #GMainContext,
2246  * which may be %NULL
2247  *
2248  * Deprecated: If you are using soup_server_listen(), etc, then
2249  * the server listens on the thread-default #GMainContext, and this
2250  * property is ignored.
2251  **/
2252 GMainContext *
2253 soup_server_get_async_context (SoupServer *server)
2254 {
2255         SoupServerPrivate *priv;
2256
2257         g_return_val_if_fail (SOUP_IS_SERVER (server), NULL);
2258         priv = soup_server_get_instance_private (server);
2259
2260         return priv->async_context;
2261 }
2262
2263 /**
2264  * SoupClientContext:
2265  *
2266  * A #SoupClientContext provides additional information about the
2267  * client making a particular request. In particular, you can use
2268  * soup_client_context_get_auth_domain() and
2269  * soup_client_context_get_auth_user() to determine if HTTP
2270  * authentication was used successfully.
2271  *
2272  * soup_client_context_get_remote_address() and/or
2273  * soup_client_context_get_host() can be used to get information for
2274  * logging or debugging purposes. soup_client_context_get_gsocket() may
2275  * also be of use in some situations (eg, tracking when multiple
2276  * requests are made on the same connection).
2277  **/
2278 G_DEFINE_BOXED_TYPE (SoupClientContext, soup_client_context, soup_client_context_ref, soup_client_context_unref)
2279
2280 /**
2281  * soup_client_context_get_socket:
2282  * @client: a #SoupClientContext
2283  *
2284  * Retrieves the #SoupSocket that @client is associated with.
2285  *
2286  * If you are using this method to observe when multiple requests are
2287  * made on the same persistent HTTP connection (eg, as the ntlm-test
2288  * test program does), you will need to pay attention to socket
2289  * destruction as well (either by using weak references, or by
2290  * connecting to the #SoupSocket::disconnected signal), so that you do
2291  * not get fooled when the allocator reuses the memory address of a
2292  * previously-destroyed socket to represent a new socket.
2293  *
2294  * Return value: (transfer none): the #SoupSocket that @client is
2295  * associated with.
2296  *
2297  * Deprecated: use soup_client_context_get_gsocket(), which returns
2298  * a #GSocket.
2299  **/
2300 SoupSocket *
2301 soup_client_context_get_socket (SoupClientContext *client)
2302 {
2303         g_return_val_if_fail (client != NULL, NULL);
2304
2305         return client->sock;
2306 }
2307
2308 /**
2309  * soup_client_context_get_gsocket:
2310  * @client: a #SoupClientContext
2311  *
2312  * Retrieves the #GSocket that @client is associated with.
2313  *
2314  * If you are using this method to observe when multiple requests are
2315  * made on the same persistent HTTP connection (eg, as the ntlm-test
2316  * test program does), you will need to pay attention to socket
2317  * destruction as well (eg, by using weak references), so that you do
2318  * not get fooled when the allocator reuses the memory address of a
2319  * previously-destroyed socket to represent a new socket.
2320  *
2321  * Return value: (nullable) (transfer none): the #GSocket that @client is
2322  * associated with, %NULL if you used soup_server_accept_iostream().
2323  *
2324  * Since: 2.48
2325  **/
2326 GSocket *
2327 soup_client_context_get_gsocket (SoupClientContext *client)
2328 {
2329         g_return_val_if_fail (client != NULL, NULL);
2330
2331         return client->gsock;
2332 }
2333
2334 /**
2335  * soup_client_context_get_address:
2336  * @client: a #SoupClientContext
2337  *
2338  * Retrieves the #SoupAddress associated with the remote end
2339  * of a connection.
2340  *
2341  * Return value: (nullable) (transfer none): the #SoupAddress
2342  * associated with the remote end of a connection, it may be
2343  * %NULL if you used soup_server_accept_iostream().
2344  *
2345  * Deprecated: Use soup_client_context_get_remote_address(), which returns
2346  * a #GSocketAddress.
2347  **/
2348 SoupAddress *
2349 soup_client_context_get_address (SoupClientContext *client)
2350 {
2351         g_return_val_if_fail (client != NULL, NULL);
2352
2353         return soup_socket_get_remote_address (client->sock);
2354 }
2355
2356 /**
2357  * soup_client_context_get_remote_address:
2358  * @client: a #SoupClientContext
2359  *
2360  * Retrieves the #GSocketAddress associated with the remote end
2361  * of a connection.
2362  *
2363  * Return value: (nullable) (transfer none): the #GSocketAddress
2364  * associated with the remote end of a connection, it may be
2365  * %NULL if you used soup_server_accept_iostream().
2366  *
2367  * Since: 2.48
2368  **/
2369 GSocketAddress *
2370 soup_client_context_get_remote_address (SoupClientContext *client)
2371 {
2372         g_return_val_if_fail (client != NULL, NULL);
2373
2374         if (client->remote_addr)
2375                 return client->remote_addr;
2376
2377         client->remote_addr = client->gsock ?
2378                 g_socket_get_remote_address (client->gsock, NULL) :
2379                 soup_address_get_gsockaddr (soup_socket_get_remote_address (client->sock));
2380
2381         return client->remote_addr;
2382 }
2383
2384 /**
2385  * soup_client_context_get_local_address:
2386  * @client: a #SoupClientContext
2387  *
2388  * Retrieves the #GSocketAddress associated with the local end
2389  * of a connection.
2390  *
2391  * Return value: (nullable) (transfer none): the #GSocketAddress
2392  * associated with the local end of a connection, it may be
2393  * %NULL if you used soup_server_accept_iostream().
2394  *
2395  * Since: 2.48
2396  **/
2397 GSocketAddress *
2398 soup_client_context_get_local_address (SoupClientContext *client)
2399 {
2400         g_return_val_if_fail (client != NULL, NULL);
2401
2402         if (client->local_addr)
2403                 return client->local_addr;
2404
2405         client->local_addr = client->gsock ?
2406                 g_socket_get_local_address (client->gsock, NULL) :
2407                 soup_address_get_gsockaddr (soup_socket_get_local_address (client->sock));
2408
2409         return client->local_addr;
2410 }
2411
2412 /**
2413  * soup_client_context_get_host:
2414  * @client: a #SoupClientContext
2415  *
2416  * Retrieves the IP address associated with the remote end of a
2417  * connection.
2418  *
2419  * Return value: (nullable): the IP address associated with the remote
2420  * end of a connection, it may be %NULL if you used
2421  * soup_server_accept_iostream().
2422  **/
2423 const char *
2424 soup_client_context_get_host (SoupClientContext *client)
2425 {
2426         g_return_val_if_fail (client != NULL, NULL);
2427
2428         if (client->remote_ip)
2429                 return client->remote_ip;
2430
2431         if (client->gsock) {
2432                 GSocketAddress *addr = soup_client_context_get_remote_address (client);
2433                 GInetAddress *iaddr;
2434
2435                 if (!addr || !G_IS_INET_SOCKET_ADDRESS (addr))
2436                         return NULL;
2437                 iaddr = g_inet_socket_address_get_address (G_INET_SOCKET_ADDRESS (addr));
2438                 client->remote_ip = g_inet_address_to_string (iaddr);
2439         } else {
2440                 SoupAddress *addr;
2441
2442                 G_GNUC_BEGIN_IGNORE_DEPRECATIONS;
2443                 addr = soup_client_context_get_address (client);
2444                 G_GNUC_END_IGNORE_DEPRECATIONS;
2445                 client->remote_ip = g_strdup (soup_address_get_physical (addr));
2446         }
2447
2448         return client->remote_ip;
2449 }
2450
2451 /**
2452  * soup_client_context_get_auth_domain:
2453  * @client: a #SoupClientContext
2454  *
2455  * Checks whether the request associated with @client has been
2456  * authenticated, and if so returns the #SoupAuthDomain that
2457  * authenticated it.
2458  *
2459  * Return value: (transfer none) (nullable): a #SoupAuthDomain, or
2460  * %NULL if the request was not authenticated.
2461  **/
2462 SoupAuthDomain *
2463 soup_client_context_get_auth_domain (SoupClientContext *client)
2464 {
2465         g_return_val_if_fail (client != NULL, NULL);
2466
2467         return client->auth_domain;
2468 }
2469
2470 /**
2471  * soup_client_context_get_auth_user:
2472  * @client: a #SoupClientContext
2473  *
2474  * Checks whether the request associated with @client has been
2475  * authenticated, and if so returns the username that the client
2476  * authenticated as.
2477  *
2478  * Return value: (nullable): the authenticated-as user, or %NULL if
2479  * the request was not authenticated.
2480  **/
2481 const char *
2482 soup_client_context_get_auth_user (SoupClientContext *client)
2483 {
2484         g_return_val_if_fail (client != NULL, NULL);
2485
2486         return client->auth_user;
2487 }
2488
2489 /**
2490  * soup_client_context_steal_connection:
2491  * @client: a #SoupClientContext
2492  *
2493  * "Steals" the HTTP connection associated with @client from its
2494  * #SoupServer. This happens immediately, regardless of the current
2495  * state of the connection; if the response to the current
2496  * #SoupMessage has not yet finished being sent, then it will be
2497  * discarded; you can steal the connection from a
2498  * #SoupMessage:wrote-informational or #SoupMessage:wrote-body signal
2499  * handler if you need to wait for part or all of the response to be
2500  * sent.
2501  *
2502  * Note that when calling this function from C, @client will most
2503  * likely be freed as a side effect.
2504  *
2505  * Return value: (transfer full): the #GIOStream formerly associated
2506  *   with @client (or %NULL if @client was no longer associated with a
2507  *   connection). No guarantees are made about what kind of #GIOStream
2508  *   is returned.
2509  *
2510  * Since: 2.50
2511  **/
2512 GIOStream *
2513 soup_client_context_steal_connection (SoupClientContext *client)
2514 {
2515         GIOStream *stream;
2516
2517         g_return_val_if_fail (client != NULL, NULL);
2518
2519         soup_client_context_ref (client);
2520
2521         stream = soup_message_io_steal (client->msg);
2522         if (stream) {
2523                 g_object_set_data_full (G_OBJECT (stream), "GSocket",
2524                                         soup_socket_steal_gsocket (client->sock),
2525                                         g_object_unref);
2526         }
2527
2528         socket_disconnected (client->sock, client);
2529         soup_client_context_unref (client);
2530
2531         return stream;
2532 }
2533
2534
2535 /**
2536  * SoupServerCallback:
2537  * @server: the #SoupServer
2538  * @msg: the message being processed
2539  * @path: the path component of @msg's Request-URI
2540  * @query: (element-type utf8 utf8) (allow-none): the parsed query
2541  *   component of @msg's Request-URI
2542  * @client: additional contextual information about the client
2543  * @user_data: the data passed to soup_server_add_handler() or
2544  *   soup_server_add_early_handler().
2545  *
2546  * A callback used to handle requests to a #SoupServer.
2547  *
2548  * @path and @query contain the likewise-named components of the
2549  * Request-URI, subject to certain assumptions. By default,
2550  * #SoupServer decodes all percent-encoding in the URI path, such that
2551  * "/foo%<!-- -->2Fbar" is treated the same as "/foo/bar". If your
2552  * server is serving resources in some non-POSIX-filesystem namespace,
2553  * you may want to distinguish those as two distinct paths. In that
2554  * case, you can set the %SOUP_SERVER_RAW_PATHS property when creating
2555  * the #SoupServer, and it will leave those characters undecoded. (You
2556  * may want to call soup_uri_normalize() to decode any percent-encoded
2557  * characters that you aren't handling specially.)
2558  *
2559  * @query contains the query component of the Request-URI parsed
2560  * according to the rules for HTML form handling. Although this is the
2561  * only commonly-used query string format in HTTP, there is nothing
2562  * that actually requires that HTTP URIs use that format; if your
2563  * server needs to use some other format, you can just ignore @query,
2564  * and call soup_message_get_uri() and parse the URI's query field
2565  * yourself.
2566  *
2567  * See soup_server_add_handler() and soup_server_add_early_handler()
2568  * for details of what handlers can/should do.
2569  **/
2570
2571 static SoupServerHandler *
2572 get_or_create_handler (SoupServer *server, const char *exact_path)
2573 {
2574         SoupServerPrivate *priv = soup_server_get_instance_private (server);
2575         SoupServerHandler *handler;
2576
2577         exact_path = NORMALIZED_PATH (exact_path);
2578
2579         handler = soup_path_map_lookup (priv->handlers, exact_path);
2580         if (handler && !strcmp (handler->path, exact_path))
2581                 return handler;
2582
2583         handler = g_slice_new0 (SoupServerHandler);
2584         handler->path = g_strdup (exact_path);
2585         soup_path_map_add (priv->handlers, exact_path, handler);
2586
2587         return handler;
2588 }
2589
2590 /**
2591  * soup_server_add_handler:
2592  * @server: a #SoupServer
2593  * @path: (allow-none): the toplevel path for the handler
2594  * @callback: callback to invoke for requests under @path
2595  * @user_data: data for @callback
2596  * @destroy: destroy notifier to free @user_data
2597  *
2598  * Adds a handler to @server for requests under @path. If @path is
2599  * %NULL or "/", then this will be the default handler for all
2600  * requests that don't have a more specific handler. (Note though that
2601  * if you want to handle requests to the special "*" URI, you must
2602  * explicitly register a handler for "*"; the default handler will not
2603  * be used for that case.)
2604  *
2605  * For requests under @path (that have not already been assigned a
2606  * status code by a #SoupAuthDomain, an early #SoupServerHandler, or a
2607  * signal handler), @callback will be invoked after receiving the
2608  * request body; the message's #SoupMessage:method,
2609  * #SoupMessage:request-headers, and #SoupMessage:request-body fields
2610  * will be filled in.
2611  *
2612  * After determining what to do with the request, the callback must at
2613  * a minimum call soup_message_set_status() (or
2614  * soup_message_set_status_full()) on the message to set the response
2615  * status code. Additionally, it may set response headers and/or fill
2616  * in the response body.
2617  *
2618  * If the callback cannot fully fill in the response before returning
2619  * (eg, if it needs to wait for information from a database, or
2620  * another network server), it should call soup_server_pause_message()
2621  * to tell @server to not send the response right away. When the
2622  * response is ready, call soup_server_unpause_message() to cause it
2623  * to be sent.
2624  *
2625  * To send the response body a bit at a time using "chunked" encoding,
2626  * first call soup_message_headers_set_encoding() to set
2627  * %SOUP_ENCODING_CHUNKED on the #SoupMessage:response-headers. Then call
2628  * soup_message_body_append() (or soup_message_body_append_buffer())
2629  * to append each chunk as it becomes ready, and
2630  * soup_server_unpause_message() to make sure it's running. (The
2631  * server will automatically pause the message if it is using chunked
2632  * encoding but no more chunks are available.) When you are done, call
2633  * soup_message_body_complete() to indicate that no more chunks are
2634  * coming.
2635  **/
2636 void
2637 soup_server_add_handler (SoupServer            *server,
2638                          const char            *path,
2639                          SoupServerCallback     callback,
2640                          gpointer               user_data,
2641                          GDestroyNotify         destroy)
2642 {
2643         SoupServerHandler *handler;
2644
2645         g_return_if_fail (SOUP_IS_SERVER (server));
2646         g_return_if_fail (callback != NULL);
2647
2648         handler = get_or_create_handler (server, path);
2649         if (handler->destroy)
2650                 handler->destroy (handler->user_data);
2651
2652         handler->callback   = callback;
2653         handler->destroy    = destroy;
2654         handler->user_data  = user_data;
2655 }
2656
2657 /**
2658  * soup_server_add_early_handler:
2659  * @server: a #SoupServer
2660  * @path: (allow-none): the toplevel path for the handler
2661  * @callback: callback to invoke for requests under @path
2662  * @user_data: data for @callback
2663  * @destroy: destroy notifier to free @user_data
2664  *
2665  * Adds an "early" handler to @server for requests under @path. Note
2666  * that "normal" and "early" handlers are matched up together, so if
2667  * you add a normal handler for "/foo" and an early handler for
2668  * "/foo/bar", then a request to "/foo/bar" (or any path below it)
2669  * will run only the early handler. (But if you add both handlers at
2670  * the same path, then both will get run.)
2671  *
2672  * For requests under @path (that have not already been assigned a
2673  * status code by a #SoupAuthDomain or a signal handler), @callback
2674  * will be invoked after receiving the request headers, but before
2675  * receiving the request body; the message's #SoupMessage:method and
2676  * #SoupMessage:request-headers fields will be filled in.
2677  *
2678  * Early handlers are generally used for processing requests with
2679  * request bodies in a streaming fashion. If you determine that the
2680  * request will contain a message body, normally you would call
2681  * soup_message_body_set_accumulate() on the message's
2682  * #SoupMessage:request-body to turn off request-body accumulation,
2683  * and connect to the message's #SoupMessage::got-chunk signal to
2684  * process each chunk as it comes in.
2685  *
2686  * To complete the message processing after the full message body has
2687  * been read, you can either also connect to #SoupMessage::got-body,
2688  * or else you can register a non-early handler for @path as well. As
2689  * long as you have not set the #SoupMessage:status-code by the time
2690  * #SoupMessage::got-body is emitted, the non-early handler will be
2691  * run as well.
2692  *
2693  * Since: 2.50
2694  **/
2695 void
2696 soup_server_add_early_handler (SoupServer            *server,
2697                                const char            *path,
2698                                SoupServerCallback     callback,
2699                                gpointer               user_data,
2700                                GDestroyNotify         destroy)
2701 {
2702         SoupServerHandler *handler;
2703
2704         g_return_if_fail (SOUP_IS_SERVER (server));
2705         g_return_if_fail (callback != NULL);
2706
2707         handler = get_or_create_handler (server, path);
2708         if (handler->early_destroy)
2709                 handler->early_destroy (handler->early_user_data);
2710
2711         handler->early_callback   = callback;
2712         handler->early_destroy    = destroy;
2713         handler->early_user_data  = user_data;
2714 }
2715
2716 /**
2717  * SoupServerWebsocketCallback:
2718  * @server: the #SoupServer
2719  * @path: the path component of @msg's Request-URI
2720  * @connection: the newly created WebSocket connection
2721  * @client: additional contextual information about the client
2722  * @user_data: the data passed to @soup_server_add_handler
2723  *
2724  * A callback used to handle WebSocket requests to a #SoupServer. The
2725  * callback will be invoked after sending the handshake response back
2726  * to the client (and is only invoked if the handshake was
2727  * successful).
2728  *
2729  * @path contains the path of the Request-URI, subject to the same
2730  * rules as #SoupServerCallback (qv).
2731  **/
2732
2733 /**
2734  * soup_server_add_websocket_handler:
2735  * @server: a #SoupServer
2736  * @path: (allow-none): the toplevel path for the handler
2737  * @origin: (allow-none): the origin of the connection
2738  * @protocols: (allow-none) (array zero-terminated=1): the protocols
2739  *   supported by this handler
2740  * @callback: callback to invoke for successful WebSocket requests under @path
2741  * @user_data: data for @callback
2742  * @destroy: destroy notifier to free @user_data
2743  *
2744  * Adds a WebSocket handler to @server for requests under @path. (If
2745  * @path is %NULL or "/", then this will be the default handler for
2746  * all requests that don't have a more specific handler.)
2747  *
2748  * When a path has a WebSocket handler registered, @server will check
2749  * incoming requests for WebSocket handshakes after all other handlers
2750  * have run (unless some earlier handler has already set a status code
2751  * on the message), and update the request's status, response headers,
2752  * and response body accordingly.
2753  *
2754  * If @origin is non-%NULL, then only requests containing a matching
2755  * "Origin" header will be accepted. If @protocols is non-%NULL, then
2756  * only requests containing a compatible "Sec-WebSocket-Protocols"
2757  * header will be accepted. More complicated requirements can be
2758  * handled by adding a normal handler to @path, and having it perform
2759  * whatever checks are needed (possibly calling
2760  * soup_server_check_websocket_handshake() one or more times), and
2761  * setting a failure status code if the handshake should be rejected.
2762  **/
2763 void
2764 soup_server_add_websocket_handler (SoupServer                   *server,
2765                                    const char                   *path,
2766                                    const char                   *origin,
2767                                    char                        **protocols,
2768                                    SoupServerWebsocketCallback   callback,
2769                                    gpointer                      user_data,
2770                                    GDestroyNotify                destroy)
2771 {
2772         SoupServerHandler *handler;
2773
2774         g_return_if_fail (SOUP_IS_SERVER (server));
2775         g_return_if_fail (callback != NULL);
2776
2777         handler = get_or_create_handler (server, path);
2778         if (handler->websocket_destroy)
2779                 handler->websocket_destroy (handler->websocket_user_data);
2780         if (handler->websocket_origin)
2781                 g_free (handler->websocket_origin);
2782         if (handler->websocket_protocols)
2783                 g_strfreev (handler->websocket_protocols);
2784         g_list_free_full (handler->websocket_extensions, g_object_unref);
2785
2786         handler->websocket_callback   = callback;
2787         handler->websocket_destroy    = destroy;
2788         handler->websocket_user_data  = user_data;
2789         handler->websocket_origin     = g_strdup (origin);
2790         handler->websocket_protocols  = g_strdupv (protocols);
2791         handler->websocket_extensions = NULL;
2792 }
2793
2794 /**
2795  * soup_server_remove_handler:
2796  * @server: a #SoupServer
2797  * @path: the toplevel path for the handler
2798  *
2799  * Removes all handlers (early and normal) registered at @path.
2800  **/
2801 void
2802 soup_server_remove_handler (SoupServer *server, const char *path)
2803 {
2804         SoupServerPrivate *priv;
2805
2806         g_return_if_fail (SOUP_IS_SERVER (server));
2807         priv = soup_server_get_instance_private (server);
2808
2809         soup_path_map_remove (priv->handlers, NORMALIZED_PATH (path));
2810 }
2811
2812 /**
2813  * soup_server_add_auth_domain:
2814  * @server: a #SoupServer
2815  * @auth_domain: a #SoupAuthDomain
2816  *
2817  * Adds an authentication domain to @server. Each auth domain will
2818  * have the chance to require authentication for each request that
2819  * comes in; normally auth domains will require authentication for
2820  * requests on certain paths that they have been set up to watch, or
2821  * that meet other criteria set by the caller. If an auth domain
2822  * determines that a request requires authentication (and the request
2823  * doesn't contain authentication), @server will automatically reject
2824  * the request with an appropriate status (401 Unauthorized or 407
2825  * Proxy Authentication Required). If the request used the
2826  * "100-continue" Expectation, @server will reject it before the
2827  * request body is sent.
2828  **/
2829 void
2830 soup_server_add_auth_domain (SoupServer *server, SoupAuthDomain *auth_domain)
2831 {
2832         SoupServerPrivate *priv;
2833
2834         g_return_if_fail (SOUP_IS_SERVER (server));
2835         priv = soup_server_get_instance_private (server);
2836
2837         priv->auth_domains = g_slist_append (priv->auth_domains, auth_domain);
2838         g_object_ref (auth_domain);
2839 }
2840
2841 /**
2842  * soup_server_remove_auth_domain:
2843  * @server: a #SoupServer
2844  * @auth_domain: a #SoupAuthDomain
2845  *
2846  * Removes @auth_domain from @server.
2847  **/
2848 void
2849 soup_server_remove_auth_domain (SoupServer *server, SoupAuthDomain *auth_domain)
2850 {
2851         SoupServerPrivate *priv;
2852
2853         g_return_if_fail (SOUP_IS_SERVER (server));
2854         priv = soup_server_get_instance_private (server);
2855
2856         priv->auth_domains = g_slist_remove (priv->auth_domains, auth_domain);
2857         g_object_unref (auth_domain);
2858 }
2859
2860 /**
2861  * soup_server_pause_message:
2862  * @server: a #SoupServer
2863  * @msg: a #SoupMessage associated with @server.
2864  *
2865  * Pauses I/O on @msg. This can be used when you need to return from
2866  * the server handler without having the full response ready yet. Use
2867  * soup_server_unpause_message() to resume I/O.
2868  *
2869  * This must only be called on #SoupMessages which were created by the
2870  * #SoupServer and are currently doing I/O, such as those passed into a
2871  * #SoupServerCallback or emitted in a #SoupServer::request-read signal.
2872  **/
2873 void
2874 soup_server_pause_message (SoupServer *server,
2875                            SoupMessage *msg)
2876 {
2877         g_return_if_fail (SOUP_IS_SERVER (server));
2878         g_return_if_fail (SOUP_IS_MESSAGE (msg));
2879
2880         soup_message_io_pause (msg);
2881 }
2882
2883 /**
2884  * soup_server_unpause_message:
2885  * @server: a #SoupServer
2886  * @msg: a #SoupMessage associated with @server.
2887  *
2888  * Resumes I/O on @msg. Use this to resume after calling
2889  * soup_server_pause_message(), or after adding a new chunk to a
2890  * chunked response.
2891  *
2892  * I/O won't actually resume until you return to the main loop.
2893  *
2894  * This must only be called on #SoupMessages which were created by the
2895  * #SoupServer and are currently doing I/O, such as those passed into a
2896  * #SoupServerCallback or emitted in a #SoupServer::request-read signal.
2897  **/
2898 void
2899 soup_server_unpause_message (SoupServer *server,
2900                              SoupMessage *msg)
2901 {
2902         g_return_if_fail (SOUP_IS_SERVER (server));
2903         g_return_if_fail (SOUP_IS_MESSAGE (msg));
2904
2905         soup_message_io_unpause (msg);
2906 }
2907
2908 /**
2909  * soup_server_add_websocket_extension:
2910  * @server: a #SoupServer
2911  * @extension_type: a #GType
2912  *
2913  * Add support for a WebSocket extension of the given @extension_type.
2914  * When a WebSocket client requests an extension of @extension_type,
2915  * a new #SoupWebsocketExtension of type @extension_type will be created
2916  * to handle the request.
2917  *
2918  * You can also add support for a WebSocket extension to the server at
2919  * construct time by using the %SOUP_SERVER_ADD_WEBSOCKET_EXTENSION property.
2920  * Note that #SoupWebsocketExtensionDeflate is supported by default, use
2921  * soup_server_remove_websocket_extension() if you want to disable it.
2922  *
2923  * Since: 2.68
2924  */
2925 void
2926 soup_server_add_websocket_extension (SoupServer *server, GType extension_type)
2927 {
2928         SoupServerPrivate *priv;
2929
2930         g_return_if_fail (SOUP_IS_SERVER (server));
2931
2932         priv = soup_server_get_instance_private (server);
2933         if (!g_type_is_a (extension_type, SOUP_TYPE_WEBSOCKET_EXTENSION)) {
2934                 g_warning ("Type '%s' is not a SoupWebsocketExtension", g_type_name (extension_type));
2935                 return;
2936         }
2937
2938         g_ptr_array_add (priv->websocket_extension_types, g_type_class_ref (extension_type));
2939 }
2940
2941 /**
2942  * soup_server_remove_websocket_extension:
2943  * @server: a #SoupServer
2944  * @extension_type: a #GType
2945  *
2946  * Removes support for WebSocket extension of type @extension_type (or any subclass of
2947  * @extension_type) from @server. You can also remove extensions enabled by default
2948  * from the server at construct time by using the %SOUP_SERVER_REMOVE_WEBSOCKET_EXTENSION
2949  * property.
2950  *
2951  * Since: 2.68
2952  */
2953 void
2954 soup_server_remove_websocket_extension (SoupServer *server, GType extension_type)
2955 {
2956         SoupServerPrivate *priv;
2957         SoupWebsocketExtensionClass *extension_class;
2958         guint i;
2959
2960         g_return_if_fail (SOUP_IS_SERVER (server));
2961
2962         priv = soup_server_get_instance_private (server);
2963         if (!g_type_is_a (extension_type, SOUP_TYPE_WEBSOCKET_EXTENSION)) {
2964                 g_warning ("Type '%s' is not a SoupWebsocketExtension", g_type_name (extension_type));
2965                 return;
2966         }
2967
2968         extension_class = g_type_class_peek (extension_type);
2969         for (i = 0; i < priv->websocket_extension_types->len; i++) {
2970                 if (priv->websocket_extension_types->pdata[i] == (gpointer)extension_class) {
2971                         g_ptr_array_remove_index (priv->websocket_extension_types, i);
2972                         break;
2973                 }
2974         }
2975 }