150 lines
4.0 KiB
C
150 lines
4.0 KiB
C
#include <string.h>
|
|
|
|
#include "lnm/http/req.h"
|
|
#include "lnm/loop.h"
|
|
#include "lsm/store.h"
|
|
|
|
#include "lander.h"
|
|
|
|
static void randomize_key(char *key, int len) {
|
|
size_t charset_len = strlen(lander_key_charset);
|
|
|
|
for (int i = 0; i < len; i++) {
|
|
key[i] = lander_key_charset[rand() % charset_len];
|
|
}
|
|
|
|
key[len] = '\0';
|
|
}
|
|
|
|
/**
|
|
* Insert a new entry into the store.
|
|
*
|
|
* @return true on success, false otherwise
|
|
*/
|
|
bool lander_insert_entry(lnm_http_loop_ctx *ctx, bool secure) {
|
|
lnm_http_loop_gctx *gctx = ctx->g;
|
|
lander_gctx *c_gctx = gctx->c;
|
|
lander_ctx *c_ctx = ctx->c;
|
|
|
|
const char *key_s;
|
|
size_t key_len = lnm_http_req_route_segment(&key_s, &ctx->req, "key");
|
|
|
|
lsm_str *key;
|
|
|
|
if (key_len == 0) {
|
|
// Generate a random key to insert
|
|
key_len = secure ? 16 : 4;
|
|
char *key_s = malloc((key_len + 1) * sizeof(char));
|
|
|
|
randomize_key(key_s, key_len);
|
|
lsm_str_init(&key, key_s);
|
|
} else {
|
|
lsm_str_init_copy_n(&key, key_s, key_len);
|
|
}
|
|
|
|
// TODO free key on error
|
|
switch (lsm_store_insert(&c_ctx->entry, c_gctx->store, key)) {
|
|
case lsm_error_already_present:
|
|
ctx->res.status = lnm_http_status_conflict;
|
|
return false;
|
|
case lsm_error_ok:
|
|
break;
|
|
default:
|
|
ctx->res.status = lnm_http_status_internal_server_error;
|
|
return false;
|
|
}
|
|
|
|
// Add location header
|
|
char *buf = malloc(key_len + 2);
|
|
memcpy(&buf[1], lsm_str_ptr(key), key_len);
|
|
buf[0] = '/';
|
|
buf[key_len + 1] = '\0';
|
|
|
|
lnm_http_res_add_header(&ctx->res, lnm_http_header_location, buf, true);
|
|
ctx->res.status = lnm_http_status_created;
|
|
|
|
return true;
|
|
}
|
|
|
|
static lnm_http_step_err __lander_post_redirect(lnm_http_conn *conn,
|
|
bool secure) {
|
|
lnm_http_loop_ctx *ctx = conn->ctx;
|
|
lander_ctx *c_ctx = ctx->c;
|
|
|
|
if (!lander_insert_entry(ctx, secure)) {
|
|
return lnm_http_step_err_res;
|
|
}
|
|
|
|
lsm_entry_attr_insert_uint8_t(c_ctx->entry, lander_attr_type_entry_type,
|
|
lander_entry_type_redirect);
|
|
|
|
return lnm_http_step_err_done;
|
|
}
|
|
|
|
lnm_http_step_err lander_post_redirect(lnm_http_conn *conn) {
|
|
return __lander_post_redirect(conn, false);
|
|
}
|
|
|
|
lnm_http_step_err lander_post_redirect_secure(lnm_http_conn *conn) {
|
|
return __lander_post_redirect(conn, true);
|
|
}
|
|
|
|
lnm_http_step_err lander_post_redirect_body_to_attr(lnm_http_conn *conn) {
|
|
lnm_http_loop_ctx *ctx = conn->ctx;
|
|
lander_ctx *c_ctx = ctx->c;
|
|
|
|
lsm_str *attr_value;
|
|
lsm_str_init_copy_n(&attr_value, ctx->req.body.buf, ctx->req.body.len);
|
|
lsm_entry_attr_insert(c_ctx->entry, lander_attr_type_url, attr_value);
|
|
|
|
return lnm_http_step_err_done;
|
|
}
|
|
|
|
static lnm_http_step_err __lander_post_paste(lnm_http_conn *conn, bool secure) {
|
|
lnm_http_loop_ctx *ctx = conn->ctx;
|
|
lander_ctx *c_ctx = ctx->c;
|
|
|
|
if (!lander_insert_entry(ctx, secure)) {
|
|
return lnm_http_step_err_res;
|
|
}
|
|
|
|
lsm_entry_attr_insert_uint8_t(c_ctx->entry, lander_attr_type_entry_type,
|
|
lander_entry_type_paste);
|
|
lander_header_to_attr(ctx, "X-Lander-Filename", lander_attr_type_file_name);
|
|
|
|
return lnm_http_step_err_done;
|
|
}
|
|
|
|
lnm_http_step_err lander_post_paste(lnm_http_conn *conn) {
|
|
return __lander_post_paste(conn, false);
|
|
}
|
|
|
|
lnm_http_step_err lander_post_paste_secure(lnm_http_conn *conn) {
|
|
return __lander_post_paste(conn, true);
|
|
}
|
|
|
|
static lnm_http_step_err __lander_post_file(lnm_http_conn *conn, bool secure) {
|
|
lnm_http_loop_ctx *ctx = conn->ctx;
|
|
lander_ctx *c_ctx = ctx->c;
|
|
|
|
if (!lander_insert_entry(ctx, secure)) {
|
|
return lnm_http_step_err_res;
|
|
}
|
|
|
|
lsm_entry_attr_insert_uint8_t(c_ctx->entry, lander_attr_type_entry_type,
|
|
lander_entry_type_file);
|
|
lander_header_to_attr(ctx, "X-Lander-Content-Type",
|
|
lander_attr_type_content_type);
|
|
lander_header_to_attr(ctx, "X-Lander-Filename", lander_attr_type_file_name);
|
|
|
|
return lnm_http_step_err_done;
|
|
}
|
|
|
|
lnm_http_step_err lander_post_file(lnm_http_conn *conn) {
|
|
return __lander_post_file(conn, false);
|
|
}
|
|
|
|
lnm_http_step_err lander_post_file_secure(lnm_http_conn *conn) {
|
|
return __lander_post_file(conn, true);
|
|
}
|