Module http/index

http/index
Stability: unstable, and it inherits rather than owns that: this file declares no members of its own, so its stability is exactly the union of the three modules it fronts, each of which carries its own `## Stability` section and its own open question — connection pooling in `./client.yo`, the `get_header`/`HeaderMap` duplication in `./http.yo`, and the idle timeout `./server.yo` needs before it can hold a connection open. What IS stable about this file is the barrel shape: `import("std/http")` will keep exporting those three modules, and adding a fourth would be additive. — stable modules only change additively; this one may still change.

HTTP/1.1 — the module you import. It is a barrel: it re-exports ./http.yo (the pure types and parsers), ./client.yo (fetch / fetch_with) and ./server.yo (HttpServer over TcpListener), so import("std/http") gives the whole surface.

./wire.yo is deliberately NOT re-exported. Message framing — Content-Length, chunked decoding, and what a read leaves behind — is shared by the client and the server but is not a public API: it is std-internal so that the framing rules can change with the pooling work without that being a breaking change to std/http.

{ fetch } :: import("std/http");
{ IoExn } :: import("std/error");

resp := io.await(fetch(`http://example.com`, io), IoExn(io : io, exn : exn));
println(resp.body);

Stability

unstable, and it inherits rather than owns that: this file declares no members of its own, so its stability is exactly the union of the three modules it fronts, each of which carries its own ## Stability section and its own open question — connection pooling in ./client.yo, the get_header/HeaderMap duplication in ./http.yo, and the idle timeout ./server.yo needs before it can hold a connection open. What IS stable about this file is the barrel shape: import("std/http") will keep exporting those three modules, and adding a fourth would be additive.

Types

HttpError enum
HttpError

HTTP client error variants.

Variants

VariantFieldsDescription
ConnectionFailedmsg: String

Failed to connect to the remote host.

InvalidUrlmsg: String

The URL could not be parsed.

Timeout

The whole request (every connect, write, read and redirect hop) did not finish within FetchOptions.timeout. Never raised without one.

TooManyRedirects

The server kept redirecting past FetchOptions.max_redirects hops.

UnsupportedSchemescheme: String

The URL scheme is neither http nor https (https speaks real TLS through std/crypto/tls, D6). Anything else is refused before any DNS or socket work — never downgraded (plans/archive/STD_API_AUDIT.md C1).

ResponseTooLarge

The raw response (status line, headers and body) grew past FetchOptions.max_response_bytes; the connection is dropped there.

MalformedChunkedBodymsg: String

A Transfer-Encoding: chunked body broke the RFC 9112 §7.1 framing — a chunk size that is not hex, a missing CRLF after a chunk, or a body that ended before its terminating zero chunk. msg says which.

MalformedContentLengthmsg: String

A Content-Length header field whose value is not a single non-negative integer, or two Content-Length field lines that disagree. RFC 9112 §6.3 makes that unrecoverable framing rather than a body-less message, so it is raised instead of being read as "absent". msg names the defect.

Othermsg: String

An unclassified HTTP error.

Trait Implementations

impl(generic(T : Type), where(T <: ToString), T : (ToString))
impl(generic(T : Type), where(T <: ToString), T : (ToString), Format)
format : fn(self : Self, spec : str) -> String

Render self under spec. An unrecognised spec degrades to the plain to_string() rendering rather than failing.

Parameters

NameTypeNotes
selfSelf
specstr

Returns: String

Methods
to_string : (HttpError) fn(self : HttpError) -> String

Serialize to wire format, on the status line's own version (so a parsed response round-trips). A Content-Length header is added when none is present (the byte length of body), so the peer can delimit the message without waiting for close.

Parameters

NameTypeNotes
selfHttpError

Returns: String

source : (HttpError) fn(self : HttpError) -> Option(dyn( + ToString))

The error that caused this one, or .None at the root of the chain.

Rust's Error::source. Defaulted to .None, so an error with nothing underneath it implements the trait by saying only what it is; a wrapper overrides it to hand back what it wrapped. Walking the chain to the root cause is not expressible yet — the returned Dyn loses the Error trait on an erased receiver, so a caller can print one link but cannot follow it (#521, issues/self-trait-in-a-return-type-loses-the-trait-on-an-erased-receiver.md).

Parameters

NameTypeNotes
selfHttpError

Returns: Option(dyn( + ToString))

HttpMethod enum
HttpMethod

Standard HTTP request methods.

Variants

VariantFieldsDescription
GET
POST
PUT
DELETE
HEAD
PATCH
OPTIONS

Trait Implementations

impl(generic(T : Type), where(T <: ToString), T : (ToString))
impl(generic(T : Type), where(T <: ToString), T : (ToString), Format)
format : fn(self : Self, spec : str) -> String

Render self under spec. An unrecognised spec degrades to the plain to_string() rendering rather than failing.

Parameters

NameTypeNotes
selfSelf
specstr

Returns: String

Methods
to_string : (HttpMethod) fn(self : HttpMethod) -> String

Serialize to wire format, on the status line's own version (so a parsed response round-trips). A Content-Length header is added when none is present (the byte length of body), so the peer can delimit the message without waiting for close.

Parameters

NameTypeNotes
selfHttpMethod

Returns: String

from_string : (HttpMethod) fn(s : String) -> Option(HttpMethod)

Parse a request-line method token (case-sensitive, as RFC 9110 §9.1 requires). .None for anything not in the enum.

Parameters

NameTypeNotes
sString

Returns: Option(HttpMethod)

HttpHeader object
HttpHeader

An HTTP header as a name-value pair.

Fields

NameTypeDescription
nameString
valueString
Methods
new : (HttpHeader) fn(name : String, value : String) -> HttpHeader

Create a response with the given status and reason phrase.

Parameters

NameTypeNotes
nameString
valueString

Returns: HttpHeader

HeaderMap object
HeaderMap

A header section — Rust's http::HeaderMap.

Two properties HTTP requires and a HashMap(String, String) cannot give:

  • field names are case-insensitive (RFC 9110 §5.1), so Content-Type and content-type are the same field. Comparison folds ASCII case; the name is STORED as written, because that is what goes on the wire.
  • a field may appear more than once (Set-Cookie always does), and the order of the repeated values is significant. So this is a multimap that preserves insertion order, backed by a list rather than a hash table.

insert replaces every existing value for a name, append adds one — the same split Rust draws, and the reason set_header on a request used to silently accumulate duplicates.

Fields

NameTypeDescription
_entriesArrayList(HttpHeader)

Trait Implementations

impl(generic(T : Type), where(T <: ToString), T : (ToString))
impl(generic(T : Type), where(T <: ToString), T : (ToString), Format)
format : fn(self : Self, spec : str) -> String

Render self under spec. An unrecognised spec degrades to the plain to_string() rendering rather than failing.

Parameters

NameTypeNotes
selfSelf
specstr

Returns: String

Methods
new : (HeaderMap) fn() -> HeaderMap

Create a response with the given status and reason phrase.

Returns: HeaderMap

len : (HeaderMap) fn(self : HeaderMap) -> usize

Number of field LINES, counting each repeat of a name separately.

Parameters

NameTypeNotes
selfHeaderMap

Returns: usize

is_empty : (HeaderMap) fn(self : HeaderMap) -> bool

True when there are no field lines.

Parameters

NameTypeNotes
selfHeaderMap

Returns: bool

get : (HeaderMap) fn(self : HeaderMap, name : String) -> Option(String)

The first value for name, or .None. Case-insensitive.

Parameters

NameTypeNotes
selfHeaderMap
nameString

Returns: Option(String)

get_all : (HeaderMap) fn(self : HeaderMap, name : String) -> ArrayList(String)

Every value for name, in the order the field lines appeared. Empty when the field is absent — which is what makes Set-Cookie usable.

Parameters

NameTypeNotes
selfHeaderMap
nameString

Returns: ArrayList(String)

contains_key : (HeaderMap) fn(self : HeaderMap, name : String) -> bool

True when name has at least one value. Case-insensitive.

Parameters

NameTypeNotes
selfHeaderMap
nameString

Returns: bool

append : (HeaderMap) fn(self : HeaderMap, name : String, value : String) -> unit

Add a value for name, KEEPING any existing values. Rust's HeaderMap::append.

Parameters

NameTypeNotes
selfHeaderMap
nameString
valueString

Returns: unit

remove : (HeaderMap) fn(self : HeaderMap, name : String) -> usize

Remove every value for name, returning how many field lines went.

Parameters

NameTypeNotes
selfHeaderMap
nameString

Returns: usize

insert : (HeaderMap) fn(self : HeaderMap, name : String, value : String) -> Option(String)

Set name to exactly value, dropping every value it had. Rust's HeaderMap::insert. Returns the first previous value, if any — a caller overwriting a header usually wants to know it was there.

Parameters

NameTypeNotes
selfHeaderMap
nameString
valueString

Returns: Option(String)

entries : (HeaderMap) fn(self : HeaderMap) -> ArrayList(HttpHeader)

The field lines in order — for serialization and iteration. The list is a snapshot: pushing to it does not change the map.

Parameters

NameTypeNotes
selfHeaderMap

Returns: ArrayList(HttpHeader)

to_string : (HeaderMap) fn(self : HeaderMap) -> String

Serialize to wire format, on the status line's own version (so a parsed response round-trips). A Content-Length header is added when none is present (the byte length of body), so the peer can delimit the message without waiting for close.

Parameters

NameTypeNotes
selfHeaderMap

Returns: String

StatusCode struct
StatusCode

An HTTP status code — Rust's http::StatusCode.

A u16 newtype rather than a bare integer, so the CLASS predicates (is_success, is_client_error, ...) live with the value instead of being re-derived at every call site, and so a status cannot be confused with a port, a length or a byte count. u16 because RFC 9110 SS15 fixes the range at three digits: a status is never negative, which an i32 allowed.

Fields

NameTypeDescription
codeu16

Trait Implementations

impl(generic(T : Type), where(T <: ToString), T : (ToString))
impl(generic(T : Type), where(T <: ToString), T : (ToString), Format)
format : fn(self : Self, spec : str) -> String

Render self under spec. An unrecognised spec degrades to the plain to_string() rendering rather than failing.

Parameters

NameTypeNotes
selfSelf
specstr

Returns: String

Methods
from_u16 : (StatusCode) fn(code : u16) -> Option(StatusCode)

Wrap a raw code, or .None when it is outside the 100-599 range RFC 9110 SS15 defines. An unrecognized code INSIDE the range is accepted — a client must treat an unknown 4xx as 400, so refusing it would break the very forward-compatibility the classes exist for.

Parameters

NameTypeNotes
codeu16

Returns: Option(StatusCode)

as_u16 : (StatusCode) fn(self : StatusCode) -> u16

The raw code.

Parameters

NameTypeNotes
selfStatusCode

Returns: u16

is_informational : (StatusCode) fn(self : StatusCode) -> bool

1xx — the request was received and the process continues.

Parameters

NameTypeNotes
selfStatusCode

Returns: bool

is_success : (StatusCode) fn(self : StatusCode) -> bool

2xx — the request succeeded.

Parameters

NameTypeNotes
selfStatusCode

Returns: bool

is_redirection : (StatusCode) fn(self : StatusCode) -> bool

3xx — further action is needed to complete the request.

Parameters

NameTypeNotes
selfStatusCode

Returns: bool

is_client_error : (StatusCode) fn(self : StatusCode) -> bool

4xx — the request was malformed or cannot be fulfilled.

Parameters

NameTypeNotes
selfStatusCode

Returns: bool

is_server_error : (StatusCode) fn(self : StatusCode) -> bool

5xx — the server failed to fulfil an apparently valid request.

Parameters

NameTypeNotes
selfStatusCode

Returns: bool

is_error : (StatusCode) fn(self : StatusCode) -> bool

True if the status is 4xx or 5xx.

Parameters

NameTypeNotes
selfStatusCode

Returns: bool

reason : (StatusCode) fn(self : StatusCode) -> String

The reason phrase RFC 9110 registers for this code, or Unknown.

The phrase is ADVISORY: a server may send any text and a client must not act on it — which is why this is a lookup here rather than a field, and why HttpResponse keeps whatever phrase the peer actually sent.

Parameters

NameTypeNotes
selfStatusCode

Returns: String

to_string : (StatusCode) fn(self : StatusCode) -> String

Serialize to wire format, on the status line's own version (so a parsed response round-trips). A Content-Length header is added when none is present (the byte length of body), so the peer can delimit the message without waiting for close.

Parameters

NameTypeNotes
selfStatusCode

Returns: String

== : (StatusCode) fn(lhs : StatusCode, rhs : StatusCode) -> bool

Parameters

NameTypeNotes
lhsStatusCode
rhsStatusCode

Returns: bool

!= : (StatusCode) fn(lhs : StatusCode, rhs : StatusCode) -> bool

Parameters

NameTypeNotes
lhsStatusCode
rhsStatusCode

Returns: bool

< : (StatusCode) fn(lhs : StatusCode, rhs : StatusCode) -> bool

Parameters

NameTypeNotes
lhsStatusCode
rhsStatusCode

Returns: bool

<= : (StatusCode) fn(lhs : StatusCode, rhs : StatusCode) -> bool

Parameters

NameTypeNotes
lhsStatusCode
rhsStatusCode

Returns: bool

> : (StatusCode) fn(lhs : StatusCode, rhs : StatusCode) -> bool

Parameters

NameTypeNotes
lhsStatusCode
rhsStatusCode

Returns: bool

>= : (StatusCode) fn(lhs : StatusCode, rhs : StatusCode) -> bool

Parameters

NameTypeNotes
lhsStatusCode
rhsStatusCode

Returns: bool

cmp : (StatusCode) fn(lhs : StatusCode, rhs : StatusCode) -> Ordering

Parameters

NameTypeNotes
lhsStatusCode
rhsStatusCode

Returns: Ordering

OK : (StatusCode) fn() -> StatusCode

Returns: StatusCode

CREATED : (StatusCode) fn() -> StatusCode

Returns: StatusCode

ACCEPTED : (StatusCode) fn() -> StatusCode

Returns: StatusCode

NO_CONTENT : (StatusCode) fn() -> StatusCode

Returns: StatusCode

MOVED_PERMANENTLY : (StatusCode) fn() -> StatusCode

Returns: StatusCode

FOUND : (StatusCode) fn() -> StatusCode

Returns: StatusCode

NOT_MODIFIED : (StatusCode) fn() -> StatusCode

Returns: StatusCode

TEMPORARY_REDIRECT : (StatusCode) fn() -> StatusCode

Returns: StatusCode

PERMANENT_REDIRECT : (StatusCode) fn() -> StatusCode

Returns: StatusCode

BAD_REQUEST : (StatusCode) fn() -> StatusCode

Returns: StatusCode

UNAUTHORIZED : (StatusCode) fn() -> StatusCode

Returns: StatusCode

FORBIDDEN : (StatusCode) fn() -> StatusCode

Returns: StatusCode

NOT_FOUND : (StatusCode) fn() -> StatusCode

Returns: StatusCode

METHOD_NOT_ALLOWED : (StatusCode) fn() -> StatusCode

Returns: StatusCode

CONFLICT : (StatusCode) fn() -> StatusCode

Returns: StatusCode

CONTENT_TOO_LARGE : (StatusCode) fn() -> StatusCode

Returns: StatusCode

TOO_MANY_REQUESTS : (StatusCode) fn() -> StatusCode

Returns: StatusCode

INTERNAL_SERVER_ERROR : (StatusCode) fn() -> StatusCode

Returns: StatusCode

NOT_IMPLEMENTED : (StatusCode) fn() -> StatusCode

Returns: StatusCode

BAD_GATEWAY : (StatusCode) fn() -> StatusCode

Returns: StatusCode

SERVICE_UNAVAILABLE : (StatusCode) fn() -> StatusCode

Returns: StatusCode

GATEWAY_TIMEOUT : (StatusCode) fn() -> StatusCode

Returns: StatusCode

HttpRequest object
HttpRequest

An HTTP request with method, path, headers, and optional body.

Fields

NameTypeDescription
methodHttpMethod
pathString
headersHeaderMap

The response's header fields, in the order they arrived. A multimap: use headers.get_all(name) when a field can repeat, and note that HttpResponse.to_string writes these verbatim.

bodyString

The body as received, byte-transparent — it is sliced out of the raw message on the CRLFCRLF boundary and wrapped without UTF-8 validation, so a binary body survives (a String here is a byte container, and body.as_bytes() is the safe way to read one).

Trait Implementations

impl(generic(T : Type), where(T <: ToString), T : (ToString))
impl(generic(T : Type), where(T <: ToString), T : (ToString), Format)
format : fn(self : Self, spec : str) -> String

Render self under spec. An unrecognised spec degrades to the plain to_string() rendering rather than failing.

Parameters

NameTypeNotes
selfSelf
specstr

Returns: String

Methods
new : (HttpRequest) fn(method : HttpMethod, path : String) -> HttpRequest

Create a response with the given status and reason phrase.

Parameters

NameTypeNotes
methodHttpMethod
pathString

Returns: HttpRequest

header : (HttpRequest) fn(self : HttpRequest, name : String, value : String) -> HttpRequest

Add a header and return the response (builder pattern). APPENDS, so a repeatable field can be built up by chaining.

Parameters

NameTypeNotes
selfHttpRequest
nameString
valueString

Returns: HttpRequest

with_body : (HttpRequest) fn(self : HttpRequest, body : String) -> HttpRequest

Set the body and return the response (builder pattern).

Parameters

NameTypeNotes
selfHttpRequest
bodyString

Returns: HttpRequest

set_host : (HttpRequest) fn(self : HttpRequest, host : String) -> unit

Set the Host header, REPLACING any existing one — there is exactly one Host per request (RFC 9112 SS3.2), and appending a second used to put both on the wire.

Parameters

NameTypeNotes
selfHttpRequest
hostString

Returns: unit

set_header : (HttpRequest) fn(self : HttpRequest, name : String, value : String) -> unit

Set a header, REPLACING every existing value for that name.

Parameters

NameTypeNotes
selfHttpRequest
nameString
valueString

Returns: unit

set_body : (HttpRequest) fn(self : HttpRequest, body : String) -> unit

Set the request body.

Parameters

NameTypeNotes
selfHttpRequest
bodyString

Returns: unit

get_header : (HttpRequest) fn(self : HttpRequest, name : String) -> Option(String)

Look up a header value by name (case-insensitive). The first value, when the field repeats — self.headers.get_all(name) for all of them, which is what Set-Cookie needs.

Parameters

NameTypeNotes
selfHttpRequest
nameString

Returns: Option(String)

to_string : (HttpRequest) fn(self : HttpRequest) -> String

Serialize to wire format, on the status line's own version (so a parsed response round-trips). A Content-Length header is added when none is present (the byte length of body), so the peer can delimit the message without waiting for close.

Parameters

NameTypeNotes
selfHttpRequest

Returns: String

HttpResponse object
HttpResponse

An HTTP response with status, headers, and body.

Fields

NameTypeDescription
statusStatusCode

The status. A StatusCode, not a bare i32 — the class predicates belong with the value, and a status is never negative.

status_textString

The reason phrase as the peer sent it, which may be anything (RFC 9110 §15 makes it advisory). status.reason() gives the registered phrase instead; keeping both means a proxy can pass the original through.

versionString

The version on the status line, as received — HTTP/1.1 or HTTP/1.0. Kept for the same reason status_text is: a proxy passes it through, and connection reuse turns on it (an HTTP/1.0 response without Connection: keep-alive ends its connection, RFC 9112 §9.3). HttpResponse.new defaults it to HTTP/1.1.

headersHeaderMap

The response's header fields, in the order they arrived. A multimap: use headers.get_all(name) when a field can repeat, and note that HttpResponse.to_string writes these verbatim.

bodyString

The body as received, byte-transparent — it is sliced out of the raw message on the CRLFCRLF boundary and wrapped without UTF-8 validation, so a binary body survives (a String here is a byte container, and body.as_bytes() is the safe way to read one).

Trait Implementations

impl(generic(T : Type), where(T <: ToString), T : (ToString))
impl(generic(T : Type), where(T <: ToString), T : (ToString), Format)
format : fn(self : Self, spec : str) -> String

Render self under spec. An unrecognised spec degrades to the plain to_string() rendering rather than failing.

Parameters

NameTypeNotes
selfSelf
specstr

Returns: String

Methods
new : (HttpResponse) fn(status : StatusCode, status_text : String) -> HttpResponse

Create a response with the given status and reason phrase.

Parameters

NameTypeNotes
statusStatusCode
status_textString

Returns: HttpResponse

get_header : (HttpResponse) fn(self : HttpResponse, name : String) -> Option(String)

Look up a header value by name (case-insensitive). The first value, when the field repeats — self.headers.get_all(name) for all of them, which is what Set-Cookie needs.

Parameters

NameTypeNotes
selfHttpResponse
nameString

Returns: Option(String)

set_header : (HttpResponse) fn(self : HttpResponse, name : String, value : String) -> unit

Set a header, REPLACING every existing value for that name.

Parameters

NameTypeNotes
selfHttpResponse
nameString
valueString

Returns: unit

is_ok : (HttpResponse) fn(self : HttpResponse) -> bool

True if the status is 2xx.

Parameters

NameTypeNotes
selfHttpResponse

Returns: bool

is_redirect : (HttpResponse) fn(self : HttpResponse) -> bool

True if the status is 3xx.

Parameters

NameTypeNotes
selfHttpResponse

Returns: bool

is_error : (HttpResponse) fn(self : HttpResponse) -> bool

True if the status is 4xx or 5xx.

Parameters

NameTypeNotes
selfHttpResponse

Returns: bool

with_status : (HttpResponse) fn(status : StatusCode) -> HttpResponse

A response with status and its registered reason phrase.

Parameters

NameTypeNotes
statusStatusCode

Returns: HttpResponse

header : (HttpResponse) fn(self : HttpResponse, name : String, value : String) -> HttpResponse

Add a header and return the response (builder pattern). APPENDS, so a repeatable field can be built up by chaining.

Parameters

NameTypeNotes
selfHttpResponse
nameString
valueString

Returns: HttpResponse

with_body : (HttpResponse) fn(self : HttpResponse, body : String) -> HttpResponse

Set the body and return the response (builder pattern).

Parameters

NameTypeNotes
selfHttpResponse
bodyString

Returns: HttpResponse

to_string : (HttpResponse) fn(self : HttpResponse) -> String

Serialize to wire format, on the status line's own version (so a parsed response round-trips). A Content-Length header is added when none is present (the byte length of body), so the peer can delimit the message without waiting for close.

Parameters

NameTypeNotes
selfHttpResponse

Returns: String

HttpParseError

Why a raw HTTP message did not parse — the error of parse_request and parse_response, which are pure decoders and so return Result (D13). Each variant carries the offending text; to_string renders the line a server puts in its 400 body. Until 2026-09-06 the two functions returned Result(_, String), the one std shape a caller could neither match on nor distinguish from any other string (issues/fixed/http-parse-errors-were-bare-strings.md).

Variants

VariantFieldsDescription
Empty

No start line at all.

InvalidStatusLineline: String

A response whose first line is not HTTP/<v> <code> <text>.

InvalidStatusCodetext: String

A status code that is not an integer.

InvalidRequestLineline: String

A request line that is not exactly <method> <target> <version>.

UnknownMethodname: String

A request method outside HttpMethod.

UnsupportedVersionversion: String

A request version other than HTTP/1.1 / HTTP/1.0.

InvalidHeaderLineline: String

A header line without a :.

Trait Implementations

impl(generic(T : Type), where(T <: ToString), T : (ToString))
impl(generic(T : Type), where(T <: ToString), T : (ToString), Format)
format : fn(self : Self, spec : str) -> String

Render self under spec. An unrecognised spec degrades to the plain to_string() rendering rather than failing.

Parameters

NameTypeNotes
selfSelf
specstr

Returns: String

Methods
to_string : (HttpParseError) fn(self : HttpParseError) -> String

Serialize to wire format, on the status line's own version (so a parsed response round-trips). A Content-Length header is added when none is present (the byte length of body), so the peer can delimit the message without waiting for close.

Parameters

NameTypeNotes
selfHttpParseError

Returns: String

source : (HttpParseError) fn(self : HttpParseError) -> Option(dyn( + ToString))

The error that caused this one, or .None at the root of the chain.

Rust's Error::source. Defaulted to .None, so an error with nothing underneath it implements the trait by saying only what it is; a wrapper overrides it to hand back what it wrapped. Walking the chain to the root cause is not expressible yet — the returned Dyn loses the Error trait on an erased receiver, so a caller can print one link but cannot follow it (#521, issues/self-trait-in-a-return-type-loses-the-trait-on-an-erased-receiver.md).

Parameters

NameTypeNotes
selfHttpParseError

Returns: Option(dyn( + ToString))

FetchOptions object
FetchOptions

Options for configuring an HTTP request.

Fields

NameTypeDescription
methodHttpMethod
headersHeaderMap
bodyString
timeoutOption(Duration)

Deadline for the WHOLE request, redirects included — .None waits forever. On expiry the in-flight connection is aborted and fetch throws HttpError.Timeout.

max_redirectsusize

How many 3xx Location hops to follow before throwing HttpError.TooManyRedirects. 0 returns the first 3xx verbatim.

max_response_bytesusize

Ceiling on the raw response bytes (headers + body) buffered into memory before HttpError.ResponseTooLarge is thrown; 0 = unlimited. This client buffers the whole response into a String, so the default (64 MiB) is what stands between an unbounded server and OOM.

Methods
new : (FetchOptions) fn() -> FetchOptions

Create default options (GET, no headers, empty body, no timeout, 10 redirects, 64 MiB response ceiling).

Returns: FetchOptions

with_method : (FetchOptions) fn(self : FetchOptions, method : HttpMethod) -> FetchOptions

Set the HTTP method.

Parameters

NameTypeNotes
selfFetchOptions
methodHttpMethod

Returns: FetchOptions

with_header : (FetchOptions) fn(self : FetchOptions, name : String, value : String) -> FetchOptions

Add a request header.

Parameters

NameTypeNotes
selfFetchOptions
nameString
valueString

Returns: FetchOptions

with_body : (FetchOptions) fn(self : FetchOptions, body : String) -> FetchOptions

Set the request body.

Parameters

NameTypeNotes
selfFetchOptions
bodyString

Returns: FetchOptions

with_timeout : (FetchOptions) fn(self : FetchOptions, limit : Duration) -> FetchOptions

Give the whole request (redirects included) a deadline.

Parameters

NameTypeNotes
selfFetchOptions
limitDuration

Returns: FetchOptions

with_max_redirects : (FetchOptions) fn(self : FetchOptions, n : usize) -> FetchOptions

Cap the number of redirect hops followed (0 = return 3xx verbatim).

Parameters

NameTypeNotes
selfFetchOptions
nusize

Returns: FetchOptions

with_max_response_bytes : (FetchOptions) fn(self : FetchOptions, n : usize) -> FetchOptions

Cap the raw response bytes buffered into memory (0 = unlimited).

Parameters

NameTypeNotes
selfFetchOptions
nusize

Returns: FetchOptions

HttpServer object
HttpServer

An HTTP/1.1 server bound to a TcpListener.

Fields

NameTypeDescription
listenerTcpListener
max_request_bytesusize

Requests larger than this are answered with 413 Payload Too Large and the connection closed; serve keeps going (0 lifts the ceiling).

stoppedbool
Methods
bind : (HttpServer) fn(addr : SocketAddr, io : Io) -> Impl : (Future[Future](HttpServer) IoExn : IoExn)

Bind a listening socket on addr (port 0 picks a free port — read it back with local_addr()).

Parameters

NameTypeNotes
addrSocketAddr
ioIo

Returns: Impl : (Future[Future](HttpServer) IoExn : IoExn)

local_addr : (HttpServer) fn(self : HttpServer) -> SocketAddr

The address the server is listening on.

Parameters

NameTypeNotes
selfHttpServer

Returns: SocketAddr

with_max_request_bytes : (HttpServer) fn(self : HttpServer, n : usize) -> HttpServer

Set the request-size ceiling (builder pattern; 0 = unlimited).

Parameters

NameTypeNotes
selfHttpServer
nusize

Returns: HttpServer

serve_once : (HttpServer) fn(self : HttpServer, handler : Impl : (Fn(HttpRequest) -> HttpResponse), io : Io) -> Impl : (Future[Future](unit) IoExn : IoExn)

Accept ONE connection, read one request, run handler, write the response and close. A request that does not parse gets a 400 Bad Request whose body names the defect, without calling handler; a framing defect (oversize, unreadable Content-Length, malformed chunking) is answered the same way (413 for oversize) instead of being thrown out of the server (issues/fixed/one-malformed-request-killed-http-server-serve.md).

Parameters

NameTypeNotes
selfHttpServer
handlerImpl : (Fn(HttpRequest) -> HttpResponse)
ioIo

Returns: Impl : (Future[Future](unit) IoExn : IoExn)

serve : (HttpServer) fn(self : HttpServer, handler : Impl : (Fn(HttpRequest) -> HttpResponse), io : Io) -> Impl : (Future[Future](unit) IoExn : IoExn)

Serve connections one after another until stop() has been called (checked after each connection completes).

Parameters

NameTypeNotes
selfHttpServer
handlerImpl : (Fn(HttpRequest) -> HttpResponse)
ioIo

Returns: Impl : (Future[Future](unit) IoExn : IoExn)

stop : (HttpServer) fn(self : HttpServer) -> unit

Ask serve to return after the connection it is currently handling.

Parameters

NameTypeNotes
selfHttpServer

Returns: unit

close : (HttpServer) fn(self : HttpServer, io : Io) -> Impl : (Future[Future](unit) IoExn : IoExn)

Close the listening socket.

Parameters

NameTypeNotes
selfHttpServer
ioIo

Returns: Impl : (Future[Future](unit) IoExn : IoExn)

Functions

parse_response function
fn(raw : String) -> Result(HttpResponse, HttpParseError)

Parameters

NameTypeNotes
rawString

Returns: Result(HttpResponse, HttpParseError)

parse_request function
fn(raw : String) -> Result(HttpRequest, HttpParseError)

Parameters

NameTypeNotes
rawString

Returns: Result(HttpRequest, HttpParseError)

fetch_with function
fn(url_str : String, opts : FetchOptions, io : Io) -> Impl : (Future[Future](HttpResponse) IoExn : IoExn)

Parameters

NameTypeNotes
url_strString
optsFetchOptions
ioIo

Returns: Impl : (Future[Future](HttpResponse) IoExn : IoExn)

fetch function
fn(url_str : String, io : Io) -> Impl : (Future[Future](HttpResponse) IoExn : IoExn)

Parameters

NameTypeNotes
url_strString
ioIo

Returns: Impl : (Future[Future](HttpResponse) IoExn : IoExn)

Constants

DEFAULT_MAX_REDIRECTS constant usize

Value: 10

Value: 67108864

DEFAULT_MAX_REQUEST_BYTES constant usize

Value: 16777216