GizStack
View .mdOpen in ChatGPTOpen in Claude

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.

gizlang
import * as Http from "gizlang:http";

Types

gizlang
type Header = { name: string; value: string; }

One header: its name and value.

  • name: string
  • value: string

Request

gizlang
type Request = { method: string; path: string; headers: Vec<Header>; body: bytes; }

An HTTP request: method, path with its query, headers and body.

  • method: string
  • path: string
  • headers: Vec<gizlang_http.Header>
  • body: bytes

Response

gizlang
type Response = { status: i64; headers: Vec<Header>; body: bytes; }

An HTTP response: status, headers and body.

  • status: i64
  • headers: Vec<gizlang_http.Header>
  • body: bytes

HttpError

gizlang
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: i64
  • code: i64
  • message: string

ExchangeHandler

gizlang
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

gizlang
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.

  • buffered
  • progressive

Reply

gizlang
interface Reply { plan(self: Self): ReplyPlan; }

A value that a handler may return: it says how to answer (plan).

  • plan

Trace

gizlang
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: string
  • span: string

RequestHead

gizlang
type RequestHead = (request: Request) => Option<ExchangeHandler> effects { io, fail }

Select a streamed exchange from the request head, or use the buffered handler.

Exchange

gizlang
type Exchange

One 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

gizlang
type Incoming

A 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: i64
  • headers: Vec<gizlang_http.Header>
  • reason: string

Event

gizlang
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: string
  • data: string

Outgoing

gizlang
type Outgoing

A 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

gizlang
type Feed

A 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

gizlang
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).

  • head
  • status
  • body
  • end
  • more
  • failed

Origin

gizlang
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: bool
  • host: string
  • port: i64

Url

gizlang
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: bool
  • host: string
  • port: i64
  • target: string

PoolOptions

gizlang
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: i64
  • total: i64
  • idleMs: i64

Pool

gizlang
type Pool

HTTP/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

gizlang
type Asset = { path: string; contentType: string; body: bytes; }

An immutable content-addressed asset, shared by page shells and app hosts.

  • path: string
  • contentType: string
  • body: bytes

PartLimits

gizlang
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: i64
  • head: i64
  • field: i64
  • file: i64
  • total: i64

Part

gizlang
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: string
  • filename: _gizlang_sdk_core.Option<string>
  • contentType: string

PartEvent

gizlang
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.

  • start
  • data
  • end

Multipart

gizlang
type Multipart

A 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

gizlang
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.Dir
  • kept: Ref<_gizlang_sdk_collections.Map<string, gizlang_http.Kept>>
  • bytes: Ref<i64>

Kept

gizlang
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: i64
  • modified: i64
  • tag: string
  • headers: Vec<gizlang_http.Header>
  • body: bytes
  • whole: bool
  • checked: i64

Span

gizlang
type Span = { start: i64; end: i64; }

A byte range from START to END, END excluded.

  • start: i64
  • end: i64

ByteRange

gizlang
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.

  • valid
  • malformed
  • unsatisfiable

Balancer

gizlang
type Balancer

Requests 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

gizlang
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: i64
  • retries: i64
  • retryOn: Vec<i64>
  • replaceOn: Vec<i64>
  • fallback: _gizlang_sdk_core.Option<gizlang_http.Origin>

Relay

gizlang
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

gizlang
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

gizlang
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

gizlang
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

gizlang
type Router<T>

The compiled routes. Make it once with router before serving.

Opaque: create and use it through this module's functions.

Message

gizlang
type Message = { text: bool; data: bytes; }

One message: UTF-8 text, or binary data.

  • text: bool
  • data: bytes

WebSocket

gizlang
type WebSocket

An open WebSocket. receive gives each message; ping and close frames are answered here.

Opaque: create and use it through this module's functions.

SocketSession

gizlang
type SocketSession = (socket: mut WebSocket) => Result<bool, HttpError>

What runs on an opened server socket until it returns.

Mux

gizlang
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) => void
  • head: (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

gizlang
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

gizlang
type H2Client

An 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

gizlang
type Limiter

At most limit requests from one client (clientOf) within windowMs.

Opaque: create and use it through this module's functions.

Counted

gizlang
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: string
  • count: i64
  • first: i64
  • last: i64

Functions

header

gizlang
function header(headers: Vec<Header>, name: string): Option<string>

The first value of a header, its name in any case.

Effects: fail.

traceOf

gizlang
function traceOf(headers: Vec<Header>): Option<Trace>

The valid version-00 traceparent among headers, else none.

Effects: fail.

traceparent

gizlang
function traceparent(t: Trace): string

The traceparent value of t, sampled.

Effects: fail.

text

gizlang
function text(status: i64, body: string): Response

A plain UTF-8 text response with STATUS and BODY.

Effects: fail.

serve

gizlang
function serve<F>(listener: Listener, handler: F): i64 throws IoError

Accept 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

gizlang
function serveStreamed<F>(listener: Listener, handler: F, head: RequestHead): i64 throws IoError

serve, 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

gizlang
function serveReady<F>(set: Ready, handler: F): i64 throws IoError

Answer 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

gizlang
function serveReadyStreamed<F>(set: Ready, handler: F, head: RequestHead): i64 throws IoError

serveReady with a streamed-exchange head, as serveStreamed.

dateField

gizlang
function dateField(name: string, ms: i64, second: Ref<i64>, line: Ref<bytes>): bytes

The 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

gizlang
function chunkHead(out: mut bytes, size: i64): void

A chunk's size line (RFC 9112 7.1): SIZE in lowercase hex, then CRLF, appended to OUT.

Effects: fail.

open

gizlang
function open(stream: Stream, host: string, request: Request): Incoming throws HttpError

Send 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

gizlang
function outgoing(stream: Stream, host: string, request: Request, size: i64): Outgoing throws HttpError

Writes the head of REQUEST to HOST on STREAM, for a body of SIZE bytes (UNKNOWN_LENGTH sends it chunked).

Effects: fail, io.

feed

gizlang
function feed(): Feed

A parser of HTTP/1.1 messages that takes the bytes as they arrive.

responseFeed

gizlang
function responseFeed(): Feed

A feed of responses: each head is a status (keep: the connection can carry another request; upgrade: 101).

exchange

gizlang
function exchange(stream: Stream, host: string, request: Request): Response throws HttpError

Send 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

gizlang
function fetch(system: System, host: string, port: i64, request: Request): Response throws HttpError

A plain-HTTP request to host:port.

Effects: fail, read, write, console, io.

fetchUpTo

gizlang
function fetchUpTo(system: System, host: string, port: i64, request: Request, most: i64): Response throws HttpError

As fetch, for a response of up to most bytes (MOST_BODY holds for fetch).

Effects: fail, read, write, console, io.

url

gizlang
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

gizlang
function poolDefaults(): PoolOptions

The default pool options: POOL_PER_ORIGIN, POOL_TOTAL and POOL_IDLE_MS.

pool

gizlang
function pool(system: System, options: PoolOptions): Pool

A Pool of plain-HTTP connections; an https origin is refused (gizlang:tls's pool secures them).

Effects: fail, write.

poolDialing

gizlang
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

gizlang
function asset(extension: string, contentType: string, body: bytes): Asset

An 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

gizlang
function pathOf(request: Request): string

The request's path without its query.

Effects: fail.

query

gizlang
function query(request: Request): Params throws HttpError

The query parameters of a request: decodeForm of the text after "?".

Effects: fail.

decodeForm

gizlang
function decodeForm(encoded: string): Params throws HttpError

The 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

gizlang
function partLimits(): PartLimits

64 parts, 8 KiB heads, 1 MiB fields, 16 MiB files and 64 MiB in all.

Effects: fail.

multipart

gizlang
function multipart(contentType: string, limits: PartLimits): Multipart throws HttpError

The parser of a body with CONTENT_TYPE; 400 when it is not multipart/form-data with a valid boundary.

Effects: fail.

dispositionFilename

gizlang
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

gizlang
function attachment(name: string): string

The 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

gizlang
function encode(text: string): string

Percent-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

gizlang
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

gizlang
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

gizlang
function redirect(status: i64, location: string): Response

A redirect with STATUS to LOCATION. The body is the location as plain text.

Effects: fail.

withHeader

gizlang
function withHeader(response: Response, name: string, value: string): Response

The response with one more header.

Effects: fail.

httpDate

gizlang
function httpDate(ms: i64): string

An HTTP date (RFC 9110 5.6.7), as "Sun, 06 Nov 1994 08:49:37 GMT".

Effects: fail.

parseHttpDate

gizlang
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

gizlang
function mimeType(path: string): string

The media type of a file by its extension; text types are UTF-8.

Effects: fail.

file

gizlang
function file(dir: Dir, request: Request, path: string, nowMs: i64): Response

Serve 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

gizlang
function files(dir: Dir): Files

A cache of the files of DIR for static serving.

Effects: fail, write.

fileReply

gizlang
function fileReply(files: Files, request: Request, path: string, nowMs: i64): ReplyPlan

The 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

gizlang
function fileReplyWith(files: Files, request: Request, path: string, nowMs: i64, extra: Vec<Header>): ReplyPlan

fileReply with EXTRA headers on every answer that carries the file (a Cache-Control the caller knows, for one).

Effects: fail, read, write, io.

precompress

gizlang
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

gizlang
function publicFile(dir: Dir, path: string, data: bytes): Result<bool, string>

DATA as the public file PATH of DIR (0644).

Effects: fail, io.

notModified

gizlang
function notModified(request: Request, tag: string): bool

Whether 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

gizlang
function entityTagMatches(value: string, tag: string, strong: bool): bool

Compare 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

gizlang
function precondition(request: Request, tag: Option<string>, modified: Option<i64>, nowMs: i64): i64

RFC 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

gizlang
function rangeValidatorMatches(value: string, tag: string, modified: i64, nowMs: i64): bool

If-Range accepts one strong ETag or an exactly matching HTTP date. A stale, weak or malformed validator requires the complete representation.

Effects: fail.

gizlang
function cookie(request: Request, name: string): Option<string>

The value of the request's cookie name, as the browser sent it.

Effects: fail.

setCookie

gizlang
function setCookie(name: string, value: string, maxAge: Option<i64>, secure: bool): string throws string

Build 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

gizlang
function parseByteRange(spec: string, size: i64): ByteRange

One 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

gizlang
function proxy(pool: Pool, upstream: Origin, request: Request): Response

Forward 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

gizlang
function plainPolicy(): Policy

A policy that changes nothing.

balancer

gizlang
function balancer(pool: Pool, upstreams: Vec<Origin>, holdMs: i64): Balancer

A balancer that sends requests of POOL to UPSTREAMS and holds a failed upstream out for HOLD_MS.

Effects: fail, write.

bodyOver

gizlang
function bodyOver(request: Request, from: i64): bool

Whether 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

gizlang
function play(plan: ReplyPlan, exchange: mut Exchange): bool throws HttpError

Runs a reply plan on an exchange.

Effects: fail, read, write, console, io.

withExtra

gizlang
function withExtra(headers: Vec<Header>, extra: Vec<Header>): Vec<Header>

HEADERS with each field of EXTRA whose name they lack.

Effects: fail.

proxied

gizlang
function proxied(request: Request): Request

The request proxy sends upstream: without hop-by-hop headers and Host.

Effects: fail.

returned

gizlang
function returned(response: Response): Response

The upstream's response as proxy returns it: without hop-by-hop headers.

Effects: fail.

forwarded

gizlang
function forwarded(request: Request, proto: string): Request

The 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

gizlang
function logLine(request: Request, response: Response, ms: i64): string

An 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

gizlang
function compressed(request: Request, response: Response): Response

Negotiate 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

gizlang
function acceptsEncoding(request: Request, coding: string): bool

Content-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

gizlang
function router<T>(declarations: Vec<Route<T>>): Router<T> throws string

Compiles DECLARATIONS into a router, or gives why they are not valid (a bad pattern, a duplicate route or a bound that is exceeded).

mount

gizlang
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

gizlang
function gzip<F>(request: Request, next: F): Response

Middleware 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

gizlang
function webSocketAccept(key: string): string

The Sec-WebSocket-Accept value of a Sec-WebSocket-Key.

Effects: fail.

isWebSocket

gizlang
function isWebSocket(request: Request): bool

Whether request opens a WebSocket: a GET with Upgrade: websocket, Connection: upgrade, version 13 and a 16-byte key.

Effects: fail.

webSocket

gizlang
function webSocket(request: Request, protocol: string, session: SocketSession): ReplyPlan

The 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

gizlang
function openWebSocket(sys: System, stream: Stream, host: string, path: string, headers: Vec<Header>): WebSocket throws HttpError

Opens 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

gizlang
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

gizlang
function huffmanDecode(tree: Huffman, data: bytes): bytes throws string

The text that the Huffman code data stands for; an error for a code that is invalid or padded wrong.

Effects: fail.

newQpack

gizlang
function newQpack(): Qpack

The QPACK state: build it once and share it.

Effects: fail.

qpackDecode

gizlang
function qpackDecode(q: Qpack, block: bytes): Vec<Header> throws string

The 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

gizlang
function qpackBlock(q: Qpack, fields: Vec<Header>): bytes

A QPACK field section for FIELDS that uses only the static table (literals, never Huffman coded).

Effects: fail.

requestOf

gizlang
function requestOf(fields: Vec<Header>, peer: string): Request throws string

The 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

gizlang
function replyOn(request: Request, plan: ReplyPlan, mux: Mux): bool

Runs the reply of plan for request on a multiplexed stream; whether the reply ended whole.

Effects: fail, read, write, console, io.

openH2

gizlang
function openH2(stream: Stream, host: string, secure: bool): H2Client throws HttpError

Starts HTTP/2 on stream for host (the :authority); secure says the scheme is https.

Effects: fail, io.

clientOf

gizlang
function clientOf(request: Request, proxies: Vec<string>): string

The 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

gizlang
function limiter(limit: i64, windowMs: i64, proxies: Vec<string>): Limiter

A 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

gizlang
function Response.plan(self: Response): ReplyPlan

A buffered reply: the response as it is.

ReplyPlan.plan

gizlang
function ReplyPlan.plan(self: ReplyPlan): ReplyPlan

The plan itself.

Exchange.next

gizlang
function Exchange.next(self: mut Exchange): Option<bytes> throws HttpError

The next piece of the request body, or none at its end.

Effects: fail, read, write, console, io.

Exchange.whole

gizlang
function Exchange.whole(self: mut Exchange): Request throws HttpError

The whole request with its body read.

Effects: fail, read, write, console, io.

Exchange.acceptBody

gizlang
function Exchange.acceptBody(self: Exchange): bool throws HttpError

Send 100 Continue only after the application admits the request head.

Effects: fail, io.

Exchange.respond

gizlang
function Exchange.respond(self: mut Exchange, status: i64, headers: Vec<Header>, size: i64): bool throws HttpError

Writes 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

gizlang
function Exchange.write(self: mut Exchange, data: bytes): bool throws HttpError

Writes 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

gizlang
function Exchange.writeAll(self: mut Exchange, data: bytes): bool throws HttpError

Emit existing bytes as bounded pieces. No second framing or buffering owner.

Effects: fail, read, write, console, io.

Exchange.send

gizlang
function Exchange.send(self: mut Exchange, response: Response): bool throws HttpError

Buffered response emission through the same Exchange framing owner.

Effects: fail, read, write, console, io.

Exchange.trailers

gizlang
function Exchange.trailers(self: mut Exchange, fields: Vec<Header>): bool throws HttpError

Ends 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

gizlang
function Exchange.finish(self: mut Exchange): bool throws HttpError

Ends the response. It fails when the body is shorter than the length that the response said.

Effects: fail, read, write, console, io.

Outgoing.write

gizlang
function Outgoing.write(self: mut Outgoing, data: bytes): bool throws HttpError

Writes DATA as part of the request body. It fails after finish or past the length.

Effects: fail, io.

Outgoing.finish

gizlang
function Outgoing.finish(self: mut Outgoing): Incoming throws HttpError

Ends 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

gizlang
function Incoming.next(self: mut Incoming): Option<bytes> throws HttpError

The next piece of the body; none after the last.

Effects: fail, read, write, console, io.

Incoming.rest

gizlang
function Incoming.rest(self: mut Incoming): bytes throws HttpError

The rest of the body, at most MOST_BODY bytes.

Effects: fail, read, write, console, io.

Incoming.restUpTo

gizlang
function Incoming.restUpTo(self: mut Incoming, most: i64): bytes throws HttpError

The rest of the body, at most most bytes (a client reading a large answer).

Effects: fail, read, write, console, io.

Incoming.event

gizlang
function Incoming.event(self: mut Incoming): Option<Event> throws HttpError

The 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

gizlang
function Incoming.close(self: Incoming): void

End the connection, unless it was given back to its Pool or is closed.

Effects: fail, read, write, io.

Incoming.whole

gizlang
function Incoming.whole(self: mut Incoming): Response throws HttpError

The 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

gizlang
function Feed.skipBody(self: mut Feed): void

The current message has no body after all (a response to HEAD, which only its requester knows).

Feed.bodiless

gizlang
function Feed.bodiless(self: Feed): bool

The 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

gizlang
function Feed.untilClose(self: Feed): bool

The body runs until the peer closes; at that close the message ends.

Feed.push

gizlang
function Feed.push(self: mut Feed, data: bytes): void

Adds bytes read from the peer.

Effects: fail.

Feed.pending

gizlang
function Feed.pending(self: Feed): i64

The bytes pushed and not parsed yet.

Effects: fail.

Feed.rest

gizlang
function Feed.rest(self: Feed): bytes

Those bytes themselves: what follows an upgrade's head belongs to the new protocol (node:http's 'upgrade' head).

Effects: fail.

Feed.next

gizlang
function Feed.next(self: mut Feed): Parsed

The 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

gizlang
function Origin.authority(self: Origin): string

The 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

gizlang
function Url.text(self: Url): string

The URL written out, the port only when it is not the scheme's.

Effects: fail.

Url.resolve

gizlang
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

gizlang
function Url.origin(self: Url): Origin

The origin of the URL, for a Pool.

Pool.idle

gizlang
function Pool.idle(self: Pool): i64

The idle connections the pool keeps now (none past the idle time).

Effects: fail, read, io.

Pool.close

gizlang
function Pool.close(self: Pool): void

Close 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

gizlang
function Pool.open(self: Pool, origin: Origin, request: Request): Incoming throws HttpError

Send 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

gizlang
function Pool.openAs(self: Pool, origin: Origin, host: string, request: Request, waitMs: i64): Incoming throws HttpError

open 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

gizlang
function Pool.fetch(self: Pool, origin: Origin, request: Request): Response throws HttpError

The whole response of a pooled request.

Effects: fail, read, write, console, io.

Multipart.push

gizlang
function Multipart.push(self: mut Multipart, data: bytes): Vec<PartEvent> throws HttpError

The events that DATA completes. A malformed body is 400; a body over a bound is 413.

Effects: fail.

Multipart.finish

gizlang
function Multipart.finish(self: Multipart): bool throws HttpError

400 when the body ended before its closing delimiter.

Exchange.multipart

gizlang
function Exchange.multipart(self: Exchange, limits: PartLimits): Multipart throws HttpError

The 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

gizlang
function Exchange.parts(self: mut Exchange, parser: mut Multipart): Option<Vec<PartEvent>> throws HttpError

The 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

gizlang
function Balancer.under(self: Balancer, policy: Policy): Balancer

The same balancer (its upstreams, marks and turn are shared) under policy.

Balancer.standing

gizlang
function Balancer.standing(self: Balancer, standby: Vec<Origin>): Balancer

The 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

gizlang
function Balancer.use(self: Balancer, upstreams: Vec<Origin>): void

Replace 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

gizlang
function Balancer.follow(self: Balancer, members: Vec<Member>): void

Follow 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

gizlang
function Balancer.keepingHost(self: Balancer): Balancer

The 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

gizlang
function Balancer.open(self: Balancer, request: Request): Incoming throws HttpError

The 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

gizlang
function Balancer.send(self: Balancer, request: Request): Response

The 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

gizlang
function Balancer.relay(self: Balancer, request: Request, relay: Relay): ReplyPlan

The 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

gizlang
function Balancer.forward(self: Balancer, request: Request, relay: Relay): ReplyPlan

The 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

gizlang
function Router.resolve<T>(self: Router<T>, request: Request): Routed<T> throws Response

Resolve 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

gizlang
function Route.href<T>(self: Route<T>, params: Params): string throws string

The 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

gizlang
function Params.get(self: Params, name: string): string

A parameter's value, the first one for a name ("" when there is no such name).

Effects: fail.

Params.all

gizlang
function Params.all(self: Params, name: string): Vec<string>

Every value of a name, in order.

Effects: fail.

Params.integer

gizlang
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

gizlang
function WebSocket.closed(self: WebSocket): bool

Whether the socket is closed (by either side).

Effects: fail, read.

WebSocket.timeout

gizlang
function WebSocket.timeout(self: WebSocket, milliseconds: i64): i64 throws IoError

How long receive waits for the peer before it fails (IDLE_MS when opened).

Effects: fail, io.

WebSocket.send

gizlang
function WebSocket.send(self: WebSocket, message: string): bool throws HttpError

Sends a text message.

Effects: fail, read, io.

WebSocket.sendBytes

gizlang
function WebSocket.sendBytes(self: WebSocket, data: bytes): bool throws HttpError

Sends a binary message.

Effects: fail, read, io.

WebSocket.ping

gizlang
function WebSocket.ping(self: WebSocket, data: bytes): bool throws HttpError

Sends a ping; the peer's pong is consumed by receive.

Effects: fail, read, io.

WebSocket.close

gizlang
function WebSocket.close(self: WebSocket, code: i64, reason: string): bool

Sends a close frame once and marks the socket closed.

Effects: fail, read, write, io.

WebSocket.receive

gizlang
function WebSocket.receive(self: mut WebSocket): Option<Message> throws HttpError

The 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

gizlang
function H2Client.start(self: mut H2Client, method: string, path: string, headers: Vec<Header>, end: bool): bool throws HttpError

Opens a call: the request head, ending the stream when end says it has no body.

Effects: fail, io.

H2Client.send

gizlang
function H2Client.send(self: mut H2Client, data: bytes, end: bool): bool throws HttpError

The 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

gizlang
function H2Client.receive(self: mut H2Client): Option<bytes> throws HttpError

The next piece of the reply body; none when the reply ended (its trailers are in trailers).

Effects: fail, io.

H2Client.head

gizlang
function H2Client.head(self: mut H2Client): bool throws HttpError

Waits until the reply head arrived (status, headers).

Effects: fail, io.

H2Client.close

gizlang
function H2Client.close(self: mut H2Client): void

Closes the connection.

Effects: fail, io.

Limiter.admits

gizlang
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

gizlang
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

gizlang
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

gizlang
function Limiter.restore(self: Limiter, counts: Vec<Counted>, wallMs: i64): void

Puts 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

gizlang
const STATUS_CONTINUE = 100

The status 100, Continue.

STATUS_SWITCHING_PROTOCOLS

gizlang
const STATUS_SWITCHING_PROTOCOLS = 101

The status 101, Switching Protocols.

STATUS_OK

gizlang
const STATUS_OK = 200

The status 200, OK.

STATUS_CREATED

gizlang
const STATUS_CREATED = 201

The status 201, Created.

STATUS_NO_CONTENT

gizlang
const STATUS_NO_CONTENT = 204

The status 204, No Content.

STATUS_PARTIAL_CONTENT

gizlang
const STATUS_PARTIAL_CONTENT = 206

The status 206, Partial Content.

STATUS_MOVED_PERMANENTLY

gizlang
const STATUS_MOVED_PERMANENTLY = 301

The status 301, Moved Permanently.

STATUS_FOUND

gizlang
const STATUS_FOUND = 302

The status 302, Found.

STATUS_SEE_OTHER

gizlang
const STATUS_SEE_OTHER = 303

The status 303, See Other.

STATUS_NOT_MODIFIED

gizlang
const STATUS_NOT_MODIFIED = 304

The status 304, Not Modified.

STATUS_TEMPORARY_REDIRECT

gizlang
const STATUS_TEMPORARY_REDIRECT = 307

The status 307, Temporary Redirect.

STATUS_PERMANENT_REDIRECT

gizlang
const STATUS_PERMANENT_REDIRECT = 308

The status 308, Permanent Redirect.

STATUS_REDIRECTION_START

gizlang
const STATUS_REDIRECTION_START = 300

The first status of the redirection class (300).

STATUS_BAD_REQUEST

gizlang
const STATUS_BAD_REQUEST = 400

The status 400, Bad Request.

STATUS_UNAUTHORIZED

gizlang
const STATUS_UNAUTHORIZED = 401

The status 401, Unauthorized.

STATUS_FORBIDDEN

gizlang
const STATUS_FORBIDDEN = 403

The status 403, Forbidden.

STATUS_NOT_FOUND

gizlang
const STATUS_NOT_FOUND = 404

The status 404, Not Found.

STATUS_METHOD_NOT_ALLOWED

gizlang
const STATUS_METHOD_NOT_ALLOWED = 405

The status 405, Method Not Allowed.

STATUS_NOT_ACCEPTABLE

gizlang
const STATUS_NOT_ACCEPTABLE = 406

406: no representation matches the request's Accept headers.

STATUS_CONFLICT

gizlang
const STATUS_CONFLICT = 409

The status 409, Conflict.

STATUS_PRECONDITION_FAILED

gizlang
const STATUS_PRECONDITION_FAILED = 412

The status 412, Precondition Failed.

STATUS_CONTENT_TOO_LARGE

gizlang
const STATUS_CONTENT_TOO_LARGE = 413

The status 413, Content Too Large.

STATUS_RANGE_NOT_SATISFIABLE

gizlang
const STATUS_RANGE_NOT_SATISFIABLE = 416

The status 416, Range Not Satisfiable.

STATUS_EXPECTATION_FAILED

gizlang
const STATUS_EXPECTATION_FAILED = 417

The status 417, Expectation Failed.

STATUS_TOO_MANY_REQUESTS

gizlang
const STATUS_TOO_MANY_REQUESTS = 429

The status 429, Too Many Requests.

STATUS_HEADER_FIELDS_TOO_LARGE

gizlang
const STATUS_HEADER_FIELDS_TOO_LARGE = 431

The status 431, Request Header Fields Too Large.

STATUS_INTERNAL_ERROR

gizlang
const STATUS_INTERNAL_ERROR = 500

The status 500, Internal Server Error.

STATUS_NOT_IMPLEMENTED

gizlang
const STATUS_NOT_IMPLEMENTED = 501

The status 501, Not Implemented.

STATUS_BAD_GATEWAY

gizlang
const STATUS_BAD_GATEWAY = 502

The status 502, Bad Gateway.

STATUS_SERVICE_UNAVAILABLE

gizlang
const STATUS_SERVICE_UNAVAILABLE = 503

The status 503, Service Unavailable.

STATUS_VERSION_NOT_SUPPORTED

gizlang
const STATUS_VERSION_NOT_SUPPORTED = 505

The status 505, HTTP Version Not Supported.

MOST_HEAD

gizlang
const MOST_HEAD = 65536

Bounds 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

gizlang
const MOST_BODY = 16777216

The most bytes of a message body.

BODY_PIECE

gizlang
const BODY_PIECE = 262144

The most bytes of a message body one read takes (a body streamed to disk is read in fewer, larger pieces).

IDLE_MS

gizlang
const IDLE_MS = 60000

A connection idle this long, or this slow sending a request, is closed.

PEER_HEADER

gizlang
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

gizlang
const MOST_PIECE = 1048576

Maximum response piece. A request body read takes at most BODY_PIECE bytes.

UNKNOWN_LENGTH

gizlang
const UNKNOWN_LENGTH = -1

A 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

gizlang
const POOL_PER_ORIGIN = 64

The 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

gizlang
const POOL_TOTAL = 64

The default most idle connections that the pool keeps for all origins.

POOL_IDLE_MS

gizlang
const POOL_IDLE_MS = 30000

Less 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

gizlang
const MAX_FORM_FIELDS = 1024

The most nonempty fields that decodeForm accepts.

MAX_FORM_BYTES

gizlang
const MAX_FORM_BYTES = 1048576

The most encoded bytes that decodeForm accepts.

MOST_KEPT_FILE

gizlang
const MOST_KEPT_FILE = 1048576

The most bytes of one file that a Kept cache holds.

MOST_KEPT_BYTES

gizlang
const MOST_KEPT_BYTES = 67108864

The most bytes that a Kept cache holds in all.

KEPT_VALID_MS

gizlang
const KEPT_VALID_MS = 1000

How long a kept file is served without a check, in milliseconds.

MIN_COMPRESS

gizlang
const MIN_COMPRESS = 256

Prefer identity for short bodies when the client admits it.

MAX_ROUTES

gizlang
const MAX_ROUTES = 4096

Admission bounds cover compilation and every request, including unsuccessful searches. No regular expression or unbounded recursive backtracking is used.

MAX_ROUTE_DEPTH

gizlang
const MAX_ROUTE_DEPTH = 64

The most nested segments in one route.

MAX_ROUTE_NODES

gizlang
const MAX_ROUTE_NODES = 65536

The most nodes in the compiled route graph.

MAX_ROUTE_PATH

gizlang
const MAX_ROUTE_PATH = 8192

The longest request path that is matched, in bytes.

MAX_ROUTE_SEGMENTS

gizlang
const MAX_ROUTE_SEGMENTS = 128

The most segments in one request path.

MOST_MESSAGE

gizlang
const MOST_MESSAGE = 16777216

The largest message (all its frames) a peer may send.

CLOSE_NORMAL

gizlang
const CLOSE_NORMAL = 1000

Close codes (RFC 6455 §7.4.1).

CLOSE_PROTOCOL

gizlang
const CLOSE_PROTOCOL = 1002

The WebSocket close code 1002 (protocol).

CLOSE_INVALID

gizlang
const CLOSE_INVALID = 1007

The WebSocket close code 1007 (invalid).

CLOSE_TOO_BIG

gizlang
const CLOSE_TOO_BIG = 1009

The WebSocket close code 1009 (too big).