diff --git a/src/lander/lander.c b/src/lander/lander.c index 2fa379b..5713c58 100644 --- a/src/lander/lander.c +++ b/src/lander/lander.c @@ -16,9 +16,9 @@ http_route lander_routes[] = { .path = "^/s\\(l\\?\\)/\\([^/]*\\)$", .steps = {http_loop_step_auth, http_loop_step_body_to_buf, lander_post_redirect, NULL}}, - {.type = http_route_literal, + {.type = http_route_regex, .method = http_post, - .path = "/p/", + .path = "^/p\\(l\\?\\)/\\([^/]*\\)$", .steps = {http_loop_step_auth, lander_post_paste, http_loop_step_body_to_file, http_loop_step_switch_res, NULL}}, }; diff --git a/src/lander/lander_post.c b/src/lander/lander_post.c index cd66152..a958982 100644 --- a/src/lander/lander_post.c +++ b/src/lander/lander_post.c @@ -2,12 +2,63 @@ #include "lander.h" #include "log.h" -bool lander_post_redirect(event_loop_conn *conn) { - http_loop_ctx *ctx = conn->ctx; - +// TODO entry leaks if key is already present +static bool add_entry(char **key_ptr, int *key_len_ptr, http_loop_ctx *ctx, + Entry *entry, bool random) { // The first match group matches the "long" path bool secure = (ctx->req.regex_groups[1].rm_eo - ctx->req.regex_groups[1].rm_so) == 1; + + char *key; + int key_len = 0; + TrieExitCode res; + + if (random) { + res = trie_add_random(ctx->g->trie, &key, entry, secure); + + if (res == Ok) { + key_len = strlen(key); + } + } else { + key = (char *)&ctx->req.path[ctx->req.regex_groups[2].rm_so]; + key_len = ctx->req.regex_groups[2].rm_eo - ctx->req.regex_groups[2].rm_so; + + res = trie_add_len(ctx->g->trie, key, key_len, entry); + } + + switch (res) { + case Ok: + break; + case AlreadyPresent: + ctx->res.status = http_conflict; + return false; + default: + ctx->res.status = http_internal_server_error; + return false; + } + + // Add a slash to the key and add it as the location header + char *buf = malloc(key_len + 2); + + memcpy(&buf[1], key, key_len); + buf[0] = '/'; + buf[key_len + 1] = '\0'; + + http_res_add_header(&ctx->res, http_header_location, buf, true); + + if (key_ptr != NULL) { + *key_ptr = key; + } + + if (key_len_ptr != NULL) { + *key_len_ptr = key_len; + } + + return true; +} + +bool lander_post_redirect(event_loop_conn *conn) { + http_loop_ctx *ctx = conn->ctx; bool random = ctx->req.regex_groups[2].rm_eo == ctx->req.regex_groups[2].rm_so; @@ -18,60 +69,18 @@ bool lander_post_redirect(event_loop_conn *conn) { Entry *new_entry = entry_new(Redirect, url); + // The entry duplicates the string + free(url); + + // We don't check the result here, because we would perform the same action + // either way char *key; - int key_len; - - if (random) { - TrieExitCode res = trie_add_random(ctx->g->trie, &key, new_entry, secure); - - if (res != Ok) { - error("trie_add_random failed with exit code %i", res); - - ctx->res.status = http_internal_server_error; - conn->state = event_loop_conn_state_res; - - return true; - } - - key_len = strlen(key); - } else { - key = (char *)&ctx->req.path[ctx->req.regex_groups[2].rm_so]; - key_len = ctx->req.regex_groups[2].rm_eo - ctx->req.regex_groups[2].rm_so; - - TrieExitCode res = trie_add_len(ctx->g->trie, key, key_len, new_entry); - - switch (res) { - case Ok: - break; - case AlreadyPresent: - ctx->res.status = http_conflict; - break; - default: - ctx->res.status = http_internal_server_error; - } - - if (res != Ok) { - error("trie_add_len failed with exit code %i", res); - - conn->state = event_loop_conn_state_res; - - return true; - } - } - - // Add a slash to the key and add it as the location header - char *buf = malloc(key_len + 2); - - memcpy(&buf[1], key, key_len); - buf[0] = '/'; - buf[key_len + 1] = '\0'; + add_entry(&key, NULL, ctx, new_entry, random); if (random) { free(key); } - http_res_add_header(&ctx->res, http_header_location, buf, true); - conn->state = event_loop_conn_state_res; return true; @@ -79,37 +88,28 @@ bool lander_post_redirect(event_loop_conn *conn) { bool lander_post_paste(event_loop_conn *conn) { http_loop_ctx *ctx = conn->ctx; + bool random = + ctx->req.regex_groups[2].rm_eo == ctx->req.regex_groups[2].rm_so; char *key; + int key_len; Entry *new_entry = entry_new(Paste, ""); - TrieExitCode res = trie_add_random(ctx->g->trie, &key, new_entry, false); - if (res != Ok) { - error("trie_add_random failed with exit code %i", res); - - ctx->res.status = http_internal_server_error; + if (!add_entry(&key, &key_len, ctx, new_entry, random)) { conn->state = event_loop_conn_state_res; return true; } - // Add a slash to the key and add it as the location header - size_t key_len = strlen(key); - char *buf = malloc(key_len + 2); - - memcpy(&buf[1], key, key_len); - buf[0] = '/'; - buf[key_len + 1] = '\0'; - - http_res_add_header(&ctx->res, http_header_location, buf, true); - // TODO free this char *fname = malloc(8 + key_len); - sprintf(fname, "pastes/%s", key); + sprintf(fname, "pastes/%.*s", key_len, key); ctx->req.body_file_name = fname; - free(key); + if (random) { + free(key); + } return true; }