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\\?\\)/\\([^/]*\\)$",
|
.path = "^/s\\(l\\?\\)/\\([^/]*\\)$",
|
||||||
.steps = {http_loop_step_auth, http_loop_step_body_to_buf,
|
.steps = {http_loop_step_auth, http_loop_step_body_to_buf,
|
||||||
lander_post_redirect, NULL}},
|
lander_post_redirect, NULL}},
|
||||||
{.type = http_route_literal,
|
{.type = http_route_regex,
|
||||||
.method = http_post,
|
.method = http_post,
|
||||||
.path = "/p/",
|
.path = "^/p\\(l\\?\\)/\\([^/]*\\)$",
|
||||||
.steps = {http_loop_step_auth, lander_post_paste,
|
.steps = {http_loop_step_auth, lander_post_paste,
|
||||||
http_loop_step_body_to_file, http_loop_step_switch_res, NULL}},
|
http_loop_step_body_to_file, http_loop_step_switch_res, NULL}},
|
||||||
};
|
};
|
||||||
|
|
|
@ -2,12 +2,63 @@
|
||||||
#include "lander.h"
|
#include "lander.h"
|
||||||
#include "log.h"
|
#include "log.h"
|
||||||
|
|
||||||
bool lander_post_redirect(event_loop_conn *conn) {
|
// TODO entry leaks if key is already present
|
||||||
http_loop_ctx *ctx = conn->ctx;
|
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
|
// The first match group matches the "long" path
|
||||||
bool secure =
|
bool secure =
|
||||||
(ctx->req.regex_groups[1].rm_eo - ctx->req.regex_groups[1].rm_so) == 1;
|
(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 =
|
bool random =
|
||||||
ctx->req.regex_groups[2].rm_eo == ctx->req.regex_groups[2].rm_so;
|
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);
|
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;
|
char *key;
|
||||||
int key_len;
|
add_entry(&key, NULL, ctx, new_entry, random);
|
||||||
|
|
||||||
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';
|
|
||||||
|
|
||||||
if (random) {
|
if (random) {
|
||||||
free(key);
|
free(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
http_res_add_header(&ctx->res, http_header_location, buf, true);
|
|
||||||
|
|
||||||
conn->state = event_loop_conn_state_res;
|
conn->state = event_loop_conn_state_res;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -79,37 +88,28 @@ bool lander_post_redirect(event_loop_conn *conn) {
|
||||||
|
|
||||||
bool lander_post_paste(event_loop_conn *conn) {
|
bool lander_post_paste(event_loop_conn *conn) {
|
||||||
http_loop_ctx *ctx = conn->ctx;
|
http_loop_ctx *ctx = conn->ctx;
|
||||||
|
bool random =
|
||||||
|
ctx->req.regex_groups[2].rm_eo == ctx->req.regex_groups[2].rm_so;
|
||||||
|
|
||||||
char *key;
|
char *key;
|
||||||
|
int key_len;
|
||||||
Entry *new_entry = entry_new(Paste, "");
|
Entry *new_entry = entry_new(Paste, "");
|
||||||
TrieExitCode res = trie_add_random(ctx->g->trie, &key, new_entry, false);
|
|
||||||
|
|
||||||
if (res != Ok) {
|
if (!add_entry(&key, &key_len, ctx, new_entry, random)) {
|
||||||
error("trie_add_random failed with exit code %i", res);
|
|
||||||
|
|
||||||
ctx->res.status = http_internal_server_error;
|
|
||||||
conn->state = event_loop_conn_state_res;
|
conn->state = event_loop_conn_state_res;
|
||||||
|
|
||||||
return true;
|
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
|
// TODO free this
|
||||||
char *fname = malloc(8 + key_len);
|
char *fname = malloc(8 + key_len);
|
||||||
sprintf(fname, "pastes/%s", key);
|
sprintf(fname, "pastes/%.*s", key_len, key);
|
||||||
|
|
||||||
ctx->req.body_file_name = fname;
|
ctx->req.body_file_name = fname;
|
||||||
|
|
||||||
free(key);
|
if (random) {
|
||||||
|
free(key);
|
||||||
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue