feat(routing): make path segments easily accessible from request struct

This commit is contained in:
Jef Roosens 2024-02-25 21:50:51 +01:00
parent fbd41f7e4e
commit 3ae1b62dd0
Signed by: Jef Roosens
GPG key ID: B75D4F293C7052DB
6 changed files with 105 additions and 65 deletions

View file

@ -6,17 +6,7 @@
#include "lnm/common.h"
#include "lnm/http/req.h"
#include "lnm/http/res.h"
#define LNM_HTTP_MAX_KEY_SEGMENTS 4
typedef enum lnm_http_step_err {
lnm_http_step_err_done = 0,
lnm_http_step_err_io_needed,
lnm_http_step_err_close,
lnm_http_step_err_res,
} lnm_http_step_err;
typedef lnm_http_step_err (*lnm_http_step_fn)(lnm_http_conn *conn);
#include "lnm/http/route.h"
typedef lnm_err (*lnm_http_ctx_init_fn)(void **c_ctx, void *gctx);
@ -24,55 +14,6 @@ typedef void (*lnm_http_ctx_reset_fn)(void *c_ctx);
typedef void (*lnm_http_ctx_free_fn)(void *c_ctx);
typedef struct lnm_http_route lnm_http_route;
typedef struct lnm_http_route_match_segment {
size_t start;
size_t len;
} lnm_http_route_match_segment;
typedef struct lnm_http_route_match {
const lnm_http_route *route;
lnm_http_method method;
lnm_http_route_match_segment key_segments[LNM_HTTP_MAX_KEY_SEGMENTS];
} lnm_http_route_match;
typedef struct lnm_http_router lnm_http_router;
typedef enum lnm_http_route_err {
lnm_http_route_err_match = 0,
lnm_http_route_err_unknown_route = 1,
lnm_http_route_err_unknown_method = 2,
} lnm_http_route_err;
/**
* Allocate and initialize a new http_router.
*/
lnm_err lnm_http_router_init(lnm_http_router **out);
void lnm_http_router_free(lnm_http_router *router);
lnm_err lnm_http_router_add(lnm_http_route **out, lnm_http_router *http_router,
lnm_http_method method, const char *path);
/**
* Add all of the child router's routes to the parent router, under the given
* route prefix.
*/
lnm_err lnm_http_router_nest(lnm_http_router *parent,
const lnm_http_router *child, const char *prefix);
lnm_http_route_err lnm_http_router_route(lnm_http_route_match *out,
const lnm_http_router *router,
lnm_http_method method,
const char *path);
const lnm_http_route_match_segment *
lnm_http_route_match_get(lnm_http_route_match *match, const char *key);
lnm_err lnm_http_route_step_append(lnm_http_route *route, lnm_http_step_fn fn,
bool blocking);
/**
* Initialize a new `lnm_http_loop`.
*
@ -130,7 +71,6 @@ typedef struct lnm_http_loop_ctx {
lnm_http_loop_state state;
lnm_http_req req;
lnm_http_res res;
lnm_http_route_match match;
lnm_http_step *cur_step;
lnm_http_loop_gctx *g;
void *c;

View file

@ -9,6 +9,7 @@
#include "lnm/common.h"
#include "lnm/http/consts.h"
#include "lnm/http/route.h"
#define LNM_HTTP_MAX_REQ_HEADERS 32
#define LNM_HTTP_MAX_REGEX_GROUPS 4
@ -35,6 +36,7 @@ typedef struct lnm_http_req {
} buf;
int minor_version;
lnm_http_method method;
lnm_http_route_match route_match;
struct {
size_t o;
size_t len;
@ -108,4 +110,14 @@ lnm_err lnm_http_req_header_get(const char **out, size_t *out_len,
lnm_err lnm_http_req_header_get_s(const char **out, size_t *out_len,
lnm_http_req *req, const char *name);
/**
* Retrieve a named key segment from the matched route.
*
* @param out where to write pointer to string
* @param key key of the segment
* @return length of the outputted char buffer, or 0 if the key doesn't exist
*/
size_t lnm_http_req_route_segment(const char **out, lnm_http_req *req,
const char *key);
#endif

69
include/lnm/http/route.h Normal file
View file

@ -0,0 +1,69 @@
#ifndef LNM_HTTP_ROUTE
#define LNM_HTTP_ROUTE
#include <stdlib.h>
#include "lnm/common.h"
#include "lnm/http/consts.h"
#define LNM_HTTP_MAX_KEY_SEGMENTS 4
typedef enum lnm_http_step_err {
lnm_http_step_err_done = 0,
lnm_http_step_err_io_needed,
lnm_http_step_err_close,
lnm_http_step_err_res,
} lnm_http_step_err;
typedef lnm_http_step_err (*lnm_http_step_fn)(lnm_http_conn *conn);
typedef struct lnm_http_route lnm_http_route;
typedef struct lnm_http_route_match_segment {
size_t start;
size_t len;
} lnm_http_route_match_segment;
typedef struct lnm_http_route_match {
const lnm_http_route *route;
lnm_http_method method;
lnm_http_route_match_segment key_segments[LNM_HTTP_MAX_KEY_SEGMENTS];
} lnm_http_route_match;
typedef struct lnm_http_router lnm_http_router;
typedef enum lnm_http_route_err {
lnm_http_route_err_match = 0,
lnm_http_route_err_unknown_route = 1,
lnm_http_route_err_unknown_method = 2,
} lnm_http_route_err;
/**
* Allocate and initialize a new http_router.
*/
lnm_err lnm_http_router_init(lnm_http_router **out);
void lnm_http_router_free(lnm_http_router *router);
lnm_err lnm_http_router_add(lnm_http_route **out, lnm_http_router *http_router,
lnm_http_method method, const char *path);
/**
* Add all of the child router's routes to the parent router, under the given
* route prefix.
*/
lnm_err lnm_http_router_nest(lnm_http_router *parent,
const lnm_http_router *child, const char *prefix);
lnm_http_route_err lnm_http_router_route(lnm_http_route_match *out,
const lnm_http_router *router,
lnm_http_method method,
const char *path);
const lnm_http_route_match_segment *
lnm_http_route_match_get(lnm_http_route_match *match, const char *key);
lnm_err lnm_http_route_step_append(lnm_http_route *route, lnm_http_step_fn fn,
bool blocking);
#endif