Standard Library: std.http
● Intermediate5 min
Every type, method and function of std.http: what the spec lists, then each declaration in its source, with its examples and the line that declares it.
Spec 14.11 · learn it in HTTP.
A declaration below shows what a program writes against: a type's fields, a function's parameters, what it gives, its contracts (require, ensure) and its examples. kavach test runs every example, so each one is true of the code.
What the spec lists
| Function | Gives |
|---|---|
http.get(url) -> Response ! HttpError | GET url |
http.post(url, body) -> Response ! HttpError | POST url with body (Bytes) |
http.request(method, url, headers: [Header] = [], body: Bytes = Bytes([])) -> Response ! HttpError | Any method, with the headers given and a body: a form post with basic auth, a bearer token, PUT, PATCH, DELETE, if-none-match. HTTP/2 when the server offers it with TLS, else HTTP/1.1; host, content-length and connection are the client's own, so ones given are left out |
http.get3(url) -> Response ! HttpError | GET url over HTTP/3 |
http.open(url) -> Session ! HttpError | A session: one HTTP/1.1 connection to the server of url (http:// or https://; the path is not used), kept open for several requests |
s.get(path), s.post(path, body) -> Response ! HttpError | A request on session s's connection, waiting for its response |
s.request(method, path, headers: [Header] = [], body: Bytes = Bytes([])) -> Response ! HttpError | The same as http.request, on session s's connection |
s.close() | Closes the session's connection |
http.serve(listener, handler, limits: ServeLimits()) ! NetError | Serves HTTP on listener: each connection in a task of its own, on any core (spawn cores, 9.8), its requests answered by handler: fn(Request) -> Response, each client held to limits (below). It runs until the function that called it returns, which cancels it (9.2) |
http.text(status, body) -> Response | A response with text |
http.get_json<T>(url) -> T ! HttpError | GET url, the response's JSON body decoded into a T (json.decode<T>, 2.12) |
http.post_json<T>(url, body) -> T ! HttpError | POST url with the Json value body, the response's JSON decoded into a T |
http.json_response(status, value) -> Response | A response with the Json value value (write json.of(order) for a typed value) |
http.read_json<T>(request) -> T ! JsonError | A request's JSON body decoded into a T |
| Written | Gives |
|---|---|
form.next() -> FormPart? ! HttpError | The next part, or none after the last; data of the part before not read yet is skipped |
part.name, part.filename, part.content_type | The field's name, the file's name (String?, none for a plain field) and its content-type (text/plain when not given) |
part.read() -> Bytes? ! HttpError | The part's next piece of data, or none at its end |
part.text() -> String ! HttpError | The rest of the part as text: for small fields |
| Written | Gives |
|---|---|
http.websocket(r, session: fn(WebSocket) ! NetError) -> Response | Accepts a WebSocket (RFC 6455): 101 Switching Protocols, then session; 400 for a request that isn't one |
http.events(r, feed: fn(EventStream) ! NetError) -> Response | Server-sent events: 200 with text/event-stream, then feed |
http.websocket_connect(url) -> WebSocket ! HttpError | A client's WebSocket to ws:// or wss:// url |
ws.receive() -> WsMessage? ! NetError | The next message, WsMessage.Text(text) or WsMessage.Binary(data), or none once the other end closed |
ws.send_text(text), ws.send_bytes(data) | Sends one message |
ws.close() | Says goodbye and closes the connection |
out.send(data, event: "", id: "") | Sends one event; each line of data is a data: line |
| Function | Gives |
|---|---|
h2.request(conn, headers, body) -> H2Message ! H2Error | Sends one request on a new connection (headers start with :method, :scheme, :authority, :path) and reads the response |
h2.connect(conn) -> H2Client ! H2Error | Starts a connection that takes many requests, so a service connects once instead of once per call |
c.request(headers, body) -> H2Message ! H2Error | Sends one request on c, on a stream of its own, and reads its response. Requests from several tasks are open at once: their sends take turns, in the order they asked, and each answer goes to the task that asked, in whatever order the server sends them. A stream the server resets fails only its own request |
c.going_away() -> Bool | Whether the server said it is going away (GOAWAY) or the connection broke: a pool replaces such a client with a new one |
c.close() | Closes the connection once the request being answered is done; a request after it fails with Protocol. A client is also closed when its last holder lets it go, as its connection is (14.10) |
h2.accept(conn, data) -> Link ! H2Error | The server side of a connection that began with data |
h2.next(link) -> Next ! H2Error | Next(link:, message:): the next whole request, or none once the client is done |
h2.respond(link, stream, headers, body) -> Link ! H2Error | Sends the response on stream; headers start with :status |
h2.begin(conn, headers) -> Link ! H2Error | Opens a request on a new connection and leaves its stream open: send_data sends the body piece by piece while pull reads the answer as it arrives |
h2.send_data(link, stream, data, end) -> Link ! H2Error | Sends data on stream; end: Bool ends this side of the stream |
h2.send_headers(link, stream, headers) -> Link ! H2Error | Sends a response's headers and leaves the stream open |
h2.send_trailers(link, stream, trailers) -> Link ! H2Error | Sends header fields after the body, ending the stream |
h2.watch(link) -> H2Watched ! H2Error | The server side piece by piece: H2Watched(link:, event:), where the event is StreamOpened(stream, headers) as soon as a request's headers arrive, StreamData(stream, data) as its body arrives, StreamEnded(stream), or ClientDone. A server uses watch or next, not both |
| Function | Gives |
|---|---|
h3.request(conn, headers, body) -> H3Message ! H3Error | Sends one request on a new connection from net.connect_quic(address, ["h3"]) (headers start with :method, :scheme, :authority, :path), and reads the response |
h3.encode(headers) -> Bytes | A QPACK header block of Header(name:, value:)s |
h3.decode(block) -> [Header] ! H3Error | The headers of a QPACK block that uses no dynamic table |
| Function | Gives |
|---|---|
hpack.new_table(limit) -> Table | An empty table of at most limit bytes (HTTP/2 starts with 4096) |
hpack.decode(block, table) -> Decoded ! HpackError | Decoded(headers: [Header], table: Table); Malformed(reason) for a broken block |
hpack.encode(headers) -> Bytes | A block with each Header(name:, value:) as a literal, names in lower case |
hpack.huffman(data) -> Bytes ! HpackError | Decodes Huffman-coded text (RFC 7541 appendix B); QPACK uses the same code |
std.http.h2 · h2.kav
use std.http.h2: 4 types and 12 functions. stdlib/http/h2.kav
Next type
What next found: the link, and a request unless the client is done.
pub type Next {
pub link: Link
pub message: H2Message?
}request function
Sends one request on stream 1 of a new connection and reads the response. headers has :method, :scheme, :authority, :path.
pub fn request(conn: Connection, headers: [Header], body: Bytes) -> H2Message ! H2Error uses Netopen function
Opens a request without waiting for the answer: pull then reads it as it arrives (spec 14.14 streams on this).
pub fn open(conn: Connection, headers: [Header], body: Bytes) -> Link ! H2Error uses Netbegin function
Opens a request on stream 1 of a new connection and leaves the stream open: send_data sends its body piece by piece, and pull reads the answer as it arrives, so both can go on at once.
pub fn begin(conn: Connection, headers: [Header]) -> Link ! H2Error uses Netsend_data function
Sends data on stream; end ends this side of the stream.
pub fn send_data(link: Link, stream: Int, data: Bytes, end: Bool) -> Link ! H2Error uses Netsend_headers function
Sends a response's headers on stream and leaves it open for send_data and send_trailers.
pub fn send_headers(link: Link, stream: Int, headers: [Header]) -> Link ! H2Error uses Netsend_trailers function
Sends header fields after the body (trailers), ending the stream.
pub fn send_trailers(link: Link, stream: Int, trailers: [Header]) -> Link ! H2Error uses NetPulled type
What pull found: body bytes that arrived (maybe none yet), and the trailing headers once the answer ended.
pub type Pulled {
pub link: Link
pub data: Bytes
pub ended: Bool
pub trailers: [String: String]
}pull function
The next piece of the answer on stream 1: waits until bytes arrive or the answer ends.
pub fn pull(link: Link) -> Pulled ! H2Error uses Netaccept function
Starts the server side of a connection that began with data (the preface, or its start).
pub fn accept(conn: Connection, data: Bytes) -> Link ! H2Error uses Netnext function
The next whole request, or none once the client is done.
pub fn next(link: Link) -> Next ! H2Error uses NetH2Event type
What happened on a server's connection, in the order it happened.
pub type H2Event = StreamOpened(stream: Int, headers: [String: String]) |
StreamData(stream: Int, data: Bytes) |
StreamEnded(stream: Int) |
ClientDoneH2Watched type
What watch found: the link, and the event.
pub type H2Watched {
pub link: Link
pub event: H2Event
}watch function
The server side, piece by piece: a request's headers as soon as they arrive, then its body bytes as they arrive, then its end; ClientDone once the client is done. Use it instead of next, never with it.
pub fn watch(link: Link) -> H2Watched ! H2Error uses Netrespond function
Sends a response on stream; headers starts with :status.
pub fn respond(link: Link, stream: Int, headers: [Header], body: Bytes) -> Link ! H2Error uses Netrespond_with_trailers function
Sends a response on stream with header fields after its body (trailers), as gRPC sends its status.
pub fn respond_with_trailers(
link: Link,
stream: Int,
headers: [Header],
body: Bytes,
trailers: [Header],
) -> Link ! H2Error uses Netstd.http.h2.client · h2client.kav
use std.http.h2.client: 1 type and 1 function. stdlib/http/h2client.kav
H2Client type
A connection for many requests, from h2.connect.
pub type H2Client {
/// The turn to send, with what sending needs.
send_turn: Receiver<Sending>
send_back: Sender<Sending>
/// The connection's reading side, taken by the task that reads.
read_turn: Receiver<Link>
read_back: Sender<Link>
/// What the server lets this side send, as the reader last saw it,
/// and a signal the reader gives after each frame, for a sender
/// waiting for credit while another task reads.
credit: Shared<Credit>
credit_signal: Receiver<Bool>
signal_credit: Sender<Bool>
/// Whether a task is reading, and where each answer still awaited
/// goes: one task reads at a time and hands each answer to its task
/// as soon as it is whole, in whatever order the server sends them.
waiting: Shared<Waiting>
leaving: Shared<Bool>
}request method
Sends one request and reads its response. headers has :method, :scheme, :authority, :path.
pub fn request(self, headers: [Header], body: Bytes) -> H2Message ! H2Error uses Netgoing_away method
Whether the server said it is going away (GOAWAY), or the connection broke: a pool then replaces it with a new one.
pub fn going_away(self) -> Boolclose method
Closes the connection, once the request being sent is sent. A request after it fails, and so does one still waiting.
pub fn close(self) uses Netconnect function
Starts an HTTP/2 connection on conn for many requests.
pub fn connect(conn: Connection) -> H2Client ! H2Error uses Netstd.http.h2.serving · h2serving.kav
use std.http.h2.serving: 0 types and 1 function. stdlib/http/h2serving.kav
serve function
Serves the HTTP/2 connection conn, which began with data, until the client is done and every stream is answered.
pub fn serve(conn: Connection, data: Bytes, handler: fn(Request) -> Response, follow: Bool = true) ! H2Error uses Netstd.http.h2.wire · h2wire.kav
use std.http.h2.wire: 6 types and 22 functions. stdlib/http/h2wire.kav
H2Error type
Why an HTTP/2 exchange failed.
pub type H2Error = Network(error: NetError) |
Protocol(reason: String) |
Reset(stream: Int, code: Int)H2Message type
A whole message on one stream: headers, names in lower case and with the pseudo-headers such as :status, and the body.
pub type H2Message {
pub stream: Int
pub headers: [String: String]
pub body: Bytes
}Link type
One side of a connection, between frames.
pub type Link {
pub conn: Connection
/// Bytes read but not used yet.
pub buffer: Bytes
/// The header table for blocks the other side sends.
pub table: Table
/// How much this side may still send: on the connection, and per
/// stream (`initial` for a stream not listed).
pub window: Int
pub windows: [Int: Int]
pub initial: Int
/// The largest frame the other side takes.
pub max_frame: Int
/// Messages being received, then complete ones, in order.
pub partial: [Int: Partial]
pub done: [H2Message]
/// Streams the other side reset, with the reason's code.
pub resets: [Int: Int]
/// The stream a header block goes on with, or 0.
pub continuing: Int
/// The other side is going away (GOAWAY).
pub leaving: Bool
/// Streams `watch` has reported open and not yet ended.
pub announced: [Int: Bool]
}Frame type
One frame (RFC 9113 4.1).
pub type Frame {
pub kind: Int
pub flags: Int
pub stream: Int
pub payload: Bytes
}Partial type
A message being received.
pub type Partial {
pub headers: [String: String]
pub body: Bytes
/// A header block waiting for its CONTINUATION frames.
pub block: Bytes
pub has_headers: Bool
/// The other side ends the stream with this header block.
pub ending: Bool
}Credit type
What the other side has let this side send since the start, on the connection and per stream (initial for a stream not listed), the largest frame it takes, and the streams it reset: what a task that sends needs from the task that reads.
pub type Credit {
pub window: Int
pub windows: [Int: Int]
pub initial: Int
pub max_frame: Int
pub resets: [Int: Int]
}credit_of function
The credit the reading side l has seen.
pub fn credit_of(l: Link) -> Creditmost_streams function
How many streams a server answers at once on one connection, which it tells the client (SETTINGS_MAX_CONCURRENT_STREAMS, RFC 9113 6.5.2).
pub fn most_streams() -> Intblock_frames function
A header block on stream as frames: HEADERS, then CONTINUATION frames of at most most bytes. Written in one write, so no other frame comes between them. end ends this side's stream.
pub fn block_frames(stream: Int, headers: [Header], end: Bool, most: Int) -> Bytes
require stream >= 0 and stream <= 2_147_483_647
require most >= 1big_window function
The windows this side opens: 16 MB, so a sender rarely waits.
pub fn big_window() -> Intpreface function
"PRI * HTTP/2.0", a blank line, "SM" and a blank line.
pub fn preface() -> Byteswrite function
pub fn write(conn: Connection, data: Bytes) ! H2Error uses Netframe function
A frame's bytes: a 9-byte header, then the payload.
pub fn frame(kind: Int, flags: Int, stream: Int, payload: Bytes) -> Bytes
require kind >= 0 and kind <= 255
require flags >= 0 and flags <= 255
require stream >= 0 and stream <= 2_147_483_647
require payload.len() <= 16_777_215four function
A 32-bit number, most significant byte first.
pub fn four(n: Int) -> Bytes
require n >= 0 and n <= 4_294_967_295
example four(258) == Bytes([0, 0, 1, 2])number32 function
The 32-bit number at at.
pub fn number32(data: Bytes, at: Int) -> Int
require at >= 0 and at <= data.len() - 4
example number32(Bytes([0, 0, 1, 2]), 0) == 258setting function
One setting: a 16-bit id and a 32-bit value.
pub fn setting(id: Int, value: Int) -> Bytes
require id >= 0 and id <= 65_535
require value >= 0 and value <= 4_294_967_295step function
Reads one frame and acts on it; none when the connection closed.
pub fn step(l: Link) -> Link? ! H2Error uses Nethandle function
Acts on one frame (RFC 9113 6).
pub fn handle(link: Link, f: Frame) -> Link ! H2Error uses Netsettings function
The other side's settings: window and frame sizes matter here.
pub fn settings(link: Link, payload: Bytes) -> Link ! H2Errorheader_frame function
HEADERS and CONTINUATION frames: a header block, maybe in pieces.
pub fn header_frame(link: Link, f: Frame) -> Link ! H2Error uses Netdata_frame function
DATA frames: the body, a piece at a time.
pub fn data_frame(link: Link, f: Frame) -> Link ! H2Error uses Netunpad function
A frame's payload without its padding (flag 8).
pub fn unpad(f: Frame) -> Bytes ! H2Errorfinish function
Moves the message on stream to the complete ones.
pub fn finish(link: Link, stream: Int) -> Linksend function
Sends a header block and body on stream, in frames that fit the other side's windows; waits for WINDOW_UPDATE frames when they are full. trailers, when there are any, end the stream after the body.
pub fn send(link: Link, stream: Int, headers: [Header], body: Bytes, trailers: [Header]) -> Link ! H2Error uses Netblock function
Sends a header block on stream: a HEADERS frame, then CONTINUATION frames when it is bigger than a frame. end ends this side's stream.
pub fn block(link: Link, stream: Int, headers: [Header], end: Bool) -> Link ! H2Error uses Netdata function
Sends body on stream as DATA frames that fit the other side's windows, waiting for WINDOW_UPDATE frames when they are full. end ends this side's stream (with an empty frame when body is empty).
pub fn data(link: Link, stream: Int, body: Bytes, end: Bool) -> Link ! H2Error uses Netclient_hello function
The client's side of a connection: its settings, and room to send.
pub fn client_hello(conn: Connection) ! H2Error uses Netstd.http.h3 · h3.kav
use std.http.h3: 2 types and 3 functions. stdlib/http/h3.kav
H3Error type
Why an HTTP/3 exchange failed.
pub type H3Error = Network(error: NetError) | Protocol(reason: String)H3Message type
A response: headers, names in lower case and with :status, and the body.
pub type H3Message {
pub headers: [String: String]
pub body: Bytes
}request function
Sends one request on a new connection and reads the response. headers has :method, :scheme, :authority, :path.
pub fn request(conn: Connection, headers: [Header], body: Bytes) -> H3Message ! H3Error uses Netencode function
A QPACK header block of headers, each a literal with a literal name, names in lower case (RFC 9204 4.5.6).
pub fn encode(headers: [Header]) -> Bytesdecode function
The headers of a QPACK block that uses no dynamic table.
pub fn decode(block: Bytes) -> [Header] ! H3Errorstd.http.hpack · hpack.kav
use std.http.hpack: 4 types and 4 functions. stdlib/http/hpack.kav
Header type
One header: its name and value.
pub type Header {
pub name: String
pub value: String
}HpackError type
Why a header block can't be read.
pub type HpackError = Malformed(reason: String)Table type
The dynamic table: entries oldest first, their size, and its limit.
pub type Table {
pub entries: [Header]
pub size: Int
pub limit: Int
}Decoded type
A header block's headers, and the table after it.
pub type Decoded {
pub headers: [Header]
pub table: Table
}new_table function
An empty table that holds up to limit bytes (4096 to start with).
pub fn new_table(limit: Int) -> Tabledecode function
Reads a header block, with the table the earlier blocks left.
pub fn decode(block: Bytes, table: Table) -> Decoded ! HpackErrorencode function
A header block for headers: literals, names in lower case.
pub fn encode(headers: [Header]) -> Byteshuffman function
Decodes Huffman-coded bytes (RFC 7541 appendix B). The code is canonical: codes of one length are consecutive numbers, in symbol order, so four small tables decode it. QPACK (h3.kav) uses the same code.
pub fn huffman(data: Bytes) -> Bytes ! HpackErrorstd.http · http.kav
use std.http: 7 types and 16 functions. stdlib/http/http.kav
Request type
An HTTP request, as a server's handler gets it.
pub type Request {
pub method: String
pub path: String
/// In the order they came, names in lower case, repeats kept.
pub headers: [Header]
/// The body, when it was read whole (spec 14.11); empty otherwise.
pub body: Bytes
/// A body too large to read whole, set by the server: read it with
/// `read_body`.
pub stream: BodyStream? = none
/// The address of whoever opened the connection (`203.0.113.7:51234`),
/// set by the server; empty for a request made by hand. Behind a proxy
/// it is the proxy's.
pub peer: String = ""
/// With mutual TLS, the names of the certificate the client showed
/// (decision 0099); `none` otherwise, and for a request made by hand.
pub client_cert: ClientCert? = none
}header method
The value of the first header named name, if any.
pub fn header(self, name: String) -> String?headers_named method
The values of every header named name, in order.
pub fn headers_named(self, name: String) -> [String]read_body method
The next piece of a large body (spec 14.11), or none once it has all come; none for a body read whole.
pub fn read_body(self) -> Bytes? ! NetError uses NetBodyStream type
The part of a large request body not read yet, made by the server: kept across tasks, so the server sees how much the handler read.
pub type BodyStream {
pub conn: Connection
/// What came with the request's head, not handed out yet.
pub first: Shared<Bytes>
/// How many bytes of the body are left.
pub left: Shared<Int>
/// What came after the body: the start of the next request.
pub after: Shared<Bytes>
/// How long one piece may take to come.
pub wait: Duration
}Response type
An HTTP response.
pub type Response {
pub status: Int
/// In the order they are sent, names in lower case; a name may come
/// more than once (`set-cookie`).
pub headers: [Header]
pub body: Bytes
/// Sent after `body` as it is read (spec 14.11): a reader of
/// `fs.chunks`.
pub stream: Chunks? = none
/// What runs on the connection after the head: a WebSocket's
/// session or an event stream's feed (`http.websocket`, `http.events`).
pub take_over: TakeOver? = none
}header method
The value of the first header named name, if any.
pub fn header(self, name: String) -> String?headers_named method
The values of every header named name, in order.
pub fn headers_named(self, name: String) -> [String]ServeLimits type
What http.serve allows each client (spec 14.11), so a slow or hostile one can't hold the server: every limit has a safe default.
pub type ServeLimits {
/// The most a request's line and headers may take: 431 past it.
pub max_header_bytes: Int = 16_384
/// The most a request's body may take: 413 past it, refused by its
/// `content-length` before it is read.
pub max_body_bytes: Int = 10_000_000
/// How long a request's line and headers may take to come: 408 past
/// it (a client sending them a byte at a time can't hold a task).
pub header_timeout: Duration = 10.seconds
/// The slowest a body may come, in bytes a second, after a second's
/// grace: 408 when slower.
pub min_body_rate: Int = 1_000
/// How long a kept-open connection may wait for its next request.
pub idle_timeout: Duration = 5.seconds
/// The most connections at once: past it, 503 with `retry-after`.
pub max_connections: Int = 10_000
/// The most requests being answered at once: past it, 503.
pub max_in_flight: Int = 1_000
/// The largest request body read whole into `r.body`; a larger one is
/// read by the handler with `r.read_body()`.
pub buffered_body: Int = 1_000_000
/// What `retry-after` says on a 503, in seconds.
pub retry_after: Int = 1
/// On a stop signal, how long to finish the requests under way
/// (spec 5.8): `http.serve` holds the program's stop that long.
pub drain_timeout: Duration = 10.seconds
/// Whether a request's span continues the trace its `traceparent`
/// names (spec 14.12); `false`, for a server the internet reaches
/// directly, starts a trace of its own for each request.
pub follow_trace: Bool = true
}HttpError type
Why an HTTP request failed: Status and BadJson come from the JSON calls (get_json, post_json).
pub type HttpError = Network(error: NetError) |
BadUrl(url: String) |
BadMessage(reason: String) |
Status(code: Int) |
BadJson(error: JsonError)text function
A response with text: http.text(200, "hello").
pub fn text(status: Int, body: String) -> Responserequest function
A request with any method, headers and body, over HTTP/2 when the server offers it with TLS, else HTTP/1.1 (spec 14.11).
pub fn request(method: String, url: String, headers: [Header] = [], body: Bytes = Bytes([])) -> Response ! HttpError uses Netget function
GET url.
pub fn get(url: String) -> Response ! HttpError uses Netpost function
POST url with body.
pub fn post(url: String, body: Bytes) -> Response ! HttpError uses Netget_json function
GET url, its JSON body decoded into a T.
pub fn get_json<T>(url: String) -> T ! HttpError uses Netpost_json function
POST url with the JSON body, the JSON answer decoded into a T.
pub fn post_json<T>(url: String, body: Json) -> T ! HttpError uses Netfile function
A response with the file at path (spec 14.11), sent as it is read: its content-type from its extension, its content-length from its size.
pub fn file(path: String) -> Response ! FsError uses Fs.readTakeOver type
What a response that takes over runs on the connection, with what came after the request and the largest message allowed.
pub type TakeOver {
pub run: fn(Connection, Bytes, Int) ! NetError
}websocket function
Accepts the WebSocket request r and runs session on it (spec 14.11); 400 when r isn't one.
pub fn websocket(r: Request, session: fn(WebSocket) ! NetError) -> Responseevents function
Server-sent events, sent by feed (spec 14.11).
pub fn events(r: Request, feed: fn(EventStream) ! NetError) -> Responsewebsocket_connect function
A WebSocket to url, ws:// or wss:// (spec 14.11).
pub fn websocket_connect(url: String) -> WebSocket ! HttpError uses Netform function
The multipart/form-data form in r, read part by part (spec 14.11).
pub fn form(r: Request) -> Form ! HttpErrorjson_response function
A response with JSON: http.json_response(200, json.of(order)).
pub fn json_response(status: Int, value: Json) -> Responseread_json function
A request's JSON body decoded into a T.
pub fn read_json<T>(r: Request) -> T ! JsonErrorget3 function
GET url over HTTP/3 (an https:// URL).
pub fn get3(url: String) -> Response ! HttpError uses NetSession type
One HTTP/1.1 connection kept open for several requests to one server (spec 14.11). For one task at a time.
pub type Session {
conn: Connection
host: String
}get method
GET path on the session's connection.
pub fn get(self, path: String) -> Response ! HttpError uses Netpost method
POST path with body on the session's connection.
pub fn post(self, path: String, body: Bytes) -> Response ! HttpError uses Netrequest method
A request with any method, headers and body on the session's connection.
pub fn request(self, method: String, path: String, headers: [Header] = [], body: Bytes = Bytes([])) -> Response ! HttpError uses Netopen function
A session with the server of url: one connection, kept open.
pub fn open(url: String) -> Session ! HttpError uses Netserve function
Serves HTTP on listener: each connection in a task of its own, on any core (spec 14.11), its requests answered by handler, each client held to limits. Runs until the function that called it returns (its tasks are cancelled then, spec 9.2).
pub fn serve(listener: Listener, handler: fn(Request) -> Response, limits: ServeLimits = ServeLimits()) ! NetError uses Netstd.http.message · message.kav
use std.http.message: 1 type and 14 functions. stdlib/http/message.kav
Message type
The first line, headers and body of an HTTP message. Header names are in lower case, in the order they came, repeats kept.
pub type Message {
pub first: String
pub headers: [Header]
pub body: Bytes
}first_header function
The value of the first header named name (in lower case), if any.
pub fn first_header(headers: [Header], name: String) -> String?all_headers function
The values of every header named name (in lower case), in order.
pub fn all_headers(headers: [Header], name: String) -> [String]head_end function
Where the head of a message ends (its blank line), if it has.
pub fn head_end(data: Bytes) -> Int?plain function
HTTP/2 headers without the pseudo-headers (:status, :path, …).
pub fn plain(headers: [String: String]) -> [Header]chunked function
Whether a message's body comes in chunks (RFC 9112 7.1).
pub fn chunked(headers: [Header]) -> Booldechunk function
The data of a body sent in chunks, without the chunk sizes and the trailers; none until the last chunk (size 0) has come, or when the chunks are not well formed.
pub fn dechunk(body: Bytes) -> Bytes?whole function
The complete message at the start of data, its body sized by content-length (none means an empty body) or sent in chunks, and how many bytes of data it took; none until all of it has come.
pub fn whole(data: Bytes) -> (message: Message, used: Int)?unchunk function
A body sent in chunks: its data, and how many bytes of body it took, through the empty line after the trailers; none until all of it has come, or when the chunks are not well formed.
pub fn unchunk(body: Bytes) -> (data: Bytes, used: Int)?reason function
The reason phrase that goes with status in a status line.
pub fn reason(status: Int) -> Stringcontent_type function
The content-type of a file named path, from its extension.
pub fn content_type(path: String) -> Stringhex function
n (0 or more) in hexadecimal, as a chunk's size is written.
pub fn hex(n: Int) -> String
require n >= 0hex_digit function
The value of hexadecimal digit b, if it is one.
pub fn hex_digit(b: UInt8) -> Int?std.http.multipart · multipart.kav
use std.http.multipart: 2 types and 1 function. stdlib/http/multipart.kav
Form type
A multipart/form-data body, read part by part.
pub type Form {
request: Request
/// What divides the parts: a line end, `--` and the boundary.
delimiter: Bytes
/// What has come and not been handed out yet.
held: Shared<Bytes>
/// Whether `request.body` has been taken, for a body read whole.
taken: Shared<Bool>
/// Whether a part's data is being read.
in_part: Shared<Bool>
/// Whether the last part has ended.
ended: Shared<Bool>
}next method
The next part, or none after the last. What is left of the part before is skipped.
pub fn next(self) -> FormPart? ! HttpError uses NetFormPart type
One part of a form: a field, or a file.
pub type FormPart {
pub name: String
/// The file's name; `none` for a plain field.
pub filename: String?
pub content_type: String
form: Form
}read method
The part's next piece of data, or none at its end.
pub fn read(self) -> Bytes? ! HttpError uses Nettext method
The rest of the part as text: for small fields.
pub fn text(self) -> String ! HttpError uses Netopen function
The form in request r.
pub fn open(r: Request) -> Form ! HttpErrorstd.http.server · server.kav
use std.http.server: 0 types and 1 function. stdlib/http/server.kav
serve function
pub fn serve(listener: Listener, handler: fn(Request) -> Response, limits: ServeLimits) ! NetError uses Netstd.http.upgrade · upgrade.kav
use std.http.upgrade: 3 types and 6 functions. stdlib/http/upgrade.kav
WsMessage type
A message: text, or bytes.
pub type WsMessage = Text(text: String) | Binary(data: Bytes)WebSocket type
One end of a WebSocket.
pub type WebSocket {
conn: Connection
/// What has come and isn't read yet.
held: Shared<Bytes>
/// Whether this end is the client, which masks what it sends.
client: Bool
/// The largest message taken, in bytes.
most: Int
/// The turn to send: one slot, taken by each send while it writes
/// its whole frame, so frames from several tasks never mix.
turn: Receiver<Bool>
turn_back: Sender<Bool>
}receive method
The next message, or none once the other end closed. Pings are answered here, and a message larger than allowed closes the socket with 1009.
pub fn receive(self) -> WsMessage? ! NetError uses Netsend_text method
Sends text as one message.
pub fn send_text(self, text: String) ! NetError uses Netsend_bytes method
Sends data as one message.
pub fn send_bytes(self, data: Bytes) ! NetError uses Netclose method
Says goodbye and closes the connection.
pub fn close(self) uses Netserver_end function
The server's end of a WebSocket on conn, first what came after the request.
pub fn server_end(conn: Connection, first: Bytes, most: Int) -> WebSocketclient_end function
The client's end of a WebSocket on conn, first what came after the response.
pub fn client_end(conn: Connection, first: Bytes, most: Int) -> WebSocketEventStream type
The server-sent events of a response (text/event-stream).
pub type EventStream {
conn: Connection
}send method
Sends one event: data (a line each for its lines), with an event name and an id when given.
pub fn send(self, data: String, event: String = "", id: String = "") ! NetError uses Netevent_stream function
The events of a response on conn.
pub fn event_stream(conn: Connection) -> EventStreamaccept function
A response accepting the WebSocket request r, then running session; 400 when r isn't one.
pub fn accept(r: Request, session: fn(WebSocket) ! NetError) -> Responseevents function
A response of server-sent events, sent by feed.
pub fn events(feed: fn(EventStream) ! NetError) -> Responseconnect function
A client's WebSocket to url (ws:// or wss://).
pub fn connect(url: String) -> WebSocket ! HttpError uses Net