# 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:

- `http.Response onRequest(http.Request request)`

  Called when a request was received. Expected to return an appropriate response.

- `http.Response onServerError(core.Exception e)`

  Override to handle errors from clients.

- `http.Response onError(http.Status code)`

  Called when an immediate response should be generated. Allows generating an error page.

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` until `close` 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:

- `void default(core.Fn<http.Response, http.Request> handler)`

  Add a default route, used if no other routes are found.

## 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);
    }