From 3c1e62330c7f0d65c11a8e1582a3fd597ed076f4 Mon Sep 17 00:00:00 2001 From: Chewing_Bever Date: Sat, 2 Dec 2023 13:24:22 +0100 Subject: [PATCH] feat(lnm): implement context resetting --- lnm/include/lnm/http/req.h | 8 +++++++ lnm/include/lnm/http/res.h | 8 +++++++ lnm/src/http/lnm_http_loop_ctx.c | 10 ++++++-- lnm/src/http/lnm_http_loop_process.c | 17 ++++++++++---- lnm/src/http/lnm_http_req.c | 4 ++++ lnm/src/http/lnm_http_res.c | 35 ++++++++++++++++++++++++++++ 6 files changed, 76 insertions(+), 6 deletions(-) diff --git a/lnm/include/lnm/http/req.h b/lnm/include/lnm/http/req.h index def3ad7..1eddb26 100644 --- a/lnm/include/lnm/http/req.h +++ b/lnm/include/lnm/http/req.h @@ -49,4 +49,12 @@ typedef enum lnm_http_parse_err { */ lnm_http_parse_err lnm_http_req_parse(lnm_http_req *req, char *buf, size_t len); +/** + * Reset the given request object, free'ing all its relevant parts and allowing + * it to be reused as a new object. + * + * @param req object to reset + */ +void lnm_http_req_reset(lnm_http_req *req); + #endif diff --git a/lnm/include/lnm/http/res.h b/lnm/include/lnm/http/res.h index 8ea7636..4364597 100644 --- a/lnm/include/lnm/http/res.h +++ b/lnm/include/lnm/http/res.h @@ -108,4 +108,12 @@ void lnm_http_res_body_set_buf(lnm_http_res *res, char *buf, size_t len, */ void lnm_http_res_body_set_fn(lnm_http_res *res, data_fn fn, size_t len); +/** + * Reset the given response object, properly free'ing any allocated buffers, + * allowing it to be reused for later connections. + * + * @param res res to reset + */ +void lnm_http_res_reset(lnm_http_res *res); + #endif diff --git a/lnm/src/http/lnm_http_loop_ctx.c b/lnm/src/http/lnm_http_loop_ctx.c index 64ac8eb..87741e2 100644 --- a/lnm/src/http/lnm_http_loop_ctx.c +++ b/lnm/src/http/lnm_http_loop_ctx.c @@ -38,12 +38,18 @@ lnm_err lnm_http_loop_ctx_init(lnm_http_loop_ctx **out, void lnm_http_loop_ctx_reset(lnm_http_loop_ctx *ctx) { ctx->g->ctx_reset(ctx->c); - // TODO actual reset stuff + + lnm_http_req_reset(&ctx->req); + lnm_http_res_reset(&ctx->res); + + ctx->route = NULL; + ctx->cur_step = NULL; } void lnm_http_loop_ctx_free(lnm_http_loop_ctx *ctx) { + lnm_http_loop_ctx_reset(ctx); + ctx->g->ctx_free(ctx->c); - // TODO actual free stuff free(ctx); } diff --git a/lnm/src/http/lnm_http_loop_process.c b/lnm/src/http/lnm_http_loop_process.c index c8aed94..5952538 100644 --- a/lnm/src/http/lnm_http_loop_process.c +++ b/lnm/src/http/lnm_http_loop_process.c @@ -160,7 +160,7 @@ void lnm_http_loop_process_write_headers(lnm_http_conn *conn) { lnm_http_loop_ctx *ctx = conn->ctx; lnm_http_res *res = &ctx->res; - lnm_http_res_header *header = res->headers.current; + lnm_http_res_header *header; // Loop as long as we can still write new data and have headers to write while ((conn->w.size < LNM_LOOP_BUF_SIZE) && @@ -212,7 +212,7 @@ void lnm_http_loop_process_write_body(lnm_http_conn *conn) { case lnm_http_res_body_type_file: written = fread(&conn->w.buf[conn->w.size], 1, to_write, res->body.data.f); - if ((written == 0) && (!ferror(res->body.data.f))) { + if ((written == 0) && (ferror(res->body.data.f) != 0)) { ctx->state = lnm_http_loop_state_finish; } break; @@ -232,7 +232,16 @@ void lnm_http_loop_process_write_body(lnm_http_conn *conn) { } } -void lnm_http_loop_process_finish(lnm_http_conn *conn) {} +void lnm_http_loop_process_finish(lnm_http_conn *conn) { + // First we ensure the write buffer is fully flushed + if (conn->w.size > 0) { + return; + } + + lnm_http_loop_ctx_reset(conn->ctx); + + conn->state = lnm_loop_state_req; +} void (*process_fns[])(lnm_http_conn *conn) = { lnm_http_loop_process_parse_req, @@ -246,7 +255,7 @@ void (*process_fns[])(lnm_http_conn *conn) = { }; void lnm_http_loop_process(lnm_http_conn *conn) { - lnm_http_loop_ctx *ctx = conn->ctx; + const lnm_http_loop_ctx *ctx = conn->ctx; lnm_http_loop_state http_loop_state; lnm_loop_state loop_state = conn->state; diff --git a/lnm/src/http/lnm_http_req.c b/lnm/src/http/lnm_http_req.c index 2327ce6..33c522c 100644 --- a/lnm/src/http/lnm_http_req.c +++ b/lnm/src/http/lnm_http_req.c @@ -56,3 +56,7 @@ lnm_http_parse_err lnm_http_req_parse(lnm_http_req *req, char *buf, return lnm_http_parse_err_ok; } + +void lnm_http_req_reset(lnm_http_req *req) { + memset(req, 0, sizeof(lnm_http_req)); +} diff --git a/lnm/src/http/lnm_http_res.c b/lnm/src/http/lnm_http_res.c index adf65f0..3f2b0c0 100644 --- a/lnm/src/http/lnm_http_res.c +++ b/lnm/src/http/lnm_http_res.c @@ -62,3 +62,38 @@ void lnm_http_res_body_set_fn(lnm_http_res *res, data_fn fn, size_t len) { res->body.len = len; res->body.type = lnm_http_res_body_type_fn; } + +void lnm_http_res_reset(lnm_http_res *res) { + lnm_http_res_header *header = res->headers.head; + + while (header != NULL) { + lnm_http_res_header *next = header->next; + + if (header->name.owned) { + free(header->name.s); + } + + if (header->value.owned) { + free(header->value.s); + } + + free(header); + + header = next; + } + + if (res->body.owned) { + switch (res->body.type) { + case lnm_http_res_body_type_file: + fclose(res->body.data.f); + break; + case lnm_http_res_body_type_buf: + free(res->body.data.buf); + break; + case lnm_http_res_body_type_fn: + break; + } + } + + memset(res, 0, sizeof(lnm_http_res)); +}