From 18d67fb69f775c490268cf42518ce0b09ea9644d Mon Sep 17 00:00:00 2001 From: Chewing_Bever Date: Mon, 29 May 2023 12:43:50 +0200 Subject: [PATCH] feat: routes now specify a method --- .gitignore | 1 + include/http.h | 10 +++++----- include/http_loop.h | 4 +++- src/http/http_res_names.c | 1 + src/http_loop/http_loop_ctx.c | 1 + src/http_loop/http_loop_req.c | 14 ++++++++++---- src/http_loop/http_loop_res.c | 11 +++++++++++ src/main.c | 15 ++++++++------- 8 files changed, 40 insertions(+), 17 deletions(-) diff --git a/.gitignore b/.gitignore index c015b60..35f41da 100644 --- a/.gitignore +++ b/.gitignore @@ -5,3 +5,4 @@ compile_commands.json lander.data* pastes/ .cache/ +vgcore.* diff --git a/include/http.h b/include/http.h index 11a05e2..dda8164 100644 --- a/include/http.h +++ b/include/http.h @@ -11,11 +11,11 @@ extern const char *http_response_type_names[5][32]; typedef enum http_request_method { - http_request_method_get = 0, - http_request_method_post = 1, - http_request_method_put = 2, - http_request_method_patch = 3, - http_request_method_delete = 4 + http_get = 0, + http_post = 1, + http_put = 2, + http_patch = 3, + http_delete = 4 } http_request_method; extern const char *request_method_names[]; diff --git a/include/http_loop.h b/include/http_loop.h index 4d07b87..81ac4b5 100644 --- a/include/http_loop.h +++ b/include/http_loop.h @@ -14,6 +14,7 @@ typedef enum 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 *); @@ -93,7 +94,8 @@ 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(const char *body, size_t body_len, bool owned); +void http_loop_res_set_body(http_loop_ctx *ctx, const char *body, + size_t body_len, bool owned); /** * Initialize a new http loop diff --git a/src/http/http_res_names.c b/src/http/http_res_names.c index 028e217..5160d8d 100644 --- a/src/http/http_res_names.c +++ b/src/http/http_res_names.c @@ -3,6 +3,7 @@ // clang-format off const char *http_response_type_names[5][32] = { + // 1xx { "Continue", // 100 "Switching Protocols", // 101, diff --git a/src/http_loop/http_loop_ctx.c b/src/http_loop/http_loop_ctx.c index 1efaa2e..432281f 100644 --- a/src/http_loop/http_loop_ctx.c +++ b/src/http_loop/http_loop_ctx.c @@ -35,6 +35,7 @@ void http_loop_ctx_reset(http_loop_ctx *ctx) { ctx->res.body = NULL; + ctx->res.type = 0; ctx->res.head_len = 0; ctx->res.head_written = 0; ctx->res.body_len = 0; diff --git a/src/http_loop/http_loop_req.c b/src/http_loop/http_loop_req.c index bca88a3..3c6ac6e 100644 --- a/src/http_loop/http_loop_req.c +++ b/src/http_loop/http_loop_req.c @@ -79,6 +79,7 @@ void http_loop_route_request(event_loop_conn *conn) { ctx->req.path); http_route *route; + bool path_matched = false; for (size_t i = 0; i < gctx->route_count; i++) { route = &gctx->routes[i]; @@ -86,16 +87,21 @@ void http_loop_route_request(event_loop_conn *conn) { switch (route->type) { case http_route_literal: if (strncmp(route->path, ctx->req.path, ctx->req.path_len) == 0) { - ctx->route = route; - return; + path_matched = true; + + if (ctx->req.method == route->method) { + ctx->route = route; + return; + } } + break; // TODO case http_route_regex:; } } - // Fallthrough is to write a 404 - ctx->res.type = http_not_found; + // Fallthrough case + ctx->res.type = path_matched ? http_method_not_allowed : http_not_found; conn->state = event_loop_conn_state_res; } diff --git a/src/http_loop/http_loop_res.c b/src/http_loop/http_loop_res.c index 7148cd4..d9ad02c 100644 --- a/src/http_loop/http_loop_res.c +++ b/src/http_loop/http_loop_res.c @@ -9,6 +9,10 @@ static const char *http_response_format = "HTTP/1.1 %i %s\n" "Content-Length: %lu\n\n"; void http_loop_init_header(http_response *res) { + if (res->type == 0) { + res->type = http_ok; + } + const char *response_type_name = http_response_type_names[res->type / 100 - 1][res->type % 100]; @@ -61,3 +65,10 @@ void http_loop_write_response(event_loop_conn *conn) { res->body_written += bytes_to_write; } } + +void http_loop_res_set_body(http_loop_ctx *ctx, const char *body, + size_t body_len, bool owned) { + ctx->res.body = body; + ctx->res.body_len = body_len; + ctx->res.owns_body = owned; +} diff --git a/src/main.c b/src/main.c index 3e3c77e..20e8c85 100644 --- a/src/main.c +++ b/src/main.c @@ -14,19 +14,20 @@ const char index_page[] = " \n" "\n"; -bool http_write_404(event_loop_conn *conn) { +bool lander_get_index(event_loop_conn *conn) { http_loop_ctx *ctx = conn->ctx; - ctx->res.type = 200; - ctx->res.body = index_page; - ctx->res.body_len = sizeof(index_page) - 1; - ctx->res.owns_body = false; + + http_loop_res_set_body(ctx, index_page, sizeof(index_page) - 1, false); + conn->state = event_loop_conn_state_res; return true; } -http_route routes[] = { - {.type = http_route_literal, .path = "/", .steps = {http_write_404, NULL}}}; +http_route routes[] = {{.type = http_route_literal, + .method = http_get, + .path = "/", + .steps = {lander_get_index, NULL}}}; int main() { setvbuf(stdout, NULL, _IONBF, 0);