feat: fully support redirect & paste routes
ci/woodpecker/pr/woodpecker Pipeline failed
Details
ci/woodpecker/pr/woodpecker Pipeline failed
Details
parent
58e2d8a02e
commit
a6257a923d
|
@ -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}},
|
||||
};
|
||||
|
|
|
@ -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;
|
||||
|
||||
if (random) {
|
||||
free(key);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue