Default maximum request-body size: 1 MiB.
This is one of the finite production defaults used by
default_config.
Server :: # (opaque)
Configure and run an inbound HTTP server.
Server requests deliberately use a different type from outbound
http.Request: their bodies are request-scoped streams instead of complete
byte lists.
init! = || Ok({
config: Server.default_config.with_listen({ host: "127.0.0.1", port: 8080 }),
context: {},
})
respond! = |request, {}| {
body = request.body().with_limit(64 * 1024).read_all!()?
response = Response.from_status(200).with_body(body)
Ok(Server.respond(response))
}
shutdown! = |_, {}| Ok({})
An unhandled semantic error returned by respond! is inspected, logged to
stderr with request context, and converted to a 500 response. Unhandled
init! and shutdown! errors are logged and produce process exit code 1.
Default maximum request-body size: 1 MiB.
This is one of the finite production defaults used by
default_config.
Default maximum chunk delivered by Body.read!:
64 KiB.
Default number of request-body chunks buffered per request.
Default maximum number of concurrently active connections.
Default maximum number of concurrently executing Roc handlers.
Default finite queue capacity for handlers waiting to execute.
default_config : Config
Safe defaults: loopback-only; finite connection, handler, and handler queue limits; a 1 MiB request limit; one buffered 64 KiB chunk; and bounded graceful shutdown. Exceeding the drain deadline forces process exit without running the shutdown hook, because a request handler may still be using the application context.
with_listen : Config, { host : Str, port : U16 } -> Config
Set the listener host and port. The default is loopback-only on port 8000.
with_limits : Config, { max_connections : U32, max_handlers : U16, max_queued_handlers : U16 } -> Config
Set connection, active-handler, and queued-handler capacity together. Saturated handler queues receive 503 responses.
with_request_body_limits : Config, { max_bytes : U64, chunk_bytes : U32, buffered_chunks : U16 } -> Config
Set all finite inbound request-body limits.
with_request_body_limit : Config, U64 -> Config
Set only the maximum total bytes accepted for each request body.
with_graceful_shutdown : Config, { drain_timeout_ms : U64, hook_timeout_ms : U64 } -> Config
Set the request-drain deadline and final shutdown-hook deadline.
respond : Response -> Outcome
Return a response and keep serving requests.
stop_after : Response -> Outcome
Return a final response, then begin graceful shutdown with exit code 0.
stop_after_with_code : Response, I64 -> Outcome
Return a final response, then begin graceful shutdown with the given exit code.
:= [
Config(
{
listen : { host : Str, port : U16 },
limits : {
max_connections : U32,
max_handlers : U16,
max_queued_handlers : U16,
},
request_bodies : {
max_bytes : U64,
chunk_bytes : U32,
buffered_chunks : U16,
},
graceful_shutdown : {
drain_timeout_ms : U64,
hook_timeout_ms : U64,
},
},
),
]
Opaque runtime configuration returned from the application's init!
function. Use the builders below so future server settings can be added
without invalidating application record construction.
to_host : Config -> {
host : Str,
port : U16,
body_max_bytes : U64,
body_chunk_bytes : U32,
body_buffered_chunks : U16,
drain_timeout_ms : U64,
hook_timeout_ms : U64,
max_connections : U32,
max_handlers : U16,
max_queued_handlers : U16,
}
Platform ABI conversion hook; not an application API. Applications
should use default_config and the with_*
builders.
:= [
Body(
{
host_id : U64,
limit_bytes : U64,
content_length : [Unknown, Known(U64)],
},
),
]
A request-scoped inbound body. The host expires this capability when the request handler returns, and permits only one active reader at a time.
to_inspect : Body -> Str
Render a body without exposing its request-scoped host identifier.
Platform ABI conversion hook; not an application API.
The maximum number of bytes this request body may deliver.
content_length : Body -> [Unknown, Known(U64)]
The declared Content-Length, when the request supplied one. The stream still enforces its byte limit independently of this untrusted value.
with_limit : Body, U64 -> Body
Return the same request stream with a stricter total byte limit. Limits may only be narrowed, never widened beyond the server configuration.
Read the next bounded chunk. End is stable and may be observed more than once. Concurrent reads of one body return ConcurrentRead.
Read all remaining bytes while enforcing this body's current limit. Prefer read! for large or incrementally processed payloads.
:= {
method : Method,
headers : List(Header),
target : Str,
body : Body,
}
An inbound server request. Its body is always streaming; use
Body.read_all! only when a bounded complete
body is appropriate.
:= [
Respond(Response),
StopAfter({ response : Response, exit_code : I64 }),
]
A successful request outcome. StopAfter sends its response while beginning graceful shutdown; the first shutdown cause wins.
ShutdownReason : [
ApplicationRequested,
Interrupt,
Terminate,
StartupFailed(Str),
RuntimeFailed(Str),
]
Why the server is invoking the application's final shutdown hook.