Module http/http

http/http
Stability: unstable — the type surface was reworked on 2026-09-09 (`StatusCode` replacing a bare `status_code : i32`, `HeaderMap` replacing `ArrayList(HttpHeader)`) and gained `HttpResponse.version` on 2026-09-10 for connection reuse, so it is inside its one-release window. One decided-convention violation is still standing: `HttpRequest`/ `HttpResponse` carry `get_header`/`set_header` beside the `HeaderMap`'s own Rust-shaped `get`/`insert`/`append`, which is two spellings for one operation and the `get_*` prefix D2 rules out — the plan lists `get_header` among its D2 violations. Removing the pair is breaking, so it waits for a window; the multimap and `StatusCode` themselves are expected to stay. — stable modules only change additively; this one may still change.

HTTP core types — HttpMethod, StatusCode, HeaderMap, HttpRequest, HttpResponse, and the two parsers that turn wire bytes into them.

Pure values and pure text: nothing in this file does I/O or blocks, so it is equally usable in a client, in a server, and in a test. The parsers return Result(_, HttpParseError) rather than throwing (D13), which is what lets HttpServer.serve answer a malformed request with a 400 and keep serving instead of unwinding out of its accept loop.

Two shapes are worth knowing before reading further, because both differ from the obvious data structure: a header field name compares case-insensitively but is STORED as written (that is what goes on the wire), and a field may legitimately REPEAT with the order significant (Set-Cookie always does) — so headers are an insertion-ordered multimap, not a HashMap(String, String). And a status is a u16 newtype with 22 named constructors rather than an enum, because the registered set is OPEN: a peer may send a code this list does not carry, and an enum would have to reject or box it.

Stability

unstable — the type surface was reworked on 2026-09-09 (StatusCode replacing a bare status_code : i32, HeaderMap replacing ArrayList(HttpHeader)) and gained HttpResponse.version on 2026-09-10 for connection reuse, so it is inside its one-release window. One decided-convention violation is still standing: HttpRequest/ HttpResponse carry get_header/set_header beside the HeaderMap's own Rust-shaped get/insert/append, which is two spellings for one operation and the get_* prefix D2 rules out — the plan lists get_header among its D2 violations. Removing the pair is breaking, so it waits for a window; the multimap and StatusCode themselves are expected to stay.

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

impl(HttpMethod, ToString(...))
to_string : ( self -> match( self, .GET => `GET`, .POST => `POST`, .PUT => `PUT`, .DELETE => `DELETE`, .HEAD => `HEAD`, .PATCH => `PATCH`, .OPTIONS => `OPTIONS` ) )
impl(HttpMethod, ...)
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)

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

HttpHeader object
HttpHeader

An HTTP header as a name-value pair.

Fields

NameTypeDescription
nameString
valueString
impl(HttpHeader, ...)
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

impl(HeaderMap, ...)
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

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)

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

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)

impl(HeaderMap, ToString(...))
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

impl(StatusCode, ...)
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

impl(StatusCode, ToString(...))
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

impl(StatusCode, Eq(StatusCode)(...))
impl(StatusCode, Ord(StatusCode)(...))
impl(StatusCode, ...)
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

Methods
== : (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

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

impl(HttpRequest, ...)
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

NameTypeNotesDescription
selfHttpRequest
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).

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

NameTypeNotesDescription
selfHttpRequest
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).

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)

impl(HttpRequest, ToString(...))
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

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

Create a response with the given status and reason phrase.

Parameters

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

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

NameTypeNotesDescription
statusStatusCode

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

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

NameTypeNotesDescription
selfHttpResponse
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).

Returns: HttpResponse

impl(HttpResponse, ToString(...))
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))

Functions

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

Parse a raw HTTP response into an HttpResponse.

The head is split from the body on the \r\n\r\n boundary and the body is sliced as BYTES — it may be binary, and it used to be reassembled by splitting the WHOLE message on \r\n and re-joining the tail lines one concatenation at a time: quadratic in the body size, and a substring over a UTF-8 continuation byte panics.

Parameters

NameTypeNotes
rawString

Returns: Result(HttpResponse, HttpParseError)

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

Parse a raw HTTP/1.1 request (request line, headers, body) into an HttpRequest. The body is taken verbatim — read_http_message has already decoded chunked framing when it read the message. Errors name the defect (Invalid request line, unknown method, unsupported HTTP version).

Parameters

NameTypeNotes
rawString

Returns: Result(HttpRequest, HttpParseError)