Nilorea Library
C utilities for networking, threading, graphics
Loading...
Searching...
No Matches
n_http_router.h File Reference

HTTP router: static route tables, typed placeholders, specificity. More...

#include "nilorea/n_http_req.h"
#include <stddef.h>
Include dependency graph for n_http_router.h:
This graph shows which files directly or indirectly include this file:

Go to the source code of this file.

Data Structures

struct  N_ROUTE
 one route of a table More...
struct  N_ROUTE_MATCH
 a successful match: the route and its decoded placeholder values More...

Macros

#define N_ROUTE_GET   N_HTTP_REQ_METHOD_BIT(N_HTTP_REQ_GET)
 route accepts GET (and so HEAD)
#define N_ROUTE_HEAD   N_HTTP_REQ_METHOD_BIT(N_HTTP_REQ_HEAD)
 route accepts HEAD only (rare: GET routes answer HEAD already)
#define N_ROUTE_NAME_MAX   31
 longest placeholder name
#define N_ROUTE_PARAMS_MAX   8
 most placeholders in one route
#define N_ROUTE_POST   N_HTTP_REQ_METHOD_BIT(N_HTTP_REQ_POST)
 route accepts POST

Typedefs

typedef int(* n_route_handler) (void *ctx, const struct N_ROUTE_MATCH *match)
 a route handler: ctx is the caller's request context

Enumerations

enum  N_ROUTER_RESULT { N_ROUTER_FOUND = 0 , N_ROUTER_NOT_FOUND = 1 , N_ROUTER_METHOD_NOT_ALLOWED = 2 , N_ROUTER_BAD_REQUEST = 3 }
 result of n_router_match() More...

Functions

const char * n_route_param (const N_ROUTE_MATCH *m, const char *name, size_t *len)
 decoded value of a placeholder
int n_router_add (N_ROUTER *r, const N_ROUTE *routes, size_t count)
 compile and add a route table
int n_router_allow_header (unsigned allowed, char *out, size_t size)
 write an Allow header value ("GET, HEAD, POST") for a method mask
int n_router_check (const N_ROUTER *r, char *err, size_t errsz)
 refuse ambiguous routes: two routes sharing a method that can match the same path with the same specificity
size_t n_router_count (const N_ROUTER *r)
 number of routes added
void n_router_free (N_ROUTER **r)
 free a router and set *r to NULL (the route tables are not touched)
N_ROUTER_RESULT n_router_match (const N_ROUTER *r, n_http_req_method method, const char *path, size_t len, N_ROUTE_MATCH *match, unsigned *allowed)
 find the route for a method and a path
N_ROUTER * n_router_new (void)
 new, empty router
const N_ROUTE * n_router_route (const N_ROUTER *r, size_t i)
 the i-th route added (to check caller policies at start-up)

Detailed Description

HTTP router: static route tables, typed placeholders, specificity.

Routes are declared in static tables, one line each:

static const N_ROUTE PUBLIC[] = {
    {N_ROUTE_GET, "/", h_home, NULL},
    {N_ROUTE_GET, "/{y:d4}/{m:d2}/{d:d2}/{slug:slug}/", h_post, NULL},
    {N_ROUTE_GET, "/media/{id:hex16}/{w:int4}/{name:seg}", h_variant, NULL},
};

A pattern is a '/'-separated list of segments, each either a literal ("feed", matched exactly and case-sensitively against the raw path) or one placeholder "{name:type}" ("{name}" is "{name:seg}"). A trailing '/' in the pattern requires one in the path. Types are checked on the RAW segment, before decoding, so a percent-encoded byte never satisfies a digit, hex or slug type:

type raw segment
dN exactly N digits (N 1..18)
hexN exactly N lowercase hex digits (N 1..64)
intN 1 to N digits (N 1..18)
slug 1 to 120 of a-z 0-9 '_' '-'
seg 1 to 255 bytes, no '/'
rest the remainder of the path, '/' included, last only

Captured values are strictly percent-decoded into the match (a malformed escape, a decoded NUL or ill-formed UTF-8 in ANY segment of the path makes the whole request a 400, before any route is tried).

When several routes match, the most specific wins, segment by segment from the left: a literal beats dN/hexN, which beat intN, then slug, seg, rest. So "/feed/" wins over "/{slug}/" whatever the table order, and n_router_check() refuses only real ambiguities (two routes the rule cannot order, like a duplicate or d4 against hex4). A route allowing GET also answers HEAD.

The router does no allocation per request and keeps pointers to the route tables: they must outlive it (static tables do).

Author
Castagnier Mickael
Version
1.0
Date
2026

Definition in file n_http_router.h.