diff --git a/src/http.c b/src/http.c index b8fd093..15e2cfb 100644 --- a/src/http.c +++ b/src/http.c @@ -41,8 +41,6 @@ void lx_http_handle_data(lx_connection_t *conn) { lx_close(conn); return; } - - log_info("Received: %d bytes, buffer size: %ld, nread size: %ld", bytes, conn->size, req->parser.nread); lx_buf_t input = { .buf = conn->buf, .size = conn->size }; int parser_code = lx_http_parser_exec(&req->parser, &input); diff --git a/src/http_parser.c b/src/http_parser.c index fe9fa1c..81d32ca 100644 --- a/src/http_parser.c +++ b/src/http_parser.c @@ -43,6 +43,8 @@ const char *lx_http_map_code(lx_parser_status_t code) { return "Limit of max headers exceeded."; case LX_INVALID_CONTENT_LENGTH: return "Invalid content-length header value."; + case LX_CONTENT_LENGTH_DUPLICATE: + return "Received duplicated content-length header with different value."; default: return "Unknown HTTP parser code."; } @@ -111,6 +113,7 @@ void lx_http_parser_init(lx_http_parser_t *parser) { parser->nread = 0; parser->nheaders = 0; parser->content_length = 0; + parser->content_length_received = 0; parser->header_key.start = NULL; parser->header_key.size = 0; @@ -125,6 +128,13 @@ void lx_http_parser_init(lx_http_parser_t *parser) { parser->method.size = 0; } +enum lx_http_connection_header { + LX_KEEP_ALIVE, + LX_UPGRADE, + LX_CLOSE, + LX_INVALID +}; + // TODO: it would be more performant to detect specific headers during processing int lx_on_header_complete(lx_http_parser_t *parser) { http_raw_header_t *header = parser->req->raw_headers + parser->nheaders; @@ -139,7 +149,13 @@ int lx_on_header_complete(lx_http_parser_t *parser) { if (result == -1) { return LX_INVALID_CONTENT_LENGTH; } + + if (parser->content_length_received && parser->content_length != result) { + return LX_CONTENT_LENGTH_DUPLICATE; + } + parser->content_length = result; + parser->content_length_received = 1; } break; default: diff --git a/src/http_parser.h b/src/http_parser.h index 7bf905a..f43f903 100644 --- a/src/http_parser.h +++ b/src/http_parser.h @@ -12,7 +12,8 @@ typedef enum lx_parser_status { LX_INVALID_HEADER_KEY_CHAR, LX_INVALID_HEADER_VALUE_CHAR, LX_TOO_MANY_HEADERS, - LX_INVALID_CONTENT_LENGTH + LX_INVALID_CONTENT_LENGTH, + LX_CONTENT_LENGTH_DUPLICATE } lx_parser_status_t; typedef struct lx_buf { @@ -63,6 +64,7 @@ typedef struct lx_http_parser { slice_t header_key; slice_t header_value; size_t content_length; + int content_length_received: 1; unsigned nheaders; } lx_http_parser_t; diff --git a/src/http_request.h b/src/http_request.h index 56505ca..3357ad4 100644 --- a/src/http_request.h +++ b/src/http_request.h @@ -54,6 +54,7 @@ typedef struct http_raw_header { struct http_request_s { char *path; http_method_t method; + int persistent: 1; char *body; size_t body_size; lx_http_parser_t parser; @@ -71,6 +72,7 @@ static http_request_t *http_request_alloc() { req->connection = NULL; lx_http_parser_init(&req->parser); req->parser.req = req; + req->persistent = 1; return req; }