An empty store — one per session.
A byte count as a person would read it: 0 bytes, 812 bytes, 4.2 KB, 1.3 MB.
Whether a content type is something a terminal should be asked to print.
Whether a name is one HTTP will carry — the token characters RFC 9110 allows, and no others.
A header as it was typed, or null where that is not a header at all.
A [verb:]url argument, split.
Which request an argument names: a name (#3), a position counted back (2), or a URL.
The most recent request a [verb:]url means, or null where the session never made one.
The request a RequestReference picks out, or null where the session made no such one.
Sends one request and records everything about it, including the ways it can go wrong.
The absolute URL a target means, or null where it means nothing usable.
url, with params folded into its query: { page: 2 } on /api/users is /api/users?page=2.
Replaces the default user-agent with the page's own, which is the one a server should see.
Files a request, newest last, naming it as it goes and dropping the oldest once there are REQUESTS_KEPT of them.
One request and whatever became of it.
-
at: number
When it was made, for ordering and for saying how long ago.
-
failed: string | null
Why there is no reply, said the way it would be said out loud.
nullwhere there is one. -
id: number
What this request is called for the rest of the session:
#3, and.request #3afterwards. -
ms: number
Wall-clock milliseconds, rounded — a REPL has no use for the fractions.
-
request: Request
The request, exactly as it was made.
-
response: Response | null
nullwhere it failed before a reply — DNS, connection refused, timeout.
A session's HTTP state: the headers it will send next, and everything it has sent.
-
headers: Map<string, string>
Saved for every upcoming request, lower-cased.
.header listprints this. -
lastId: number
The last id handed out. Kept here rather than counted from
requests.length, which stops being the number of requests made the moment the cap drops the oldest one — and an id that starts repeating is worse than no id at all. -
requests: HttpRequest[]
Oldest first, newest last, capped at REQUESTS_KEPT.
-
scratchpadText: string
The body buffer
.post … :opens: one for the life of the session, so reopening it continues the same thought rather than starting a blank one — the request equivalent of the scratchpad a prompt keeps. Saved empty is how it is cleared.
What was actually handed to fetch — the request, as this session made it.
-
body: string | null
nullfor the verbs that carry nothing, which is not the same as an empty body. -
headers: ReadonlyMap<string, string>
Lower-cased names, because HTTP says they are the same header either way.
-
url: string
Absolute, already resolved against the page.
-
verb: string
Upper case, the way HTTP writes it and every log prints it.
What came back. Absent on an HttpRequest that never got a reply.
-
binary: boolean
True where the content type is not something a terminal should be asked to print.
-
body: string
Decoded text, or
''where the body was not text. -
bodyTruncated: boolean
True where the body was longer than the cap and the rest was dropped, unread.
-
bytes: number
The size on the wire, which is the honest number even where the body was not kept.
-
headers: ReadonlyMap<string, string>
Lower-cased names, as they came off the wire.
-
status: number
The code, which is an answer even when it is a 404.
-
statusText: string
''where the protocol does not carry one — HTTP/2 never does.
| { kind: "position"; back: number; }
| { kind: "url"; verb: string | null; url: string; }
How a request was asked for — what parseRequestKind read, and what a miss has to explain.
What a session sends before you have said anything about headers.
How many requests a session keeps.
Usage
import * as mod from "lib/repl/http-service.ts";