gizlang:http
HTTP/1.1 (RFC 9112) over any Stream of gizlang:system, so HTTPS is the same code over a stream secured by gizlang:tls. serve keeps its connections in a Ready set, without a task each, and answers what they send in a few worker tasks; exchange sends one request and reads its response, and a Pool keeps client connections alive to send more on them. Header names are kept in lower case.
import * as Http from "gizlang:http";Types
Header
type Header = { name: string; value: string; }One header: its name and value.
name:stringvalue:string
Request
type Request = { method: string; path: string; headers: Vec<Header>; body: bytes; }An HTTP request: method, path with its query, headers and body.
method:stringpath:stringheaders:Vec<gizlang_http.Header>body:bytes
Response
type Response = { status: i64; headers: Vec<Header>; body: bytes; }An HTTP response: status, headers and body.
status:i64headers:Vec<gizlang_http.Header>body:bytes
HttpError
type HttpError = { status: i64; code: i64; message: string; }status is the HTTP status a server answers with (400, 413, 431, 501), or 0 when the connection itself failed; code is then the IoError's.
status:i64code:i64message:string
ExchangeHandler
type ExchangeHandler = (exchange: mut Exchange) => Result<bool, HttpError>A handler that writes its reply to the exchange itself. It returns whether the reply is complete.
ReplyPlan
type ReplyPlan = | { kind: "buffered"; response: Response; } | { kind: "progressive"; render: ExchangeHandler; }One reply contract for buffered handlers and progressive renderers. Ordinary Response handlers retain static dispatch; a mixed handler may return Reply. Progressive callbacks must finish the borrowed exchange before succeeding.
bufferedprogressive
Reply
interface Reply { plan(self: Self): ReplyPlan; }A value that a handler may return: it says how to answer (plan).
plan
Trace
type Trace = { id: string; span: string; }A W3C trace context (the traceparent header): the trace id (32 lowercase hex digits) and the span id (16) of the caller's span, neither all zeros.
id:stringspan:string
RequestHead
type RequestHead = (request: Request) => Option<ExchangeHandler> effects { io, fail }Select a streamed exchange from the request head, or use the buffered handler.
Exchange
type ExchangeOne request's exchange. On a multiplexed transport (_mux: HTTP/2 or HTTP/3) the same methods frame the reply as HEADERS and DATA.
request:gizlang_http.Request
Incoming
type IncomingA response whose body is read as it arrives (an event stream, a long
download): next gives each piece the connection delivers, event each
server-sent event, rest all that is left, whole the response. close
ends the connection. Reading to the end leaves a one-shot connection open,
and gives a pooled connection back to its Pool.
status:i64headers:Vec<gizlang_http.Header>reason:string
Event
type Event = { name: string; data: string; }A server-sent event (text/event-stream): its name ("message" when the event names none) and its data lines joined by "\n".
name:stringdata:string
Outgoing
type OutgoingA bounded request writer. The caller supplies the exact body length (UNKNOWN_LENGTH sends the body chunked) and writes pieces; finish refuses truncation before reading the response.
Opaque: create and use it through this module's functions.
Feed
type FeedA request parser fed the bytes its caller reads (a JavaScript runtime's socket), with the rules of serve: the
same head and body parsing, one message after another. A response feed (responseFeed) parses responses as
exchange does, interim ones included.
Opaque: create and use it through this module's functions.
Parsed
type Parsed = | { kind: "head"; request: Request; http10: bool; keep: bool; upgrade: bool; } | { kind: "status"; status: i64; reason: string; headers: Vec<Header>; http10: bool; keep: bool; upgrade: bool; } | { kind: "body"; data: bytes; } | { kind: "end"; } | { kind: "more"; } | { kind: "failed"; error: HttpError; }What the fed bytes give next: a request head (keep: the connection stays open after its response; upgrade: the request asks for another protocol or is CONNECT), a piece of its body, the end of the message, a need for more bytes, or a parse error (then the feed stops).
headstatusbodyendmorefailed
Origin
type Origin = { secure: bool; host: string; port: i64; }Where a pooled request goes: an origin (RFC 6454) is the scheme, the host and the port. Connections are kept and reused only for the same origin.
secure:boolhost:stringport:i64
Url
type Url = { secure: bool; host: string; port: i64; target: string; }An absolute http or https URL as a client uses it: whether it is secure, the host, the port (the scheme's when none is written) and the request target (path and query, "/" at least; a fragment is dropped).
secure:boolhost:stringport:i64target:string
PoolOptions
type PoolOptions = { perOrigin: i64; total: i64; idleMs: i64; }A Pool's bounds: the idle connections kept for one origin and for all origins, and how long one is kept idle (0 keeps none).
perOrigin:i64total:i64idleMs:i64
Pool
type PoolHTTP/1.1 keep-alive connections (RFC 9112 9.3) that requests share, kept
per origin. A request takes an idle connection of its origin, or else
dials a new one; the response gives it back when its body is read to the
end. A connection is never given back after an error, after close of an
unfinished body, when either side sends connection: close, or when the
response has no framing (its body ends when the connection does). An
HTTPS connection keeps its TLS session, so a reused one does no new
handshake. A Pool belongs to the thread (World) that made it; the tasks of
that thread may share it.
options:gizlang_http.PoolOptions
Asset
type Asset = { path: string; contentType: string; body: bytes; }An immutable content-addressed asset, shared by page shells and app hosts.
path:stringcontentType:stringbody:bytes
PartLimits
type PartLimits = { parts: i64; head: i64; field: i64; file: i64; total: i64; }The bounds of a multipart/form-data body: the number of parts, the head bytes of one part, the bytes of one field (a part without a filename), of one file, and of the whole body. Over a bound, the body is 413.
parts:i64head:i64field:i64file:i64total:i64
Part
type Part = { name: string; filename: Option<string>; contentType: string; }The head of one part: its form field name, its filename when it is a file, and its media type ("text/plain" when the part names none).
name:stringfilename:_gizlang_sdk_core.Option<string>contentType:string
PartEvent
type PartEvent = | { kind: "start"; part: Part; } | { kind: "data"; data: bytes; } | { kind: "end"; }What a multipart body gives in order: each part starts, gives its bytes in pieces, and ends.
startdataend
Multipart
type MultipartA multipart/form-data body (RFC 7578) read as it arrives: push takes the bytes in pieces of any size and
gives the events they complete. It keeps less than one delimiter of a part's bytes, or one part head.
Opaque: create and use it through this module's functions.
Files
type Files = { dir: Dir; kept: Ref<Map<string, Kept>>; bytes: Ref<i64>; }The files below dir that fileReply serves. They keep, for each file
served, its validators, its response headers and, up to MOST_KEPT_FILE bytes
(MOST_KEPT_BYTES in all), its body, as nginx's open_file_cache keeps
handles. A kept file is checked against the folder (one stat) at most once
in KEPT_VALID_MS. Make one for each serving thread (it holds a Ref).
dir:gizlang_system.Dirkept:Ref<_gizlang_sdk_collections.Map<string, gizlang_http.Kept>>bytes:Ref<i64>
Kept
type Kept = { size: i64; modified: i64; tag: string; headers: Vec<Header>; body: bytes; whole: bool; checked: i64; }A file's validators and headers; its body when whole.
size:i64modified:i64tag:stringheaders:Vec<gizlang_http.Header>body:byteswhole:boolchecked:i64
Span
type Span = { start: i64; end: i64; }A byte range from START to END, END excluded.
start:i64end:i64
ByteRange
type ByteRange = | { kind: "valid"; span: Span; } | { kind: "malformed"; } | { kind: "unsatisfiable"; }The parsed Range header: a valid span, a malformed header, or a range outside the file.
validmalformedunsatisfiable
Balancer
type BalancerRequests shared by several upstreams in turn. An upstream that cannot be reached is skipped for holdMs, and an idempotent request (GET, HEAD, OPTIONS, PUT, DELETE) that failed on it goes to the next one; other methods are not sent twice, but go on when the connection was refused (nothing was sent). The standby upstreams (standing) are tried, in their order, only after the upstreams.
Opaque: create and use it through this module's functions.
Policy
type Policy = { waitMs: i64; retries: i64; retryOn: Vec<i64>; replaceOn: Vec<i64>; fallback: Option<Origin>; }How a balancer treats failures. waitMs: the longest wait for a response head (0: none). retries: more tries of an idempotent request
when an upstream answers with a status in retryOn. replaceOn: statuses (and an upstream that cannot be reached, as 502) whose answer
is replaced by the page fallback serves at "/", with the status kept.
waitMs:i64retries:i64retryOn:Vec<i64>replaceOn:Vec<i64>fallback:_gizlang_sdk_core.Option<gizlang_http.Origin>
Relay
type Relay = { extra: Vec<Header>; done: (status: i64, sent: i64) => void; }What a relay adds to an answer and learns from it: extra, header fields put on it unless the upstream gave one of that name, and
done, called once when the answer has ended or failed with its status and the body bytes sent (101 with none for an upgrade).
extra:Vec<gizlang_http.Header>done:(status: i64, sent: i64) => void
Params
type Params = { names: Vec<string>; values: Vec<string>; }One declaration owns dispatch and reverse URLs. Compile the declarations
once before serving; resolution never reparses a pattern. A literal beats
a single-segment {name}, which beats a final *name, independently of
registration order.
names:Vec<string>values:Vec<string>
Route
type Route<T> = { method: string; pattern: string; target: T; }One route: the METHOD, the PATTERN (literals, {name} segments and an optional last *name) and the TARGET that it selects.
Opaque: create and use it through this module's functions.
Routed
type Routed<T> = { target: T; params: Params; }The result of a match: the target and the values of the pattern's names.
Opaque: create and use it through this module's functions.
Router
type Router<T>The compiled routes. Make it once with router before serving.
Opaque: create and use it through this module's functions.
Message
type Message = { text: bool; data: bytes; }One message: UTF-8 text, or binary data.
text:booldata:bytes
WebSocket
type WebSocketAn open WebSocket. receive gives each message; ping and close frames are answered here.
Opaque: create and use it through this module's functions.
SocketSession
type SocketSession = (socket: mut WebSocket) => Result<bool, HttpError>What runs on an opened server socket until it returns.
Mux
type Mux = { pieces: Task.Channel<bytes>; consumed: (count: i64) => void; head: (status: i64, headers: Vec<Header>, length: i64, end: bool) => Result<bool, HttpError>; data: (data: bytes, end: bool) => Result<bool, HttpError>; trailers: (fields: Vec<Header>) => Result<bool, HttpError>; ended: Ref<bool>; }The stream of an Exchange on a multiplexed transport: the request body pieces arrive on pieces (consumed returns their flow-control
credit), and the reply leaves as head, data and trailers; ended says the stream ended with the reply.
pieces:gizlang_task.Channel<bytes>consumed:(index: i64) => voidhead:(status: i64, headers: Vec<gizlang_http.Header>, length: i64, end: bool) => _gizlang_sdk_core.Result<bool, gizlang_http.HttpError>data:(data: bytes, end: bool) => _gizlang_sdk_core.Result<bool, gizlang_http.HttpError>trailers:(fields: Vec<gizlang_http.Header>) => _gizlang_sdk_core.Result<bool, gizlang_http.HttpError>ended:Ref<bool>
Qpack
type Qpack = { table: Vec<Header>; tree: Huffman; }The QPACK static table with the Huffman tree, the state that qpackDecode and qpackBlock share (build it once).
table:Vec<gizlang_http.Header>tree:gizlang_http.Huffman
H2Client
type H2ClientAn HTTP/2 connection as a client.
status:i64— The reply's status, 0 until its head arrived.headers:Vec<gizlang_http.Header>trailers:Vec<gizlang_http.Header>
Limiter
type LimiterAt most limit requests from one client (clientOf) within windowMs.
Opaque: create and use it through this module's functions.
Counted
type Counted = { client: string; count: i64; first: i64; last: i64; }What a store keeps of a client's requests in the window: how many, and the wall-clock time (ms) of the first and the last.
client:stringcount:i64first:i64last:i64
Functions
header
function header(headers: Vec<Header>, name: string): Option<string>The first value of a header, its name in any case.
Effects: fail.
traceOf
function traceOf(headers: Vec<Header>): Option<Trace>The valid version-00 traceparent among headers, else none.
Effects: fail.
traceparent
function traceparent(t: Trace): stringThe traceparent value of t, sampled.
Effects: fail.
text
function text(status: i64, body: string): ResponseA plain UTF-8 text response with STATUS and BODY.
Effects: fail.
serve
function serve<F>(listener: Listener, handler: F): i64 throws IoErrorAccept connections and answer each request with handler(request), until accepting fails (as when the listener is closed) or the task is cancelled, which closes the connections. A connection waits in a Ready set between requests; a handler fault ends only the connection it was answering, and a connection idle for IDLE_MS is closed.
serveStreamed
function serveStreamed<F>(listener: Listener, handler: F, head: RequestHead): i64 throws IoErrorserve, and head chooses a streamed exchange for a request from its head (an upload, a long response); the requests it leaves go to handler.
serveReady
function serveReady<F>(set: Ready, handler: F): i64 throws IoErrorAnswer the requests of the connections a Ready set reports, as serve does, until the set stops (gizlang:tls's serve fills the set itself).
serveReadyStreamed
function serveReadyStreamed<F>(set: Ready, handler: F, head: RequestHead): i64 throws IoErrorserveReady with a streamed-exchange head, as serveStreamed.
dateField
function dateField(name: string, ms: i64, second: Ref<i64>, line: Ref<bytes>): bytesThe Date field line NAME: <IMF-fixdate> CRLF for wall time MS, made at most once a second into LINE for the second in SECOND: Web.serve's "date" and node:http's "Date" share this one cache rule.
Effects: fail, read, write.
chunkHead
function chunkHead(out: mut bytes, size: i64): voidA chunk's size line (RFC 9112 7.1): SIZE in lowercase hex, then CRLF, appended to OUT.
Effects: fail.
open
function open(stream: Stream, host: string, request: Request): Incoming throws HttpErrorSend one request on a stream and read the response head; the body is then
read from the Incoming, which owns the stream. host is sent as the Host
header, and connection: close asks the server to end the connection.
Effects: fail, write, io.
outgoing
function outgoing(stream: Stream, host: string, request: Request, size: i64): Outgoing throws HttpErrorWrites the head of REQUEST to HOST on STREAM, for a body of SIZE bytes (UNKNOWN_LENGTH sends it chunked).
Effects: fail, io.
feed
function feed(): FeedA parser of HTTP/1.1 messages that takes the bytes as they arrive.
responseFeed
function responseFeed(): FeedA feed of responses: each head is a status (keep: the connection can carry another request; upgrade: 101).
exchange
function exchange(stream: Stream, host: string, request: Request): Response throws HttpErrorSend one request on a stream and read the whole response; the stream is
closed after it. host is sent as the Host header.
Effects: fail, read, write, console, io.
fetch
function fetch(system: System, host: string, port: i64, request: Request): Response throws HttpErrorA plain-HTTP request to host:port.
Effects: fail, read, write, console, io.
fetchUpTo
function fetchUpTo(system: System, host: string, port: i64, request: Request, most: i64): Response throws HttpErrorAs fetch, for a response of up to most bytes (MOST_BODY holds for fetch).
Effects: fail, read, write, console, io.
url
function url(text: string): Option<Url>text as an http or https URL; none for another scheme, user info, an
empty host or a bad port.
Effects: fail.
poolDefaults
function poolDefaults(): PoolOptionsThe default pool options: POOL_PER_ORIGIN, POOL_TOTAL and POOL_IDLE_MS.
pool
function pool(system: System, options: PoolOptions): PoolA Pool of plain-HTTP connections; an https origin is refused (gizlang:tls's
pool secures them).
Effects: fail, write.
poolDialing
function poolDialing(options: PoolOptions, dial: (origin: Origin) => Result<Stream, HttpError>): Pool requires options.perOrigin> = 0 && options.total> = 0 && options.idleMs> = 0 { const empty: Vec<Parked> = []A Pool whose new connections come from dial, which connects to an
origin and secures it when it is https.
Effects: fail, write.
asset
function asset(extension: string, contentType: string, body: bytes): AssetAn asset with BODY at a content-addressed path: the SHA-256 of BODY, then EXTENSION. Thus the path changes when the body changes, and the asset can be cached for ever.
Effects: fail.
pathOf
function pathOf(request: Request): stringThe request's path without its query.
Effects: fail.
query
function query(request: Request): Params throws HttpErrorThe query parameters of a request: decodeForm of the text after "?".
Effects: fail.
decodeForm
function decodeForm(encoded: string): Params throws HttpErrorThe pairs of an application/x-www-form-urlencoded text (a form body or a query), decoded, in order, with all duplicate values ("+" is a space). Empty parts are skipped. Invalid encoding or excess input returns 400.
Effects: fail.
partLimits
function partLimits(): PartLimits64 parts, 8 KiB heads, 1 MiB fields, 16 MiB files and 64 MiB in all.
Effects: fail.
multipart
function multipart(contentType: string, limits: PartLimits): Multipart throws HttpErrorThe parser of a body with CONTENT_TYPE; 400 when it is not multipart/form-data with a valid boundary.
Effects: fail.
dispositionFilename
function dispositionFilename(value: string): Option<string>The file name a Content-Disposition value gives (RFC 6266): filename* (RFC 8187, UTF-8'' and percent escapes)
before filename; none when it gives none.
Effects: fail.
attachment
function attachment(name: string): stringThe Content-Disposition value that saves a download as name (RFC 6266): filename in printable ASCII ('"' and ''
as '_'), and filename* with the whole name in UTF-8.
Effects: fail.
encode
function encode(text: string): stringPercent-encoding (RFC 3986): every byte but A-Z a-z 0-9 - . _ ~ as %XX, so
the text is one query value or path segment. decode reads it back.
Effects: fail.
decode
function decode(encoded: string, plusIsSpace: bool): Option<string>Percent-decoding (RFC 3986); none for a bad escape or a result that is not UTF-8. In a query, "+" also stands for a space.
Effects: fail.
under
function under(path: string, prefix: string): Option<string>The rest of path below prefix ("/static/a.css" under "/static" is
"/a.css"); none when the path is not there. A prefix matches whole
segments only: "/static" does not take "/statics".
Effects: fail.
redirect
function redirect(status: i64, location: string): ResponseA redirect with STATUS to LOCATION. The body is the location as plain text.
Effects: fail.
withHeader
function withHeader(response: Response, name: string, value: string): ResponseThe response with one more header.
Effects: fail.
httpDate
function httpDate(ms: i64): stringAn HTTP date (RFC 9110 5.6.7), as "Sun, 06 Nov 1994 08:49:37 GMT".
Effects: fail.
parseHttpDate
function parseHttpDate(value: string, nowMs: i64): Option<i64>RFC 9110 HTTP-date, including both obsolete forms. nowMs resolves the RFC 850 two-digit year at the exact fifty-year calendar boundary. UTC leap second 60 maps to the next representable Unix second.
Effects: fail.
mimeType
function mimeType(path: string): stringThe media type of a file by its extension; text types are UTF-8.
Effects: fail.
file
function file(dir: Dir, request: Request, path: string, nowMs: i64): ResponseServe the file at path (still percent-encoded, as in the request) below
dir, as nginx serves root: GET and HEAD; "index.html" for a directory,
and a redirect to the slash form for a directory named without it; the
media type; ETag and Last-Modified with ordered HTTP preconditions; and one
byte range (206, or 416 past the end). nowMs is the caller's System.time()
instant, needed to resolve obsolete two-digit HTTP years. Paths
cannot leave dir or follow links (gizlang:system).
Effects: fail, io.
files
function files(dir: Dir): FilesA cache of the files of DIR for static serving.
Effects: fail, write.
fileReply
function fileReply(files: Files, request: Request, path: string, nowMs: i64): ReplyPlanThe same file policy as file(), with known-length bounded transport output. A kept body answers from memory. A larger file holds the opened inode from admission until emission; HEAD never reads its body. Publish files immutably (a new name for new content): a kept file can answer its old content for KEPT_VALID_MS after a change.
Effects: fail, read, write, io.
fileReplyWith
function fileReplyWith(files: Files, request: Request, path: string, nowMs: i64, extra: Vec<Header>): ReplyPlanfileReply with EXTRA headers on every answer that carries the file (a Cache-Control the caller knows, for one).
Effects: fail, read, write, io.
precompress
function precompress(dir: Dir, names: Vec<string>): Result<bool, string>Writes name.gz beside each of NAMES in DIR, for codedFor to answer with, as 0644: the files are public, and a server
running as another user reads them. gzip only: it is Gizlang, so serving code needs no native library on a deploy host;
name.br (brotli, a native library) is written at build time.
Effects: fail, io.
publicFile
function publicFile(dir: Dir, path: string, data: bytes): Result<bool, string>DATA as the public file PATH of DIR (0644).
Effects: fail, io.
notModified
function notModified(request: Request, tag: string): boolWhether the request's If-None-Match names tag (an ETag with its quotes):
"*", or a list of tags compared weakly (W/ ignored), as RFC 9110 says for
GET; the caller then answers 304 with the headers it would have sent.
Effects: fail.
entityTagMatches
function entityTagMatches(value: string, tag: string, strong: bool): boolCompare an HTTP ETag list. Quoted commas are opaque tag bytes. Malformed lists do not match; weak tags participate only in weak comparison.
Effects: fail.
precondition
function precondition(request: Request, tag: Option<string>, modified: Option<i64>, nowMs: i64): i64RFC 9110 precondition order. Zero permits execution; a conditional status is final. Invalid dates are ignored; timestamps compare at second precision. nowMs is supplied by the caller for deterministic obsolete-year resolution.
Effects: fail.
rangeValidatorMatches
function rangeValidatorMatches(value: string, tag: string, modified: i64, nowMs: i64): boolIf-Range accepts one strong ETag or an exactly matching HTTP date. A stale, weak or malformed validator requires the complete representation.
Effects: fail.
cookie
function cookie(request: Request, name: string): Option<string>The value of the request's cookie name, as the browser sent it.
Effects: fail.
setCookie
function setCookie(name: string, value: string, maxAge: Option<i64>, secure: bool): string throws stringBuild a Set-Cookie value with Path=/, HttpOnly and SameSite=Lax. maxAge is seconds: none makes a session cookie; zero deletes with an empty value. secure adds Secure. Reject negative ages, non-token names and values outside the unquoted cookie-octets of RFC 6265 section 4.1.1.
Effects: fail.
parseByteRange
function parseByteRange(spec: string, size: i64): ByteRangeOne half-open interval from RFC 9110's single byte-range grammar. Callers choose whether to ignore malformed input (HTTP files) or reject it (S3).
Effects: fail.
proxy
function proxy(pool: Pool, upstream: Origin, request: Request): ResponseForward the request to the upstream origin and return its response, as
nginx's proxy_pass with upstream keep-alive: the request goes on a kept
connection of pool (a new one only when none is idle), hop-by-hop
headers (RFC 9110 7.6.1) are dropped both ways, and the upstream's own
authority is sent as Host. 502 when it cannot be reached or answers badly.
Effects: fail, read, write, console, io.
plainPolicy
function plainPolicy(): PolicyA policy that changes nothing.
balancer
function balancer(pool: Pool, upstreams: Vec<Origin>, holdMs: i64): BalancerA balancer that sends requests of POOL to UPSTREAMS and holds a failed upstream out for HOLD_MS.
Effects: fail, write.
bodyOver
function bodyOver(request: Request, from: i64): boolWhether the request has a body that is chunked or of at least FROM bytes, which a server may stream instead of holding.
Effects: fail.
play
function play(plan: ReplyPlan, exchange: mut Exchange): bool throws HttpErrorRuns a reply plan on an exchange.
Effects: fail, read, write, console, io.
withExtra
function withExtra(headers: Vec<Header>, extra: Vec<Header>): Vec<Header>HEADERS with each field of EXTRA whose name they lack.
Effects: fail.
proxied
function proxied(request: Request): RequestThe request proxy sends upstream: without hop-by-hop headers and Host.
Effects: fail.
returned
function returned(response: Response): ResponseThe upstream's response as proxy returns it: without hop-by-hop headers.
Effects: fail.
forwarded
function forwarded(request: Request, proto: string): RequestThe request as an edge forwards it: the client's address (from the socket, never from the client) appended to X-Forwarded-For, and the scheme and Host the client used in X-Forwarded-Proto and X-Forwarded-Host. What a client sent under those names is dropped.
Effects: fail.
logLine
function logLine(request: Request, response: Response, ms: i64): stringAn access log line at ms (milliseconds since 1970 UTC, System.time()):
time, request line, status, body bytes, referrer and user agent, as nginx's
combined format without the client address.
Effects: fail.
compressed
function compressed(request: Request, response: Response): ResponseNegotiate buffered gzip/identity through the shared coding policy. Both variants vary on Accept-Encoding; no acceptable representation answers 406. Already coded bytes and byte ranges retain their admitted representation.
Effects: fail.
acceptsEncoding
function acceptsEncoding(request: Request, coding: string): boolContent-coding admission shared by buffered and progressive responses. Explicit codings override wildcard admission. Identity is acceptable by default unless identity;q=0 or an unoverridden *;q=0 excludes it.
Effects: fail.
router
function router<T>(declarations: Vec<Route<T>>): Router<T> throws stringCompiles DECLARATIONS into a router, or gives why they are not valid (a bad pattern, a duplicate route or a bound that is exceeded).
mount
function mount<T, U>(prefix: string, declarations: Vec<Route<T>>, target: (part: T) => U): Vec<Route<U>>DECLARATIONS of a part of an app placed under PREFIX ("" or "/admin"): each pattern after the prefix, each target made by TARGET, so the part is declared once and composed into any app's routes.
gzip
function gzip<F>(request: Request, next: F): ResponseMiddleware is a function of the request and the next handler (any function from Request to Response) that may answer itself, change the request it passes on or change the response, as Actix's wrap or Express's use; they compose by nesting, outermost first: gzip(request, (r) => logged(r, site)). gzip compresses what the rest answers (compressed above).
webSocketAccept
function webSocketAccept(key: string): stringThe Sec-WebSocket-Accept value of a Sec-WebSocket-Key.
Effects: fail.
isWebSocket
function isWebSocket(request: Request): boolWhether request opens a WebSocket: a GET with Upgrade: websocket,
Connection: upgrade, version 13 and a 16-byte key.
Effects: fail.
webSocket
function webSocket(request: Request, protocol: string, session: SocketSession): ReplyPlanThe reply that opens a WebSocket for request and runs session on it,
then closes it; 426 when the request does not open one (isWebSocket).
protocol, when not "", is the subprotocol it answers with. A web app's
cross-site openings are refused before this (Web.crossSite).
Effects: fail.
openWebSocket
function openWebSocket(sys: System, stream: Stream, host: string, path: string, headers: Vec<Header>): WebSocket throws HttpErrorOpens a WebSocket at path of host as a client on stream, sending
headers too (an Origin, a Sec-WebSocket-Protocol).
Effects: fail, write, io.
replyFields
function replyFields(headers: Vec<Header>, length: i64, date: bytes): Vec<Header>The fields of a reply on HTTP/2 or HTTP/3: lower case, without HTTP/1.1 connection fields, with a Date (from DATE, a "date: ...\r\n" line, as the connection makes it) and a Content-Length when LENGTH is known.
Effects: fail.
huffmanDecode
function huffmanDecode(tree: Huffman, data: bytes): bytes throws stringThe text that the Huffman code data stands for; an error for a code that is invalid or padded wrong.
Effects: fail.
newQpack
function newQpack(): QpackThe QPACK state: build it once and share it.
Effects: fail.
qpackDecode
function qpackDecode(q: Qpack, block: bytes): Vec<Header> throws stringThe fields of a QPACK field section (RFC 9204 §4.5) that uses only the static table: the connection announces a dynamic table of capacity 0, so a section that needs one is an error.
Effects: fail.
qpackBlock
function qpackBlock(q: Qpack, fields: Vec<Header>): bytesA QPACK field section for FIELDS that uses only the static table (literals, never Huffman coded).
Effects: fail.
requestOf
function requestOf(fields: Vec<Header>, peer: string): Request throws stringThe request that HTTP/2 or HTTP/3 header fields make (RFC 9113 §8.3, RFC 9114 §4.3); an error for a malformed set.
Effects: fail.
replyOn
function replyOn(request: Request, plan: ReplyPlan, mux: Mux): boolRuns the reply of plan for request on a multiplexed stream; whether the reply ended whole.
Effects: fail, read, write, console, io.
openH2
function openH2(stream: Stream, host: string, secure: bool): H2Client throws HttpErrorStarts HTTP/2 on stream for host (the :authority); secure says the scheme is https.
Effects: fail, io.
clientOf
function clientOf(request: Request, proxies: Vec<string>): stringThe client of a request: the socket's peer (the server sets it, PEER_HEADER), or, when the peer is one of proxies, the last X-Forwarded-For value, which that proxy appended (the values before it came from the client and can be forged). Empty when the peer is not known.
Effects: fail.
limiter
function limiter(limit: i64, windowMs: i64, proxies: Vec<string>): LimiterA limiter of LIMIT requests from one client within WINDOWMS; PROXIES are the addresses whose X-Forwarded-For hop names the client.
Effects: fail, write.
Methods
Response.plan
function Response.plan(self: Response): ReplyPlanA buffered reply: the response as it is.
ReplyPlan.plan
function ReplyPlan.plan(self: ReplyPlan): ReplyPlanThe plan itself.
Exchange.next
function Exchange.next(self: mut Exchange): Option<bytes> throws HttpErrorThe next piece of the request body, or none at its end.
Effects: fail, read, write, console, io.
Exchange.whole
function Exchange.whole(self: mut Exchange): Request throws HttpErrorThe whole request with its body read.
Effects: fail, read, write, console, io.
Exchange.acceptBody
function Exchange.acceptBody(self: Exchange): bool throws HttpErrorSend 100 Continue only after the application admits the request head.
Effects: fail, io.
Exchange.respond
function Exchange.respond(self: mut Exchange, status: i64, headers: Vec<Header>, size: i64): bool throws HttpErrorWrites the status line and HEADERS of a reply with SIZE body bytes. UNKNOWN_LENGTH gives a chunked body.
Effects: fail, read, write, console, io.
Exchange.write
function Exchange.write(self: mut Exchange, data: bytes): bool throws HttpErrorWrites DATA as part of the response body. It fails before the response starts, after it ends, or past its length.
Effects: fail, read, write, console, io.
Exchange.writeAll
function Exchange.writeAll(self: mut Exchange, data: bytes): bool throws HttpErrorEmit existing bytes as bounded pieces. No second framing or buffering owner.
Effects: fail, read, write, console, io.
Exchange.send
function Exchange.send(self: mut Exchange, response: Response): bool throws HttpErrorBuffered response emission through the same Exchange framing owner.
Effects: fail, read, write, console, io.
Exchange.trailers
function Exchange.trailers(self: mut Exchange, fields: Vec<Header>): bool throws HttpErrorEnds an HTTP/2 reply with trailer fields (a HEADERS frame that ends the stream), after respond and any write; gRPC's status travels so. HTTP/1.1 replies have none.
Effects: fail, read, write, console, io.
Exchange.finish
function Exchange.finish(self: mut Exchange): bool throws HttpErrorEnds the response. It fails when the body is shorter than the length that the response said.
Effects: fail, read, write, console, io.
Outgoing.write
function Outgoing.write(self: mut Outgoing, data: bytes): bool throws HttpErrorWrites DATA as part of the request body. It fails after finish or past the length.
Effects: fail, io.
Outgoing.finish
function Outgoing.finish(self: mut Outgoing): Incoming throws HttpErrorEnds the request and reads the head of the response. It fails when the body is shorter than its length.
Effects: fail, write, io.
Incoming.next
function Incoming.next(self: mut Incoming): Option<bytes> throws HttpErrorThe next piece of the body; none after the last.
Effects: fail, read, write, console, io.
Incoming.rest
function Incoming.rest(self: mut Incoming): bytes throws HttpErrorThe rest of the body, at most MOST_BODY bytes.
Effects: fail, read, write, console, io.
Incoming.restUpTo
function Incoming.restUpTo(self: mut Incoming, most: i64): bytes throws HttpErrorThe rest of the body, at most most bytes (a client reading a large answer).
Effects: fail, read, write, console, io.
Incoming.event
function Incoming.event(self: mut Incoming): Option<Event> throws HttpErrorThe next server-sent event; none at the end of the stream. Comment lines (":" first, as keep-alives) and events without data are skipped; a line ends at LF, CRLF or CR.
Effects: fail, read, write, console, io.
Incoming.close
function Incoming.close(self: Incoming): voidEnd the connection, unless it was given back to its Pool or is closed.
Effects: fail, read, write, io.
Incoming.whole
function Incoming.whole(self: mut Incoming): Response throws HttpErrorThe whole response. After its body a pooled connection goes back to its Pool, and any other connection is closed.
Effects: fail, read, write, console, io.
Feed.skipBody
function Feed.skipBody(self: mut Feed): voidThe current message has no body after all (a response to HEAD, which only its requester knows).
Feed.bodiless
function Feed.bodiless(self: Feed): boolThe message whose head the feed just gave has no body (no Transfer-Encoding, and no or a zero Content-Length): its next result is its end.
Feed.untilClose
function Feed.untilClose(self: Feed): boolThe body runs until the peer closes; at that close the message ends.
Feed.push
function Feed.push(self: mut Feed, data: bytes): voidAdds bytes read from the peer.
Effects: fail.
Feed.pending
function Feed.pending(self: Feed): i64The bytes pushed and not parsed yet.
Effects: fail.
Feed.rest
function Feed.rest(self: Feed): bytesThose bytes themselves: what follows an upgrade's head belongs to the new protocol (node:http's 'upgrade' head).
Effects: fail.
Feed.next
function Feed.next(self: mut Feed): ParsedThe next result of the pushed bytes. A step that needs more bytes leaves the feed as it was, so it starts again when they come.
Effects: fail, io.
Origin.authority
function Origin.authority(self: Origin): stringThe Host field of a request to the origin (RFC 9110 7.2): the host, in brackets when it is an IPv6 literal, then ":port" unless the port is the default of the scheme (80, or 443 for https).
Effects: fail.
Url.text
function Url.text(self: Url): stringThe URL written out, the port only when it is not the scheme's.
Effects: fail.
Url.resolve
function Url.resolve(self: Url, location: string): Option<Url>location (a redirect's: absolute, scheme-relative, a path or relative to
this one's directory) read against this URL.
Effects: fail.
Url.origin
function Url.origin(self: Url): OriginThe origin of the URL, for a Pool.
Pool.idle
function Pool.idle(self: Pool): i64The idle connections the pool keeps now (none past the idle time).
Effects: fail, read, io.
Pool.close
function Pool.close(self: Pool): voidClose the idle connections, and refuse new requests. A connection still lent to an Incoming is closed when that Incoming ends.
Effects: fail, read, write, io.
Pool.open
function Pool.open(self: Pool, origin: Origin, request: Request): Incoming throws HttpErrorSend request to origin on a pooled connection and read the response
head; the body is then read from the Incoming. The request's own
connection: close is sent and ends the connection after the response.
An idle connection can be stale (its server closed it while it waited):
when such a reused connection ends before any byte of a response, an
idempotent request is sent one more time, on a new connection. No other
failure is sent again.
Effects: fail, read, write, console, io.
Pool.openAs
function Pool.openAs(self: Pool, origin: Origin, host: string, request: Request, waitMs: i64): Incoming throws HttpErroropen with host as the Host the origin is sent (a proxy that keeps the client's own), and the response head awaited at most waitMs
milliseconds (0: without a limit).
Effects: fail, read, write, console, io.
Pool.fetch
function Pool.fetch(self: Pool, origin: Origin, request: Request): Response throws HttpErrorThe whole response of a pooled request.
Effects: fail, read, write, console, io.
Multipart.push
function Multipart.push(self: mut Multipart, data: bytes): Vec<PartEvent> throws HttpErrorThe events that DATA completes. A malformed body is 400; a body over a bound is 413.
Effects: fail.
Multipart.finish
function Multipart.finish(self: Multipart): bool throws HttpError400 when the body ended before its closing delimiter.
Exchange.multipart
function Exchange.multipart(self: Exchange, limits: PartLimits): Multipart throws HttpErrorThe parser of this exchange's multipart/form-data body within LIMITS, after 100 Continue when the client
expects it. parts then reads the body with it.
Effects: fail, io.
Exchange.parts
function Exchange.parts(self: mut Exchange, parser: mut Multipart): Option<Vec<PartEvent>> throws HttpErrorThe events of the next piece of the body as it arrives, and none at its end (400 when PARSER has not seen the closing delimiter). The body is never held whole: the caller keeps what it needs. let parser = try exchange.multipart(Http.partLimits()); while (true) { match (try exchange.parts(parser)) { Option.some(events) => { ... } Option.none() => { break; } } }
Effects: fail, read, write, console, io.
Balancer.under
function Balancer.under(self: Balancer, policy: Policy): BalancerThe same balancer (its upstreams, marks and turn are shared) under policy.
Balancer.standing
function Balancer.standing(self: Balancer, standby: Vec<Origin>): BalancerThe same balancer with STANDBY: upstreams that get a request only when no upstream can take it (for example a server that starts the upstream that is down).
Balancer.use
function Balancer.use(self: Balancer, upstreams: Vec<Origin>): voidReplace the upstreams (for example the live members of a mesh, as they change). The marks of unreachable ones are cleared.
Effects: fail, write.
Balancer.follow
function Balancer.follow(self: Balancer, members: Vec<Member>): voidFollow a mesh: the upstreams become the live members, at their meta port (as a number) on their host. Call it before a send with
mesh.alive(); a member whose meta is not a port is left out.
Effects: fail, write.
Balancer.keepingHost
function Balancer.keepingHost(self: Balancer): BalancerThe same balancer (its upstreams, marks and turn are shared) that sends the request's own Host to the upstream, as a reverse proxy does for sites that tell their hosts apart.
Balancer.open
function Balancer.open(self: Balancer, request: Request): Incoming throws HttpErrorThe response head of the next upstream in turn that can be reached, its body still to be read. A request that no upstream took
(no connection was made, or it was refused) goes to the next. An idempotent request (GET, HEAD, OPTIONS, PUT, DELETE) that failed
on one goes to the next too, and one that got a status of the policy's retryOn goes again (to the next upstream, the same one
when it is alone) up to retries more times; another request is not sent twice.
Effects: fail, read, write, console, io.
Balancer.send
function Balancer.send(self: Balancer, request: Request): ResponseThe answer of the next upstream in turn that can be reached (as proxy), or 502 when none can.
Effects: fail, read, write, console, io.
Balancer.relay
function Balancer.relay(self: Balancer, request: Request, relay: Relay): ReplyPlanThe answer of the next upstream in turn that can be reached, as it arrives: the status and headers go on at once and each piece of the body as the upstream delivers it (a download, an event stream), so nothing is held back and no size is bounded. A request that asks to upgrade the connection (a WebSocket) is joined to the upstream's: after its 101 the two carry bytes both ways.
Effects: fail, read, write, console, io.
Balancer.forward
function Balancer.forward(self: Balancer, request: Request, relay: Relay): ReplyPlanThe reply for a request whose body is still on the client's connection: the body goes to the first upstream that can be reached as it arrives (its Content-Length, else chunked), so nothing is held and no size is bounded. A body sent cannot be sent again, so only the dial can fall to the next upstream, and a failure after the first byte is a 502.
Router.resolve
function Router.resolve<T>(self: Router<T>, request: Request): Routed<T> throws ResponseResolve exactly once. Path specificity is decided before method lookup: a recognized static path with a different method is 405, not a capture fallback. HEAD uses its explicit binding before GET; the HTTP writer suppresses its body.
Route.href
function Route.href<T>(self: Route<T>, params: Params): string throws stringThe path of this route with PARAMS: the declaration is the one source of a link, not a second pattern string. Capture values are decoded values: a segment's slash is escaped, a rest's slashes are kept as intentional boundaries. Query fields use encode separately.
Params.get
function Params.get(self: Params, name: string): stringA parameter's value, the first one for a name ("" when there is no such name).
Effects: fail.
Params.all
function Params.all(self: Params, name: string): Vec<string>Every value of a name, in order.
Effects: fail.
Params.integer
function Params.integer(self: Params, name: string): Option<i64>A parameter as a decimal integer, none when it is not one.
Effects: fail.
WebSocket.closed
function WebSocket.closed(self: WebSocket): boolWhether the socket is closed (by either side).
Effects: fail, read.
WebSocket.timeout
function WebSocket.timeout(self: WebSocket, milliseconds: i64): i64 throws IoErrorHow long receive waits for the peer before it fails (IDLE_MS when opened).
Effects: fail, io.
WebSocket.send
function WebSocket.send(self: WebSocket, message: string): bool throws HttpErrorSends a text message.
Effects: fail, read, io.
WebSocket.sendBytes
function WebSocket.sendBytes(self: WebSocket, data: bytes): bool throws HttpErrorSends a binary message.
Effects: fail, read, io.
WebSocket.ping
function WebSocket.ping(self: WebSocket, data: bytes): bool throws HttpErrorSends a ping; the peer's pong is consumed by receive.
Effects: fail, read, io.
WebSocket.close
function WebSocket.close(self: WebSocket, code: i64, reason: string): boolSends a close frame once and marks the socket closed.
Effects: fail, read, write, io.
WebSocket.receive
function WebSocket.receive(self: mut WebSocket): Option<Message> throws HttpErrorThe next message; none once the socket is closed (a close frame, the end of the stream). A protocol violation closes the socket with its code and fails.
Effects: fail, read, write, io.
H2Client.start
function H2Client.start(self: mut H2Client, method: string, path: string, headers: Vec<Header>, end: bool): bool throws HttpErrorOpens a call: the request head, ending the stream when end says it has no body.
Effects: fail, io.
H2Client.send
function H2Client.send(self: mut H2Client, data: bytes, end: bool): bool throws HttpErrorThe request body: data within the flow-control windows (it waits for the peer's WINDOW_UPDATE), the last piece with end.
Effects: fail, io.
H2Client.receive
function H2Client.receive(self: mut H2Client): Option<bytes> throws HttpErrorThe next piece of the reply body; none when the reply ended (its trailers are in trailers).
Effects: fail, io.
H2Client.head
function H2Client.head(self: mut H2Client): bool throws HttpErrorWaits until the reply head arrived (status, headers).
Effects: fail, io.
H2Client.close
function H2Client.close(self: mut H2Client): voidCloses the connection.
Effects: fail, io.
Limiter.admits
function Limiter.admits(self: Limiter, request: Request): Option<Response>Counts the request, or answers 429 with Retry-After in its place. A refused request is not counted. Clients quiet for a window are forgotten, so many addresses cannot grow the table.
Effects: fail, read, write, io.
Limiter.charges
function Limiter.charges(self: Limiter, request: Request, units: i64): Option<Response>admits for a request that costs UNITS of the limit (bytes in blocks, say): refused when the window cannot hold all of them. A cost over the whole limit counts as the limit.
Effects: fail, read, write, io.
Limiter.counted
function Limiter.counted(self: Limiter, wallMs: i64, atLeast: i64): Vec<Counted>The clients with at least atLeast requests in the window, as a store keeps them. wallMs is the wall clock now (System.time): the
limiter counts on a monotonic clock that restarts with the process. A client with few requests is not worth a row, and a restart
gives it a new budget it was far from using.
Effects: fail, read, io.
Limiter.restore
function Limiter.restore(self: Limiter, counts: Vec<Counted>, wallMs: i64): voidPuts what counted kept back: each client's requests are spread evenly from its first to its last time, and the ones that have left the window by wallMs are dropped.
Effects: fail, read, write, io.
Constants
STATUS_CONTINUE
const STATUS_CONTINUE = 100The status 100, Continue.
STATUS_SWITCHING_PROTOCOLS
const STATUS_SWITCHING_PROTOCOLS = 101The status 101, Switching Protocols.
STATUS_OK
const STATUS_OK = 200The status 200, OK.
STATUS_CREATED
const STATUS_CREATED = 201The status 201, Created.
STATUS_NO_CONTENT
const STATUS_NO_CONTENT = 204The status 204, No Content.
STATUS_PARTIAL_CONTENT
const STATUS_PARTIAL_CONTENT = 206The status 206, Partial Content.
STATUS_MOVED_PERMANENTLY
const STATUS_MOVED_PERMANENTLY = 301The status 301, Moved Permanently.
STATUS_FOUND
const STATUS_FOUND = 302The status 302, Found.
STATUS_SEE_OTHER
const STATUS_SEE_OTHER = 303The status 303, See Other.
STATUS_NOT_MODIFIED
const STATUS_NOT_MODIFIED = 304The status 304, Not Modified.
STATUS_TEMPORARY_REDIRECT
const STATUS_TEMPORARY_REDIRECT = 307The status 307, Temporary Redirect.
STATUS_PERMANENT_REDIRECT
const STATUS_PERMANENT_REDIRECT = 308The status 308, Permanent Redirect.
STATUS_REDIRECTION_START
const STATUS_REDIRECTION_START = 300The first status of the redirection class (300).
STATUS_BAD_REQUEST
const STATUS_BAD_REQUEST = 400The status 400, Bad Request.
STATUS_UNAUTHORIZED
const STATUS_UNAUTHORIZED = 401The status 401, Unauthorized.
STATUS_FORBIDDEN
const STATUS_FORBIDDEN = 403The status 403, Forbidden.
STATUS_NOT_FOUND
const STATUS_NOT_FOUND = 404The status 404, Not Found.
STATUS_METHOD_NOT_ALLOWED
const STATUS_METHOD_NOT_ALLOWED = 405The status 405, Method Not Allowed.
STATUS_NOT_ACCEPTABLE
const STATUS_NOT_ACCEPTABLE = 406406: no representation matches the request's Accept headers.
STATUS_CONFLICT
const STATUS_CONFLICT = 409The status 409, Conflict.
STATUS_PRECONDITION_FAILED
const STATUS_PRECONDITION_FAILED = 412The status 412, Precondition Failed.
STATUS_CONTENT_TOO_LARGE
const STATUS_CONTENT_TOO_LARGE = 413The status 413, Content Too Large.
STATUS_RANGE_NOT_SATISFIABLE
const STATUS_RANGE_NOT_SATISFIABLE = 416The status 416, Range Not Satisfiable.
STATUS_EXPECTATION_FAILED
const STATUS_EXPECTATION_FAILED = 417The status 417, Expectation Failed.
STATUS_TOO_MANY_REQUESTS
const STATUS_TOO_MANY_REQUESTS = 429The status 429, Too Many Requests.
STATUS_HEADER_FIELDS_TOO_LARGE
const STATUS_HEADER_FIELDS_TOO_LARGE = 431The status 431, Request Header Fields Too Large.
STATUS_INTERNAL_ERROR
const STATUS_INTERNAL_ERROR = 500The status 500, Internal Server Error.
STATUS_NOT_IMPLEMENTED
const STATUS_NOT_IMPLEMENTED = 501The status 501, Not Implemented.
STATUS_BAD_GATEWAY
const STATUS_BAD_GATEWAY = 502The status 502, Bad Gateway.
STATUS_SERVICE_UNAVAILABLE
const STATUS_SERVICE_UNAVAILABLE = 503The status 503, Service Unavailable.
STATUS_VERSION_NOT_SUPPORTED
const STATUS_VERSION_NOT_SUPPORTED = 505The status 505, HTTP Version Not Supported.
MOST_HEAD
const MOST_HEAD = 65536Bounds a peer cannot push past: the request or status line and headers, and a body. A server holds at most 65,536 connections (gizlang:system's Ready set); accepting waits beyond it.
MOST_BODY
const MOST_BODY = 16777216The most bytes of a message body.
BODY_PIECE
const BODY_PIECE = 262144The most bytes of a message body one read takes (a body streamed to disk is read in fewer, larger pieces).
IDLE_MS
const IDLE_MS = 60000A connection idle this long, or this slow sending a request, is closed.
PEER_HEADER
const PEER_HEADER = "x-peer-address"The header that carries the address of the socket's peer. The server sets it on every request and drops any that the client sent, so a handler can trust it; a proxy's own address is here, and the client behind it is the last X-Forwarded-For value.
MOST_PIECE
const MOST_PIECE = 1048576Maximum response piece. A request body read takes at most BODY_PIECE bytes.
UNKNOWN_LENGTH
const UNKNOWN_LENGTH = -1A streamed response whose size is not known before rendering begins. respond/write/finish use HTTP chunk framing; the same Exchange owns both known-size transfers and progressive rendering.
POOL_PER_ORIGIN
const POOL_PER_ORIGIN = 64The default most idle connections kept for one origin (connections in use are never limited), as nginx's
keepalive 64. Below the requests in flight to one origin, each surplus connection closes after its request and the
next one dials again: at 8, half the bench proxy's requests connected anew: 61k req/s instead of 158k.
POOL_TOTAL
const POOL_TOTAL = 64The default most idle connections that the pool keeps for all origins.
POOL_IDLE_MS
const POOL_IDLE_MS = 30000Less than the idle limit of common servers (nginx 75 s, gizlang:http's IDLE_MS 60 s), so most idle connections are closed here first.
MAX_FORM_FIELDS
const MAX_FORM_FIELDS = 1024The most nonempty fields that decodeForm accepts.
MAX_FORM_BYTES
const MAX_FORM_BYTES = 1048576The most encoded bytes that decodeForm accepts.
MOST_KEPT_FILE
const MOST_KEPT_FILE = 1048576The most bytes of one file that a Kept cache holds.
MOST_KEPT_BYTES
const MOST_KEPT_BYTES = 67108864The most bytes that a Kept cache holds in all.
KEPT_VALID_MS
const KEPT_VALID_MS = 1000How long a kept file is served without a check, in milliseconds.
MIN_COMPRESS
const MIN_COMPRESS = 256Prefer identity for short bodies when the client admits it.
MAX_ROUTES
const MAX_ROUTES = 4096Admission bounds cover compilation and every request, including unsuccessful searches. No regular expression or unbounded recursive backtracking is used.
MAX_ROUTE_DEPTH
const MAX_ROUTE_DEPTH = 64The most nested segments in one route.
MAX_ROUTE_NODES
const MAX_ROUTE_NODES = 65536The most nodes in the compiled route graph.
MAX_ROUTE_PATH
const MAX_ROUTE_PATH = 8192The longest request path that is matched, in bytes.
MAX_ROUTE_SEGMENTS
const MAX_ROUTE_SEGMENTS = 128The most segments in one request path.
MOST_MESSAGE
const MOST_MESSAGE = 16777216The largest message (all its frames) a peer may send.
CLOSE_NORMAL
const CLOSE_NORMAL = 1000Close codes (RFC 6455 §7.4.1).
CLOSE_PROTOCOL
const CLOSE_PROTOCOL = 1002The WebSocket close code 1002 (protocol).
CLOSE_INVALID
const CLOSE_INVALID = 1007The WebSocket close code 1007 (invalid).
CLOSE_TOO_BIG
const CLOSE_TOO_BIG = 1009The WebSocket close code 1009 (too big).