diff --git a/include/http/types.h b/include/http/types.h index cccf0a0..5b75bea 100644 --- a/include/http/types.h +++ b/include/http/types.h @@ -124,8 +124,7 @@ extern const char *http_header_names[]; typedef enum http_header { http_header_connection = 0, http_header_location, - http_header_content_type, - http_header_content_disposition + http_header_content_type } http_header; typedef enum http_body_type { diff --git a/include/lander.h b/include/lander.h index bff41fd..de89437 100644 --- a/include/lander.h +++ b/include/lander.h @@ -20,9 +20,16 @@ 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, @@ -60,15 +67,11 @@ bool lander_remove_entry(event_loop_conn *conn); bool lander_post_file(event_loop_conn *conn); /** - * Store the requested header as an attribute, if it's present. + * Parse any custom headers and add them as attributes to the context's LSM + * entry */ -void lander_header_to_attr(http_loop_ctx *ctx, char *header, - lander_attr_type attr_type); +bool lander_headers_to_attrs(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); +bool lander_attrs_to_headers(event_loop_conn *conn); #endif diff --git a/landerctl b/landerctl index 57ff78f..74a7ed3 100755 --- a/landerctl +++ b/landerctl @@ -3,49 +3,53 @@ 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 ] || [ "$1" = sl ]; then +elif [ "$1" = s ]; then curl \ - --fail \ -w "${URL}%header{location}" \ -XPOST \ -d "$2" \ -H "X-Api-Key: $API_KEY" \ - "$URL/$1/$3" + "$URL/s/$3" -elif [ "$1" = p ] || [ "$1" = pl ]; then +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 curl \ - --fail \ -w "${URL}%header{location}" \ -XPOST \ -H "X-Api-Key: $API_KEY" \ - -H "X-Lander-Filename: ${filename}" \ --data-binary @"$2" \ - "$URL/$1/$3" + "$URL/p/$3" -elif [ "$1" = f ] || [ "$1" = fl ]; then +elif [ "$1" = pl ]; 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/$1/$3" + "$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" elif [ "$1" = d ]; then curl \ - --fail \ -XDELETE \ -H "X-Api-Key: $API_KEY" \ "$URL/$2" diff --git a/src/http/http_consts.c b/src/http/http_consts.c index 8aa6f4b..6a6e15c 100644 --- a/src/http/http_consts.c +++ b/src/http/http_consts.c @@ -96,8 +96,7 @@ const char *http_status_names[][32] = { const char *http_header_names[] = { "Connection", "Location", - "Content-Type", - "Content-Disposition" + "Content-Type" }; const char *http_mime_type_names[][2] = { diff --git a/src/lander/lander.c b/src/lander/lander.c index 442847a..06395cb 100644 --- a/src/lander/lander.c +++ b/src/lander/lander.c @@ -1,5 +1,4 @@ #include -#include #include "http/types.h" #include "http_loop.h" @@ -20,7 +19,7 @@ http_route lander_routes[] = { .type = http_route_regex, .method = http_get, .path = "^/([^/]+)$", - .steps = {lander_get_entry, NULL}, + .steps = {lander_get_entry, lander_attrs_to_headers, NULL}, .steps_res = {http_loop_step_write_header, lander_stream_body_to_client, NULL}, }, @@ -53,11 +52,18 @@ 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_stream_body_to_entry, NULL}, + lander_post_file, lander_headers_to_attrs, + 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)); } @@ -71,37 +77,3 @@ 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); - } -} diff --git a/src/lander/lander_get.c b/src/lander/lander_get.c index 102c631..bd62a16 100644 --- a/src/lander/lander_get.c +++ b/src/lander/lander_get.c @@ -1,7 +1,6 @@ #include #include "event_loop.h" -#include "http/res.h" #include "http/types.h" #include "lander.h" #include "log.h" @@ -74,23 +73,6 @@ 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); - - lsm_str *value; - char *buf; - - if (lsm_entry_attr_get(&value, c_ctx->entry, lander_attr_type_file_name) == - lsm_error_ok) { - buf = malloc(24 + lsm_str_len(value)); - int len = lsm_str_len(value); - sprintf(buf, "attachment; filename=\"%*s\"", len, lsm_str_ptr(value)); - } else { - buf = malloc(11); - strcpy(buf, "attachment"); - } - - http_res_add_header(&ctx->res, http_header_content_disposition, buf, true); } bool lander_get_entry(event_loop_conn *conn) { diff --git a/src/lander/lander_post.c b/src/lander/lander_post.c index b630373..cdde6d0 100644 --- a/src/lander/lander_post.c +++ b/src/lander/lander_post.c @@ -104,7 +104,6 @@ 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; } @@ -120,9 +119,6 @@ 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; } diff --git a/src/lander/lander_steps.c b/src/lander/lander_steps.c index 7804df5..c84f9d2 100644 --- a/src/lander/lander_steps.c +++ b/src/lander/lander_steps.c @@ -20,3 +20,54 @@ 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; +}