feat(lander): store filename if provided

lsm
Jef Roosens 2023-11-12 16:13:54 +01:00
parent 04aef2643f
commit 6a5b23afaa
Signed by: Jef Roosens
GPG Key ID: B75D4F293C7052DB
6 changed files with 71 additions and 95 deletions

View File

@ -20,16 +20,9 @@ typedef enum lander_attr_type : uint8_t {
lander_attr_type_entry_type = 0,
lander_attr_type_content_type = 1,
lander_attr_type_url = 2,
lander_attr_type_file_name = 3,
} lander_attr_type;
typedef struct {
char *header;
lander_attr_type attr_type;
http_header header_type;
} header_to_attr;
extern header_to_attr header_to_attrs[];
typedef enum lander_entry_type : uint8_t {
lander_entry_type_redirect = 0,
lander_entry_type_paste = 1,
@ -67,11 +60,15 @@ bool lander_remove_entry(event_loop_conn *conn);
bool lander_post_file(event_loop_conn *conn);
/**
* Parse any custom headers and add them as attributes to the context's LSM
* entry
* Store the requested header as an attribute, if it's present.
*/
bool lander_headers_to_attrs(event_loop_conn *conn);
void lander_header_to_attr(http_loop_ctx *ctx, char *header,
lander_attr_type attr_type);
bool lander_attrs_to_headers(event_loop_conn *conn);
/**
* Store the attribute's value as the provided header, if present.
*/
void lander_attr_to_header(http_loop_ctx *ctx, lander_attr_type attr_type,
http_header header_type);
#endif

View File

@ -3,53 +3,49 @@
API_KEY=test
URL=http://localhost:18080
if [[ "$2" != '-' ]]; then
filename="$2"
content_type="$(file --mime-type --brief $2)"
fi
if [ "$1" = g ]; then
curl -is "$URL/$2" |
sed -En 's/^[lL]ocation: (.*)/\1/p'
elif [ "$1" = s ]; then
elif [ "$1" = s ] || [ "$1" = sl ]; then
curl \
--fail \
-w "${URL}%header{location}" \
-XPOST \
-d "$2" \
-H "X-Api-Key: $API_KEY" \
"$URL/s/$3"
"$URL/$1/$3"
elif [ "$1" = sl ]; then
curl \
-w "${URL}%header{location}" \
-XPOST \
-d "$2" \
-H "X-Api-Key: $API_KEY" \
"$URL/sl/$3"
elif [ "$1" = p ]; then
elif [ "$1" = p ] || [ "$1" = pl ]; then
curl \
--fail \
-w "${URL}%header{location}" \
-XPOST \
-H "X-Api-Key: $API_KEY" \
-H "X-Lander-Filename: ${filename}" \
--data-binary @"$2" \
"$URL/p/$3"
"$URL/$1/$3"
elif [ "$1" = pl ]; then
elif [ "$1" = f ] || [ "$1" = fl ]; then
curl \
--fail \
-w "${URL}%header{location}" \
-XPOST \
-H "X-Api-Key: $API_KEY" \
-H "X-Lander-Content-Type: ${content_type}" \
-H "X-Lander-Filename: ${filename}" \
--data-binary @"$2" \
"$URL/pl/$3"
elif [ "$1" = f ]; then
curl \
-w "${URL}%header{location}" \
-XPOST \
-H "X-Api-Key: $API_KEY" \
-H "X-Lander-Content-Type: $(file --mime-type --brief $2)" \
--data-binary @"$2" \
"$URL/f/$3"
"$URL/$1/$3"
elif [ "$1" = d ]; then
curl \
--fail \
-XDELETE \
-H "X-Api-Key: $API_KEY" \
"$URL/$2"

View File

@ -1,4 +1,5 @@
#include <stdio.h>
#include <string.h>
#include "http/types.h"
#include "http_loop.h"
@ -19,7 +20,7 @@ http_route lander_routes[] = {
.type = http_route_regex,
.method = http_get,
.path = "^/([^/]+)$",
.steps = {lander_get_entry, lander_attrs_to_headers, NULL},
.steps = {lander_get_entry, NULL},
.steps_res = {http_loop_step_write_header, lander_stream_body_to_client,
NULL},
},
@ -52,18 +53,11 @@ http_route lander_routes[] = {
.method = http_post,
.path = "^/f(l?)/([^/]*)$",
.steps = {http_loop_step_auth, http_loop_step_parse_content_length,
lander_post_file, lander_headers_to_attrs,
lander_stream_body_to_entry, NULL},
lander_post_file, lander_stream_body_to_entry, NULL},
.steps_res = {http_loop_step_write_header, http_loop_step_write_body,
NULL}},
};
header_to_attr header_to_attrs[] = {
{"X-Lander-Content-Type", lander_attr_type_content_type,
http_header_content_type},
{NULL, 0, 0},
};
void *lander_gctx_init() { return calloc(1, sizeof(lander_gctx)); }
void *lander_ctx_init() { return calloc(1, sizeof(lander_ctx)); }
@ -77,3 +71,37 @@ void lander_ctx_reset(lander_ctx *ctx) {
}
void lander_ctx_free(lander_ctx *ctx) { free(ctx); }
void lander_header_to_attr(http_loop_ctx *ctx, char *header_name,
lander_attr_type attr_type) {
lander_ctx *c_ctx = ctx->c;
for (size_t i = 0; i < ctx->req.num_headers; i++) {
struct phr_header *header = &ctx->req.headers[i];
if (strncmp(header->name, header_name, header->name_len) == 0) {
if (header->value_len > 0) {
lsm_str *value;
lsm_str_init_copy_n(&value, (char *)header->value, header->value_len);
lsm_entry_attr_insert(c_ctx->entry, attr_type, value);
}
return;
}
}
}
void lander_attr_to_header(http_loop_ctx *ctx, lander_attr_type attr_type,
http_header header_type) {
lander_ctx *c_ctx = ctx->c;
lsm_str *value;
if (lsm_entry_attr_get(&value, c_ctx->entry, attr_type) == lsm_error_ok) {
char *buf = malloc(lsm_str_len(value) + 1);
memcpy(buf, lsm_str_ptr(value), lsm_str_len(value));
buf[lsm_str_len(value)] = '\0';
http_res_add_header(&ctx->res, header_type, buf, true);
}
}

View File

@ -73,6 +73,8 @@ void lander_get_file(event_loop_conn *conn) {
lander_ctx *c_ctx = ctx->c;
ctx->res.body.expected_len = lsm_entry_data_len(c_ctx->entry);
lander_attr_to_header(ctx, lander_attr_type_content_type,
http_header_content_type);
}
bool lander_get_entry(event_loop_conn *conn) {

View File

@ -104,6 +104,7 @@ bool lander_post_paste(event_loop_conn *conn) {
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 true;
}
@ -119,6 +120,9 @@ bool lander_post_file(event_loop_conn *conn) {
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 true;
}

View File

@ -20,54 +20,3 @@ bool lander_stream_body_to_entry(event_loop_conn *conn) {
return lsm_entry_data_len(c_ctx->entry) == ctx->req.body.expected_len;
}
bool lander_headers_to_attrs(event_loop_conn *conn) {
http_loop_ctx *ctx = conn->ctx;
lander_ctx *c_ctx = ctx->c;
for (size_t i = 0; i < ctx->req.num_headers; i++) {
struct phr_header *header = &ctx->req.headers[i];
int j = 0;
while (header_to_attrs[j].header != NULL) {
if (strncmp(header->name, header_to_attrs[j].header, header->name_len) ==
0) {
lsm_str *value;
lsm_str_init_copy_n(&value, (char *)header->value, header->value_len);
lsm_entry_attr_insert(c_ctx->entry, header_to_attrs[j].attr_type,
value);
break;
}
j++;
}
}
return true;
}
bool lander_attrs_to_headers(event_loop_conn *conn) {
http_loop_ctx *ctx = conn->ctx;
lander_ctx *c_ctx = ctx->c;
int j = 0;
lsm_str *value;
while (header_to_attrs[j].header != NULL) {
if (lsm_entry_attr_get(&value, c_ctx->entry,
header_to_attrs[j].attr_type) == lsm_error_ok) {
char *buf = malloc(lsm_str_len(value) + 1);
memcpy(buf, lsm_str_ptr(value), lsm_str_len(value));
buf[lsm_str_len(value)] = '\0';
http_res_add_header(&ctx->res, header_to_attrs[j].header_type, buf, true);
}
j++;
}
return true;
}