diff --git a/lnm/include/lnm/http/req.h b/lnm/include/lnm/http/req.h index e43063c..5d8f46a 100644 --- a/lnm/include/lnm/http/req.h +++ b/lnm/include/lnm/http/req.h @@ -33,6 +33,9 @@ typedef struct lnm_http_req { struct phr_header arr[LNM_HTTP_MAX_REQ_HEADERS]; size_t len; } headers; + struct { + uint64_t expected_len; + } body; uint64_t content_length; } lnm_http_req; diff --git a/lnm/include/lnm/http/res.h b/lnm/include/lnm/http/res.h index b34f5da..ee2a079 100644 --- a/lnm/include/lnm/http/res.h +++ b/lnm/include/lnm/http/res.h @@ -7,8 +7,8 @@ #include "lnm/common.h" #include "lnm/http/consts.h" -typedef lnm_err (*data_fn)(size_t *written, char *buf, lnm_http_conn *conn, - size_t offset, size_t len); +typedef lnm_err (*data_fn)(uint64_t *written, char *buf, lnm_http_conn *conn, + uint64_t offset, uint64_t len); /** * Linked list elements used to store the response headers diff --git a/lnm/src/http/lnm_http_loop_process.c b/lnm/src/http/lnm_http_loop_process.c index 32bc840..2a6649a 100644 --- a/lnm/src/http/lnm_http_loop_process.c +++ b/lnm/src/http/lnm_http_loop_process.c @@ -12,7 +12,7 @@ /* static const lnm_http_loop_state lnm_http_loop_state_first_req = * lnm_http_loop_state_parse_req; */ static const lnm_http_loop_state lnm_http_loop_state_first_res = - lnm_http_loop_state_write_status_line; + lnm_http_loop_state_add_headers; void lnm_http_loop_process_parse_req(lnm_http_conn *conn) { lnm_http_loop_ctx *ctx = conn->ctx; @@ -52,7 +52,7 @@ void lnm_http_loop_process_route(lnm_http_conn *conn) { int match_level = 0; lnm_http_route *route; - for (size_t i = 0; i < gctx->routes.len && match_level < 2; i++) { + for (size_t i = 0; i < gctx->routes.len && match_level < 3; i++) { route = gctx->routes.arr[i]; bool matched_path; @@ -69,20 +69,21 @@ void lnm_http_loop_process_route(lnm_http_conn *conn) { } // Remember the previous match levels - int new_match_level = matched_path + (route->method == ctx->req.method); + int new_match_level = 2 * matched_path + (route->method == ctx->req.method); match_level = match_level < new_match_level ? new_match_level : match_level; } switch (match_level) { case 0: + case 1: ctx->res.status = lnm_http_status_not_found; ctx->state = lnm_http_loop_state_first_res; break; - case 1: + case 2: ctx->res.status = lnm_http_status_method_not_allowed; ctx->state = lnm_http_loop_state_first_res; break; - case 2: + case 3: ctx->route = route; ctx->cur_step = route->step; ctx->state = lnm_http_loop_state_parse_headers; @@ -138,21 +139,19 @@ void lnm_http_loop_state_process_add_headers(lnm_http_conn *conn) { lnm_http_loop_ctx *ctx = conn->ctx; lnm_http_res *res = &ctx->res; - if (res->body.len > 0) { - uint64_t digits = lnm_digits(res->body.len); - char *buf = malloc(digits + 1); + uint64_t digits = lnm_digits(res->body.len); + char *buf = malloc(digits + 1); - if (buf == NULL) { - conn->state = lnm_loop_state_end; + if (buf == NULL) { + conn->state = lnm_loop_state_end; - return; - } - - sprintf(buf, "%lu", res->body.len); - lnm_http_res_add_header_len(res, lnm_http_header_content_length, buf, - digits, true); + return; } + sprintf(buf, "%lu", res->body.len); + lnm_http_res_add_header_len(res, lnm_http_header_content_length, buf, + digits, true); + ctx->state = lnm_http_loop_state_write_status_line; } diff --git a/lnm/src/http/lnm_http_req.c b/lnm/src/http/lnm_http_req.c index ba7cccc..fa6e1da 100644 --- a/lnm/src/http/lnm_http_req.c +++ b/lnm/src/http/lnm_http_req.c @@ -16,9 +16,11 @@ lnm_http_parse_err lnm_http_req_parse(lnm_http_req *req, char *buf, int req_len = phr_parse_request( buf, len, &method, &method_len, (const char **)&path, &path_len, - &req->minor_version, req->headers.arr, &req->headers.len, 0); + &req->minor_version, req->headers.arr, &req->headers.len, req->len); if (req_len == -1) { + req->len = len; + return lnm_http_parse_err_invalid; } else if (req_len == -2) { return lnm_http_parse_err_incomplete;