144 lines
4.2 KiB
C
144 lines
4.2 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"
|
|
|
|
#define LNM_HTTP_MAX_KEY_SEGMENTS 4
|
|
|
|
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);
|
|
|
|
typedef struct lnm_http_route lnm_http_route;
|
|
|
|
typedef struct lnm_http_route_match_segment {
|
|
size_t start;
|
|
size_t len;
|
|
} lnm_http_route_match_segment;
|
|
|
|
typedef struct lnm_http_route_match {
|
|
const lnm_http_route *route;
|
|
lnm_http_method method;
|
|
lnm_http_route_match_segment key_segments[LNM_HTTP_MAX_KEY_SEGMENTS];
|
|
} lnm_http_route_match;
|
|
|
|
typedef struct lnm_http_router lnm_http_router;
|
|
|
|
typedef enum lnm_http_route_err {
|
|
lnm_http_route_err_match = 0,
|
|
lnm_http_route_err_unknown_route = 1,
|
|
lnm_http_route_err_unknown_method = 2,
|
|
} lnm_http_route_err;
|
|
|
|
/**
|
|
* Allocate and initialize a new http_router.
|
|
*/
|
|
lnm_err lnm_http_router_init(lnm_http_router **out);
|
|
|
|
void lnm_http_router_free(lnm_http_router *router);
|
|
|
|
lnm_err lnm_http_router_add(lnm_http_route **out, lnm_http_router *http_router,
|
|
lnm_http_method method, const char *path);
|
|
|
|
/**
|
|
* Add all of the child router's routes to the parent router, under the given
|
|
* route prefix.
|
|
*/
|
|
lnm_err lnm_http_router_nest(lnm_http_router *parent,
|
|
const lnm_http_router *child, const char *prefix);
|
|
|
|
lnm_http_route_err lnm_http_router_route(lnm_http_route_match *out,
|
|
const lnm_http_router *router,
|
|
lnm_http_method method,
|
|
const char *path);
|
|
|
|
const lnm_http_route_match_segment *
|
|
lnm_http_route_match_get(lnm_http_route_match *match, const char *key);
|
|
|
|
lnm_err lnm_http_route_step_append(lnm_http_route *route, lnm_http_step_fn fn,
|
|
bool blocking);
|
|
|
|
/**
|
|
* 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);
|
|
|
|
void lnm_http_loop_router_set(lnm_http_loop *hl, lnm_http_router *router);
|
|
|
|
lnm_err lnm_http_loop_run(lnm_http_loop *hl, uint16_t port,
|
|
size_t epoll_threads, size_t worker_threads);
|
|
|
|
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 {
|
|
lnm_http_router *router;
|
|
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_match match;
|
|
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
|