flare_mlake · API · http

flare.http.request

HTTP request type.

Structs

Method

struct Method

HTTP request method string constants (RFC 7231 §4).

Implements Movable

comptime GET = String("GET")
comptime POST = String("POST")
comptime PUT = String("PUT")
comptime PATCH = String("PATCH")
comptime DELETE = String("DELETE")
comptime HEAD = String("HEAD")
comptime OPTIONS = String("OPTIONS")
comptime CONNECT = String("CONNECT")
comptime TRACE = String("TRACE")

Request

struct Request

An HTTP/1.1 request.

Fields: method: HTTP method string (use Method.* constants). url: Request target (path + query), e.g. "/items?page=1". headers: Request headers (owned HeaderMap). body: Request body bytes (empty for GET/HEAD). version: HTTP version string (default "HTTP/1.1"). peer: Kernel-reported peer address. Populated by the reactor at accept time from TcpStream.peer_addr(). Direct Request constructions (tests, the client side) default to SocketAddr.localhost(0) so the field is always observable without having to special-case "did the reactor populate it." Note: this is the kernel's view of the peer; flare does not interpret X-Forwarded-For, Forwarded:, or PROXY-protocol metadata. expose_errors: When True, 4xx / 5xx responses generated from a raised Error may include the verbatim message in their body — useful in local dev. Default False so production servers send a fixed status reason and log the message (with any user-controlled bytes) to stderr rather than echoing it back. Carried on the request because flare is shared-nothing thread-per-core and the policy is set per-server (per-ServerConfig); the reactor copies ServerConfig.expose_error_messages onto every parsed Request and _bad_request_from_error reads it.

Path parameters extracted by Router live on a private field that is lazily allocated on the first Router match. Handlers that never go through a Router (the plaintext bench, pure static handlers) therefore pay zero allocation cost per request. Access params via req.params() or the convenience req.param(name) / req.has_param(name) helpers.

This type is Movable (owns the header map and body) but not Copyable to avoid accidental deep copies.

Example:

var req = Request(method=Method.POST, url="http://api.example.com/items")
req.headers.set("Content-Type", "application/json")
req.body = '{"name":"flare"}'.as_bytes()

Implements Movable

Fields
method: String
url: String
headers: HeaderMap
body: List[UInt8]
trailers: HeaderMap: Trailer fields sent after the body (RFC 9110 sec 6.5); fields that may not appear in a trailer are dropped.
body_pipe: Optional[ArcPointer[BodyPipe]]: Set when the body is still arriving (HTTP/3 with Http3Config.stream_request_bodies): read it with :meth:body_stream; :attr:body holds nothing then.
version: String
peer: SocketAddr: Kernel-reported peer SocketAddr. See struct docstring.
expose_errors: Bool: Whether 4xx / 5xx responses may echo raised Error messages. Default False; the reactor copies ServerConfig.expose_error_messages onto every parsed request. See struct docstring.

__init__

def __init__(out self, method: String, url: String, body: List[UInt8] = List(), version: String = "HTTP/1.1", peer: SocketAddr = SocketAddr(IpAddr(String("127.0.0.1"), False), UInt16(0)), expose_errors: Bool = False)

Create a new HTTP request.

Args
method: HTTP method string.
url: Full URL or request target.
body: Request body bytes; empty by default.
version: HTTP version; "HTTP/1.1" by default.
peer: Peer SocketAddr; defaults to 127.0.0.1:0 for direct constructions. The reactor passes the kernel-reported peer captured at accept time.
expose_errors: Whether handler / extractor error messages may flow into the response body. Default False (production-safe). The reactor copies this from ServerConfig.expose_error_messages.

__deinit__

def __deinit__(deinit self)

test_get

def test_get(url: String) -> Self

Construct a GET request for cookbook examples and unit tests.

Equivalent to Request(method=Method.GET, url=url) but spells the intent without re-stating the keyword arg trio. Defaults: empty body, HTTP/1.1, 127.0.0.1:0 peer, expose_errors=False, no TLS info.

Args
url: Request target (path + optional query string).

test_post

def test_post(url: String, body: String, content_type: String = "application/octet-stream") -> Self

Construct a POST request with a string body.

Convenience factory for cookbook examples and unit tests that want to drive an extractor / handler with a synthetic body without writing the Request(method="POST", url=url, version="HTTP/1.1") + per-byte body.append(...) loop the synthetic-request shape used to require.

Args
url: Request target (path + optional query string).
body: Body bytes as a UTF-8 String. Empty string is fine.
content_type: Value for the Content-Type header. Defaults to "application/octet-stream"; pass "application/json" for JSON bodies and "application/x-www-form-urlencoded" for form bodies.

has_params

def has_params(self) -> Bool

Return True if a Router populated this request's path params.

params_mut

def params_mut(mut self) -> ref[self._params] Dict[String, String]

Lazily allocate and return a mutable reference to the path-params dict.

Router calls this when it captures path parameters on a matched route. Tests and examples can call it to construct a Request with synthetic path params without going through a Router (e.g. when unit-testing a handler that reads req.param("id")). The underlying Dict is allocated on first call, so requests that never see a Router pay zero allocation cost.

Production handlers should not call this — Router owns param-population on the request path, and writing through this accessor mid-request would be surprising. It's public only so the test surface doesn't have to reach for an underscored name.

param

def param(self, name: String) -> String

Return path param name. Raises Error if missing.

Equivalent to req.params()[name] but does not allocate an empty Dict when no params are present (raises immediately instead).

has_param

def has_param(self, name: String) -> Bool

Return True if path param name is set (no allocation).

param_opt

def param_opt(self, name: String) -> Optional[String]

Return path param name as Optional[String] (None on miss).

Uniform miss-behavior matrix -- every request-value source (path param / query param / cookie) offers the same three accessors:

  • base (param / query_param / cookie): the domain-appropriate default. param raises because a missing path param is a routing/programming error, not client input; query_param / cookie return "" because those are genuinely optional client input.
  • *_opt -> Optional[String]: None on absent, Optional("") on present-empty (distinguishes the two).
  • *_or(name, default) -> String: default on absent.

Pick *_opt for uniform absence handling regardless of source.

param_or

def param_or(self, name: String, default: String = "") -> String

Return path param name, or default when absent.

The non-raising convenience form of param (see param_opt for the full uniform-accessor matrix).

query_param

def query_param(self, name: String) -> String

Return the first query-string value for name, or "".

Scans the URL's query string (the substring after ?, stopping at #) for name=value pairs separated by &. Case-sensitive key match. Does not percent-decode; callers should decode if they expect encoded bytes. Allocation-free on requests that have no query string (fast path checks for ? in the URL first).

Args
name: Query parameter name.

has_query_param

def has_query_param(self, name: String) -> Bool

Return True if query parameter name is present (even if empty).

Args
name: Query parameter name.

query_param_opt

def query_param_opt(self, name: String) -> Optional[String]

Return query param name as Optional[String] (None when the key is absent; Optional("") for a present-empty value).

Companion to param_opt / cookie_opt for uniform miss semantics.

query_param_or

def query_param_or(self, name: String, default: String) -> String

Return query param name, or default when the key is absent (unlike query_param's bare "", which cannot tell absent from present-empty). Uniform with param_or / cookie_or.

body_stream

def body_stream(self) -> Optional[ChunkSourceBox]

The body as a source that yields it as it arrives, or None when the body is already whole in :attr:body. Set it as a response's body_stream to stream the upload back out.

text

def text(self) -> String

Decode the request body as a UTF-8 string.

Invalid UTF-8 sequences are replaced with the Unicode replacement character; the body comes from the client, so this never raises on malformed input.

json

def json(self) -> Value

Parse the request body as JSON.

Raises Error: If the body is not valid JSON.

content_length

def content_length(self) -> Int

Return the Content-Length header value, or 0 if absent or not a plain decimal of at most 18 digits.

cookies

def cookies(self) -> CookieJar

Parse the Cookie request header(s) into a CookieJar.

Walks every Cookie header value (multiple headers are legal under RFC 7230 paragraph 3.2.2) and feeds each to parse_cookie_header. Returns an empty jar if no Cookie header is present.

connection_close

def connection_close(self) -> Bool

Return True if Connection: close is set.