lander/include/http_loop.h

133 lines
3.1 KiB
C

#ifndef LANDER_HTTP_LOOP
#define LANDER_HTTP_LOOP
#include <regex.h>
#include "event_loop.h"
#include "http.h"
#include "trie.h"
#define MIN(x, y) (((x) < (y)) ? (x) : (y))
#define MAX(x, y) (((x) > (y)) ? (x) : (y))
typedef enum http_route_type {
http_route_literal = 0,
http_route_regex = 1,
} http_route_type;
typedef struct http_route {
http_route_type type;
http_request_method method;
char *path;
regex_t *regex;
bool (*steps[5])(event_loop_conn *);
} http_route;
/*
* Global context passed to every connection using the same pointer
*/
typedef struct http_loop_gctx {
http_route *routes;
size_t route_count;
Trie *trie;
const char *api_key;
} http_loop_gctx;
/*
* Initialize a new global context
*/
http_loop_gctx *http_loop_gctx_init();
/*
* Invidivual context initialized for every connection
*/
typedef struct http_loop_ctx {
http_request req;
http_response res;
http_route *route;
size_t current_step;
http_loop_gctx *g;
} http_loop_ctx;
/*
* Initialize a context struct
*/
http_loop_ctx *http_loop_ctx_init(http_loop_gctx *g);
/*
* Resets an already allocated context so that it can be reused for a new
* request.
*/
void http_loop_ctx_reset(http_loop_ctx *ctx);
/*
* Free a context struct
*/
void http_loop_ctx_free(http_loop_ctx *ctx);
/*
* Process incoming data as an HTTP request. This is the "handle_data" function
* for the event loop.
*/
bool http_loop_handle_request(event_loop_conn *conn);
/*
* Write the HTTP response to the file descriptor. This is the "write_data"
* function for the event loop.
*/
void http_loop_write_response(event_loop_conn *conn);
/*
* Try to parse the incoming data as an HTTP request.
*/
http_parse_error http_loop_parse_request(event_loop_conn *conn);
/*
* Try to match the parsed request with one of the defined routes, aka route the
* request.
*/
void http_loop_route_request(event_loop_conn *conn);
/*
* Advance the processing of the routed request's processing by cycling through
* the request's various steps.
*/
void http_loop_process_request(event_loop_conn *conn);
/*
* Set the request body to the given buffer. If owned is set to true, the body
* buffer will be free'd after the request has finished.
*/
void http_loop_res_set_body_buf(http_loop_ctx *ctx, const char *body,
size_t body_len, bool owned);
void http_loop_res_set_body_file(http_loop_ctx *ctx, const char *filename);
void http_loop_res_add_header(http_loop_ctx *ctx, http_header type,
const char *value, bool owned);
void http_loop_res_set_mime_type(http_loop_ctx *ctx, http_mime_type mime_type);
/*
* Request step that consumes the request body and stores it in a buffer
*/
bool http_loop_step_body_to_buf(event_loop_conn *conn);
bool http_loop_step_body_to_file(event_loop_conn *conn);
/*
* Authenticate the request using the X-Api-Key header
*/
bool http_loop_step_auth(event_loop_conn *conn);
bool http_loop_step_switch_res(event_loop_conn *conn);
/**
* Initialize a new http loop
*/
event_loop *http_loop_init(http_loop_gctx *gctx);
void http_loop_run(event_loop *el, int port);
#endif