Compare commits

..

No commits in common. "8ae59f1031f5ad439e462f0de3da1144afa0d095" and "ad243ea9f5279b1526c92f61567f873a7414d9c9" have entirely different histories.

12 changed files with 128 additions and 195 deletions

View File

@ -42,32 +42,36 @@ void lander_ctx_free(lander_ctx *ctx);
lnm_http_step_err lander_get_index(lnm_http_conn *conn); lnm_http_step_err lander_get_index(lnm_http_conn *conn);
lnm_http_step_err lander_get_entry(lnm_http_conn *conn); bool lander_get_entry(event_loop_conn *conn);
lnm_http_step_err lander_post_redirect(lnm_http_conn *conn); bool lander_post_redirect(event_loop_conn *conn);
lnm_http_step_err lander_post_paste(lnm_http_conn *conn); bool lander_post_paste(event_loop_conn *conn);
lnm_http_step_err lander_stream_body_to_entry(lnm_http_conn *conn); bool lander_post_paste(event_loop_conn *conn);
bool lander_post_redirect(event_loop_conn *conn);
bool lander_stream_body_to_entry(event_loop_conn *conn);
bool lander_stream_body_to_client(event_loop_conn *conn); bool lander_stream_body_to_client(event_loop_conn *conn);
lnm_http_step_err lander_post_redirect_body_to_attr(lnm_http_conn *conn); bool lander_post_redirect_body_to_attr(event_loop_conn *conn);
lnm_http_step_err lander_remove_entry(lnm_http_conn *conn); bool lander_remove_entry(event_loop_conn *conn);
lnm_http_step_err lander_post_file(lnm_http_conn *conn); bool lander_post_file(event_loop_conn *conn);
/** /**
* Store the requested header as an attribute, if it's present. * Store the requested header as an attribute, if it's present.
*/ */
void lander_header_to_attr(lnm_http_loop_ctx *ctx, const char *header, void lander_header_to_attr(http_loop_ctx *ctx, const char *header,
lander_attr_type attr_type); lander_attr_type attr_type);
/** /**
* Store the attribute's value as the provided header, if present. * Store the attribute's value as the provided header, if present.
*/ */
void lander_attr_to_header(lnm_http_loop_ctx *ctx, lander_attr_type attr_type, void lander_attr_to_header(http_loop_ctx *ctx, lander_attr_type attr_type,
lnm_http_header header_type); http_header header_type);
#endif #endif

View File

@ -128,6 +128,4 @@ typedef struct lnm_http_loop_ctx {
void *c; void *c;
} lnm_http_loop_ctx; } lnm_http_loop_ctx;
lnm_http_step_err lnm_http_loop_step_body_to_buf(lnm_http_conn *conn);
#endif #endif

View File

@ -35,10 +35,8 @@ typedef struct lnm_http_req {
} headers; } headers;
struct { struct {
uint64_t expected_len; uint64_t expected_len;
uint64_t len;
char *buf;
bool owned;
} body; } body;
uint64_t content_length;
} lnm_http_req; } lnm_http_req;
typedef enum lnm_http_parse_err { typedef enum lnm_http_parse_err {

View File

@ -99,7 +99,7 @@ void lnm_http_loop_process_parse_headers(lnm_http_conn *conn) {
size_t value_len; size_t value_len;
if (lnm_http_req_header_get(&value, &value_len, req, if (lnm_http_req_header_get(&value, &value_len, req,
lnm_http_header_content_length) == lnm_err_ok) { lnm_http_header_content_length) == lnm_err_ok) {
req->body.expected_len = lnm_atoi(value, value_len); req->content_length = lnm_atoi(value, value_len);
} }
ctx->state = lnm_http_loop_state_steps; ctx->state = lnm_http_loop_state_steps;
@ -149,8 +149,8 @@ void lnm_http_loop_state_process_add_headers(lnm_http_conn *conn) {
} }
sprintf(buf, "%lu", res->body.len); sprintf(buf, "%lu", res->body.len);
lnm_http_res_add_header_len(res, lnm_http_header_content_length, buf, digits, lnm_http_res_add_header_len(res, lnm_http_header_content_length, buf,
true); digits, true);
ctx->state = lnm_http_loop_state_write_status_line; ctx->state = lnm_http_loop_state_write_status_line;
} }

View File

@ -1,24 +0,0 @@
#include <string.h>
#include "lnm/http/loop.h"
#include "lnm/loop.h"
lnm_http_step_err lnm_http_loop_step_body_to_buf(lnm_http_conn *conn) {
lnm_http_loop_ctx *ctx = conn->ctx;
if (ctx->req.body.buf == NULL) {
ctx->req.body.buf = malloc(ctx->req.body.expected_len * sizeof(char));
ctx->req.body.len = 0;
}
size_t to_read = LNM_MIN(conn->r.size - conn->r.read,
ctx->req.body.expected_len - ctx->req.body.len);
memcpy(&ctx->req.body.buf[ctx->req.body.len], &conn->r.buf[conn->r.read],
to_read);
ctx->req.body.len += to_read;
conn->r.read += to_read;
return ctx->req.body.len == ctx->req.body.expected_len
? lnm_http_step_err_done
: lnm_http_step_err_io_needed;
}

View File

@ -63,10 +63,6 @@ lnm_http_parse_err lnm_http_req_parse(lnm_http_req *req, char *buf,
} }
void lnm_http_req_reset(lnm_http_req *req) { void lnm_http_req_reset(lnm_http_req *req) {
if (req->body.owned) {
free(req->body.buf);
}
memset(req, 0, sizeof(lnm_http_req)); memset(req, 0, sizeof(lnm_http_req));
} }

View File

@ -84,30 +84,36 @@ void lander_ctx_reset(lander_ctx *ctx) {
void lander_ctx_free(lander_ctx *ctx) { free(ctx); } void lander_ctx_free(lander_ctx *ctx) { free(ctx); }
void lander_header_to_attr(lnm_http_loop_ctx *ctx, const char *header_name, void lander_header_to_attr(http_loop_ctx *ctx, const char *header_name,
lander_attr_type attr_type) { lander_attr_type attr_type) {
lander_ctx *c_ctx = ctx->c; lander_ctx *c_ctx = ctx->c;
const char *header_value; for (size_t i = 0; i < ctx->req.num_headers; i++) {
size_t header_value_len; const struct phr_header *header = &ctx->req.headers[i];
if (lnm_http_req_header_get_s(&header_value, &header_value_len, &ctx->req, if (strncmp(header->name, header_name, header->name_len) == 0) {
header_name) == lnm_err_ok) { if (header->value_len > 0) {
lsm_str *value; lsm_str *value;
lsm_str_init_copy_n(&value, (char *)header_value, header_value_len); lsm_str_init_copy_n(&value, (char *)header->value, header->value_len);
lsm_entry_attr_insert(c_ctx->entry, attr_type, value); lsm_entry_attr_insert(c_ctx->entry, attr_type, value);
}
return;
}
} }
} }
void lander_attr_to_header(lnm_http_loop_ctx *ctx, lander_attr_type attr_type, void lander_attr_to_header(http_loop_ctx *ctx, lander_attr_type attr_type,
lnm_http_header header_type) { http_header header_type) {
lander_ctx *c_ctx = ctx->c; lander_ctx *c_ctx = ctx->c;
lsm_str *value; lsm_str *value;
if (lsm_entry_attr_get(&value, c_ctx->entry, attr_type) == lsm_error_ok) { if (lsm_entry_attr_get(&value, c_ctx->entry, attr_type) == lsm_error_ok) {
lnm_http_res_add_header_len(&ctx->res, header_type, char *buf = malloc(lsm_str_len(value) + 1);
(char *)lsm_str_ptr(value), lsm_str_len(value), memcpy(buf, lsm_str_ptr(value), lsm_str_len(value));
false); buf[lsm_str_len(value)] = '\0';
http_res_add_header(&ctx->res, header_type, buf, true);
} }
} }

View File

@ -1,30 +1,29 @@
#include "lnm/loop.h"
#include "lander.h" #include "lander.h"
lnm_http_step_err lander_remove_entry(lnm_http_conn *conn) { bool lander_remove_entry(event_loop_conn *conn) {
lnm_http_loop_ctx *ctx = conn->ctx; http_loop_ctx *ctx = conn->ctx;
lander_ctx *c_ctx = ctx->c; lander_ctx *c_ctx = ctx->c;
lnm_http_loop_gctx *gctx = ctx->g; http_loop_gctx *gctx = ctx->g;
lander_gctx *c_gctx = gctx->c; lander_gctx *c_gctx = gctx->c;
const char *key_s = &ctx->req.path.s[ctx->req.path.groups[1].rm_so]; const char *key_s = &ctx->req.path[ctx->req.regex_groups[1].rm_so];
int key_len = ctx->req.path.groups[1].rm_eo - ctx->req.path.groups[1].rm_so; int key_len = ctx->req.regex_groups[1].rm_eo - ctx->req.regex_groups[1].rm_so;
lsm_str *key; lsm_str *key;
lsm_str_init_copy_n(&key, (char *)key_s, key_len); lsm_str_init_copy_n(&key, (char *)key_s, key_len);
switch (lsm_store_open_write(&c_ctx->entry, c_gctx->store, key)) { switch (lsm_store_open_write(&c_ctx->entry, c_gctx->store, key)) {
case lsm_error_ok: case lsm_error_ok:
lsm_entry_remove(c_ctx->entry);
break; break;
case lsm_error_not_found: case lsm_error_not_found:
ctx->res.status = lnm_http_status_not_found; ctx->res.status = http_not_found;
break; return true;
default: default:
ctx->res.status = lnm_http_status_internal_server_error; ctx->res.status = http_internal_server_error;
break; return true;
} }
return lnm_http_step_err_done; lsm_entry_remove(c_ctx->entry);
return true;
} }

View File

@ -1,7 +1,5 @@
#include <stdio.h> #include <stdio.h>
#include "lnm/http/consts.h"
#include "lnm/http/loop.h"
#include "lnm/loop.h" #include "lnm/loop.h"
#include "event_loop.h" #include "event_loop.h"
@ -26,14 +24,17 @@ lnm_http_step_err lander_get_index(lnm_http_conn *conn) {
lnm_http_res_body_set_buf(&ctx->res, (char *)index_page, lnm_http_res_body_set_buf(&ctx->res, (char *)index_page,
sizeof(index_page) - 1, false); sizeof(index_page) - 1, false);
lnm_http_res_add_header(&ctx->res, lnm_http_header_content_type, "text/html",
false);
/* http_res_set_body_buf(&ctx->res, index_page, sizeof(index_page) - 1,
* false); */
/* http_res_set_mime_type(&ctx->res, http_mime_html); */
/* conn->state = event_loop_conn_state_res; */
return lnm_http_step_err_done; return lnm_http_step_err_done;
} }
lnm_http_step_err lander_get_redirect(lnm_http_conn *conn) { void lander_get_redirect(event_loop_conn *conn) {
lnm_http_loop_ctx *ctx = conn->ctx; http_loop_ctx *ctx = conn->ctx;
lander_ctx *c_ctx = ctx->c; lander_ctx *c_ctx = ctx->c;
// For redirects, the URL is stored as an in-memory attribute // For redirects, the URL is stored as an in-memory attribute
@ -44,55 +45,43 @@ lnm_http_step_err lander_get_redirect(lnm_http_conn *conn) {
lsm_error_ok) { lsm_error_ok) {
error("Entry of type redirect detected without URL attribute"); error("Entry of type redirect detected without URL attribute");
ctx->res.status = lnm_http_status_internal_server_error; ctx->res.status = http_internal_server_error;
lsm_entry_close(c_ctx->entry); lsm_entry_close(c_ctx->entry);
c_ctx->entry = NULL; c_ctx->entry = NULL;
return lnm_http_step_err_res; return;
} }
lnm_http_res_add_header_len(&ctx->res, lnm_http_header_location, char *buf = malloc(lsm_str_len(url_attr_val) + 1);
(char *)lsm_str_ptr(url_attr_val), memcpy(buf, lsm_str_ptr(url_attr_val), lsm_str_len(url_attr_val));
lsm_str_len(url_attr_val), false);
ctx->res.status = lnm_http_status_moved_permanently; buf[lsm_str_len(url_attr_val)] = '\0';
return lnm_http_step_err_done; 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;
} }
lnm_err lander_entry_data_streamer(uint64_t *written, char *buf, void lander_get_paste(event_loop_conn *conn) {
lnm_http_conn *conn, uint64_t offset, http_loop_ctx *ctx = conn->ctx;
uint64_t len) {
// TODO respect offset variable
lnm_http_loop_ctx *ctx = conn->ctx;
lander_ctx *c_ctx = ctx->c; lander_ctx *c_ctx = ctx->c;
lsm_entry_data_read(written, buf, c_ctx->entry, len); ctx->res.body.expected_len = lsm_entry_data_len(c_ctx->entry);
http_res_set_mime_type(&ctx->res, http_mime_txt);
return lnm_err_ok;
} }
lnm_http_step_err lander_get_paste(lnm_http_conn *conn) { void lander_get_file(event_loop_conn *conn) {
lnm_http_loop_ctx *ctx = conn->ctx; http_loop_ctx *ctx = conn->ctx;
lander_ctx *c_ctx = ctx->c; lander_ctx *c_ctx = ctx->c;
lnm_http_res_body_set_fn(&ctx->res, lander_entry_data_streamer, ctx->res.body.expected_len = lsm_entry_data_len(c_ctx->entry);
lsm_entry_data_len(c_ctx->entry));
lnm_http_res_add_header(&ctx->res, lnm_http_header_content_type, "text/plain",
false);
return lnm_http_step_err_done;
}
lnm_http_step_err lander_get_file(lnm_http_conn *conn) {
lnm_http_loop_ctx *ctx = conn->ctx;
lander_ctx *c_ctx = ctx->c;
lnm_http_res_body_set_fn(&ctx->res, lander_entry_data_streamer,
lsm_entry_data_len(c_ctx->entry));
lander_attr_to_header(ctx, lander_attr_type_content_type, lander_attr_to_header(ctx, lander_attr_type_content_type,
lnm_http_header_content_type); http_header_content_type);
lsm_str *value; lsm_str *value;
char *buf; char *buf;
@ -101,26 +90,23 @@ lnm_http_step_err lander_get_file(lnm_http_conn *conn) {
lsm_error_ok) { lsm_error_ok) {
buf = malloc(24 + lsm_str_len(value)); buf = malloc(24 + lsm_str_len(value));
int len = lsm_str_len(value); int len = lsm_str_len(value);
sprintf(buf, "attachment; filename=\"%.*s\"", len, lsm_str_ptr(value)); sprintf(buf, "attachment; filename=\"%*s\"", len, lsm_str_ptr(value));
} else { } else {
buf = malloc(11); buf = malloc(11);
strcpy(buf, "attachment"); strcpy(buf, "attachment");
} }
lnm_http_res_add_header(&ctx->res, lnm_http_header_content_disposition, buf, http_res_add_header(&ctx->res, http_header_content_disposition, buf, true);
true);
return lnm_http_step_err_done;
} }
lnm_http_step_err lander_get_entry(lnm_http_conn *conn) { bool lander_get_entry(event_loop_conn *conn) {
lnm_http_loop_ctx *ctx = conn->ctx; http_loop_ctx *ctx = conn->ctx;
lander_ctx *c_ctx = ctx->c; lander_ctx *c_ctx = ctx->c;
lnm_http_loop_gctx *gctx = ctx->g; http_loop_gctx *gctx = ctx->g;
lander_gctx *c_gctx = gctx->c; lander_gctx *c_gctx = gctx->c;
const char *key_s = &ctx->req.path.s[ctx->req.path.groups[1].rm_so]; const char *key_s = &ctx->req.path[ctx->req.regex_groups[1].rm_so];
int key_len = ctx->req.path.groups[1].rm_eo - ctx->req.path.groups[1].rm_so; int key_len = ctx->req.regex_groups[1].rm_eo - ctx->req.regex_groups[1].rm_so;
lsm_str *key; lsm_str *key;
lsm_str_init_copy_n(&key, (char *)key_s, key_len); lsm_str_init_copy_n(&key, (char *)key_s, key_len);
@ -129,32 +115,32 @@ lnm_http_step_err lander_get_entry(lnm_http_conn *conn) {
case lsm_error_ok: case lsm_error_ok:
break; break;
case lsm_error_not_found: case lsm_error_not_found:
ctx->res.status = lnm_http_status_not_found; ctx->res.status = http_not_found;
return lnm_http_step_err_res; conn->state = event_loop_conn_state_res;
return true;
default: default:
ctx->res.status = lnm_http_status_internal_server_error; ctx->res.status = http_internal_server_error;
return lnm_http_step_err_res; conn->state = event_loop_conn_state_res;
return true;
} }
lander_entry_type t; lander_entry_type t;
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);
lnm_http_step_err res;
switch (t) { switch (t) {
case lander_entry_type_redirect: case lander_entry_type_redirect:
res = lander_get_redirect(conn); lander_get_redirect(conn);
break; break;
case lander_entry_type_paste: case lander_entry_type_paste:
res = lander_get_paste(conn); lander_get_paste(conn);
break; break;
case lander_entry_type_file: case lander_entry_type_file:
res = lander_get_file(conn); lander_get_file(conn);
break; break;
} }
return res; return true;
} }
bool lander_stream_body_to_client(event_loop_conn *conn) { bool lander_stream_body_to_client(event_loop_conn *conn) {

View File

@ -1,7 +1,6 @@
#include "http/res.h" #include "http/res.h"
#include "http/types.h" #include "http/types.h"
#include "lander.h" #include "lander.h"
#include "lnm/loop.h"
#include "log.h" #include "log.h"
#include "lsm/store.h" #include "lsm/store.h"
@ -20,26 +19,26 @@ static void randomize_key(char *key, int len) {
* *
* @return true on success, false otherwise * @return true on success, false otherwise
*/ */
bool lander_insert_entry(lnm_http_loop_ctx *ctx) { bool lander_insert_entry(http_loop_ctx *ctx) {
lnm_http_loop_gctx *gctx = ctx->g; http_loop_gctx *gctx = ctx->g;
lander_gctx *c_gctx = gctx->c; lander_gctx *c_gctx = gctx->c;
lander_ctx *c_ctx = ctx->c; lander_ctx *c_ctx = ctx->c;
lsm_str *key; lsm_str *key;
int key_len; int key_len;
if (ctx->req.path.groups[2].rm_eo == ctx->req.path.groups[2].rm_so) { if (ctx->req.regex_groups[2].rm_eo == ctx->req.regex_groups[2].rm_so) {
// Generate a random key to insert // Generate a random key to insert
bool secure = bool secure =
(ctx->req.path.groups[1].rm_eo - ctx->req.path.groups[1].rm_so) == 1; (ctx->req.regex_groups[1].rm_eo - ctx->req.regex_groups[1].rm_so) == 1;
key_len = secure ? 16 : 4; key_len = secure ? 16 : 4;
char *key_s = malloc((key_len + 1) * sizeof(char)); char *key_s = malloc((key_len + 1) * sizeof(char));
randomize_key(key_s, key_len); randomize_key(key_s, key_len);
lsm_str_init(&key, key_s); lsm_str_init(&key, key_s);
} else { } else {
const char *key_s = &ctx->req.path.s[ctx->req.path.groups[2].rm_so]; const char *key_s = &ctx->req.path[ctx->req.regex_groups[2].rm_so];
key_len = ctx->req.path.groups[2].rm_eo - ctx->req.path.groups[2].rm_so; key_len = ctx->req.regex_groups[2].rm_eo - ctx->req.regex_groups[2].rm_so;
lsm_str_init_copy_n(&key, key_s, key_len); lsm_str_init_copy_n(&key, key_s, key_len);
} }
@ -47,12 +46,12 @@ bool lander_insert_entry(lnm_http_loop_ctx *ctx) {
// TODO free key on error // TODO free key on error
switch (lsm_store_insert(&c_ctx->entry, c_gctx->store, key)) { switch (lsm_store_insert(&c_ctx->entry, c_gctx->store, key)) {
case lsm_error_already_present: case lsm_error_already_present:
ctx->res.status = lnm_http_status_conflict; ctx->res.status = http_conflict;
return false; return false;
case lsm_error_ok: case lsm_error_ok:
break; break;
default: default:
ctx->res.status = lnm_http_status_internal_server_error; ctx->res.status = http_internal_server_error;
return false; return false;
} }
@ -62,58 +61,61 @@ bool lander_insert_entry(lnm_http_loop_ctx *ctx) {
buf[0] = '/'; buf[0] = '/';
buf[key_len + 1] = '\0'; buf[key_len + 1] = '\0';
lnm_http_res_add_header(&ctx->res, lnm_http_header_location, buf, true); http_res_add_header(&ctx->res, http_header_location, buf, true);
ctx->res.status = lnm_http_status_created; ctx->res.status = http_created;
return true; return true;
} }
lnm_http_step_err lander_post_redirect(lnm_http_conn *conn) { bool lander_post_redirect(event_loop_conn *conn) {
lnm_http_loop_ctx *ctx = conn->ctx; http_loop_ctx *ctx = conn->ctx;
lander_ctx *c_ctx = ctx->c; lander_ctx *c_ctx = ctx->c;
if (!lander_insert_entry(ctx)) { if (!lander_insert_entry(ctx)) {
return lnm_http_step_err_res; conn->state = event_loop_conn_state_res;
return true;
} }
lsm_entry_attr_insert_uint8_t(c_ctx->entry, lander_attr_type_entry_type, lsm_entry_attr_insert_uint8_t(c_ctx->entry, lander_attr_type_entry_type,
lander_entry_type_redirect); lander_entry_type_redirect);
return lnm_http_step_err_done; return true;
} }
lnm_http_step_err lander_post_redirect_body_to_attr(lnm_http_conn *conn) { bool lander_post_redirect_body_to_attr(event_loop_conn *conn) {
lnm_http_loop_ctx *ctx = conn->ctx; http_loop_ctx *ctx = conn->ctx;
lander_ctx *c_ctx = ctx->c; lander_ctx *c_ctx = ctx->c;
lsm_str *attr_value; lsm_str *attr_value;
lsm_str_init_copy_n(&attr_value, ctx->req.body.buf, ctx->req.body.len); 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); lsm_entry_attr_insert(c_ctx->entry, lander_attr_type_url, attr_value);
return lnm_http_step_err_done; return true;
} }
lnm_http_step_err lander_post_paste(lnm_http_conn *conn) { bool lander_post_paste(event_loop_conn *conn) {
lnm_http_loop_ctx *ctx = conn->ctx; http_loop_ctx *ctx = conn->ctx;
lander_ctx *c_ctx = ctx->c; lander_ctx *c_ctx = ctx->c;
if (!lander_insert_entry(ctx)) { if (!lander_insert_entry(ctx)) {
return lnm_http_step_err_res; conn->state = event_loop_conn_state_res;
return true;
} }
lsm_entry_attr_insert_uint8_t(c_ctx->entry, lander_attr_type_entry_type, lsm_entry_attr_insert_uint8_t(c_ctx->entry, lander_attr_type_entry_type,
lander_entry_type_paste); lander_entry_type_paste);
lander_header_to_attr(ctx, "X-Lander-Filename", lander_attr_type_file_name); lander_header_to_attr(ctx, "X-Lander-Filename", lander_attr_type_file_name);
return lnm_http_step_err_done; return true;
} }
lnm_http_step_err lander_post_file(lnm_http_conn *conn) { bool lander_post_file(event_loop_conn *conn) {
lnm_http_loop_ctx *ctx = conn->ctx; http_loop_ctx *ctx = conn->ctx;
lander_ctx *c_ctx = ctx->c; lander_ctx *c_ctx = ctx->c;
if (!lander_insert_entry(ctx)) { if (!lander_insert_entry(ctx)) {
return lnm_http_step_err_res; conn->state = event_loop_conn_state_res;
return true;
} }
lsm_entry_attr_insert_uint8_t(c_ctx->entry, lander_attr_type_entry_type, lsm_entry_attr_insert_uint8_t(c_ctx->entry, lander_attr_type_entry_type,
@ -122,5 +124,5 @@ lnm_http_step_err lander_post_file(lnm_http_conn *conn) {
lander_attr_type_content_type); lander_attr_type_content_type);
lander_header_to_attr(ctx, "X-Lander-Filename", lander_attr_type_file_name); lander_header_to_attr(ctx, "X-Lander-Filename", lander_attr_type_file_name);
return lnm_http_step_err_done; return true;
} }

View File

@ -1,26 +1,22 @@
#include <string.h> #include <string.h>
#include "lander.h" #include "lander.h"
#include "lnm/http/loop.h"
#include "lnm/loop.h"
lnm_http_step_err lander_stream_body_to_entry(lnm_http_conn *conn) { bool lander_stream_body_to_entry(event_loop_conn *conn) {
lnm_http_loop_ctx *ctx = conn->ctx; http_loop_ctx *ctx = conn->ctx;
lander_ctx *c_ctx = ctx->c; lander_ctx *c_ctx = ctx->c;
uint64_t to_append = uint64_t to_append =
MIN(conn->r.size - conn->r.read, MIN(conn->rbuf_size - conn->rbuf_read,
ctx->req.body.expected_len - lsm_entry_data_len(c_ctx->entry)); ctx->req.body.expected_len - lsm_entry_data_len(c_ctx->entry));
lsm_str *data; lsm_str *data;
lsm_str_init_copy_n(&data, (char *)&conn->r.buf[conn->r.read], to_append); lsm_str_init_copy_n(&data, (char *)&conn->rbuf[conn->rbuf_read], to_append);
lsm_entry_data_append(c_ctx->entry, data); lsm_entry_data_append(c_ctx->entry, data);
conn->r.read += to_append; conn->rbuf_read += to_append;
lsm_str_free(data); lsm_str_free(data);
return lsm_entry_data_len(c_ctx->entry) == ctx->req.body.expected_len return lsm_entry_data_len(c_ctx->entry) == ctx->req.body.expected_len;
? lnm_http_step_err_done
: lnm_http_step_err_io_needed;
} }

View File

@ -19,34 +19,6 @@ lnm_http_loop *loop_init(lander_gctx *gctx) {
lnm_http_route_init_literal(&route, lnm_http_method_get, "/", step); lnm_http_route_init_literal(&route, lnm_http_method_get, "/", step);
lnm_http_loop_route_add(hl, route); lnm_http_loop_route_add(hl, route);
lnm_http_step_init(&step, lander_get_entry);
lnm_http_route_init_regex(&route, lnm_http_method_get, "^/([^/]+)$", 1, step);
lnm_http_loop_route_add(hl, route);
lnm_http_step_init(&step, lander_post_redirect);
lnm_http_route_init_regex(&route, lnm_http_method_post, "^/s(l?)/([^/]*)$", 2,
step);
lnm_http_step_append(&step, step, lnm_http_loop_step_body_to_buf);
lnm_http_step_append(&step, step, lander_post_redirect_body_to_attr);
lnm_http_loop_route_add(hl, route);
lnm_http_step_init(&step, lander_post_paste);
lnm_http_route_init_regex(&route, lnm_http_method_post, "^/p(l?)/([^/]*)$", 2,
step);
lnm_http_step_append(&step, step, lander_stream_body_to_entry);
lnm_http_loop_route_add(hl, route);
lnm_http_step_init(&step, lander_post_file);
lnm_http_route_init_regex(&route, lnm_http_method_post, "^/f(l?)/([^/]*)$", 2,
step);
lnm_http_step_append(&step, step, lander_stream_body_to_entry);
lnm_http_loop_route_add(hl, route);
lnm_http_step_init(&step, lander_remove_entry);
lnm_http_route_init_regex(&route, lnm_http_method_delete, "^/([^/]+)$", 1,
step);
lnm_http_loop_route_add(hl, route);
return hl; return hl;
} }