1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
#ifndef __ROUTER_H
#define __ROUTER_H
#include "http_request.h"
#include "http_response.h"
/**
* A file system router for the web server. It stores handlers for paths and
* dispatches requests to the appropriate handler. For example, the handler for
* `/cat` might respond with a picture of a cat while `/roll` might respond with
* a random dice roll.
*
* If no matching path has been registered for a handler, it falls back to a
* fallback handler.
*/
typedef struct router router_t;
/**
* Represents a handler for a given route.
*
* It accepts a request, borrowing it, and returns a owned bytes
* which should be responded with.
*/
typedef bytes_t *(*route_handler_t)(request_t *);
/**
* Initialize a router with a fallback handler, which will be called on all
* requests which don't match a registered path.
*
* Note that route_handler_t is a function pointer type and function pointers
* are always borrowed.
*
* `max_routes` specifies the maximum number of routes (not including the
* fallback handler) that the router can hold.
*/
router_t *router_init(size_t max_routes, route_handler_t fallback_handler);
/**
* Registers the route `path` with the router such that requests with that path
* will be send to `handler.`
*
* If the route has already been registered, replaces the old handler.
*
* If the max number of routes have already been registered and the route is not
* a replacement route, does nothing (however, if the route is a replacement
* route then the replacement is still performed even if the router is full).
*
* This function does not take ownership of path and instead creates a copy.
*/
void router_register(router_t *router, const char *path, route_handler_t handler);
/**
* Dispatch a request to the matching route handler, or the fallback if none
* exists. Dispatching, here, simply means invoking the previously registered
* route handler and returning the result, which is an owned array of bytes.
*
* If the set handler returns `NULL,` the the request is instead sent to the
* fallback handler.
*
* Takes ownership of `request`.
*/
bytes_t *router_dispatch(router_t *router, request_t *request);
/**
* Frees all resources associated with the router. Note that function pointers
* are pointers to code, which is owned by the program like a string literal,
* and are always borrowed (and, correspondingly, they shouldn't be freed).
*
*/
void router_free(router_t *router);
#endif