feat: PoC uploading of pastes
This commit is contained in:
parent
dfbd179c7a
commit
87312f2d84
6 changed files with 122 additions and 27 deletions
|
|
@ -53,35 +53,50 @@ static bool string_to_num(size_t *res, const char *s, size_t len) {
|
|||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
* Try to find and parse the Content-Length header. This function returns true
|
||||
* if it was successful. If false is returned, the underlying step should
|
||||
* immediately exit.
|
||||
*/
|
||||
static bool try_parse_content_length(event_loop_conn *conn) {
|
||||
http_loop_ctx *ctx = conn->ctx;
|
||||
|
||||
for (size_t i = 0; i < ctx->req.num_headers; i++) {
|
||||
struct phr_header *header = &ctx->req.headers[i];
|
||||
|
||||
if (strncmp(header->name, "Content-Length", header->name_len) == 0) {
|
||||
// If the content length header is present but contains an invalid
|
||||
// number, we return a bad request error
|
||||
if (!string_to_num(&ctx->req.body_len, header->value,
|
||||
header->value_len)) {
|
||||
ctx->res.status = http_bad_request;
|
||||
conn->state = event_loop_conn_state_res;
|
||||
|
||||
return false;
|
||||
}
|
||||
// The content length was actually 0, so we can instantly return here
|
||||
else if (ctx->req.body_len == 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// A zero here means there's no content length header
|
||||
if (ctx->req.body_len == 0) {
|
||||
ctx->res.status = http_length_required;
|
||||
conn->state = event_loop_conn_state_res;
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool http_loop_step_body_to_buf(event_loop_conn *conn) {
|
||||
http_loop_ctx *ctx = conn->ctx;
|
||||
|
||||
if (ctx->req.body_len == 0) {
|
||||
for (size_t i = 0; i < ctx->req.num_headers; i++) {
|
||||
struct phr_header *header = &ctx->req.headers[i];
|
||||
|
||||
if (strncmp(header->name, "Content-Length", header->name_len) == 0) {
|
||||
// If the content length header is present but contains an invalid
|
||||
// number, we return a bad request error
|
||||
if (!string_to_num(&ctx->req.body_len, header->value,
|
||||
header->value_len)) {
|
||||
ctx->res.status = http_bad_request;
|
||||
conn->state = event_loop_conn_state_res;
|
||||
|
||||
return true;
|
||||
}
|
||||
// The content length was actually 0, so we can instantly return here
|
||||
else if (ctx->req.body_len == 0) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// A zero here means there's no content length header
|
||||
if (ctx->req.body_len == 0) {
|
||||
ctx->res.status = http_length_required;
|
||||
conn->state = event_loop_conn_state_res;
|
||||
|
||||
if (!try_parse_content_length(conn)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -95,6 +110,30 @@ bool http_loop_step_body_to_buf(event_loop_conn *conn) {
|
|||
memcpy(&ctx->req.body.buf[ctx->req.body_received],
|
||||
&conn->rbuf[conn->rbuf_read], bytes_to_copy);
|
||||
ctx->req.body_received += bytes_to_copy;
|
||||
conn->rbuf_read += bytes_to_copy;
|
||||
|
||||
return ctx->req.body_received == ctx->req.body_len;
|
||||
}
|
||||
|
||||
bool http_loop_step_body_to_file(event_loop_conn *conn) {
|
||||
http_loop_ctx *ctx = conn->ctx;
|
||||
|
||||
if (ctx->req.body_len == 0) {
|
||||
if (!try_parse_content_length(conn)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
ctx->req.body_type = http_body_file;
|
||||
ctx->req.body.file = fopen(ctx->req.body_file_name, "wb");
|
||||
ctx->req.body_received = 0;
|
||||
}
|
||||
|
||||
size_t bytes_to_write = MIN(conn->rbuf_size - conn->rbuf_read,
|
||||
ctx->req.body_len - ctx->req.body_received);
|
||||
size_t bytes_written = fwrite(&conn->rbuf[conn->rbuf_read], sizeof(uint8_t),
|
||||
bytes_to_write, ctx->req.body.file);
|
||||
ctx->req.body_received += bytes_written;
|
||||
conn->rbuf_read += bytes_written;
|
||||
|
||||
return ctx->req.body_received == ctx->req.body_len;
|
||||
}
|
||||
|
|
@ -116,3 +155,9 @@ bool http_loop_step_auth(event_loop_conn *conn) {
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool http_loop_step_switch_res(event_loop_conn *conn) {
|
||||
conn->state = event_loop_conn_state_res;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue