#ifndef LNM_HTTP_LOOP #define LNM_HTTP_LOOP #include #include "lnm/common.h" #include "lnm/http/req.h" #include "lnm/http/res.h" 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 lnm_err (*lnm_http_ctx_init_fn)(void **c_ctx, void *gctx); typedef void (*lnm_http_ctx_reset_fn)(void *c_ctx); typedef void (*lnm_http_ctx_free_fn)(void *c_ctx); /** * Initialize a new `lnm_http_loop`. * * @param out where to store pointer to new `lnm_http_loop` */ 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); /** * Initialize a new step. * * @param out where to store pointer to new `lnm_http_step` * @param fn step function */ lnm_err lnm_http_step_init(lnm_http_step **out, lnm_http_step_fn fn); /** * Append the given step fn to the step. * * @param out where to store pointer to new `lnm_http_step` * @param step step to append new step to * @param fn step function */ lnm_err lnm_http_step_append(lnm_http_step **out, lnm_http_step *step, lnm_http_step_fn fn); /** * Initialize a new route of type literal. * * @param out where to store pointer to new `lnm_http_route` * @param path literal path to match * @param step step to process request with */ lnm_err lnm_http_route_init_literal(lnm_http_route **out, lnm_http_method method, const char *path, lnm_http_step *step); /** * Initialize a new route of type regex. * * @param out where to store pointer to new `lnm_http_route` * @param pattern regex pattern * @param regex_group_count how many regex groups are contained in the pattern * @param step step to process request with */ 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); /** * Add a new route to the HTTP route. * * @param hl HTTP loop to modify * @param route route to add */ lnm_err lnm_http_loop_route_add(lnm_http_loop *hl, lnm_http_route *route); lnm_err lnm_http_loop_run(lnm_http_loop *hl, uint16_t port); void lnm_http_loop_set_api_key(lnm_http_loop *hl, const char *api_key); void lnm_http_loop_set_server(lnm_http_loop *hl, const char *value); /** * Represents what state an HTTP loop request is currently in. */ typedef enum lnm_http_loop_state { // Parse the HTTP request lnm_http_loop_state_parse_req = 0, // Route the request lnm_http_loop_state_route, // Parse specific headers (e.g. Content-Length) lnm_http_loop_state_parse_headers, // Execute the various steps defined for the route lnm_http_loop_state_steps, // Add certain automatically added headers lnm_http_loop_state_add_headers, // Write the response status line lnm_http_loop_state_write_status_line, // Write the various response headers lnm_http_loop_state_write_headers, // Write the request body lnm_http_loop_state_write_body, // Clean up the request and reset the state for a next request lnm_http_loop_state_finish, } lnm_http_loop_state; typedef struct lnm_http_loop_gctx { struct { lnm_http_route **arr; size_t len; } routes; lnm_http_ctx_init_fn ctx_init; lnm_http_ctx_reset_fn ctx_reset; lnm_http_ctx_free_fn ctx_free; const char *api_key; const char *server; void *c; } lnm_http_loop_gctx; typedef struct lnm_http_loop_ctx { lnm_http_loop_state state; lnm_http_req req; lnm_http_res res; lnm_http_route *route; lnm_http_step *cur_step; lnm_http_loop_gctx *g; void *c; } lnm_http_loop_ctx; lnm_http_step_err lnm_http_loop_step_body_to_buf(lnm_http_conn *conn); lnm_http_step_err lnm_http_loop_step_auth(lnm_http_conn *conn); #endif