diff --git a/Makefile b/Makefile index d6d9364..f2c448c 100644 --- a/Makefile +++ b/Makefile @@ -39,11 +39,7 @@ objs: $(OBJS) liblsm: $(MAKE) -C lsm -.PHONY: liblnm -liblnm: - $(MAKE) -C lnm - -$(BIN): liblsm liblnm $(OBJS) +$(BIN): liblsm $(OBJS) $(CC) -o $@ $(OBJS) $(_LDFLAGS) $(BUILD_DIR)/$(SRC_DIR)/%.c.o: $(SRC_DIR)/%.c @@ -72,7 +68,7 @@ run: $(BIN) valgrind: $(BIN) LANDER_API_KEY=test \ LANDER_DATA_DIR=data \ - valgrind --track-origins=yes '$(BUILD_DIR)/$(BIN_FILENAME)' + valgrind '$(BUILD_DIR)/$(BIN_FILENAME)' .PHONY: test test: $(TARGETS_TEST) diff --git a/config.mk b/config.mk index 244a7b2..da3e0b8 100644 --- a/config.mk +++ b/config.mk @@ -7,9 +7,9 @@ SRC_DIR = src TEST_DIR = test THIRDPARTY_DIR = thirdparty -INC_DIRS = include $(THIRDPARTY_DIR)/include lsm/include lnm/include -LIBS = m lsm lnm -LIB_DIRS = ./lsm/build ./lnm/build +INC_DIRS = include $(THIRDPARTY_DIR)/include lsm/include +LIBS = m lsm +LIB_DIRS = ./lsm/build # -MMD: generate a .d file for every source file. This file can be imported by # make and makes make aware that a header file has been changed, ensuring an diff --git a/include/lander.h b/include/lander.h index 7220559..a30c32d 100644 --- a/include/lander.h +++ b/include/lander.h @@ -1,11 +1,8 @@ #ifndef LANDER #define LANDER -#include "lnm/common.h" -#include "lnm/http/loop.h" -#include "lsm/store.h" - #include "http_loop.h" +#include "lsm/store.h" extern http_route lander_routes[6]; extern const char lander_key_charset[]; @@ -34,13 +31,13 @@ typedef enum lander_entry_type : uint8_t { void *lander_gctx_init(); -lnm_err lander_ctx_init(void **c_ctx, void *gctx); +void *lander_ctx_init(); void lander_ctx_reset(lander_ctx *ctx); void lander_ctx_free(lander_ctx *ctx); -lnm_http_step_err lander_get_index(lnm_http_conn *conn); +bool lander_get_index(event_loop_conn *conn); bool lander_get_entry(event_loop_conn *conn); diff --git a/lnm/include/lnm/common.h b/lnm/include/lnm/common.h index 8cc982e..9c95d52 100644 --- a/lnm/include/lnm/common.h +++ b/lnm/include/lnm/common.h @@ -79,11 +79,4 @@ uint64_t lnm_ipow(uint64_t base, uint64_t power); */ uint64_t lnm_atoi(const char *s, size_t len); -/** - * Calculate how many base 10 digits the given number consists of. - * - * @param num number to use - */ -uint64_t lnm_digits(uint64_t num); - #endif diff --git a/lnm/include/lnm/http/consts.h b/lnm/include/lnm/http/consts.h index 89622a3..37f3239 100644 --- a/lnm/include/lnm/http/consts.h +++ b/lnm/include/lnm/http/consts.h @@ -7,11 +7,11 @@ extern const char *lnm_http_method_names[]; extern const size_t lnm_http_method_names_len; typedef enum lnm_http_method { - lnm_http_method_get = 0, - lnm_http_method_post, - lnm_http_method_put, - lnm_http_method_patch, - lnm_http_method_delete + http_method_get = 0, + http_method_post, + http_method_put, + http_method_patch, + http_method_delete } lnm_http_method; extern const char *lnm_http_status_names[][32]; diff --git a/lnm/include/lnm/http/loop.h b/lnm/include/lnm/http/loop.h index 482560d..12ff602 100644 --- a/lnm/include/lnm/http/loop.h +++ b/lnm/include/lnm/http/loop.h @@ -32,20 +32,12 @@ lnm_err lnm_http_loop_init(lnm_http_loop **out, void *c_gctx, 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 + * @param fn step funcitonn */ lnm_err lnm_http_step_append(lnm_http_step **out, lnm_http_step *step, lnm_http_step_fn fn); @@ -79,9 +71,7 @@ lnm_err lnm_http_route_init_regex(lnm_http_route **out, lnm_http_method method, * @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_route_add(lnm_http_loop *hl, lnm_http_route *route); /** * Represents what state an HTTP loop request is currently in. @@ -95,8 +85,6 @@ typedef enum lnm_http_loop_state { 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 diff --git a/lnm/include/lnm/http/res.h b/lnm/include/lnm/http/res.h index b34f5da..4364597 100644 --- a/lnm/include/lnm/http/res.h +++ b/lnm/include/lnm/http/res.h @@ -45,12 +45,12 @@ typedef struct lnm_http_res { FILE *f; data_fn fn; } data; - uint64_t len; + size_t len; bool owned; lnm_http_res_body_type type; } body; // General-purpose; meaning depends on the current state - uint64_t written; + size_t written; } lnm_http_res; /** diff --git a/lnm/src/http/lnm_http_loop.c b/lnm/src/http/lnm_http_loop.c index 6cd7d53..e79d3c3 100644 --- a/lnm/src/http/lnm_http_loop.c +++ b/lnm/src/http/lnm_http_loop.c @@ -20,9 +20,6 @@ lnm_err lnm_http_loop_init(lnm_http_loop **out, void *c_gctx, 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; @@ -45,9 +42,7 @@ 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; - } + step->next = *out; return lnm_err_ok; } @@ -101,28 +96,3 @@ lnm_err lnm_http_route_init_regex(lnm_http_route **out, lnm_http_method method, 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) { - LNM_RES(lnm_loop_setup(hl, port)); - return lnm_loop_run(hl); -} diff --git a/lnm/src/http/lnm_http_loop_process.c b/lnm/src/http/lnm_http_loop_process.c index 32bc840..9090df2 100644 --- a/lnm/src/http/lnm_http_loop_process.c +++ b/lnm/src/http/lnm_http_loop_process.c @@ -12,7 +12,7 @@ /* static const lnm_http_loop_state lnm_http_loop_state_first_req = * lnm_http_loop_state_parse_req; */ static const lnm_http_loop_state lnm_http_loop_state_first_res = - lnm_http_loop_state_write_status_line; + lnm_http_loop_state_write_headers; void lnm_http_loop_process_parse_req(lnm_http_conn *conn) { lnm_http_loop_ctx *ctx = conn->ctx; @@ -65,7 +65,6 @@ void lnm_http_loop_process_route(lnm_http_conn *conn) { matched_path = regexec(route->route.regex, ctx->req.path.s, LNM_HTTP_MAX_REGEX_GROUPS, ctx->req.path.groups, 0) == 0; - break; } // Remember the previous match levels @@ -106,12 +105,9 @@ void lnm_http_loop_process_parse_headers(lnm_http_conn *conn) { void lnm_http_loop_process_steps(lnm_http_conn *conn) { lnm_http_loop_ctx *ctx = conn->ctx; - lnm_http_step *step = NULL; + lnm_http_step *step; - // Loop until we either: - // - reach the end of the chain of steps, indicated by NULL - // - have a step that's waiting for I/O - while ((ctx->cur_step != NULL) && (step != ctx->cur_step)) { + do { step = ctx->cur_step; switch (step->fn(conn)) { @@ -128,34 +124,16 @@ void lnm_http_loop_process_steps(lnm_http_conn *conn) { break; } } + // Loop until we either: + // - reach the end of the chain of steps, indicated by NULL + // - have a step that's waiting for I/O + while ((ctx->cur_step != NULL) && (step != ctx->cur_step)); if (ctx->cur_step == NULL) { - ctx->state = lnm_http_loop_state_add_headers; + ctx->state = lnm_http_loop_state_write_headers; } } -void lnm_http_loop_state_process_add_headers(lnm_http_conn *conn) { - lnm_http_loop_ctx *ctx = conn->ctx; - lnm_http_res *res = &ctx->res; - - if (res->body.len > 0) { - uint64_t digits = lnm_digits(res->body.len); - char *buf = malloc(digits + 1); - - if (buf == NULL) { - conn->state = lnm_loop_state_end; - - return; - } - - sprintf(buf, "%lu", res->body.len); - lnm_http_res_add_header_len(res, lnm_http_header_content_length, buf, - digits, true); - } - - ctx->state = lnm_http_loop_state_write_status_line; -} - // This function is intentionally written inefficiently for now, as it will most // likely only have to run once for each response void lnm_http_loop_process_write_status_line(lnm_http_conn *conn) { @@ -221,13 +199,7 @@ void lnm_http_loop_process_write_headers(lnm_http_conn *conn) { } } - // The headers should end with an additional newline. If there's no space left - // in the write buffer, we don't switch states so we can re-try this write - // later - if ((res->headers.current == NULL) && (conn->w.size < LNM_LOOP_BUF_SIZE)) { - conn->w.buf[conn->w.size] = '\n'; - conn->w.size++; - + if (res->headers.current == NULL) { ctx->state = ctx->res.body.len > 0 ? lnm_http_loop_state_write_body : lnm_http_loop_state_finish; } @@ -286,34 +258,12 @@ void (*process_fns[])(lnm_http_conn *conn) = { lnm_http_loop_process_route, lnm_http_loop_process_parse_headers, lnm_http_loop_process_steps, - lnm_http_loop_state_process_add_headers, lnm_http_loop_process_write_status_line, lnm_http_loop_process_write_headers, lnm_http_loop_process_write_body, lnm_http_loop_process_finish, }; -lnm_loop_state state_map[] = { - // parse_req - lnm_loop_state_req, - // route - lnm_loop_state_req, - // parse_headers - lnm_loop_state_req, - // steps - lnm_loop_state_req, - // add_headers - lnm_loop_state_req, - // write_status_line - lnm_loop_state_res, - // write_headers - lnm_loop_state_res, - // write_body - lnm_loop_state_res, - // finish - lnm_loop_state_res, -}; - void lnm_http_loop_process(lnm_http_conn *conn) { const lnm_http_loop_ctx *ctx = conn->ctx; @@ -321,21 +271,13 @@ void lnm_http_loop_process(lnm_http_conn *conn) { lnm_loop_state loop_state = conn->state; // We stop processing if: - // - the event loop state has been explicitely changed inside the executed - // step, as we need to switch to the other I/O loop - // - the event loop state needs to be changed because the next step should be - // run in another event loop state + // - the event loop state has changed, as we need to switch to the other I/O + // loop // - the process fn returned without changing the HTTP loop state, indicating // it's waiting for I/O do { http_loop_state = ctx->state; process_fns[http_loop_state](conn); - } while ((conn->state == loop_state) && - (conn->state == state_map[http_loop_state]) && - (http_loop_state != ctx->state)); - - // Check required to prevent overwriting manually set event loop state - conn->state = - conn->state == loop_state ? state_map[http_loop_state] : conn->state; + } while ((conn->state == loop_state) && (http_loop_state != ctx->state)); } diff --git a/lnm/src/http/lnm_http_req.c b/lnm/src/http/lnm_http_req.c index ba7cccc..1588bcd 100644 --- a/lnm/src/http/lnm_http_req.c +++ b/lnm/src/http/lnm_http_req.c @@ -37,8 +37,6 @@ lnm_http_parse_err lnm_http_req_parse(lnm_http_req *req, char *buf, return lnm_http_parse_err_unknown_method; } - // Path will always end with a newline, which we can safely set to nul - path[path_len] = '\0'; char *question_mark = strchr(path, '?'); // Only store query if the path doesn't simply end with a question mark diff --git a/lnm/src/lnm_utils.c b/lnm/src/lnm_utils.c index 85094bd..ce60803 100644 --- a/lnm/src/lnm_utils.c +++ b/lnm/src/lnm_utils.c @@ -43,15 +43,3 @@ uint64_t lnm_atoi(const char *s, size_t len) { return res; } - -uint64_t lnm_digits(uint64_t num) { - int digits = 1; - - while (num > 9) { - digits++; - - num /= 10; - } - - return digits; -} diff --git a/lnm/src/loop/lnm_loop.c b/lnm/src/loop/lnm_loop.c index f44c829..c550009 100644 --- a/lnm/src/loop/lnm_loop.c +++ b/lnm/src/loop/lnm_loop.c @@ -1,7 +1,6 @@ #include #include #include -#include #include #include "lnm/common.h" @@ -44,9 +43,7 @@ lnm_err lnm_loop_accept(lnm_loop *l) { // Append connection to list of connections if ((size_t)conn_fd >= l->conns.len) { lnm_loop_conn **new = - l->conns.len == 0 - ? calloc(sizeof(lnm_loop_conn *), conn_fd + 1) - : realloc(l->conns.arr, sizeof(lnm_loop_conn *) * (conn_fd + 1)); + realloc(l->conns.arr, sizeof(lnm_loop_conn *) * (conn_fd + 1)); if (new == NULL) { close(conn_fd); diff --git a/src/lander/lander.c b/src/lander/lander.c index 6d316d2..5d1c1fe 100644 --- a/src/lander/lander.c +++ b/src/lander/lander.c @@ -1,12 +1,10 @@ #include #include -#include "lnm/common.h" -#include "lsm/store.h" - #include "http/types.h" #include "http_loop.h" #include "lander.h" +#include "lsm/store.h" const char lander_key_charset[] = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"; @@ -62,17 +60,7 @@ http_route lander_routes[] = { void *lander_gctx_init() { return calloc(1, sizeof(lander_gctx)); } -lnm_err lander_ctx_init(void **c_ctx, void *gctx) { - lander_ctx *ctx = calloc(1, sizeof(lander_ctx)); - - if (ctx == NULL) { - return lnm_err_failed_alloc; - } - - *c_ctx = ctx; - - return lnm_err_ok; -} +void *lander_ctx_init() { return calloc(1, sizeof(lander_ctx)); } void lander_ctx_reset(lander_ctx *ctx) { if (ctx->entry != NULL) { diff --git a/src/lander/lander_get.c b/src/lander/lander_get.c index 3d05c4d..102c631 100644 --- a/src/lander/lander_get.c +++ b/src/lander/lander_get.c @@ -1,7 +1,5 @@ #include -#include "lnm/loop.h" - #include "event_loop.h" #include "http/res.h" #include "http/types.h" @@ -19,18 +17,14 @@ static const char index_page[] = " \n" "\n"; -lnm_http_step_err lander_get_index(lnm_http_conn *conn) { - lnm_http_loop_ctx *ctx = conn->ctx; +bool lander_get_index(event_loop_conn *conn) { + http_loop_ctx *ctx = conn->ctx; - lnm_http_res_body_set_buf(&ctx->res, (char *)index_page, - sizeof(index_page) - 1, false); + http_res_set_body_buf(&ctx->res, index_page, sizeof(index_page) - 1, false); + http_res_set_mime_type(&ctx->res, http_mime_html); - /* http_res_set_body_buf(&ctx->res, index_page, sizeof(index_page) - 1, - * false); */ - /* http_res_set_mime_type(&ctx->res, http_mime_html); */ - - /* conn->state = event_loop_conn_state_res; */ - return lnm_http_step_err_done; + conn->state = event_loop_conn_state_res; + return true; } void lander_get_redirect(event_loop_conn *conn) { diff --git a/src/main.c b/src/main.c index 78ead69..2f52fc1 100644 --- a/src/main.c +++ b/src/main.c @@ -2,26 +2,9 @@ #include #include -#include "lnm/http/loop.h" - #include "lander.h" #include "log.h" -lnm_http_loop *loop_init(lander_gctx *gctx) { - lnm_http_loop *hl; - lnm_http_step *step = NULL; - lnm_http_route *route; - lnm_http_loop_init(&hl, gctx, lander_ctx_init, - (lnm_http_ctx_reset_fn)lander_ctx_reset, - (lnm_http_ctx_free_fn)lander_ctx_free); - - lnm_http_step_init(&step, lander_get_index); - lnm_http_route_init_literal(&route, lnm_http_method_get, "/", step); - lnm_http_loop_route_add(hl, route); - - return hl; -} - #define ENV(var, env_var) \ const char *var = getenv(env_var); \ if (var == NULL) { \ @@ -61,15 +44,12 @@ int main() { } info("Store loaded containing %lu entries", lsm_store_size(c_gctx->store)); - lnm_http_loop *hl = loop_init(c_gctx); - lnm_http_loop_run(hl, port); - /* http_loop *hl = http_loop_init( */ - /* lander_routes, sizeof(lander_routes) / sizeof(lander_routes[0]), - * c_gctx, */ - /* lander_ctx_init, (void (*)(void *))lander_ctx_reset, */ - /* (void (*)(void *))lander_ctx_free); */ - /* http_loop_set_api_key(hl, api_key); */ + http_loop *hl = http_loop_init( + lander_routes, sizeof(lander_routes) / sizeof(lander_routes[0]), c_gctx, + lander_ctx_init, (void (*)(void *))lander_ctx_reset, + (void (*)(void *))lander_ctx_free); + http_loop_set_api_key(hl, api_key); - /* http_loop_run(hl, port); */ + http_loop_run(hl, port); }