From dfbd179c7a531d91e9779ab8c6b002302dd76963 Mon Sep 17 00:00:00 2001 From: Chewing_Bever Date: Tue, 30 May 2023 09:37:40 +0200 Subject: [PATCH] feat: paved the way for uploading pastes --- include/http.h | 24 +++++++++++------ include/lander.h | 4 +++ src/http_loop/http_loop_ctx.c | 25 +++++++++-------- src/http_loop/http_loop_res.c | 10 +++---- src/http_loop/http_loop_tools.c | 15 ++++++----- src/lander/lander.c | 45 ------------------------------- src/lander/lander_get.c | 48 +++++++++++++++++++++++++++++++++ src/lander/lander_post.c | 2 +- 8 files changed, 96 insertions(+), 77 deletions(-) diff --git a/include/http.h b/include/http.h index b3531ce..8c1cf82 100644 --- a/include/http.h +++ b/include/http.h @@ -3,6 +3,7 @@ #include #include +#include #include #include "picohttpparser.h" @@ -24,6 +25,11 @@ typedef enum http_request_method { extern const char *request_method_names[]; extern const size_t request_method_names_len; +typedef enum http_body_type { + http_body_buf = 0, + http_body_file = 1 +} http_body_type; + /* * Struct representing the specific type of request */ @@ -35,7 +41,11 @@ typedef struct http_request { size_t path_len; const char *query; size_t query_len; - char *body; + http_body_type body_type; + union { + char *buf; + FILE *file; + } body; size_t body_len; size_t body_received; regmatch_t regex_groups[HTTP_MAX_REGEX_GROUPS]; @@ -130,18 +140,16 @@ typedef struct http_response_header { bool owned; } http_response_header; -typedef enum http_response_body_type { - http_response_body_buf = 0, - http_response_body_file = 1 -} http_response_body_type; - typedef struct http_response { http_response_type status; const char *head; size_t head_len; size_t head_written; - http_response_body_type body_type; - void *body; + http_body_type body_type; + union { + char *buf; + FILE *file; + } body; size_t body_len; size_t body_written; // If false, the body won't be freed diff --git a/include/lander.h b/include/lander.h index 8e2f4db..cb3dd69 100644 --- a/include/lander.h +++ b/include/lander.h @@ -5,6 +5,10 @@ extern http_route lander_routes[3]; +bool lander_get_index(event_loop_conn *conn); + +bool lander_get_entry(event_loop_conn *conn); + bool lander_post_redirect(event_loop_conn *conn); #endif diff --git a/src/http_loop/http_loop_ctx.c b/src/http_loop/http_loop_ctx.c index 6945ff8..9696956 100644 --- a/src/http_loop/http_loop_ctx.c +++ b/src/http_loop/http_loop_ctx.c @@ -26,9 +26,13 @@ void http_loop_ctx_reset(http_loop_ctx *ctx) { ctx->route = NULL; ctx->current_step = 0; - if (ctx->req.body != NULL) { - free((void *)ctx->req.body); - ctx->req.body = NULL; + if (ctx->req.body_type == http_body_buf && ctx->req.body.buf != NULL) { + free(ctx->req.body.buf); + ctx->req.body.buf = NULL; + } else if (ctx->req.body_type == http_body_file && + ctx->req.body.file != NULL) { + fclose(ctx->req.body.file); + ctx->req.body.file = NULL; } if (ctx->res.head != NULL) { @@ -36,16 +40,15 @@ void http_loop_ctx_reset(http_loop_ctx *ctx) { ctx->res.head = NULL; } - if (ctx->res.body != NULL) { - if (ctx->res.body_type == http_response_body_buf && ctx->res.owns_body) { - free((void *)ctx->res.body); - } else if (ctx->res.body_type == http_response_body_file) { - fclose(ctx->res.body); - } + if (ctx->res.body_type == http_body_buf && ctx->res.body.buf != NULL) { + free(ctx->res.body.buf); + ctx->res.body.buf = NULL; + } else if (ctx->res.body_type == http_body_file && + ctx->res.body.file != NULL) { + fclose(ctx->res.body.file); + ctx->res.body.file = NULL; } - ctx->res.body = NULL; - for (size_t i = 0; i < ctx->res.header_count; i++) { if (ctx->res.headers[i].owned) { free((void *)ctx->res.headers[i].value); diff --git a/src/http_loop/http_loop_res.c b/src/http_loop/http_loop_res.c index 98563a2..9b5e6f0 100644 --- a/src/http_loop/http_loop_res.c +++ b/src/http_loop/http_loop_res.c @@ -81,15 +81,15 @@ void http_loop_write_response(event_loop_conn *conn) { size_t bytes_written; switch (res->body_type) { - case http_response_body_buf: - memcpy(&conn->wbuf[conn->wbuf_size], - &((const char *)res->body)[res->body_written], bytes_to_write); + case http_body_buf: + memcpy(&conn->wbuf[conn->wbuf_size], &(res->body.buf)[res->body_written], + bytes_to_write); conn->wbuf_size += bytes_to_write; res->body_written += bytes_to_write; break; - case http_response_body_file: + case http_body_file: bytes_written = fread(&conn->wbuf[conn->wbuf_size], sizeof(uint8_t), - bytes_to_write, res->body); + bytes_to_write, res->body.file); conn->wbuf_size += bytes_written; res->body_written += bytes_written; break; diff --git a/src/http_loop/http_loop_tools.c b/src/http_loop/http_loop_tools.c index fcd2a22..68e266e 100644 --- a/src/http_loop/http_loop_tools.c +++ b/src/http_loop/http_loop_tools.c @@ -6,8 +6,8 @@ void http_loop_res_set_body_buf(http_loop_ctx *ctx, const char *body, size_t body_len, bool owned) { - ctx->res.body_type = http_response_body_buf; - ctx->res.body = (void *)body; + ctx->res.body_type = http_body_buf; + ctx->res.body.buf = (char *)body; ctx->res.body_len = body_len; ctx->res.owns_body = owned; } @@ -19,8 +19,8 @@ void http_loop_res_set_body_file(http_loop_ctx *ctx, const char *filename) { // TODO error handling FILE *f = fopen(filename, "r"); - ctx->res.body_type = http_response_body_file; - ctx->res.body = f; + ctx->res.body_type = http_body_file; + ctx->res.body.file = f; ctx->res.body_len = st.st_size; } @@ -85,14 +85,15 @@ bool http_loop_step_body_to_buf(event_loop_conn *conn) { return true; } - ctx->req.body = malloc(ctx->req.body_len * sizeof(uint8_t)); + ctx->req.body_type = http_body_buf; + ctx->req.body.buf = malloc(ctx->req.body_len * sizeof(uint8_t)); ctx->req.body_received = 0; } size_t bytes_to_copy = MIN(conn->rbuf_size - conn->rbuf_read, ctx->req.body_len - ctx->req.body_received); - memcpy(&ctx->req.body[ctx->req.body_received], &conn->rbuf[conn->rbuf_read], - bytes_to_copy); + memcpy(&ctx->req.body.buf[ctx->req.body_received], + &conn->rbuf[conn->rbuf_read], bytes_to_copy); ctx->req.body_received += bytes_to_copy; return ctx->req.body_received == ctx->req.body_len; diff --git a/src/lander/lander.c b/src/lander/lander.c index df76ece..fc245f3 100644 --- a/src/lander/lander.c +++ b/src/lander/lander.c @@ -2,51 +2,6 @@ #include "lander.h" -static const char index_page[] = - "\n" - "\n" - " \n" - "

r8r.be

\n" - "

This is the URL shortener and pastebin accompanying my site, The Rusty Bever.

\n" - " \n" - "\n"; - -bool lander_get_index(event_loop_conn *conn) { - http_loop_ctx *ctx = conn->ctx; - - http_loop_res_set_body_buf(ctx, index_page, sizeof(index_page) - 1, false); - - conn->state = event_loop_conn_state_res; - return true; -} - -bool lander_get_entry(event_loop_conn *conn) { - http_loop_ctx *ctx = conn->ctx; - - const char *key = &ctx->req.path[ctx->req.regex_groups[1].rm_so]; - int key_len = ctx->req.regex_groups[1].rm_eo - ctx->req.regex_groups[1].rm_so; - - Entry *entry; - TrieExitCode res = trie_search_len(ctx->g->trie, &entry, key, key_len); - - if (res == NotFound) { - ctx->res.status = http_not_found; - } else if (entry->type == Redirect) { - ctx->res.status = http_moved_permanently; - http_loop_res_add_header(ctx, http_header_location, entry->string, false); - } else if (entry->type == Paste) { - char fname[8 + key_len]; - sprintf(fname, "pastes/%.*s", key_len, key); - - http_loop_res_set_body_file(ctx, fname); - } - - conn->state = event_loop_conn_state_res; - - return true; -} - http_route lander_routes[] = { {.type = http_route_literal, .method = http_get, diff --git a/src/lander/lander_get.c b/src/lander/lander_get.c index e69de29..c512730 100644 --- a/src/lander/lander_get.c +++ b/src/lander/lander_get.c @@ -0,0 +1,48 @@ +#include + +#include "lander.h" + +static const char index_page[] = + "\n" + "\n" + " \n" + "

r8r.be

\n" + "

This is the URL shortener and pastebin accompanying my site, The Rusty Bever.

\n" + " \n" + "\n"; + +bool lander_get_index(event_loop_conn *conn) { + http_loop_ctx *ctx = conn->ctx; + + http_loop_res_set_body_buf(ctx, index_page, sizeof(index_page) - 1, false); + + conn->state = event_loop_conn_state_res; + return true; +} + +bool lander_get_entry(event_loop_conn *conn) { + http_loop_ctx *ctx = conn->ctx; + + const char *key = &ctx->req.path[ctx->req.regex_groups[1].rm_so]; + int key_len = ctx->req.regex_groups[1].rm_eo - ctx->req.regex_groups[1].rm_so; + + Entry *entry; + TrieExitCode res = trie_search_len(ctx->g->trie, &entry, key, key_len); + + if (res == NotFound) { + ctx->res.status = http_not_found; + } else if (entry->type == Redirect) { + ctx->res.status = http_moved_permanently; + http_loop_res_add_header(ctx, http_header_location, entry->string, false); + } else if (entry->type == Paste) { + char fname[8 + key_len]; + sprintf(fname, "pastes/%.*s", key_len, key); + + http_loop_res_set_body_file(ctx, fname); + } + + conn->state = event_loop_conn_state_res; + + return true; +} diff --git a/src/lander/lander_post.c b/src/lander/lander_post.c index 45f39df..47f64ea 100644 --- a/src/lander/lander_post.c +++ b/src/lander/lander_post.c @@ -6,7 +6,7 @@ bool lander_post_redirect(event_loop_conn *conn) { // Allocate a new buffer to pass to the trie char *url = malloc(ctx->req.body_len + 1); - memcpy(url, ctx->req.body, ctx->req.body_len); + memcpy(url, ctx->req.body.buf, ctx->req.body_len); url[ctx->req.body_len] = '\0'; char *key;