slate:llhttp
The HTTP parser itself — the state machine under slate:http.
import { httpParser, httpFeed, httpTake } from slate:llhttp
httpParser httpStream httpFeed httpTake httpTakePart httpFinish httpClose httpUpgraded httpHeading httpReading
httpHeading(p) says whether a request’s head is part way through arriving — true from its first
byte until the blank line that ends it, again for a pipelined request’s next head, and false before,
after, and once the parser has refused something. It is what a header-read deadline is built on: a
deadline on the whole request cannot tell a client dribbling its headers from one sending a large body
slowly. It asks a parser made by httpParser; a streaming parser hands its head over as a part, and
asking one is refused.
httpReading(p) says whether a request is part way through arriving, whatever part — true from its
first byte to the end of its message, head, body and trailer, and false between requests, before any byte,
and once the parser has refused something. httpHeading is false once a head is complete, and a
complete pipelined request that has been read but not taken looks like an idle connection to it;
httpReading stays true across all of that, so a server can start a request’s clock on a request that
arrived in the same read as the end of the last one. It is refused for a streaming parser too.
This is the lowest module slate has, and it is public on purpose. slate:http is the server a program
wants; this is for the programs that want something else — a proxy, a client that keeps its connections, a
test double that has to answer exactly the bytes it was asked about, or a protocol that begins as HTTP and
then stops being it. Every one of those is an ordinary package, where otherwise it would have been a
change to slate.
Node hid the same seam and its own client had to route around it: undici carries llhttp compiled to
wasm because internalBinding('http_parser') is not reachable. Two parsers in one process is the cost of
that policy.
The names keep their http prefix rather than being shortened to fit the module. They are the seam
slate:http is written against and they are spelled this way inside it, so a reader moving between the
module’s source and a package that uses the same calls sees one vocabulary.
Under slate js the grammar is written out rather than bound, node’s
own parser being unreachable from a program — which is the seam node hid and the reason undici carries
llhttp compiled to wasm. The two readings answer the same things about the same bytes, which is what
tests/js/p26.sl is for; a browser has no sockets to read from and every name refuses there.