Skip to content

std/http

std/http — HTTP/1.1 request parsing, response building, and serialization. Helpers that compose on top of the runtime’s raw tcp_* socket primitives so user code (and the auto-synthesised handler main()) can do request → response work without rolling its own parser. Migrated from the auto-injected prelude per docs/PRELUDE-TO-MODULES.md. The auto-prelude declares import "std/http"; so existing bare-name callers keep working unchanged. Scope: HTTP/1.1 only, Content-Length-delimited bodies, no chunked transfer encoding, no persistent connections (every response advertises Connection: close), max 8 KiB headers, max 1 MiB body. Sufficient for CLI tools and edge handlers; the bigger story (keep-alive, TE chunked, TLS) waits on a richer lang shape.

pub function http_status_text(code: i32): string

http_status_text(code) — IANA reason phrase for the common HTTP status codes (RFC 9110). Returns "" for unknown codes — callers should fall back to a generic phrase rather than emitting nothing.

pub function is_valid_http_status(code: i32): boolean

is_valid_http_status(code) — true if code is in the RFC 9110 range of [100, 599]. The full HTTP status range is 100..999 by the BNF but only the first three centuries have semantic meaning; servers shouldn’t emit codes outside [100, 599].

pub function http_response_ok(body: string): HttpResponse

http_response_ok(body) — 200 OK with the given body. http_response_text(status, body) — explicit status code. http_response_not_found() — common 404 builder. Saves the HttpResponse { status: 200, body: ... } boiler- plate at every handler call site.

pub function http_response_text(status: i32, body: string): HttpResponse
pub function http_response_not_found(): HttpResponse
pub function http_response_bad_request(body: string): HttpResponse

http_response_bad_request(body) — 400 with the given body. Common shape for validation-failure responses.

pub function http_response_internal_error(body: string): HttpResponse

http_response_internal_error(body) — 500. The default body shape for unhandled / unexpected exceptions in a handler.

pub function http_response_redirect(location: string): HttpResponse

http_response_redirect(location) — 302 Found with the redirect target both in the body (for clients that ignore headers) and as a real Location: header.

pub function http_response_no_content(): HttpResponse

http_response_no_content() — 204 No Content, empty body. The standard “I handled it, nothing to say” response for DELETE / PUT / etc.

pub function http_path_segments(path: string): string[]

http_path_segments(path) — split an HTTP path into non-empty components. Drops the leading ”/” and any double slashes; query string (?...) is also stripped. Useful for simple routing — /api/users/42["api", "users", "42"].

pub function http_url_path_only(path: string): string

http_url_path_only(path) — strip the query string (everything from the first ? onward). Returns path unchanged when there’s no query. Companion to http_path_segments when callers want the bare path without splitting.

pub function http_user_agent_is_bot(ua: string): boolean

http_user_agent_is_bot(ua) — heuristic bot detection via the User-Agent string. Checks for common bot tokens (“bot”, “crawler”, “spider”, “slurp”) case-insensitively. False negatives are common (sophisticated bots forge UAs); false positives possible (a browser called “BotSimulator”). Use as a hint, not a security control.

pub function http_header_value(block: string, key: string): Option[string]

http_header_value(headers, key) — Option[string] for the value of a case-insensitive header lookup. Headers are expected to be the raw HTTP header block separated by CRLF, key:value pairs. Trim whitespace around the value. Returns the FIRST matching header; for multi-valued headers callers need a richer parser.

pub function http_parse_request(buf: string): Option[HttpRequest]

http_parse_request(buf) parses a full HTTP/1.1 request out of a buffer the caller has already read from the wire. Caller is responsible for accumulating bytes via tcp_recv until the buffer holds at least the header block (terminated by \r\n\r\n) plus Content-Length bytes of body — the parser returns None on a partial buffer rather than blocking, so callers driving the read loop can keep recv’ing until parse succeeds (or a hard cap fires).

Caps: headers must fit in the first 8 KiB, body capped at 1 MiB. Both surface as None so the caller can close the socket without a response (HTTP/1.1 §10 allows server- side reset on malformed input).

pub function http_serialize_response(resp: HttpResponse): string

http_serialize_response(resp) builds the wire-format response from an HttpResponse. Always advertises Connection: close so the client’s read() returns the EOF that tells it the response is complete after the caller’s tcp_send finishes the write. No keep-alive, no chunked TE.

pub function (r: HttpRequest) body_string(): string

(r: HttpRequest).body_string() — body as a UTF-8 string. Forward-compatibility shim for the eventual Stream[bytes] body shape.

pub function (r: HttpRequest) body_bytes(): u8[]

(r: HttpRequest).body_bytes() — body as a u8 array. Same shape forward-compat as body_string; converts the current string body through s.bytes().

pub function (r: HttpRequest) body_len(): i32

(r: HttpRequest).body_len() — body length in bytes. Common shape (len(req.body)) that should also be forward-compatible — once the field becomes Stream[bytes], reading the length requires the stream to either be fully consumed or to carry a Content-Length-derived pre-known length. This shim returns the current in-memory string’s length.

pub function (r: HttpResponse) with_header(name: string, value: string): HttpResponse

(r: HttpResponse).with_header(name, value) — replace any existing entries for name (set semantics) and return the updated response. Rebind: r = r.with_header(k, v);.

pub function (r: HttpResponse) with_appended_header(name: string, value: string): HttpResponse

(r: HttpResponse).with_appended_header(name, value) — add an entry without replacing existing same-name entries (append semantics — duplicate-safe, e.g. Set-Cookie).