feat(lnm): part of routing code
ci/woodpecker/push/build Pipeline was successful
Details
ci/woodpecker/push/build Pipeline was successful
Details
parent
d119f85260
commit
8c21ccf58b
|
@ -56,7 +56,8 @@ lnm_err lnm_http_step_append(lnm_http_step **out, lnm_http_step *step,
|
||||||
* @param path literal path to match
|
* @param path literal path to match
|
||||||
* @param step step to process request with
|
* @param step step to process request with
|
||||||
*/
|
*/
|
||||||
lnm_err lnm_http_route_init_literal(lnm_http_route **out, const char *path,
|
lnm_err lnm_http_route_init_literal(lnm_http_route **out,
|
||||||
|
lnm_http_method method, const char *path,
|
||||||
lnm_http_step *step);
|
lnm_http_step *step);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -67,8 +68,9 @@ lnm_err lnm_http_route_init_literal(lnm_http_route **out, const char *path,
|
||||||
* @param regex_group_count how many regex groups are contained in the pattern
|
* @param regex_group_count how many regex groups are contained in the pattern
|
||||||
* @param step step to process request with
|
* @param step step to process request with
|
||||||
*/
|
*/
|
||||||
lnm_err lnm_http_route_init_regex(lnm_http_route **out, const char *pattern,
|
lnm_err lnm_http_route_init_regex(lnm_http_route **out, lnm_http_method method,
|
||||||
int regex_group_count, lnm_http_step *step);
|
const char *pattern, int regex_group_count,
|
||||||
|
lnm_http_step *step);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add a new route to the HTTP route.
|
* Add a new route to the HTTP route.
|
||||||
|
@ -101,6 +103,7 @@ typedef struct lnm_http_loop_gctx {
|
||||||
typedef struct lnm_http_loop_ctx {
|
typedef struct lnm_http_loop_ctx {
|
||||||
lnm_http_loop_state state;
|
lnm_http_loop_state state;
|
||||||
lnm_http_req req;
|
lnm_http_req req;
|
||||||
|
lnm_http_route *route;
|
||||||
lnm_http_loop_gctx *g;
|
lnm_http_loop_gctx *g;
|
||||||
void *c;
|
void *c;
|
||||||
} lnm_http_loop_ctx;
|
} lnm_http_loop_ctx;
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#ifndef LNM_HTTP_REQ
|
#ifndef LNM_HTTP_REQ
|
||||||
#define LNM_HTTP_REQ
|
#define LNM_HTTP_REQ
|
||||||
|
|
||||||
|
#include <regex.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
#include "picohttpparser.h"
|
#include "picohttpparser.h"
|
||||||
|
@ -8,6 +9,7 @@
|
||||||
#include "lnm/http/consts.h"
|
#include "lnm/http/consts.h"
|
||||||
|
|
||||||
#define LNM_HTTP_MAX_REQ_HEADERS 32
|
#define LNM_HTTP_MAX_REQ_HEADERS 32
|
||||||
|
#define LNM_HTTP_MAX_REGEX_GROUPS 4
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents the parsed HTTP request
|
* Represents the parsed HTTP request
|
||||||
|
@ -19,6 +21,7 @@ typedef struct lnm_http_req {
|
||||||
struct {
|
struct {
|
||||||
const char *s;
|
const char *s;
|
||||||
size_t len;
|
size_t len;
|
||||||
|
regmatch_t groups[LNM_HTTP_MAX_REGEX_GROUPS];
|
||||||
} path;
|
} path;
|
||||||
struct {
|
struct {
|
||||||
const char *s;
|
const char *s;
|
||||||
|
|
|
@ -20,6 +20,7 @@ typedef struct lnm_http_route {
|
||||||
regex_t *regex;
|
regex_t *regex;
|
||||||
const char *s;
|
const char *s;
|
||||||
} route;
|
} route;
|
||||||
|
lnm_http_method method;
|
||||||
lnm_http_route_type type;
|
lnm_http_route_type type;
|
||||||
int regex_group_count;
|
int regex_group_count;
|
||||||
lnm_http_step *step;
|
lnm_http_step *step;
|
||||||
|
@ -63,4 +64,6 @@ void lnm_http_loop_ctx_reset(lnm_http_loop_ctx *ctx);
|
||||||
|
|
||||||
void lnm_http_loop_ctx_free(lnm_http_loop_ctx *ctx);
|
void lnm_http_loop_ctx_free(lnm_http_loop_ctx *ctx);
|
||||||
|
|
||||||
|
void lnm_http_loop_process(lnm_http_conn *conn);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -19,6 +19,7 @@ lnm_err lnm_http_loop_init(lnm_http_loop **out, void *c_gctx,
|
||||||
ctx_init, ctx_reset, ctx_free),
|
ctx_init, ctx_reset, ctx_free),
|
||||||
free(hl));
|
free(hl));
|
||||||
|
|
||||||
|
hl->data_read = lnm_http_loop_process;
|
||||||
*out = hl;
|
*out = hl;
|
||||||
|
|
||||||
return lnm_err_ok;
|
return lnm_err_ok;
|
||||||
|
@ -58,19 +59,22 @@ lnm_err lnm_http_route_init(lnm_http_route **out) {
|
||||||
return lnm_err_ok;
|
return lnm_err_ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
lnm_err lnm_http_route_init_literal(lnm_http_route **out, const char *path,
|
lnm_err lnm_http_route_init_literal(lnm_http_route **out,
|
||||||
|
lnm_http_method method, const char *path,
|
||||||
lnm_http_step *step) {
|
lnm_http_step *step) {
|
||||||
LNM_RES(lnm_http_route_init(out));
|
LNM_RES(lnm_http_route_init(out));
|
||||||
|
|
||||||
(*out)->type = lnm_http_route_type_literal;
|
(*out)->type = lnm_http_route_type_literal;
|
||||||
|
(*out)->method = method;
|
||||||
(*out)->route.s = path;
|
(*out)->route.s = path;
|
||||||
(*out)->step = step;
|
(*out)->step = step;
|
||||||
|
|
||||||
return lnm_err_ok;
|
return lnm_err_ok;
|
||||||
}
|
}
|
||||||
|
|
||||||
lnm_err lnm_http_route_init_regex(lnm_http_route **out, const char *pattern,
|
lnm_err lnm_http_route_init_regex(lnm_http_route **out, lnm_http_method method,
|
||||||
int regex_group_count, lnm_http_step *step) {
|
const char *pattern, int regex_group_count,
|
||||||
|
lnm_http_step *step) {
|
||||||
regex_t *regex = calloc(1, sizeof(regex_t));
|
regex_t *regex = calloc(1, sizeof(regex_t));
|
||||||
|
|
||||||
if (regex == NULL) {
|
if (regex == NULL) {
|
||||||
|
@ -84,6 +88,7 @@ lnm_err lnm_http_route_init_regex(lnm_http_route **out, const char *pattern,
|
||||||
|
|
||||||
LNM_RES2(lnm_http_route_init(out), free(regex));
|
LNM_RES2(lnm_http_route_init(out), free(regex));
|
||||||
|
|
||||||
|
(*out)->method = method;
|
||||||
(*out)->type = lnm_http_route_type_regex;
|
(*out)->type = lnm_http_route_type_regex;
|
||||||
(*out)->route.regex = regex;
|
(*out)->route.regex = regex;
|
||||||
(*out)->regex_group_count = regex_group_count;
|
(*out)->regex_group_count = regex_group_count;
|
||||||
|
|
|
@ -1,3 +1,6 @@
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
#include "lnm/http/loop.h"
|
#include "lnm/http/loop.h"
|
||||||
#include "lnm/http/loop_internal.h"
|
#include "lnm/http/loop_internal.h"
|
||||||
#include "lnm/http/req.h"
|
#include "lnm/http/req.h"
|
||||||
|
@ -12,6 +15,7 @@ void lnm_http_loop_process_parse_req(lnm_http_conn *conn) {
|
||||||
|
|
||||||
switch (res) {
|
switch (res) {
|
||||||
case lnm_http_parse_err_ok:
|
case lnm_http_parse_err_ok:
|
||||||
|
conn->r.read += ctx->req.len;
|
||||||
ctx->state = lnm_http_loop_state_steps;
|
ctx->state = lnm_http_loop_state_steps;
|
||||||
break;
|
break;
|
||||||
case lnm_http_parse_err_incomplete:
|
case lnm_http_parse_err_incomplete:
|
||||||
|
@ -31,7 +35,38 @@ void lnm_http_loop_process_parse_req(lnm_http_conn *conn) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void lnm_http_loop_process_route(lnm_http_conn *conn) {}
|
void lnm_http_loop_process_route(lnm_http_conn *conn) {
|
||||||
|
lnm_http_loop_ctx *ctx = conn->ctx;
|
||||||
|
lnm_http_loop_gctx *gctx = ctx->g;
|
||||||
|
|
||||||
|
// 0: no match
|
||||||
|
// 1: matched route, but not method
|
||||||
|
// 2: fully matched route
|
||||||
|
int match_level = 0;
|
||||||
|
lnm_http_route *route;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < gctx->routes.len && match_level < 2; i++) {
|
||||||
|
route = gctx->routes.arr[i];
|
||||||
|
bool matched_path;
|
||||||
|
|
||||||
|
switch (route->type) {
|
||||||
|
case lnm_http_route_type_literal:
|
||||||
|
matched_path =
|
||||||
|
strncmp(route->route.s, ctx->req.path.s, ctx->req.path.len) == 0;
|
||||||
|
break;
|
||||||
|
case lnm_http_route_type_regex:
|
||||||
|
matched_path =
|
||||||
|
regexec(route->route.regex, ctx->req.path.s,
|
||||||
|
LNM_HTTP_MAX_REGEX_GROUPS, ctx->req.path.groups, 0) == 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remember the previous match levels
|
||||||
|
int new_match_level = matched_path + (route->method == ctx->req.method);
|
||||||
|
match_level = match_level < new_match_level ? new_match_level : match_level;
|
||||||
|
}
|
||||||
|
|
||||||
|
ctx->route = match_level == 2 ? route : NULL;
|
||||||
|
}
|
||||||
|
|
||||||
void lnm_http_loop_process_steps(lnm_http_conn *conn) {
|
void lnm_http_loop_process_steps(lnm_http_conn *conn) {
|
||||||
/* lnm_http_loop_ctx *ctx = conn->ctx; */
|
/* lnm_http_loop_ctx *ctx = conn->ctx; */
|
||||||
|
|
Loading…
Reference in New Issue