Deviopath › Node.js

Incremental HTTP Request Parser

Hard · HTTP

Node's http module uses a C parser (llhttp) that receives raw TCP data in chunks and emits complete requests. A chunk can end anywhere: in the middle of a header name, between \r and \n, or inside the body. With keep-alive, one chunk can also contain several requests back to back (pipelining).

Implement a simplified parser: class HttpParser with feed(chunk), which returns an array of the requests completed by that chunk (often []), each as { method, path, version, headers, body }.

- A request is a request line, header lines, an empty line, then the body. Lines end with \r\n. Empty lines before a request line are ignored (RFC 9112 allows them between pipelined requests).

- The request line is METHOD target HTTP/x.y with single spaces: the method is capital letters, the target has no spaces, and x and y are single digits. version is "x.y".

- A header line is name:value. The name is letters, digits and - only, with nothing between it and the colon. Store names in lowercase and trim spaces around the value. If a name repeats, join the values with ", ".

- The body length is the content-length header, which must be digits only; without it the body is empty. The body is ASCII (1 character = 1 byte). Requests here never use Transfer-Encoding.

- Anything invalid (a bad request line, a header line without a valid name and colon, or a content-length that is not only digits, so two Content-Length headers are rejected too) → throw an Error with the message "Bad Request".

The driver runParser(chunks) is already written: it feeds the chunks in order and collects the requests. If feed throws, it adds { error: message } and stops.

Next: Cron Expression: Next Runs