lander/lnm/src/http/lnm_http_loop.c

139 lines
3.5 KiB
C

#include <stdlib.h>
#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;
}