lander/lnm/include/lnm/http/loop.h

142 lines
4.0 KiB
C

#ifndef LNM_HTTP_LOOP
#define LNM_HTTP_LOOP
#include <stdlib.h>
#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, int thread_count);
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