HTTP API, limits and errors
ASPL 0.7.0 · Current release
Published native 0.7.0 signatures, message limits, handlers, session owners, snapshots and recoverable failures.
On this page
Native serving and session owners
Native only, published ASPL 0.7.0. Read the HTTP guide, example collection and native requirements. Browser and private embedding reject HTTP before execution with unsupported-supplied-library-profile.
serve drives handlers until shutdown and returns result<unit> after releasing its server and child work. start instead completes startup and returns result<Session<C,S>>. Its listeners are ready when it succeeds. Handlers run only when the application calls progress; transport maintenance during input or drawing dispatches no source handlers. progress obeys ProgressBudget, not an unlimited event loop. A validated network attempt freezes configure, and one validated serving attempt consumes the execution's only serving slot even if bind or TLS startup later fails. Pure validation refusals leave that slot and configuration available. Client calls work before, inside and after serving.
Session<C,S> / جلسة<C,S> is an opaque managed owner. Copies share one native resource and shared close. It can be retained in application values but cannot enter configuration/state type arguments at any depth. There is no constructor, public field, equality, or ordinary foreign conversion. Losing the last reachable alias closes its resource; execution termination revokes owners too. Native storage remains charged until cleanup reaches quiescence. Configuration/state copies retain the same managed handles, not cloned mutable native resources.
Application-only operations are start, progress, stop_session, close_session, session_config, session_state, replace_session_state, snapshot_session_state and replace_session_state_if_current. Handler-only operations take the invocation's Context: read_config, read_state, replace_state, snapshot_state, replace_state_if_current, stop and check_response. The checker rejects application-only calls on a handler path, even through helpers. Context expires when its invocation ends and cannot escape or enter aggregates. In Raylib programs, configure/request/serve/start/progress/stop/close are outside-frame operations; the copied application state/config helpers are frame-allowed. An active frame returns http.invalid_order for forbidden calls. Invalid application context returns http.invalid_context.
SessionStatus / حالة_جلسة has SESSION_RUNNING / جلسة_تعمل, SESSION_DRAINING / جلسة_تستكمل_الإغلاق and SESSION_CLOSED / جلسة_مغلقة. stop_session requests drain; continue calling progress until closed. close_session revokes and releases the owner, invalidating every alias. Normal closed progress reports closed, repeated stop/close succeeds, and closed state/config helpers return http.closed_session. A safely released host failure remains latched. Terminal cleanup failure is not a recoverable result.
read_state and session_state return copied values. Mutating them publishes nothing. Unconditional replace_state or replace_session_state replaces the whole state. StateSnapshot<S> / لقطة_حالة<S> has one read-only value / قيمة field plus hidden session/version identity. Snapshot values survive close but grant no Context authority. Every successful publication advances the version. Conditional replacement returns successful true for a current snapshot, successful false for a stale same-session snapshot, or failed http.invalid_argument for a foreign-session snapshot. A read, outbound wait and replacement are not atomic; use conditional publication to detect changes across a wait. See the session example.
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 come from the reviewed public declaration catalog. 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.
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> |
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 validated serve or start attempt,
including failed startup after validation, 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 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.
Configuration and startup
Use configure(RuntimeConfig) before the first validated network attempt. Invalid ranges or idle_client_connections > outbound_connections return http.invalid_argument without freezing settings. Validated client/serving attempts freeze settings even if transport startup fails; later configuration returns http.already_started. Helpers and offline check/build do not initialize HTTP. Options, listeners and application configuration are copied, not live mutable settings.
Listener::tls=false requires empty certificate/key paths; true requires both nonempty paths. A listener port is 1..65535, and IPv6 listeners are IPv6-only. Validated serve/start consumes the execution's one serving slot. Startup failure releases already-created listeners and work before returning its stable code. Correct the inputs and start a new execution. See deployment configuration and the limits example.
Default and private trust
Default ClientOptions selects host CA discovery, with use_private_ca=false and empty ca_file. use_private_ca=true requires a nonempty private PEM CA path and replaces the host store. Invalid flag/path combinations give http.invalid_argument. Unavailable, malformed, unreadable or oversized selected trust gives http.ca_load_failed before connecting; loaded but unrelated trust gives http.tls_verify_failed during verification. These choices never disable chain, date or identity checks.
The first existing default bundle is authoritative. A bad selected bundle does not fall through, and SSL_CERT_FILE/SSL_CERT_DIR do not override discovery. When no candidate bundle exists, bounded directory discovery applies. Successfully parsed trust is pinned for the execution. See the exact discovery order and local preparation; do not infer that every host trust layout works.
Context-bound upstream requests
request(ClientRequest, ClientOptions) inside a handler requires its live request frame. read_config(ctx) returns the serving application's copied configuration; in the service family, it supplies the upstream URL and explicit CA path. A server's incoming certificate/key is independent of its outgoing trust. The checked handler forwards status and body bytes deliberately, without copying compressed peer representation metadata.
Complete 404/500 responses remain successful client results. Recoverable child failure reaches a live parent as an ordinary result; the sample maps its stable code to a 502 body. Parent expiry, detected disconnect or drain expiry revokes child work and discards late handler output/publication rather than delivering a failed result into the cancelled handler. Child deadlines cannot extend the parent deadline. There is no automatic retry, outbound proxy or rollback of peer effects. Follow the complete TLS upstream exercise.
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.
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 or start |
http.host_failure |
Unexpected host/session failure after cleanup |
http.closed_session |
Application state/config access after shared close |
http.invalid_context |
Operation outside its permitted application context |
http.invalid_order |
Outside-frame operation during an active drawing frame |
Current 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.
Use the current deployment guide for the published native 0.7.0 workflows. The earlier raw deployment source (opens in a new tab) retains its earlier release scope.