feat(lander): introduce file entry type
parent
3d48ee8019
commit
7fac278ead
|
@ -4,7 +4,7 @@
|
||||||
#include "http_loop.h"
|
#include "http_loop.h"
|
||||||
#include "lsm/store.h"
|
#include "lsm/store.h"
|
||||||
|
|
||||||
extern http_route lander_routes[5];
|
extern http_route lander_routes[6];
|
||||||
|
|
||||||
typedef struct lander_gctx {
|
typedef struct lander_gctx {
|
||||||
const char *data_dir;
|
const char *data_dir;
|
||||||
|
@ -27,6 +27,7 @@ typedef enum lander_attr_type : uint8_t {
|
||||||
typedef enum lander_entry_type : uint8_t {
|
typedef enum lander_entry_type : uint8_t {
|
||||||
lander_entry_type_redirect = 0,
|
lander_entry_type_redirect = 0,
|
||||||
lander_entry_type_paste = 1,
|
lander_entry_type_paste = 1,
|
||||||
|
lander_entry_type_file = 2,
|
||||||
} lander_entry_type;
|
} lander_entry_type;
|
||||||
|
|
||||||
void *lander_gctx_init();
|
void *lander_gctx_init();
|
||||||
|
@ -59,4 +60,6 @@ bool lander_post_redirect_body_to_attr(event_loop_conn *conn);
|
||||||
|
|
||||||
bool lander_remove_entry(event_loop_conn *conn);
|
bool lander_remove_entry(event_loop_conn *conn);
|
||||||
|
|
||||||
|
bool lander_post_file_lsm(event_loop_conn *conn);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -38,4 +38,12 @@ elif [ "$1" = pl ]; then
|
||||||
-H "X-Api-Key: $API_KEY" \
|
-H "X-Api-Key: $API_KEY" \
|
||||||
--data-binary @"$2" \
|
--data-binary @"$2" \
|
||||||
"$URL/pl/$3"
|
"$URL/pl/$3"
|
||||||
|
|
||||||
|
elif [ "$1" = f ]; then
|
||||||
|
curl \
|
||||||
|
-w "${URL}%header{location}" \
|
||||||
|
-XPOST \
|
||||||
|
-H "X-Api-Key: $API_KEY" \
|
||||||
|
--data-binary @"$2" \
|
||||||
|
"$URL/f/$3"
|
||||||
fi
|
fi
|
||||||
|
|
|
@ -44,6 +44,13 @@ http_route lander_routes[] = {
|
||||||
lander_post_paste_lsm, lander_stream_body_to_entry, NULL},
|
lander_post_paste_lsm, lander_stream_body_to_entry, NULL},
|
||||||
.steps_res = {http_loop_step_write_header, http_loop_step_write_body,
|
.steps_res = {http_loop_step_write_header, http_loop_step_write_body,
|
||||||
NULL}},
|
NULL}},
|
||||||
|
{.type = http_route_regex,
|
||||||
|
.method = http_post,
|
||||||
|
.path = "^/f(l?)/([^/]*)$",
|
||||||
|
.steps = {http_loop_step_auth, http_loop_step_parse_content_length,
|
||||||
|
lander_post_file_lsm, lander_stream_body_to_entry, NULL},
|
||||||
|
.steps_res = {http_loop_step_write_header, http_loop_step_write_body,
|
||||||
|
NULL}},
|
||||||
};
|
};
|
||||||
|
|
||||||
void *lander_gctx_init() { return calloc(1, sizeof(lander_gctx)); }
|
void *lander_gctx_init() { return calloc(1, sizeof(lander_gctx)); }
|
||||||
|
|
|
@ -26,6 +26,55 @@ bool lander_get_index(event_loop_conn *conn) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void lander_get_redirect(event_loop_conn *conn) {
|
||||||
|
http_loop_ctx *ctx = conn->ctx;
|
||||||
|
lander_ctx *c_ctx = ctx->c;
|
||||||
|
|
||||||
|
// For redirects, the URL is stored as an in-memory attribute
|
||||||
|
lsm_str *url_attr_val;
|
||||||
|
|
||||||
|
// This shouldn't be able to happen
|
||||||
|
if (lsm_entry_attr_get(&url_attr_val, c_ctx->entry, lander_attr_type_url) !=
|
||||||
|
lsm_error_ok) {
|
||||||
|
error("Entry of type redirect detected without URL attribute");
|
||||||
|
|
||||||
|
ctx->res.status = http_internal_server_error;
|
||||||
|
lsm_entry_close(c_ctx->entry);
|
||||||
|
c_ctx->entry = NULL;
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
char *buf = malloc(lsm_str_len(url_attr_val) + 1);
|
||||||
|
memcpy(buf, lsm_str_ptr(url_attr_val), lsm_str_len(url_attr_val));
|
||||||
|
|
||||||
|
buf[lsm_str_len(url_attr_val)] = '\0';
|
||||||
|
|
||||||
|
ctx->res.status = http_moved_permanently;
|
||||||
|
http_res_add_header(&ctx->res, http_header_location, buf, true);
|
||||||
|
|
||||||
|
// We no longer need the entry at this point, so we can unlock it early
|
||||||
|
// This will also signal to the response code not to read any data from
|
||||||
|
// the entry
|
||||||
|
lsm_entry_close(c_ctx->entry);
|
||||||
|
c_ctx->entry = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void lander_get_paste(event_loop_conn *conn) {
|
||||||
|
http_loop_ctx *ctx = conn->ctx;
|
||||||
|
lander_ctx *c_ctx = ctx->c;
|
||||||
|
|
||||||
|
ctx->res.body.expected_len = lsm_entry_data_len(c_ctx->entry);
|
||||||
|
http_res_set_mime_type(&ctx->res, http_mime_txt);
|
||||||
|
}
|
||||||
|
|
||||||
|
void lander_get_file(event_loop_conn *conn) {
|
||||||
|
http_loop_ctx *ctx = conn->ctx;
|
||||||
|
lander_ctx *c_ctx = ctx->c;
|
||||||
|
|
||||||
|
ctx->res.body.expected_len = lsm_entry_data_len(c_ctx->entry);
|
||||||
|
}
|
||||||
|
|
||||||
bool lander_get_entry_lsm(event_loop_conn *conn) {
|
bool lander_get_entry_lsm(event_loop_conn *conn) {
|
||||||
http_loop_ctx *ctx = conn->ctx;
|
http_loop_ctx *ctx = conn->ctx;
|
||||||
lander_ctx *c_ctx = ctx->c;
|
lander_ctx *c_ctx = ctx->c;
|
||||||
|
@ -53,38 +102,16 @@ bool lander_get_entry_lsm(event_loop_conn *conn) {
|
||||||
lsm_entry_attr_get_uint8_t((uint8_t *)&t, c_ctx->entry,
|
lsm_entry_attr_get_uint8_t((uint8_t *)&t, c_ctx->entry,
|
||||||
lander_attr_type_entry_type);
|
lander_attr_type_entry_type);
|
||||||
|
|
||||||
if (t == lander_entry_type_redirect) {
|
switch (t) {
|
||||||
// For redirects, the URL is stored as an in-memory attribute
|
case lander_entry_type_redirect:
|
||||||
lsm_str *url_attr_val;
|
lander_get_redirect(conn);
|
||||||
|
break;
|
||||||
// This shouldn't be able to happen
|
case lander_entry_type_paste:
|
||||||
if (lsm_entry_attr_get(&url_attr_val, c_ctx->entry, lander_attr_type_url) !=
|
lander_get_paste(conn);
|
||||||
lsm_error_ok) {
|
break;
|
||||||
error("Entry of type redirect detected without URL attribute");
|
case lander_entry_type_file:
|
||||||
|
lander_get_file(conn);
|
||||||
ctx->res.status = http_internal_server_error;
|
break;
|
||||||
lsm_entry_close(c_ctx->entry);
|
|
||||||
c_ctx->entry = NULL;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *buf = malloc(lsm_str_len(url_attr_val) + 1);
|
|
||||||
memcpy(buf, lsm_str_ptr(url_attr_val), lsm_str_len(url_attr_val));
|
|
||||||
|
|
||||||
buf[lsm_str_len(url_attr_val)] = '\0';
|
|
||||||
|
|
||||||
ctx->res.status = http_moved_permanently;
|
|
||||||
http_res_add_header(&ctx->res, http_header_location, buf, true);
|
|
||||||
|
|
||||||
// We no longer need the entry at this point, so we can unlock it early
|
|
||||||
// This will also signal to the response code not to read any data from
|
|
||||||
// the entry
|
|
||||||
lsm_entry_close(c_ctx->entry);
|
|
||||||
c_ctx->entry = NULL;
|
|
||||||
} else {
|
|
||||||
ctx->res.body.expected_len = lsm_entry_data_len(c_ctx->entry);
|
|
||||||
http_res_set_mime_type(&ctx->res, http_mime_txt);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
@ -164,6 +164,21 @@ bool lander_post_paste_lsm(event_loop_conn *conn) {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool lander_post_file_lsm(event_loop_conn *conn) {
|
||||||
|
http_loop_ctx *ctx = conn->ctx;
|
||||||
|
lander_ctx *c_ctx = ctx->c;
|
||||||
|
|
||||||
|
if (!lander_insert_entry(ctx)) {
|
||||||
|
conn->state = event_loop_conn_state_res;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
lsm_entry_attr_insert_uint8_t(c_ctx->entry, lander_attr_type_entry_type,
|
||||||
|
lander_entry_type_file);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
bool lander_stream_body_to_entry(event_loop_conn *conn) {
|
bool lander_stream_body_to_entry(event_loop_conn *conn) {
|
||||||
http_loop_ctx *ctx = conn->ctx;
|
http_loop_ctx *ctx = conn->ctx;
|
||||||
lander_ctx *c_ctx = ctx->c;
|
lander_ctx *c_ctx = ctx->c;
|
||||||
|
|
Loading…
Reference in New Issue