#include #include "lnm/common.h" #include "lnm/http/loop.h" #include "lnm/http/loop_internal.h" #include "lnm/loop_internal.h" lnm_err lnm_http_loop_init(lnm_http_loop **out, void *c_gctx, lnm_http_ctx_init_fn ctx_init, lnm_http_ctx_reset_fn ctx_reset, lnm_http_ctx_free_fn ctx_free) { lnm_http_loop *hl = calloc(1, sizeof(lnm_http_loop)); if (hl == NULL) { return lnm_err_failed_alloc; } LNM_RES2(lnm_http_loop_gctx_init((lnm_http_loop_gctx **)&hl->gctx, c_gctx, ctx_init, ctx_reset, ctx_free), free(hl)); hl->data_read = lnm_http_loop_process; hl->data_write = lnm_http_loop_process; hl->ctx_init = (lnm_err(*)(void **, void *))lnm_http_loop_ctx_init; hl->ctx_free = (void (*)(void *))lnm_http_loop_ctx_free; *out = hl; return lnm_err_ok; } lnm_err lnm_http_step_init(lnm_http_step **out, lnm_http_step_fn fn) { lnm_http_step *step = calloc(1, sizeof(lnm_http_step)); if (step == NULL) { return lnm_err_failed_alloc; } step->fn = fn; *out = step; return lnm_err_ok; } lnm_err lnm_http_step_append(lnm_http_step **out, lnm_http_step *step, lnm_http_step_fn fn) { LNM_RES(lnm_http_step_init(out, fn)); if (step != NULL) { step->next = *out; } return lnm_err_ok; } lnm_err lnm_http_route_init(lnm_http_route **out) { lnm_http_route *route = calloc(1, sizeof(lnm_http_route)); if (route == NULL) { return lnm_err_failed_alloc; } *out = route; return lnm_err_ok; } lnm_err lnm_http_route_init_literal(lnm_http_route **out, lnm_http_method method, const char *path, lnm_http_step *step) { LNM_RES(lnm_http_route_init(out)); (*out)->type = lnm_http_route_type_literal; (*out)->method = method; (*out)->route.s = path; (*out)->step = step; return lnm_err_ok; } lnm_err lnm_http_route_init_regex(lnm_http_route **out, lnm_http_method method, const char *pattern, int regex_group_count, lnm_http_step *step) { regex_t *regex = calloc(1, sizeof(regex_t)); if (regex == NULL) { return lnm_err_failed_alloc; } if (regcomp(regex, pattern, REG_EXTENDED) != 0) { free(regex); return lnm_err_bad_regex; } LNM_RES2(lnm_http_route_init(out), free(regex)); (*out)->method = method; (*out)->type = lnm_http_route_type_regex; (*out)->route.regex = regex; (*out)->regex_group_count = regex_group_count; (*out)->step = step; return lnm_err_ok; } lnm_err lnm_http_loop_route_add(lnm_http_loop *hl, lnm_http_route *route) { lnm_http_loop_gctx *gctx = hl->gctx; lnm_http_route **new_routes = gctx->routes.len > 0 ? realloc(gctx->routes.arr, (gctx->routes.len + 1) * sizeof(lnm_http_route *)) : malloc(sizeof(lnm_http_route *)); if (new_routes == NULL) { return lnm_err_failed_alloc; } new_routes[gctx->routes.len] = route; gctx->routes.arr = new_routes; gctx->routes.len++; return lnm_err_ok; } lnm_err lnm_http_loop_run(lnm_http_loop *hl, uint16_t port, int thread_count) { LNM_RES(lnm_loop_setup(hl, port)); return lnm_loop_run(hl, thread_count); } void lnm_http_loop_set_api_key(lnm_http_loop *hl, const char *api_key) { lnm_http_loop_gctx *gctx = hl->gctx; gctx->api_key = api_key; } void lnm_http_loop_set_server(lnm_http_loop *hl, const char *server) { lnm_http_loop_gctx *gctx = hl->gctx; gctx->server = server; }