feat: abstract http body
This commit is contained in:
parent
a6257a923d
commit
bbfea5876e
9 changed files with 100 additions and 75 deletions
|
|
@ -26,29 +26,13 @@ void http_loop_ctx_reset(http_loop_ctx *ctx) {
|
|||
ctx->route = NULL;
|
||||
ctx->current_step = 0;
|
||||
|
||||
if (ctx->req.body_type == http_body_buf && ctx->req.body.buf != NULL) {
|
||||
free(ctx->req.body.buf);
|
||||
ctx->req.body.buf = NULL;
|
||||
} else if (ctx->req.body_type == http_body_file &&
|
||||
ctx->req.body.file != NULL) {
|
||||
fclose(ctx->req.body.file);
|
||||
ctx->req.body.file = NULL;
|
||||
}
|
||||
|
||||
if (ctx->res.head != NULL) {
|
||||
free((void *)ctx->res.head);
|
||||
ctx->res.head = NULL;
|
||||
}
|
||||
|
||||
if (ctx->res.body_type == http_body_buf && ctx->res.body.buf != NULL &&
|
||||
ctx->res.owns_body) {
|
||||
free(ctx->res.body.buf);
|
||||
ctx->res.body.buf = NULL;
|
||||
} else if (ctx->res.body_type == http_body_file &&
|
||||
ctx->res.body.file != NULL) {
|
||||
fclose(ctx->res.body.file);
|
||||
ctx->res.body.file = NULL;
|
||||
}
|
||||
http_body_reset(&ctx->req.body);
|
||||
http_body_reset(&ctx->res.body);
|
||||
|
||||
for (size_t i = 0; i < ctx->res.header_count; i++) {
|
||||
if (ctx->res.headers[i].owned) {
|
||||
|
|
@ -61,7 +45,4 @@ void http_loop_ctx_reset(http_loop_ctx *ctx) {
|
|||
ctx->res.status = 0;
|
||||
ctx->res.head_len = 0;
|
||||
ctx->res.head_written = 0;
|
||||
ctx->res.body_len = 0;
|
||||
ctx->res.body_written = 0;
|
||||
ctx->res.owns_body = false;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -21,7 +21,7 @@ void http_loop_init_header(http_response *res) {
|
|||
|
||||
// First we calculate the size of the start of the header
|
||||
int buf_size = snprintf(NULL, 0, http_response_format, res->status,
|
||||
response_type_name, res->body_len);
|
||||
response_type_name, res->body.expected_len);
|
||||
|
||||
// We add each header's required size
|
||||
for (size_t i = 0; i < res->header_count; i++) {
|
||||
|
|
@ -34,7 +34,7 @@ void http_loop_init_header(http_response *res) {
|
|||
// with the required final newline
|
||||
char *buf = malloc(buf_size + 1);
|
||||
buf_size = sprintf(buf, http_response_format, res->status, response_type_name,
|
||||
res->body_len);
|
||||
res->body.expected_len);
|
||||
|
||||
for (size_t i = 0; i < res->header_count; i++) {
|
||||
buf_size +=
|
||||
|
|
@ -59,7 +59,7 @@ void http_loop_write_response(event_loop_conn *conn) {
|
|||
// The final iteration marks the end of the response, after which we reset the
|
||||
// context so a next request can be processed
|
||||
if (res->head_written == res->head_len &&
|
||||
res->body_written == res->body_len) {
|
||||
res->body.expected_len == res->body.len) {
|
||||
http_loop_ctx_reset(conn->ctx);
|
||||
conn->state = event_loop_conn_state_req;
|
||||
return;
|
||||
|
|
@ -75,23 +75,23 @@ void http_loop_write_response(event_loop_conn *conn) {
|
|||
res->head_written += bytes_to_write;
|
||||
}
|
||||
|
||||
if (res->body_written < res->body_len) {
|
||||
size_t bytes_to_write = MIN(res->body_len - res->body_written,
|
||||
if (res->body.len < res->body.expected_len) {
|
||||
size_t bytes_to_write = MIN(res->body.expected_len - res->body.len,
|
||||
EVENT_LOOP_BUFFER_SIZE - conn->wbuf_size);
|
||||
size_t bytes_written;
|
||||
|
||||
switch (res->body_type) {
|
||||
switch (res->body.type) {
|
||||
case http_body_buf:
|
||||
memcpy(&conn->wbuf[conn->wbuf_size], &(res->body.buf)[res->body_written],
|
||||
memcpy(&conn->wbuf[conn->wbuf_size], &(res->body.buf)[res->body.len],
|
||||
bytes_to_write);
|
||||
conn->wbuf_size += bytes_to_write;
|
||||
res->body_written += bytes_to_write;
|
||||
res->body.len += bytes_to_write;
|
||||
break;
|
||||
case http_body_file:
|
||||
bytes_written = fread(&conn->wbuf[conn->wbuf_size], sizeof(uint8_t),
|
||||
bytes_to_write, res->body.file);
|
||||
conn->wbuf_size += bytes_written;
|
||||
res->body_written += bytes_written;
|
||||
res->body.len += bytes_written;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ static bool try_parse_content_length(event_loop_conn *conn) {
|
|||
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,
|
||||
if (!string_to_num(&ctx->req.body.expected_len, header->value,
|
||||
header->value_len)) {
|
||||
ctx->res.status = http_bad_request;
|
||||
conn->state = event_loop_conn_state_res;
|
||||
|
|
@ -44,14 +44,14 @@ static bool try_parse_content_length(event_loop_conn *conn) {
|
|||
return false;
|
||||
}
|
||||
// The content length was actually 0, so we can instantly return here
|
||||
else if (ctx->req.body_len == 0) {
|
||||
else if (ctx->req.body.expected_len == 0) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// A zero here means there's no content length header
|
||||
if (ctx->req.body_len == 0) {
|
||||
if (ctx->req.body.expected_len == 0) {
|
||||
ctx->res.status = http_length_required;
|
||||
conn->state = event_loop_conn_state_res;
|
||||
|
||||
|
|
@ -64,47 +64,47 @@ static bool try_parse_content_length(event_loop_conn *conn) {
|
|||
bool http_loop_step_body_to_buf(event_loop_conn *conn) {
|
||||
http_loop_ctx *ctx = conn->ctx;
|
||||
|
||||
if (ctx->req.body_len == 0) {
|
||||
if (ctx->req.body.expected_len == 0) {
|
||||
if (!try_parse_content_length(conn)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
ctx->req.body_type = http_body_buf;
|
||||
ctx->req.body.buf = malloc(ctx->req.body_len * sizeof(uint8_t));
|
||||
ctx->req.body_received = 0;
|
||||
ctx->req.body.type = http_body_buf;
|
||||
ctx->req.body.buf = malloc(ctx->req.body.expected_len * sizeof(uint8_t));
|
||||
ctx->req.body.len = 0;
|
||||
}
|
||||
|
||||
size_t bytes_to_copy = MIN(conn->rbuf_size - conn->rbuf_read,
|
||||
ctx->req.body_len - ctx->req.body_received);
|
||||
memcpy(&ctx->req.body.buf[ctx->req.body_received],
|
||||
ctx->req.body.expected_len - ctx->req.body.len);
|
||||
memcpy(&ctx->req.body.buf[ctx->req.body.len],
|
||||
&conn->rbuf[conn->rbuf_read], bytes_to_copy);
|
||||
ctx->req.body_received += bytes_to_copy;
|
||||
ctx->req.body.len += bytes_to_copy;
|
||||
conn->rbuf_read += bytes_to_copy;
|
||||
|
||||
return ctx->req.body_received == ctx->req.body_len;
|
||||
return ctx->req.body.len == ctx->req.body.expected_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 (ctx->req.body.expected_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;
|
||||
ctx->req.body.type = http_body_file;
|
||||
ctx->req.body.file = fopen(ctx->req.body.fname, "wb");
|
||||
ctx->req.body.len = 0;
|
||||
}
|
||||
|
||||
size_t bytes_to_write = MIN(conn->rbuf_size - conn->rbuf_read,
|
||||
ctx->req.body_len - ctx->req.body_received);
|
||||
ctx->req.body.expected_len - ctx->req.body.len);
|
||||
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;
|
||||
ctx->req.body.len += bytes_written;
|
||||
conn->rbuf_read += bytes_written;
|
||||
|
||||
return ctx->req.body_received == ctx->req.body_len;
|
||||
return ctx->req.body.len == ctx->req.body.expected_len;
|
||||
}
|
||||
|
||||
bool http_loop_step_auth(event_loop_conn *conn) {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue