HTTP Server
The class http.Server
implements a basic server. The server handles receiving incoming
HTTP connections, parsing them, and sending responses to them. To generate responses, it calls one
of the abstract functions below. As such, to use the server, you need to create a class that
inherits from http.Server
and overrides the functions below. It is also possible to use
http.RoutingServer
to solve routing automatically.
The server is threaded, using Storm's user threads. A new thread is created for each client that connects to the server, and the created thread handles connections in parallell. Note, however, that user threads are scheduled cooperatively. As such, this model is not too dissimilar from webservers that utilize a few threads to handle requests in a multiplexed way.
The members that need to be overridden are the following:
The server also provides the following members that are relevant to be aware of:
-
init()
Create.
-
void timeout(core.Duration d)
Set the timeout.
-
void run(core.Nat port)
Run the server on
port
untilclose
is called. -
void close()
Close the listener inside the server. This also causes 'run' to return if another thread is blocked inside it.
-
core.Bool prepareResponse(http.Request request, http.Response response)
Called before sending a request, allows a top-level hook for handling headers etc. Returns 'true' if the connection should be kept open. False otherwise.
Routing
The class http.RoutingServer
extends http.Server
and provides routing. That
way, the server is usable without subclassing.
At a conceptual level, the routing server associates each path with a function that will be called
whenever a client visits that particular path. Wildcards are supported. As such, if one path
component is *
, then any contents of that component will be considered a match. Note that wildcard
components are always matched last.
Routes are added by calling the function add
:
It is also possible to add a default handler that will be called whenever a more specific route does not exist. The default behavior of this handler is to provide a basic "page not found" message:
Example
Below is an example of using the HTTP library to create a simple server:
use core:net; use core:io; use http; use core:lang; private Str baseSite() { str { <!DOCTYPE html> <html> <body> <h1>Hello</h1> <p>Example page</p> </body> </html> }; } private Str picturesSite() { str { <!DOCTYPE html> <html> <body> <h1>Pictures</h1> <p>Pictures page</p> </body> </html> }; } void main() { RoutingServer server; // Sleep for 20 seconds, then call close to cause 'server.run' to return. spawn (() => { sleep(20 s); server.close; }).call(); // Add a handler for the route /pictures/<anything> server.route(["pictures", "*"], (request) => Response(picturesSite)); // Add a default handler. server.default((request) => Response(baseSite)); // Run the server on port 1234. server.run(1234); }