From 58a8645c6c4f1ad5260661950c3a220a254ec3eb Mon Sep 17 00:00:00 2001 From: Chewing_Bever Date: Thu, 7 Dec 2023 12:54:34 +0100 Subject: [PATCH] feat(lnm): support HEAD requests --- CHANGELOG.md | 1 + lnm/include/lnm/http/consts.h | 3 ++- lnm/src/http/lnm_http_consts.c | 3 ++- lnm/src/http/lnm_http_loop_process.c | 18 ++++++++++++++---- 4 files changed, 19 insertions(+), 6 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ea9588b..4736fb6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -17,6 +17,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * Allow custom & an arbitrary number of response headers * Better API for adding routes * State machine HTTP loop + * Auomatically support HEAD requests for all GET requests ## [0.2.0](https://git.rustybever.be/Chewing_Bever/lander/src/tag/0.2.0) diff --git a/lnm/include/lnm/http/consts.h b/lnm/include/lnm/http/consts.h index 89622a3..f543bbb 100644 --- a/lnm/include/lnm/http/consts.h +++ b/lnm/include/lnm/http/consts.h @@ -11,7 +11,8 @@ typedef enum lnm_http_method { lnm_http_method_post, lnm_http_method_put, lnm_http_method_patch, - lnm_http_method_delete + lnm_http_method_delete, + lnm_http_method_head, } lnm_http_method; extern const char *lnm_http_status_names[][32]; diff --git a/lnm/src/http/lnm_http_consts.c b/lnm/src/http/lnm_http_consts.c index 834816a..cfbee40 100644 --- a/lnm/src/http/lnm_http_consts.c +++ b/lnm/src/http/lnm_http_consts.c @@ -1,6 +1,7 @@ #include "lnm/http/consts.h" -const char *lnm_http_method_names[] = {"GET", "POST", "PUT", "PATCH", "DELETE"}; +const char *lnm_http_method_names[] = {"GET", "POST", "PUT", + "PATCH", "DELETE", "HEAD"}; const size_t lnm_http_method_names_len = sizeof(lnm_http_method_names) / sizeof(lnm_http_method_names[0]); diff --git a/lnm/src/http/lnm_http_loop_process.c b/lnm/src/http/lnm_http_loop_process.c index 8c50ec1..7c32868 100644 --- a/lnm/src/http/lnm_http_loop_process.c +++ b/lnm/src/http/lnm_http_loop_process.c @@ -68,8 +68,14 @@ void lnm_http_loop_process_route(lnm_http_conn *conn) { break; } - // Remember the previous match levels - int new_match_level = 2 * matched_path + (route->method == ctx->req.method); + // GET routes also automatically route HEAD requests + bool matched_method = route->method == ctx->req.method || + (route->method == lnm_http_method_get && + ctx->req.method == lnm_http_method_head); + int new_match_level = 2 * matched_path + matched_method; + + // Remember the previous match levels so we can return the correct status + // message match_level = match_level < new_match_level ? new_match_level : match_level; } @@ -227,8 +233,12 @@ void lnm_http_loop_process_write_headers(lnm_http_conn *conn) { conn->w.buf[conn->w.size] = '\n'; conn->w.size++; - ctx->state = ctx->res.body.len > 0 ? lnm_http_loop_state_write_body - : lnm_http_loop_state_finish; + // HEAD requests function exactly the same as GET requests, except that they + // skip the body writing part + ctx->state = + ctx->req.method != lnm_http_method_head && ctx->res.body.len > 0 + ? lnm_http_loop_state_write_body + : lnm_http_loop_state_finish; } }