# HTTP API, limits and failures

[العربية](reference.ar.md) · [Runnable guide](guide.en.md) · [Deployment](deployment.en.md)

This reference describes the supplied native ASPL 0.5.0 library. Import
`core::http` or `أساسي::ويب` in each source file that uses it. Qualify members
with the written short prefix. Arabic and English members/fields below are exact
aliases for one declaration. User names and paths are never translated.

## Explicit serving and versioned state

`Session<C,S>` / `جلسة<C,S>` and `StateSnapshot<S>` / `لقطة_حالة<S>` add
explicit serving and copied versioned state. Session is opaque and shared-close;
StateSnapshot has one read-only `value` / `قيمة` field and survives session close.
`SessionStatus` / `حالة_جلسة` has SESSION_RUNNING / جلسة_تعمل,
SESSION_DRAINING / جلسة_تستكمل_الإغلاق and SESSION_CLOSED / جلسة_مغلقة.
`ProgressBudget` / `ميزانية_تقدم` defaults to 4096 instructions, 2 active ms and
zero wait ms. The table below lists all twelve additions. [Raylib's guide](../raylib/guide.en.md#update-sound-music-and-serving-explicitly)
describes progress and drawing admission; [its reference](../raylib/reference.en.md#http-sessions)
lists the exact fields, aliases and contexts. These operations also work in
HTTP-only programs. Normal explicit handlers run only through progress, outside
frames. EndDrawing/input transport maintenance dispatches no source handler.
Session state helpers are application-only; Context helpers remain handler-only.
Stale same-session conditional publication succeeds with false. Foreign-session
snapshots fail with http.invalid_argument. Normal closed progress reports closed;
repeated stop/close succeeds. Closed state/config helpers use http.closed_session.
New frame/context/closed-session refusals carry English and Arabic sentences
through the existing code/message fields. Prior HTTP producer messages keep
their contract.

## Types, functions and defaults

`Route<C,S>` / `وجهة<C,S>`, `Router<C,S>` / `موجه<C,S>` and
`Context<C,S>` / `سياق<C,S>` have exactly two concrete application type arguments.
C and S can be admissible storable values, including records, lists, results,
Buffer, managed handles and registrations. Actual Context and exposed callable
values are excluded at every depth, including registration data. These are
supplied families, not user-defined generics. If inference cannot determine both
arguments, write them explicitly, for example `http::router<bool,i64>([])`.
All routes, handlers, configuration and state must use the same nominal C/S
identities. Imports of one canonical module share its type and callable identity.

A handler is a named top-level user function with signature
`fn(IncomingRequest, Context<C,S>) -> ServerResponse`. Refer to it by its name,
such as `handlers::handle`, without calling it. Callable values have no captured
environment. Export a module's declarations with `share` / `شارك`; other names
stay private. Ordinary callable values can be stored, passed, returned and
compared with word equality. Handler checking follows all possible targets
through modules and rejects unsafe or blocking paths. Ordinary foreign calls
and blocking line/file operations cannot become handler-safe by wrapping them.

Records below have ordinary value semantics. Message/header byte lists remain
usable after a connection or session ends. Context has no constructor or public
fields, cannot enter aggregates, escape its invocation, be compared, or cross an
ordinary foreign call. Route and Router are retainable opaque values without
public fields or live sockets. Result success is `ok` / `نجاح`, payload is
`value` / `قيمة`, error is `error` / `الخطأ`; its code is `code` / `الرمز`.
Read the payload only after checking success. Human messages may vary.

Default ClientOptions has all three flags false and an empty CA path.
Default ServerConfig has an empty listener list and must be completed before
serving. `listener` takes an address and port 1..65535, returns plain transport
and empty TLS paths. `client_request` starts with empty headers/body;
`response` starts with empty headers and false/zero representation-length
metadata. `text_response` sets the supplied Content-Type and exact UTF-8 body.
There are no optional arguments or implicit JSON transformations.

The following tables are regenerated from the reviewed declaration catalog by
`python3 tools/generate_http_reference.py`. Type notation is shared by both
locales. Numeric sizes/counts are i64, and durations are i64 milliseconds.
Ranges are inclusive. There is no unlimited sentinel. MiB means 1048576 bytes.

<!-- catalog:start -->
### `ProgressBudget` / `ميزانية_تقدم`

| English / العربية | Type / النوع | Default / الافتراضي | Range / المجال |
| --- | --- | ---: | --- |
| `max_instructions` / `حد_التعليمات` | `i64` | 4096 | 1..1048576 |
| `active_ms` / `زمن_العمل_مللي` | `i64` | 2 | 1..1000 |
| `wait_ms` / `زمن_الانتظار_مللي` | `i64` | 0 | 0..1000 |

### `Header` / `ترويسة`

| English / العربية | Type / النوع |
| --- | --- |
| `name` / `اسم` | `string` |
| `value` / `قيمة` | `list<u8>` |

### `QueryEntry` / `عنصر_استعلام`

| English / العربية | Type / النوع |
| --- | --- |
| `name` / `اسم` | `string` |
| `value` / `قيمة` | `string` |
| `has_equals` / `له_يساوي` | `bool` |

### `ClientRequest` / `طلب_عميل`

| English / العربية | Type / النوع |
| --- | --- |
| `method` / `طريقة` | `string` |
| `url` / `رابط` | `string` |
| `headers` / `ترويسات` | `list<Header>` |
| `body` / `متن` | `list<u8>` |

### `IncomingRequest` / `طلب_وارد`

| English / العربية | Type / النوع |
| --- | --- |
| `method` / `طريقة` | `string` |
| `target` / `هدف` | `string` |
| `authority` / `جهة` | `string` |
| `path` / `مسار` | `string` |
| `query` / `استعلام` | `string` |
| `has_query` / `له_استعلام` | `bool` |
| `headers` / `ترويسات` | `list<Header>` |
| `trailers` / `ترويسات_ختامية` | `list<Header>` |
| `body` / `متن` | `list<u8>` |
| `tls` / `اتصال_مشفر` | `bool` |
| `peer_address` / `عنوان_الطرف` | `string` |
| `local_address` / `عنوان_محلي` | `string` |
| `peer_port` / `منفذ_الطرف` | `i64` |
| `local_port` / `منفذ_محلي` | `i64` |
| `listener_index` / `فهرس_مستمع` | `i64` |

### `ClientResponse` / `استجابة_عميل`

| English / العربية | Type / النوع |
| --- | --- |
| `status` / `حالة` | `i64` |
| `headers` / `ترويسات` | `list<Header>` |
| `trailers` / `ترويسات_ختامية` | `list<Header>` |
| `body` / `متن` | `list<u8>` |
| `final_url` / `رابط_نهائي` | `string` |
| `redirect_count` / `عدد_تحويلات` | `i64` |
| `gzip_decoded` / `فك_ضغط_غزيب` | `bool` |
| `encoded_body_bytes` / `بايتات_متن_مرمز` | `i64` |

### `ServerResponse` / `استجابة_خادم`

| English / العربية | Type / النوع |
| --- | --- |
| `status` / `حالة` | `i64` |
| `headers` / `ترويسات` | `list<Header>` |
| `body` / `متن` | `list<u8>` |
| `has_representation_length` / `له_طول_تمثيل` | `bool` |
| `representation_length` / `طول_تمثيل` | `i64` |

### `Listener` / `مستمع`

| English / العربية | Type / النوع |
| --- | --- |
| `address` / `عنوان` | `string` |
| `port` / `منفذ` | `i64` |
| `tls` / `اتصال_مشفر` | `bool` |
| `certificate_file` / `ملف_شهادة` | `string` |
| `key_file` / `ملف_مفتاح` | `string` |

### `ClientOptions` / `خيارات_عميل`

| English / العربية | Type / النوع |
| --- | --- |
| `limits` / `حدود` | `MessageLimits` |
| `timeouts` / `مهل` | `Timeouts` |
| `follow_redirects` / `اتبع_تحويلات` | `bool` |
| `decode_gzip` / `فك_غزيب` | `bool` |
| `use_private_ca` / `استخدم_مرجع_خاص` | `bool` |
| `ca_file` / `ملف_مرجع` | `string` |

### `ServerConfig` / `إعدادات_خادم`

| English / العربية | Type / النوع |
| --- | --- |
| `listeners` / `مستمعون` | `list<Listener>` |
| `limits` / `حدود` | `MessageLimits` |
| `timeouts` / `مهل` | `Timeouts` |

### `RuntimeConfig` / `إعدادات_تنفيذ_ويب`

| English / العربية | Type / النوع | Default / الافتراضي | Range / المجال |
| --- | --- | ---: | --- |
| `vm_memory_bytes` / `بايتات_ذاكرة_آلة` | `i64` | 268435456 | 1048576..1073741824 |
| `backend_memory_bytes` / `بايتات_ذاكرة_خلفية` | `i64` | 134217728 | 1048576..1073741824 |
| `inbound_connections` / `اتصالات_واردة` | `i64` | 128 | 1..4096 |
| `outbound_connections` / `اتصالات_صادرة` | `i64` | 32 | 1..1024 |
| `idle_client_connections` / `اتصالات_عميل_خاملة` | `i64` | 16 | 1..outbound_connections / اتصالات_صادرة |
| `queued_requests` / `طلبات_منتظرة` | `i64` | 32 | 1..1024 |
| `live_handlers` / `معالجات_حية` | `i64` | 32 | 1..1024 |
| `outbound_operations` / `عمليات_صادرة` | `i64` | 32 | 1..1024 |
| `max_listeners` / `أقصى_مستمعين` | `i64` | 8 | 1..64 |
| `max_routes` / `أقصى_وجهات` | `i64` | 1024 | 1..16384 |
| `trust_configurations` / `إعدادات_ثقة` | `i64` | 16 | 1..128 |
| `tls_file_bytes` / `بايتات_ملف_تشفير` | `i64` | 1048576 | 1..16777216 |
| `query_bytes` / `بايتات_استعلام` | `i64` | 8192 | 1..1048576 |
| `query_entries` / `عدد_عناصر_استعلام` | `i64` | 1024 | 1..16384 |

### `MessageLimits` / `حدود_رسالة`

| English / العربية | Type / النوع | Default / الافتراضي | Range / المجال |
| --- | --- | ---: | --- |
| `target_bytes` / `بايتات_هدف` | `i64` | 8192 | 1..1048576 |
| `header_bytes` / `بايتات_ترويسات` | `i64` | 32768 | 1..1048576 |
| `header_fields` / `عدد_ترويسات` | `i64` | 100 | 1..4096 |
| `chunk_line_bytes` / `بايتات_سطر_جزء` | `i64` | 1024 | 1..65536 |
| `body_bytes` / `بايتات_متن` | `i64` | 16777216 | 1..1073741824 |
| `decoded_body_bytes` / `بايتات_متن_مفكوك` | `i64` | 16777216 | 1..1073741824 |
| `informational_responses` / `عدد_استجابات_تمهيدية` | `i64` | 8 | 1..64 |
| `max_redirect_hops` / `أقصى_تحويلات` | `i64` | 5 | 0..32 |

### `Timeouts` / `مهل`

| English / العربية | Type / النوع | Default / الافتراضي | Range / المجال |
| --- | --- | ---: | --- |
| `total_ms` / `مهلة_كلية` | `i64` | 30000 | 1..86400000 |
| `connect_ms` / `مهلة_اتصال` | `i64` | 10000 | 1..86400000 |
| `tls_ms` / `مهلة_تشفير` | `i64` | 10000 | 1..86400000 |
| `headers_ms` / `مهلة_ترويسات` | `i64` | 10000 | 1..86400000 |
| `body_ms` / `مهلة_متن` | `i64` | 30000 | 1..86400000 |
| `write_ms` / `مهلة_كتابة` | `i64` | 10000 | 1..86400000 |
| `idle_ms` / `مهلة_خمول` | `i64` | 30000 | 1..86400000 |
| `drain_ms` / `مهلة_تصريف` | `i64` | 5000 | 1..86400000 |
| `cleanup_ms` / `مهلة_تنظيف` | `i64` | 1000 | 1000..86400000 |

### Functions / الدوال

| English / العربية | Signature / التوقيع |
| --- | --- |
| `progress_budget` / `ميزانية_التقدم` | `() -> ProgressBudget` |
| `runtime_config` / `إعدادات_تنفيذ` | `() -> RuntimeConfig` |
| `message_limits` / `حدود_رسائل` | `() -> MessageLimits` |
| `timeouts` / `مهل_افتراضية` | `() -> Timeouts` |
| `client_options` / `خيارات_طلب` | `() -> ClientOptions` |
| `server_config` / `إعدادات_خدمة` | `() -> ServerConfig` |
| `listener` / `أنشئ_مستمع` | `(string, i64) -> result<Listener>` |
| `configure` / `اضبط` | `(RuntimeConfig) -> result<unit>` |
| `client_request` / `أنشئ_طلب` | `(string, string) -> result<ClientRequest>` |
| `request` / `اطلب` | `(ClientRequest, ClientOptions) -> result<ClientResponse>` |
| `response` / `أنشئ_استجابة` | `(i64, list<u8>) -> result<ServerResponse>` |
| `text_response` / `استجابة_نصية` | `(i64, string, string) -> result<ServerResponse>` |
| `encode_utf8` / `رمز_نص` | `(string) -> list<u8>` |
| `decode_utf8` / `فك_نص` | `(list<u8>) -> result<string>` |
| `header` / `أنشئ_ترويسة` | `(string, list<u8>) -> result<Header>` |
| `text_header` / `ترويسة_نصية` | `(string, string) -> result<Header>` |
| `header_values` / `قيم_ترويسة` | `(list<Header>, string) -> result<list<list<u8>>>` |
| `query_entries` / `عناصر_استعلام` | `(string) -> result<list<QueryEntry>>` |
| `query_values` / `قيم_استعلام` | `(list<QueryEntry>, string) -> list<string>` |
| `snapshot_state` / `التقط_الحالة` | `(Context<C,S>) -> StateSnapshot<S>` |
| `snapshot_session_state` / `التقط_حالة_الجلسة` | `(Session<C,S>) -> result<StateSnapshot<S>>` |
| `replace_session_state` / `استبدل_حالة_الجلسة` | `(Session<C,S>, S) -> result<unit>` |
| `replace_state_if_current` / `استبدل_الحالة_إن_كانت_حالية` | `(Context<C,S>, StateSnapshot<S>, S) -> result<bool>` |
| `replace_session_state_if_current` / `استبدل_حالة_الجلسة_إن_كانت_حالية` | `(Session<C,S>, StateSnapshot<S>, S) -> result<bool>` |
| `start` / `ابدأ` | `(ServerConfig, Router<C,S>, C, S) -> result<Session<C,S>>` |
| `session_config` / `إعداد_الجلسة` | `(Session<C,S>) -> result<C>` |
| `session_state` / `حالة_الجلسة` | `(Session<C,S>) -> result<S>` |
| `close_session` / `أغلق_الجلسة` | `(Session<C,S>) -> result<unit>` |
| `progress` / `تقدم` | `(Session<C,S>, ProgressBudget) -> result<SessionStatus>` |
| `stop_session` / `أوقف_الجلسة` | `(Session<C,S>) -> result<unit>` |
| `route` / `أنشئ_وجهة` | `(string, string, fn(IncomingRequest, Context<C,S>) -> ServerResponse) -> result<Route<C,S>>` |
| `router` / `أنشئ_موجه` | `(list<Route<C,S>>) -> result<Router<C,S>>` |
| `with_catch_all` / `أضف_معالج_عام` | `(Router<C,S>, fn(IncomingRequest, Context<C,S>) -> ServerResponse) -> result<Router<C,S>>` |
| `serve` / `اخدم` | `(ServerConfig, Router<C,S>, C, S) -> result<unit>` |
| `read_config` / `اقرأ_إعدادات` | `(Context<C,S>) -> C` |
| `read_state` / `اقرأ_حالة` | `(Context<C,S>) -> S` |
| `replace_state` / `استبدل_حالة` | `(Context<C,S>, S) -> unit` |
| `stop` / `أوقف` | `(Context<C,S>) -> unit` |
| `check_response` / `تحقق_استجابة` | `(Context<C,S>, IncomingRequest, ServerResponse) -> result<unit>` |
<!-- catalog:end -->

## Byte messages, headers and queries

Bodies are complete buffered `list<u8>` values. `encode_utf8` copies exact UTF-8;
`decode_utf8` rejects malformed text with `http.invalid_utf8`. Neither strips
BOM/NUL, normalizes Unicode, guesses charset nor replaces invalid bytes.
JSON is explicit text and Content-Type; no parser/serializer is included.

Headers are ordered repeated fields, with ASCII token names and byte values.
Values accept HTAB, printable ASCII and 0x80..0xFF, rejecting NUL, CR, LF, DEL
and other controls. Parsing trims surrounding SP/HTAB and preserves interior
bytes, order and name case. `header_values` matches names case-insensitively,
returns every value in order, and never joins with commas or decodes text.
Repeated Set-Cookie stays separate. Trailers remain separate from initial fields.

Applications cannot set Content-Length, Transfer-Encoding, Connection,
Keep-Alive, Proxy-Connection, TE, Trailer, Upgrade or Expect on outgoing messages,
or Host on client requests. The library derives Host/framing and provides Date
on server responses when absent. Content-Encoding is explicit application data;
server compression is not automatic. Conflicting lengths, Transfer-Encoding
with Content-Length, folded fields and ambiguous framing fail. Received control
headers remain inspectable metadata. Never copy peer compressed length/encoding
headers blindly to a new response.

Client URLs must be absolute ASCII HTTP/HTTPS URIs. Percent-encode non-ASCII
path/query text and supply internationalized hosts as A-labels. DNS, IPv4 and
bracketed IPv6 are supported. Userinfo, whitespace/controls, malformed escapes,
bad ports and IPv6 zone identifiers are rejected. Fragments are stripped; an
empty path becomes `/`. The first request preserves dot segments, slash count
and percent spelling. `final_url` removes the fragment, lowercases scheme/DNS
host, omits the default port and uses `/` for an empty path, preserving query
presence and percent spelling.

Incoming `target` preserves origin-form or HTTP/HTTPS absolute-form encoding;
OPTIONS also accepts `*`. Extract path/query before decoding. `authority` comes
from an absolute target or valid Host. `has_query` distinguishes `/p` and `/p?`.
Forwarded headers never change these fields or actual TLS/address metadata.
Listener indexes are zero-based. Invalid targets fail before handler dispatch.

`query_entries` splits the supplied raw query at `&` and the first `=` before
one percent decode. Do not pass the initial `?`. `+` stays plus, `;` stays data,
`%26` stays within an entry and `%252F` becomes `%2F`. Empty segments produce
no entries. `flag` and `flag=` differ by `has_equals`; `=x` has an empty name.
Repeated names preserve order, `%00` is a valid ASPL NUL, and malformed escape
or decoded UTF-8 failures leave the raw query available. `query_values` uses
exact decoded-name matching and maps a bare key to an empty value.

## Routes and responses

Methods are nonempty case-sensitive ASCII tokens. CONNECT and upgrades are
unsupported. Encoded paths match exactly, including escape case, slashes and
dot segments. `/a%2Fb`, `/a%2fb`, `/a/b` and `/a/../b` differ. Route paths start
with `/`, have no query/fragment and valid escapes; `*` is OPTIONS-only.
Duplicate method/path pairs and a second catch-all fail registration.

Dispatch exact routes first, then HEAD-to-GET fallback, then known-path 405,
then unknown-path catch-all or default 404. Explicit HEAD wins. Allow sorts
method tokens bytewise and adds HEAD for GET, without inventing OPTIONS.
Default text bodies are `Not found` and `Method not allowed`, with
`text/plain; charset=utf-8`. Invalid requests never reach a catch-all.

Handler statuses are final 200..599. Complete client 404/500 responses are
successful results. Informational responses are consumed within limits;
101/unsupported wire versions fail. HEAD suppresses bodies after validation and
accounting. GET fallback computes Content-Length from its returned body;
explicit HEAD/catch-all can declare representation length or omit it. Declared
length plus a nonempty HEAD body must match that body. False
`has_representation_length` requires zero `representation_length`.

204/205/304 require empty handler bodies. 204 omits Content-Length, 205 uses
zero, and 304 may declare representation length or omit it. Such metadata is
allowed only for HEAD/304 and must be nonnegative. Status rules override HEAD
fallback. Client no-body outcomes return empty body, zero encoded count and
false gzip flag without allocating or decoding a hypothetical representation.
205 still requires valid empty-message framing.

`check_response` validates session limits and metadata without sending, using
only the current invocation's request provenance. Copies retain provenance;
editing public method fields does not change real HEAD authority. A request
from another invocation or application construction fails `http.invalid_argument`.
Final validation repeats on return. An invalid/oversized handler response uses
a bounded generic 500 and closes the connection. A trap stays terminal.

Before dispatch, malformed requests use 400, target excess 414, header/trailer
excess 431, body excess 413, unsupported transfer/CONNECT 501, expectations 417,
and HTTP versions 505. Valid admitted Expect: 100-continue receives 100 before
body receipt. Phase timeouts may produce 408 while the total is live; a complete
request without dispatch/handler capacity uses 503. Close rejected connections.
Fixed rejection bodies are empty. Transport/TLS admission, parent expiry,
disconnect or budget exhaustion may close/refuse without an HTTP error reply.

## Redirects, gzip and reuse

Following and gzip decoding are false by default. Enabled following covers
301/302/303/307/308 only within one origin, comparing scheme, host and effective
port. Relative references resolve with literal dot-segment processing.
301/302 change POST to GET and drop its body; other methods retain it. 303 keeps
HEAD or selects GET and drops the body. 307/308 replay method/body exactly.
When dropping a body, remove Content-Type, Content-Encoding, Content-Language,
Content-Location, Content-Range, Digest and Content-Digest and derive new framing.

No Location returns the response. Multiple or malformed/unusable Locations
fail; an empty relative Location is valid and still bounded by the hop cap.
Valid cross-origin destinations return the current response without following,
including HTTPS-to-HTTP. `redirect_count` counts followed transitions and
`final_url` is the last requested URL. All hops share the original total deadline.
There is no automatic application transport retry, including failed reuse.

With decoding off, return encoded bytes and generate no Accept-Encoding.
With decoding on, generate `Accept-Encoding: gzip` and reject the caller's
Accept-Encoding. Missing/exact identity leaves bytes unchanged; one
case-insensitive gzip coding is decoded. Stacked/repeated/unsupported coding
fails. Validate complete members and checksums, accept concatenated members,
and reject truncation/trailing garbage. Initial headers and trailers retain
peer compressed metadata. `encoded_body_bytes` excludes transfer framing;
`body` is decoded only when `gzip_decoded` is true. Enforce both encoded and
decoded limits before accepting the next bytes.

Reuse is bounded and execution-owned. Its key includes origin and effective TLS
trust identity. Consume complete valid framing before reuse or close the socket.
Idle connections expire or may be evicted. Normal `serve` return releases its
server/child work; independent client reuse can remain until execution end.
There is no public socket/stream/client-close handle.

## State, bounds and deadlines

`read_config` and `read_state` return value snapshots. Changes to a snapshot do
not publish state. `replace_state` serializes a whole replacement; it is not an
atomic read/wait/replace transaction. Managed handles in snapshots retain the
same native owner, not a clone of its mutable native state. Extracted bytes are
independent values. Context authority expires with its handler invocation.

`configure` may replace valid execution-wide settings before the first validated
network attempt. That attempt freezes settings even if startup fails. Pure
helpers do not start networking. The execution permits one `serve` invocation,
including failed startup, and supports client calls before, inside and after it.
Options/listeners/router/configuration are copied per operation/session.

The VM default is 256 MiB and the shared backend default 128 MiB. Native charges
include retained capacities, temporary peaks, TLS/DNS/decoder state and events.
Live ASPL values remain charged to the VM. Kernel socket buffers are outside
allocator accounting, but accepted/idle sockets consume finite counts. Listen
backlog requested per listener is at most `queued_requests`, subject to host
clamping. Queue/handler/outbound saturation refuses bounded admission rather
than creating hidden queues. Host ceilings and actual memory may constrain a
valid numeric setting; a setting reserves nothing and guarantees no admission.
`idle_client_connections` must also be at most `outbound_connections`. Lowering
outbound capacity below the default 16 idle slots requires lowering idle slots
too, otherwise `configure` returns `http.invalid_argument`. The checked
[limits.aspl](../examples/http/en/limits.aspl) demonstrates refusal and correction.

All deadlines use monotonic time. Client total begins at call entry; server total
begins at its first request byte and includes queueing/CPU/outbound/writes.
`connect_ms` includes DNS/TCP/TLS together. TLS/header/body/write phases may
shorten the original total, never extend it. Child work is capped by its parent.
Server TLS handshake precedes first-request-byte total. Idle covers connection
inactivity; drain bounds shutdown waiting. Cleanup uses one original deadline
for all owned resources in its scope, default/minimum 1000 ms. 10 ms polling is
a responsiveness target, not a hard real-time guarantee.

Parent expiry/disconnect/drain cancellation revokes that invocation and its
children, discards late results/state publication, and leaves unrelated handlers
live. It does not deliver a failed result into the cancelled parent. A receive
half-close alone is not a detected disconnect. Explicit stop drains and returns
normally after release. First signal drains then ends execution with status 7;
a second skips drain. Traps use status 5, never an automatic 500. VM limits,
allocator/internal failures and failed bounded cleanup remain terminal.

## TLS inputs

TLS 1.2/1.3 clients always verify chain, dates and DNS/IP SAN identity. Direct
servers load one PEM chain and matching unencrypted key per listener. Supported
ordinary rsaEncryption keys are 2048..8192 bits, with odd exponent greater than
one and at most 32 bits. Named P-256/P-384/P-521 curves are supported. Ordinary
RSA keys with RSA-PSS signatures are supported; restricted rsassaPss keys,
Ed25519/Ed448, other curves and explicit curve parameters are excluded.

Configured TLS file size defaults to 1 MiB, range 1..16 MiB. Key files also
have a 65536-byte cap, paths are below 4096 bytes, local certificate PEM blocks at most
65536 bytes and certificate DER at most 49152 bytes. A peer certificate handshake
message is at most 524288 bytes. Trust certificates are at most 8192 including duplicates; listener
chains at most eight certificates and intermediate CAs at most six. Directory
trust scanning is limited to 16384 entries and 8192 unique regular files.
See [trust discovery and startup failure timing](deployment.en.md).

## Stable recoverable failures

All codes are ASCII and locale-independent. Constructors/helpers/networking
return ordinary recoverable results for the expected failures below. Failures
may occur after a peer has acted; they promise no remote rollback. Unexpected
session host failure cleans up before `serve` returns `http.host_failure`.

| Code / الرمز | Meaning / المعنى |
| --- | --- |
| `http.invalid_argument` | Invalid configuration, range, listener or option combination |
| `http.invalid_url` | Invalid client URL |
| `http.invalid_header` | Invalid or forbidden outgoing header |
| `http.invalid_route` | Invalid method/path or unsupported registration |
| `http.duplicate_route` | Duplicate method/path or second catch-all |
| `http.invalid_response` | Invalid handler status/body/representation metadata |
| `http.invalid_utf8` | Explicit byte/text conversion is not strict UTF-8 |
| `http.invalid_query` | Malformed percent escape |
| `http.query_limit` | Query input bytes or entry count exceeds cap |
| `http.resolve_failed` | Client or listener name resolution failed |
| `http.connect_failed` | TCP establishment or established transport failed |
| `http.tls_verify_failed` | Chain, date, SAN or DNS/IP identity verification failed |
| `http.tls_handshake_failed` | Other TLS negotiation failure |
| `http.ca_load_failed` | Unavailable, malformed, unreadable or oversized trust |
| `http.tls_config_failed` | Invalid server chain/key, encryption or mismatch |
| `http.timeout` | Client total/phase expired while caller stays live |
| `http.cancelled` | Child locally cancelled while caller stays live |
| `http.parse_failed` | Invalid/ambiguous peer syntax, framing or trailers |
| `http.truncated_body` | Length/chunk-framed response ended early |
| `http.unsupported_protocol` | Unsupported wire version, upgrade, tunnel or transfer |
| `http.unsupported_content_encoding` | Enabled decode found stacked/repeated/unsupported coding |
| `http.decode_failed` | Gzip checksum, truncation, member or trailing-garbage failure |
| `http.body_limit` | Sent/received encoded body exceeds cap |
| `http.decoded_body_limit` | Decoded body exceeds cap |
| `http.header_limit` | Header/field/chunk-line/informational cap exceeded |
| `http.target_limit` | URL or request-target exceeds cap |
| `http.resource_limit` | Backend budget or bounded configuration/cache exhausted |
| `http.overloaded` | Client/server admission capacity unavailable |
| `http.redirect_invalid` | Multiple, malformed or unusable Location values |
| `http.redirect_limit` | Next eligible hop exceeds followed-hop cap |
| `http.bind_failed` | No resolved listener address could bind |
| `http.listen_failed` | Bound listener could not start accepting |
| `http.already_started` | Frozen runtime configuration or second/nested serve |
| `http.host_failure` | Unexpected host/session failure after cleanup |

## First-release exclusions

Native HTTP/1.1 only. No browser/private embedding networking, HTTP/2/3,
CONNECT, WebSocket/other upgrade, streaming body API, multipart helpers, SSE,
JSON parsing/serialization, named route parameters, middleware, automatic
cookies/authentication, outbound proxy, automatic IDN conversion, server
compression, certificate hot reload, SNI-based server certificate selection,
client-certificate authentication or automatic cross-origin redirects.

See the [current native proof records](deployment.en.md#evidence-and-release-preparation)
for demonstrated backend eligibility and the remaining final aggregate gate.
