1 module soup.Server;
2 
3 private import gio.IOStream;
4 private import gio.Socket: GIOSocket = Socket;
5 private import gio.SocketAddress;
6 private import glib.ConstructionException;
7 private import glib.ErrorG;
8 private import glib.GException;
9 private import glib.ListSG;
10 private import glib.MainContext;
11 private import glib.Str;
12 private import gobject.ObjectG;
13 private import gobject.Signals;
14 private import soup.AuthDomain;
15 private import soup.ClientContext;
16 private import soup.Message;
17 private import soup.Socket;
18 private import soup.c.functions;
19 public  import soup.c.types;
20 private import std.algorithm;
21 
22 
23 /**
24  * #SoupServer implements a simple HTTP server.
25  * 
26  * (The following documentation describes the current #SoupServer API,
27  * available in <application>libsoup</application> 2.48 and later. See
28  * the section "<link linkend="soup-server-old-api">The Old SoupServer
29  * Listening API</link>" in the server how-to documentation for
30  * details on the older #SoupServer API.)
31  * 
32  * To begin, create a server using soup_server_new(). Add at least one
33  * handler by calling soup_server_add_handler() or
34  * soup_server_add_early_handler(); the handler will be called to
35  * process any requests underneath the path you pass. (If you want all
36  * requests to go to the same handler, just pass "/" (or %NULL) for
37  * the path.)
38  * 
39  * When a new connection is accepted (or a new request is started on
40  * an existing persistent connection), the #SoupServer will emit
41  * #SoupServer::request-started and then begin processing the request
42  * as described below, but note that once the message is assigned a
43  * #SoupMessage:status-code, then callbacks after that point will be
44  * skipped. Note also that it is not defined when the callbacks happen
45  * relative to various #SoupMessage signals.
46  * 
47  * Once the headers have been read, #SoupServer will check if there is
48  * a #SoupAuthDomain (qv) covering the Request-URI; if so, and if the
49  * message does not contain suitable authorization, then the
50  * #SoupAuthDomain will set a status of %SOUP_STATUS_UNAUTHORIZED on
51  * the message.
52  * 
53  * After checking for authorization, #SoupServer will look for "early"
54  * handlers (added with soup_server_add_early_handler()) matching the
55  * Request-URI. If one is found, it will be run; in particular, this
56  * can be used to connect to signals to do a streaming read of the
57  * request body.
58  * 
59  * (At this point, if the request headers contain "<literal>Expect:
60  * 100-continue</literal>", and a status code has been set, then
61  * #SoupServer will skip the remaining steps and return the response.
62  * If the request headers contain "<literal>Expect:
63  * 100-continue</literal>" and no status code has been set,
64  * #SoupServer will return a %SOUP_STATUS_CONTINUE status before
65  * continuing.)
66  * 
67  * The server will then read in the response body (if present). At
68  * this point, if there are no handlers at all defined for the
69  * Request-URI, then the server will return %SOUP_STATUS_NOT_FOUND to
70  * the client.
71  * 
72  * Otherwise (assuming no previous step assigned a status to the
73  * message) any "normal" handlers (added with
74  * soup_server_add_handler()) for the message's Request-URI will be
75  * run.
76  * 
77  * Then, if the path has a WebSocket handler registered (and has
78  * not yet been assigned a status), #SoupServer will attempt to
79  * validate the WebSocket handshake, filling in the response and
80  * setting a status of %SOUP_STATUS_SWITCHING_PROTOCOLS or
81  * %SOUP_STATUS_BAD_REQUEST accordingly.
82  * 
83  * If the message still has no status code at this point (and has not
84  * been paused with soup_server_pause_message()), then it will be
85  * given a status of %SOUP_STATUS_INTERNAL_SERVER_ERROR (because at
86  * least one handler ran, but returned without assigning a status).
87  * 
88  * Finally, the server will emit #SoupServer::request-finished (or
89  * #SoupServer::request-aborted if an I/O error occurred before
90  * handling was completed).
91  * 
92  * If you want to handle the special "*" URI (eg, "OPTIONS *"), you
93  * must explicitly register a handler for "*"; the default handler
94  * will not be used for that case.
95  * 
96  * If you want to process https connections in addition to (or instead
97  * of) http connections, you can either set the
98  * %SOUP_SERVER_TLS_CERTIFICATE property when creating the server, or
99  * else call soup_server_set_ssl_certificate() after creating it.
100  * 
101  * Once the server is set up, make one or more calls to
102  * soup_server_listen(), soup_server_listen_local(), or
103  * soup_server_listen_all() to tell it where to listen for
104  * connections. (All ports on a #SoupServer use the same handlers; if
105  * you need to handle some ports differently, such as returning
106  * different data for http and https, you'll need to create multiple
107  * #SoupServers, or else check the passed-in URI in the handler
108  * function.).
109  * 
110  * #SoupServer will begin processing connections as soon as you return
111  * to (or start) the main loop for the current thread-default
112  * #GMainContext.
113  */
114 public class Server : ObjectG
115 {
116 	/** the main Gtk struct */
117 	protected SoupServer* soupServer;
118 
119 	/** Get the main Gtk struct */
120 	public SoupServer* getServerStruct(bool transferOwnership = false)
121 	{
122 		if (transferOwnership)
123 			ownedRef = false;
124 		return soupServer;
125 	}
126 
127 	/** the main Gtk struct as a void* */
128 	protected override void* getStruct()
129 	{
130 		return cast(void*)soupServer;
131 	}
132 
133 	/**
134 	 * Sets our main struct and passes it to the parent class.
135 	 */
136 	public this (SoupServer* soupServer, bool ownedRef = false)
137 	{
138 		this.soupServer = soupServer;
139 		super(cast(GObject*)soupServer, ownedRef);
140 	}
141 
142 
143 	/** */
144 	public static GType getType()
145 	{
146 		return soup_server_get_type();
147 	}
148 
149 	/**
150 	 * Add a new client stream to the @server.
151 	 *
152 	 * Params:
153 	 *     stream = a #GIOStream
154 	 *     localAddr = the local #GSocketAddress associated with the @stream
155 	 *     remoteAddr = the remote #GSocketAddress associated with the @stream
156 	 *
157 	 * Returns: %TRUE on success, %FALSE if the stream could not be
158 	 *     accepted or any other error occurred (in which case @error will be
159 	 *     set).
160 	 *
161 	 * Since: 2.50
162 	 *
163 	 * Throws: GException on failure.
164 	 */
165 	public bool acceptIostream(IOStream stream, SocketAddress localAddr, SocketAddress remoteAddr)
166 	{
167 		GError* err = null;
168 
169 		auto __p = soup_server_accept_iostream(soupServer, (stream is null) ? null : stream.getIOStreamStruct(), (localAddr is null) ? null : localAddr.getSocketAddressStruct(), (remoteAddr is null) ? null : remoteAddr.getSocketAddressStruct(), &err) != 0;
170 
171 		if (err !is null)
172 		{
173 			throw new GException( new ErrorG(err) );
174 		}
175 
176 		return __p;
177 	}
178 
179 	/**
180 	 * Adds an authentication domain to @server. Each auth domain will
181 	 * have the chance to require authentication for each request that
182 	 * comes in; normally auth domains will require authentication for
183 	 * requests on certain paths that they have been set up to watch, or
184 	 * that meet other criteria set by the caller. If an auth domain
185 	 * determines that a request requires authentication (and the request
186 	 * doesn't contain authentication), @server will automatically reject
187 	 * the request with an appropriate status (401 Unauthorized or 407
188 	 * Proxy Authentication Required). If the request used the
189 	 * "100-continue" Expectation, @server will reject it before the
190 	 * request body is sent.
191 	 *
192 	 * Params:
193 	 *     authDomain = a #SoupAuthDomain
194 	 */
195 	public void addAuthDomain(AuthDomain authDomain)
196 	{
197 		soup_server_add_auth_domain(soupServer, (authDomain is null) ? null : authDomain.getAuthDomainStruct());
198 	}
199 
200 	/**
201 	 * Adds an "early" handler to @server for requests under @path. Note
202 	 * that "normal" and "early" handlers are matched up together, so if
203 	 * you add a normal handler for "/foo" and an early handler for
204 	 * "/foo/bar", then a request to "/foo/bar" (or any path below it)
205 	 * will run only the early handler. (But if you add both handlers at
206 	 * the same path, then both will get run.)
207 	 *
208 	 * For requests under @path (that have not already been assigned a
209 	 * status code by a #SoupAuthDomain or a signal handler), @callback
210 	 * will be invoked after receiving the request headers, but before
211 	 * receiving the request body; the message's #SoupMessage:method and
212 	 * #SoupMessage:request-headers fields will be filled in.
213 	 *
214 	 * Early handlers are generally used for processing requests with
215 	 * request bodies in a streaming fashion. If you determine that the
216 	 * request will contain a message body, normally you would call
217 	 * soup_message_body_set_accumulate() on the message's
218 	 * #SoupMessage:request-body to turn off request-body accumulation,
219 	 * and connect to the message's #SoupMessage::got-chunk signal to
220 	 * process each chunk as it comes in.
221 	 *
222 	 * To complete the message processing after the full message body has
223 	 * been read, you can either also connect to #SoupMessage::got-body,
224 	 * or else you can register a non-early handler for @path as well. As
225 	 * long as you have not set the #SoupMessage:status-code by the time
226 	 * #SoupMessage::got-body is emitted, the non-early handler will be
227 	 * run as well.
228 	 *
229 	 * Params:
230 	 *     path = the toplevel path for the handler
231 	 *     callback = callback to invoke for requests under @path
232 	 *     userData = data for @callback
233 	 *     destroy = destroy notifier to free @user_data
234 	 *
235 	 * Since: 2.50
236 	 */
237 	public void addEarlyHandler(string path, SoupServerCallback callback, void* userData, GDestroyNotify destroy)
238 	{
239 		soup_server_add_early_handler(soupServer, Str.toStringz(path), callback, userData, destroy);
240 	}
241 
242 	/**
243 	 * Adds a handler to @server for requests under @path. If @path is
244 	 * %NULL or "/", then this will be the default handler for all
245 	 * requests that don't have a more specific handler. (Note though that
246 	 * if you want to handle requests to the special "*" URI, you must
247 	 * explicitly register a handler for "*"; the default handler will not
248 	 * be used for that case.)
249 	 *
250 	 * For requests under @path (that have not already been assigned a
251 	 * status code by a #SoupAuthDomain, an early #SoupServerHandler, or a
252 	 * signal handler), @callback will be invoked after receiving the
253 	 * request body; the message's #SoupMessage:method,
254 	 * #SoupMessage:request-headers, and #SoupMessage:request-body fields
255 	 * will be filled in.
256 	 *
257 	 * After determining what to do with the request, the callback must at
258 	 * a minimum call soup_message_set_status() (or
259 	 * soup_message_set_status_full()) on the message to set the response
260 	 * status code. Additionally, it may set response headers and/or fill
261 	 * in the response body.
262 	 *
263 	 * If the callback cannot fully fill in the response before returning
264 	 * (eg, if it needs to wait for information from a database, or
265 	 * another network server), it should call soup_server_pause_message()
266 	 * to tell @server to not send the response right away. When the
267 	 * response is ready, call soup_server_unpause_message() to cause it
268 	 * to be sent.
269 	 *
270 	 * To send the response body a bit at a time using "chunked" encoding,
271 	 * first call soup_message_headers_set_encoding() to set
272 	 * %SOUP_ENCODING_CHUNKED on the #SoupMessage:response-headers. Then call
273 	 * soup_message_body_append() (or soup_message_body_append_buffer())
274 	 * to append each chunk as it becomes ready, and
275 	 * soup_server_unpause_message() to make sure it's running. (The
276 	 * server will automatically pause the message if it is using chunked
277 	 * encoding but no more chunks are available.) When you are done, call
278 	 * soup_message_body_complete() to indicate that no more chunks are
279 	 * coming.
280 	 *
281 	 * Params:
282 	 *     path = the toplevel path for the handler
283 	 *     callback = callback to invoke for requests under @path
284 	 *     userData = data for @callback
285 	 *     destroy = destroy notifier to free @user_data
286 	 */
287 	public void addHandler(string path, SoupServerCallback callback, void* userData, GDestroyNotify destroy)
288 	{
289 		soup_server_add_handler(soupServer, Str.toStringz(path), callback, userData, destroy);
290 	}
291 
292 	/**
293 	 * Add support for a WebSocket extension of the given @extension_type.
294 	 * When a WebSocket client requests an extension of @extension_type,
295 	 * a new #SoupWebsocketExtension of type @extension_type will be created
296 	 * to handle the request.
297 	 *
298 	 * You can also add support for a WebSocket extension to the server at
299 	 * construct time by using the %SOUP_SERVER_ADD_WEBSOCKET_EXTENSION property.
300 	 * Note that #SoupWebsocketExtensionDeflate is supported by default, use
301 	 * soup_server_remove_websocket_extension() if you want to disable it.
302 	 *
303 	 * Params:
304 	 *     extensionType = a #GType
305 	 *
306 	 * Since: 2.68
307 	 */
308 	public void addWebsocketExtension(GType extensionType)
309 	{
310 		soup_server_add_websocket_extension(soupServer, extensionType);
311 	}
312 
313 	/**
314 	 * Adds a WebSocket handler to @server for requests under @path. (If
315 	 * @path is %NULL or "/", then this will be the default handler for
316 	 * all requests that don't have a more specific handler.)
317 	 *
318 	 * When a path has a WebSocket handler registered, @server will check
319 	 * incoming requests for WebSocket handshakes after all other handlers
320 	 * have run (unless some earlier handler has already set a status code
321 	 * on the message), and update the request's status, response headers,
322 	 * and response body accordingly.
323 	 *
324 	 * If @origin is non-%NULL, then only requests containing a matching
325 	 * "Origin" header will be accepted. If @protocols is non-%NULL, then
326 	 * only requests containing a compatible "Sec-WebSocket-Protocols"
327 	 * header will be accepted. More complicated requirements can be
328 	 * handled by adding a normal handler to @path, and having it perform
329 	 * whatever checks are needed (possibly calling
330 	 * soup_server_check_websocket_handshake() one or more times), and
331 	 * setting a failure status code if the handshake should be rejected.
332 	 *
333 	 * Params:
334 	 *     path = the toplevel path for the handler
335 	 *     origin = the origin of the connection
336 	 *     protocols = the protocols
337 	 *         supported by this handler
338 	 *     callback = callback to invoke for successful WebSocket requests under @path
339 	 *     userData = data for @callback
340 	 *     destroy = destroy notifier to free @user_data
341 	 */
342 	public void addWebsocketHandler(string path, string origin, string[] protocols, SoupServerWebsocketCallback callback, void* userData, GDestroyNotify destroy)
343 	{
344 		soup_server_add_websocket_handler(soupServer, Str.toStringz(path), Str.toStringz(origin), Str.toStringzArray(protocols), callback, userData, destroy);
345 	}
346 
347 	/**
348 	 * Closes and frees @server's listening sockets. If you are using the
349 	 * old #SoupServer APIs, this also includes the effect of
350 	 * soup_server_quit().
351 	 *
352 	 * Note that if there are currently requests in progress on @server,
353 	 * that they will continue to be processed if @server's #GMainContext
354 	 * is still running.
355 	 *
356 	 * You can call soup_server_listen(), etc, after calling this function
357 	 * if you want to start listening again.
358 	 */
359 	public void disconnect()
360 	{
361 		soup_server_disconnect(soupServer);
362 	}
363 
364 	/**
365 	 * Gets @server's async_context, if you are using the old API. (With
366 	 * the new API, the server runs in the thread's thread-default
367 	 * #GMainContext, regardless of what this method returns.)
368 	 *
369 	 * This does not add a ref to the context, so you will need to ref it
370 	 * yourself if you want it to outlive its server.
371 	 *
372 	 * Deprecated: If you are using soup_server_listen(), etc, then
373 	 * the server listens on the thread-default #GMainContext, and this
374 	 * property is ignored.
375 	 *
376 	 * Returns: @server's #GMainContext,
377 	 *     which may be %NULL
378 	 */
379 	public MainContext getAsyncContext()
380 	{
381 		auto __p = soup_server_get_async_context(soupServer);
382 
383 		if(__p is null)
384 		{
385 			return null;
386 		}
387 
388 		return new MainContext(cast(GMainContext*) __p);
389 	}
390 
391 	/**
392 	 * Gets @server's listening socket, if you are using the old API.
393 	 *
394 	 * You should treat this socket as read-only; writing to it or
395 	 * modifiying it may cause @server to malfunction.
396 	 *
397 	 * Deprecated: If you are using soup_server_listen(), etc, then use
398 	 * soup_server_get_listeners() to get a list of all listening sockets,
399 	 * but note that that function returns #GSockets, not #SoupSockets.
400 	 *
401 	 * Returns: the listening socket.
402 	 */
403 	public Socket getListener()
404 	{
405 		auto __p = soup_server_get_listener(soupServer);
406 
407 		if(__p is null)
408 		{
409 			return null;
410 		}
411 
412 		return ObjectG.getDObject!(Socket)(cast(SoupSocket*) __p);
413 	}
414 
415 	/**
416 	 * Gets @server's list of listening sockets.
417 	 *
418 	 * You should treat these sockets as read-only; writing to or
419 	 * modifiying any of these sockets may cause @server to malfunction.
420 	 *
421 	 * (Beware that in contrast to the old soup_server_get_listener(), this
422 	 * function returns #GSockets, not #SoupSockets.)
423 	 *
424 	 * Returns: a
425 	 *     list of listening sockets.
426 	 */
427 	public ListSG getListeners()
428 	{
429 		auto __p = soup_server_get_listeners(soupServer);
430 
431 		if(__p is null)
432 		{
433 			return null;
434 		}
435 
436 		return new ListSG(cast(GSList*) __p);
437 	}
438 
439 	/**
440 	 * Gets the TCP port that @server is listening on, if you are using
441 	 * the old API.
442 	 *
443 	 * Deprecated: If you are using soup_server_listen(), etc, then use
444 	 * soup_server_get_uris() to get a list of all listening addresses.
445 	 *
446 	 * Returns: the port @server is listening on.
447 	 */
448 	public uint getPort()
449 	{
450 		return soup_server_get_port(soupServer);
451 	}
452 
453 	/**
454 	 * Gets a list of URIs corresponding to the interfaces @server is
455 	 * listening on. These will contain IP addresses, not hostnames, and
456 	 * will also indicate whether the given listener is http or https.
457 	 *
458 	 * Note that if you used soup_server_listen_all(), the returned URIs
459 	 * will use the addresses <literal>0.0.0.0</literal> and
460 	 * <literal>::</literal>, rather than actually returning separate URIs
461 	 * for each interface on the system.
462 	 *
463 	 * Returns: a list of
464 	 *     #SoupURIs, which you must free when you are done with it.
465 	 *
466 	 * Since: 2.48
467 	 */
468 	public ListSG getUris()
469 	{
470 		auto __p = soup_server_get_uris(soupServer);
471 
472 		if(__p is null)
473 		{
474 			return null;
475 		}
476 
477 		return new ListSG(cast(GSList*) __p, true);
478 	}
479 
480 	/**
481 	 * Checks whether @server is capable of https.
482 	 *
483 	 * In order for a server to run https, you must call
484 	 * soup_server_set_ssl_cert_file(), or set the
485 	 * #SoupServer:tls-certificate property, to provide it with a
486 	 * certificate to use.
487 	 *
488 	 * If you are using the deprecated single-listener APIs, then a return
489 	 * value of %TRUE indicates that the #SoupServer serves https
490 	 * exclusively. If you are using soup_server_listen(), etc, then a
491 	 * %TRUE return value merely indicates that the server is
492 	 * <emphasis>able</emphasis> to do https, regardless of whether it
493 	 * actually currently is or not. Use soup_server_get_uris() to see if
494 	 * it currently has any https listeners.
495 	 *
496 	 * Returns: %TRUE if @server is configured to serve https.
497 	 */
498 	public bool isHttps()
499 	{
500 		return soup_server_is_https(soupServer) != 0;
501 	}
502 
503 	/**
504 	 * This attempts to set up @server to listen for connections on
505 	 * @address.
506 	 *
507 	 * If @options includes %SOUP_SERVER_LISTEN_HTTPS, and @server has
508 	 * been configured for TLS, then @server will listen for https
509 	 * connections on this port. Otherwise it will listen for plain http.
510 	 *
511 	 * You may call this method (along with the other "listen" methods)
512 	 * any number of times on a server, if you want to listen on multiple
513 	 * ports, or set up both http and https service.
514 	 *
515 	 * After calling this method, @server will begin accepting and
516 	 * processing connections as soon as the appropriate #GMainContext is
517 	 * run.
518 	 *
519 	 * Note that #SoupServer never makes use of dual IPv4/IPv6 sockets; if
520 	 * @address is an IPv6 address, it will only accept IPv6 connections.
521 	 * You must configure IPv4 listening separately.
522 	 *
523 	 * Params:
524 	 *     address = the address of the interface to listen on
525 	 *     options = listening options for this server
526 	 *
527 	 * Returns: %TRUE on success, %FALSE if @address could not be
528 	 *     bound or any other error occurred (in which case @error will be
529 	 *     set).
530 	 *
531 	 * Since: 2.48
532 	 *
533 	 * Throws: GException on failure.
534 	 */
535 	public bool listen(SocketAddress address, SoupServerListenOptions options)
536 	{
537 		GError* err = null;
538 
539 		auto __p = soup_server_listen(soupServer, (address is null) ? null : address.getSocketAddressStruct(), options, &err) != 0;
540 
541 		if (err !is null)
542 		{
543 			throw new GException( new ErrorG(err) );
544 		}
545 
546 		return __p;
547 	}
548 
549 	/**
550 	 * This attempts to set up @server to listen for connections on all
551 	 * interfaces on the system. (That is, it listens on the addresses
552 	 * <literal>0.0.0.0</literal> and/or <literal>::</literal>, depending
553 	 * on whether @options includes %SOUP_SERVER_LISTEN_IPV4_ONLY,
554 	 * %SOUP_SERVER_LISTEN_IPV6_ONLY, or neither.) If @port is specified,
555 	 * @server will listen on that port. If it is 0, @server will find an
556 	 * unused port to listen on. (In that case, you can use
557 	 * soup_server_get_uris() to find out what port it ended up choosing.)
558 	 *
559 	 * See soup_server_listen() for more details.
560 	 *
561 	 * Params:
562 	 *     port = the port to listen on, or 0
563 	 *     options = listening options for this server
564 	 *
565 	 * Returns: %TRUE on success, %FALSE if @port could not be bound
566 	 *     or any other error occurred (in which case @error will be set).
567 	 *
568 	 * Since: 2.48
569 	 *
570 	 * Throws: GException on failure.
571 	 */
572 	public bool listenAll(uint port, SoupServerListenOptions options)
573 	{
574 		GError* err = null;
575 
576 		auto __p = soup_server_listen_all(soupServer, port, options, &err) != 0;
577 
578 		if (err !is null)
579 		{
580 			throw new GException( new ErrorG(err) );
581 		}
582 
583 		return __p;
584 	}
585 
586 	/**
587 	 * This attempts to set up @server to listen for connections on
588 	 * @fd.
589 	 *
590 	 * See soup_server_listen() for more details.
591 	 *
592 	 * Note that @server will close @fd when you free it or call
593 	 * soup_server_disconnect().
594 	 *
595 	 * Params:
596 	 *     fd = the file descriptor of a listening socket
597 	 *     options = listening options for this server
598 	 *
599 	 * Returns: %TRUE on success, %FALSE if an error occurred (in
600 	 *     which case @error will be set).
601 	 *
602 	 * Since: 2.48
603 	 *
604 	 * Throws: GException on failure.
605 	 */
606 	public bool listenFd(int fd, SoupServerListenOptions options)
607 	{
608 		GError* err = null;
609 
610 		auto __p = soup_server_listen_fd(soupServer, fd, options, &err) != 0;
611 
612 		if (err !is null)
613 		{
614 			throw new GException( new ErrorG(err) );
615 		}
616 
617 		return __p;
618 	}
619 
620 	/**
621 	 * This attempts to set up @server to listen for connections on
622 	 * "localhost" (that is, <literal>127.0.0.1</literal> and/or
623 	 * <literal>::1</literal>, depending on whether @options includes
624 	 * %SOUP_SERVER_LISTEN_IPV4_ONLY, %SOUP_SERVER_LISTEN_IPV6_ONLY, or
625 	 * neither). If @port is specified, @server will listen on that port.
626 	 * If it is 0, @server will find an unused port to listen on. (In that
627 	 * case, you can use soup_server_get_uris() to find out what port it
628 	 * ended up choosing.)
629 	 *
630 	 * See soup_server_listen() for more details.
631 	 *
632 	 * Params:
633 	 *     port = the port to listen on, or 0
634 	 *     options = listening options for this server
635 	 *
636 	 * Returns: %TRUE on success, %FALSE if @port could not be bound
637 	 *     or any other error occurred (in which case @error will be set).
638 	 *
639 	 * Since: 2.48
640 	 *
641 	 * Throws: GException on failure.
642 	 */
643 	public bool listenLocal(uint port, SoupServerListenOptions options)
644 	{
645 		GError* err = null;
646 
647 		auto __p = soup_server_listen_local(soupServer, port, options, &err) != 0;
648 
649 		if (err !is null)
650 		{
651 			throw new GException( new ErrorG(err) );
652 		}
653 
654 		return __p;
655 	}
656 
657 	/**
658 	 * This attempts to set up @server to listen for connections on
659 	 * @socket.
660 	 *
661 	 * See soup_server_listen() for more details.
662 	 *
663 	 * Params:
664 	 *     socket = a listening #GSocket
665 	 *     options = listening options for this server
666 	 *
667 	 * Returns: %TRUE on success, %FALSE if an error occurred (in
668 	 *     which case @error will be set).
669 	 *
670 	 * Since: 2.48
671 	 *
672 	 * Throws: GException on failure.
673 	 */
674 	public bool listenSocket(GIOSocket socket, SoupServerListenOptions options)
675 	{
676 		GError* err = null;
677 
678 		auto __p = soup_server_listen_socket(soupServer, (socket is null) ? null : socket.getSocketStruct(), options, &err) != 0;
679 
680 		if (err !is null)
681 		{
682 			throw new GException( new ErrorG(err) );
683 		}
684 
685 		return __p;
686 	}
687 
688 	/**
689 	 * Pauses I/O on @msg. This can be used when you need to return from
690 	 * the server handler without having the full response ready yet. Use
691 	 * soup_server_unpause_message() to resume I/O.
692 	 *
693 	 * This must only be called on #SoupMessages which were created by the
694 	 * #SoupServer and are currently doing I/O, such as those passed into a
695 	 * #SoupServerCallback or emitted in a #SoupServer::request-read signal.
696 	 *
697 	 * Params:
698 	 *     msg = a #SoupMessage associated with @server.
699 	 */
700 	public void pauseMessage(Message msg)
701 	{
702 		soup_server_pause_message(soupServer, (msg is null) ? null : msg.getMessageStruct());
703 	}
704 
705 	/**
706 	 * Stops processing for @server, if you are using the old API. Call
707 	 * this to clean up after soup_server_run_async(), or to terminate a
708 	 * call to soup_server_run().
709 	 *
710 	 * Note that messages currently in progress will continue to be
711 	 * handled, if the main loop associated with the server is resumed or
712 	 * kept running.
713 	 *
714 	 * @server is still in a working state after this call; you can start
715 	 * and stop a server as many times as you want.
716 	 *
717 	 * Deprecated: When using soup_server_listen(), etc, the server will
718 	 * always listen for connections, and will process them whenever the
719 	 * thread-default #GMainContext is running.
720 	 */
721 	public void quit()
722 	{
723 		soup_server_quit(soupServer);
724 	}
725 
726 	/**
727 	 * Removes @auth_domain from @server.
728 	 *
729 	 * Params:
730 	 *     authDomain = a #SoupAuthDomain
731 	 */
732 	public void removeAuthDomain(AuthDomain authDomain)
733 	{
734 		soup_server_remove_auth_domain(soupServer, (authDomain is null) ? null : authDomain.getAuthDomainStruct());
735 	}
736 
737 	/**
738 	 * Removes all handlers (early and normal) registered at @path.
739 	 *
740 	 * Params:
741 	 *     path = the toplevel path for the handler
742 	 */
743 	public void removeHandler(string path)
744 	{
745 		soup_server_remove_handler(soupServer, Str.toStringz(path));
746 	}
747 
748 	/**
749 	 * Removes support for WebSocket extension of type @extension_type (or any subclass of
750 	 * @extension_type) from @server. You can also remove extensions enabled by default
751 	 * from the server at construct time by using the %SOUP_SERVER_REMOVE_WEBSOCKET_EXTENSION
752 	 * property.
753 	 *
754 	 * Params:
755 	 *     extensionType = a #GType
756 	 *
757 	 * Since: 2.68
758 	 */
759 	public void removeWebsocketExtension(GType extensionType)
760 	{
761 		soup_server_remove_websocket_extension(soupServer, extensionType);
762 	}
763 
764 	/**
765 	 * Starts @server, if you are using the old API, causing it to listen
766 	 * for and process incoming connections. Unlike
767 	 * soup_server_run_async(), this creates a #GMainLoop and runs it, and
768 	 * it will not return until someone calls soup_server_quit() to stop
769 	 * the server.
770 	 *
771 	 * Deprecated: When using soup_server_listen(), etc, the server will
772 	 * always listen for connections, and will process them whenever the
773 	 * thread-default #GMainContext is running.
774 	 */
775 	public void run()
776 	{
777 		soup_server_run(soupServer);
778 	}
779 
780 	/**
781 	 * Starts @server, if you are using the old API, causing it to listen
782 	 * for and process incoming connections.
783 	 *
784 	 * The server runs in @server's #GMainContext. It will not actually
785 	 * perform any processing unless the appropriate main loop is running.
786 	 * In the simple case where you did not set the server's
787 	 * %SOUP_SERVER_ASYNC_CONTEXT property, this means the server will run
788 	 * whenever the glib main loop is running.
789 	 *
790 	 * Deprecated: When using soup_server_listen(), etc, the server will
791 	 * always listen for connections, and will process them whenever the
792 	 * thread-default #GMainContext is running.
793 	 */
794 	public void runAsync()
795 	{
796 		soup_server_run_async(soupServer);
797 	}
798 
799 	/**
800 	 * Sets @server up to do https, using the SSL/TLS certificate
801 	 * specified by @ssl_cert_file and @ssl_key_file (which may point to
802 	 * the same file).
803 	 *
804 	 * Alternatively, you can set the #SoupServer:tls-certificate property
805 	 * at construction time, if you already have a #GTlsCertificate.
806 	 *
807 	 * Params:
808 	 *     sslCertFile = path to a file containing a PEM-encoded SSL/TLS
809 	 *         certificate.
810 	 *     sslKeyFile = path to a file containing a PEM-encoded private key.
811 	 *
812 	 * Returns: success or failure.
813 	 *
814 	 * Since: 2.48
815 	 *
816 	 * Throws: GException on failure.
817 	 */
818 	public bool setSslCertFile(string sslCertFile, string sslKeyFile)
819 	{
820 		GError* err = null;
821 
822 		auto __p = soup_server_set_ssl_cert_file(soupServer, Str.toStringz(sslCertFile), Str.toStringz(sslKeyFile), &err) != 0;
823 
824 		if (err !is null)
825 		{
826 			throw new GException( new ErrorG(err) );
827 		}
828 
829 		return __p;
830 	}
831 
832 	/**
833 	 * Resumes I/O on @msg. Use this to resume after calling
834 	 * soup_server_pause_message(), or after adding a new chunk to a
835 	 * chunked response.
836 	 *
837 	 * I/O won't actually resume until you return to the main loop.
838 	 *
839 	 * This must only be called on #SoupMessages which were created by the
840 	 * #SoupServer and are currently doing I/O, such as those passed into a
841 	 * #SoupServerCallback or emitted in a #SoupServer::request-read signal.
842 	 *
843 	 * Params:
844 	 *     msg = a #SoupMessage associated with @server.
845 	 */
846 	public void unpauseMessage(Message msg)
847 	{
848 		soup_server_unpause_message(soupServer, (msg is null) ? null : msg.getMessageStruct());
849 	}
850 
851 	/**
852 	 * Emitted when processing has failed for a message; this
853 	 * could mean either that it could not be read (if
854 	 * #SoupServer::request_read has not been emitted for it yet),
855 	 * or that the response could not be written back (if
856 	 * #SoupServer::request_read has been emitted but
857 	 * #SoupServer::request_finished has not been).
858 	 *
859 	 * @message is in an undefined state when this signal is
860 	 * emitted; the signal exists primarily to allow the server to
861 	 * free any state that it may have allocated in
862 	 * #SoupServer::request_started.
863 	 *
864 	 * Params:
865 	 *     message = the message
866 	 *     client = the client context
867 	 */
868 	gulong addOnRequestAborted(void delegate(Message, ClientContext, Server) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
869 	{
870 		return Signals.connect(this, "request-aborted", dlg, connectFlags ^ ConnectFlags.SWAPPED);
871 	}
872 
873 	/**
874 	 * Emitted when the server has finished writing a response to
875 	 * a request.
876 	 *
877 	 * Params:
878 	 *     message = the message
879 	 *     client = the client context
880 	 */
881 	gulong addOnRequestFinished(void delegate(Message, ClientContext, Server) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
882 	{
883 		return Signals.connect(this, "request-finished", dlg, connectFlags ^ ConnectFlags.SWAPPED);
884 	}
885 
886 	/**
887 	 * Emitted when the server has successfully read a request.
888 	 * @message will have all of its request-side information
889 	 * filled in, and if the message was authenticated, @client
890 	 * will have information about that. This signal is emitted
891 	 * before any (non-early) handlers are called for the message,
892 	 * and if it sets the message's #status_code, then normal
893 	 * handler processing will be skipped.
894 	 *
895 	 * Params:
896 	 *     message = the message
897 	 *     client = the client context
898 	 */
899 	gulong addOnRequestRead(void delegate(Message, ClientContext, Server) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
900 	{
901 		return Signals.connect(this, "request-read", dlg, connectFlags ^ ConnectFlags.SWAPPED);
902 	}
903 
904 	/**
905 	 * Emitted when the server has started reading a new request.
906 	 * @message will be completely blank; not even the
907 	 * Request-Line will have been read yet. About the only thing
908 	 * you can usefully do with it is connect to its signals.
909 	 *
910 	 * If the request is read successfully, this will eventually
911 	 * be followed by a #SoupServer::request_read signal. If a
912 	 * response is then sent, the request processing will end with
913 	 * a #SoupServer::request_finished signal. If a network error
914 	 * occurs, the processing will instead end with
915 	 * #SoupServer::request_aborted.
916 	 *
917 	 * Params:
918 	 *     message = the new message
919 	 *     client = the client context
920 	 */
921 	gulong addOnRequestStarted(void delegate(Message, ClientContext, Server) dlg, ConnectFlags connectFlags=cast(ConnectFlags)0)
922 	{
923 		return Signals.connect(this, "request-started", dlg, connectFlags ^ ConnectFlags.SWAPPED);
924 	}
925 }