zena:http

zena
import {…} from 'zena:http';

HTTP server and middleware library for Zena.

Provides an Express-like, Zipadee-inspired HTTP framework targeting WebAssembly GC components implementing wasi:http.

Classes

App

zena
class App
Re-exported from zena:http/app.zena

An HTTP application managing a middleware pipeline.

Examples ​

zena
import { App } from 'zena:http';

export async function main(): Future<void> {
  let app = new App();

  app.use(async (req, res, next) => {
    res.body = 'Hello, world!';
  });

  let server = await app.listen(8080);
  console.log(`Listening on http://127.0.0.1:${server.port}`);
  await server.done;
}
Constructors
zena
new(options: AppOptions | null = null)
#
Methods
zena
use(middleware: Middleware): void
#

Adds a middleware to the application pipeline.

zena
async handleRequest(req: Own<Request>, res: Response): Future<void>
#

Directly dispatches a Request and Response through the application pipeline.

Catches thrown HttpError instances and translates them to HTTP status codes and responses. Any uncaught general Error results in a 500 Internal Server Error.

zena
handle(wireRequest: Own<WireRequest>): Future<Result<Own<WireResponse>, ErrorCode>>
#

Dispatches a WASI wasi:http/types request through the application pipeline and returns the wire response.

zena
async listen(port: u16 = as u16): Future<Own<Server>>
#

Binds an HTTP server on 127.0.0.1:{port} (or an ephemeral port when port is 0) and starts the accept loop in the background.

Returns a future of the server's owner, which resolves once the listener is bound, or rejects if binding fails (such as when port is already in use). The owner closes the server when it leaves scope: hold it for as long as the server should run (await server.done), or call keepOpen() to run it until close(). Cancelling the enclosing CancelScope closes the server and releases its socket.

AppOptions

zena
class AppOptions
Re-exported from zena:http/app.zena

Configuration options for the HTTP App.

Properties
zena
var dev: boolean
#

If true, include error details in responses when errors are thrown.

WireRequest

zena
resource class Request extends Resource
Extends Resource
Re-exported from wit:packages/stdlib/zena/wit#wasi:http/types

WIT resource request.

Constructors
zena
new(handle: i32)
#
Methods
zena
static new_(headers: Own<Fields>, contents: Option<Stream<u8>>, trailers: Future<Result<Option<Own<Fields>>, ErrorCode>>, options: Option<Own<RequestOptions>>): (Own<Request>, Future<Result<void, ErrorCode>>)
#
zena
getMethod(): Method
#
zena
setMethod(method: Method): boolean
#
zena
getPathWithQuery(): Option<String>
#
zena
setPathWithQuery(pathWithQuery: Option<String>): boolean
#
zena
getScheme(): Option<Scheme>
#
zena
setScheme(scheme: Option<Scheme>): boolean
#
zena
getAuthority(): Option<String>
#
zena
setAuthority(authority: Option<String>): boolean
#
zena
getOptions(): Option<Own<RequestOptions>>
#
zena
getHeaders(): Own<Fields>
#
zena
static consumeBody(this_: Own<Request>, res: Future<Result<void, ErrorCode>>): (Stream<u8>, Future<Result<Option<Own<Fields>>, ErrorCode>>)
#

WireResponse

zena
resource class Response extends Resource
Extends Resource
Re-exported from wit:packages/stdlib/zena/wit#wasi:http/types

WIT resource response.

Constructors
zena
new(handle: i32)
#
Methods
zena
static new_(headers: Own<Fields>, contents: Option<Stream<u8>>, trailers: Future<Result<Option<Own<Fields>>, ErrorCode>>): (Own<Response>, Future<Result<void, ErrorCode>>)
#
zena
getStatusCode(): u16
#
zena
setStatusCode(statusCode: u16): boolean
#
zena
getHeaders(): Own<Fields>
#
zena
static consumeBody(this_: Own<Response>, res: Future<Result<void, ErrorCode>>): (Stream<u8>, Future<Result<Option<Own<Fields>>, ErrorCode>>)
#

ErrorCode

zena
sealed class ErrorCode
Re-exported from wit:packages/stdlib/zena/wit#wasi:http/types

WIT variant error-code.

Variants
zena
case ErrorCodeDNSTimeout
#
zena
case ErrorCodeDNSError(value: DNSErrorPayload)
#
zena
case ErrorCodeDestinationNotFound
#
zena
case ErrorCodeDestinationUnavailable
#
zena
case ErrorCodeDestinationIPProhibited
#
zena
case ErrorCodeDestinationIPUnroutable
#
zena
case ErrorCodeConnectionRefused
#
zena
case ErrorCodeConnectionTerminated
#
zena
case ErrorCodeConnectionTimeout
#
zena
case ErrorCodeConnectionReadTimeout
#
zena
case ErrorCodeConnectionWriteTimeout
#
zena
case ErrorCodeConnectionLimitReached
#
zena
case ErrorCodeTLSProtocolError
#
zena
case ErrorCodeTLSCertificateError
#
zena
case ErrorCodeTLSAlertReceived(value: TLSAlertReceivedPayload)
#
zena
case ErrorCodeHTTPRequestDenied
#
zena
case ErrorCodeHTTPRequestLengthRequired
#
zena
case ErrorCodeHTTPRequestBodySize(value: Option<u64>)
#
zena
case ErrorCodeHTTPRequestMethodInvalid
#
zena
case ErrorCodeHTTPRequestURIInvalid
#
zena
case ErrorCodeHTTPRequestURITooLong
#
zena
case ErrorCodeHTTPRequestHeaderSectionSize(value: Option<u32>)
#
zena
case ErrorCodeHTTPRequestHeaderSize(value: Option<FieldSizePayload>)
#
zena
case ErrorCodeHTTPRequestTrailerSectionSize(value: Option<u32>)
#
zena
case ErrorCodeHTTPRequestTrailerSize(value: FieldSizePayload)
#
zena
case ErrorCodeHTTPResponseIncomplete
#
zena
case ErrorCodeHTTPResponseHeaderSectionSize(value: Option<u32>)
#
zena
case ErrorCodeHTTPResponseHeaderSize(value: FieldSizePayload)
#
zena
case ErrorCodeHTTPResponseBodySize(value: Option<u64>)
#
zena
case ErrorCodeHTTPResponseTrailerSectionSize(value: Option<u32>)
#
zena
case ErrorCodeHTTPResponseTrailerSize(value: FieldSizePayload)
#
zena
case ErrorCodeHTTPResponseTransferCoding(value: Option<String>)
#
zena
case ErrorCodeHTTPResponseContentCoding(value: Option<String>)
#
zena
case ErrorCodeHTTPResponseTimeout
#
zena
case ErrorCodeHTTPUpgradeFailed
#
zena
case ErrorCodeHTTPProtocolError
#
zena
case ErrorCodeLoopDetected
#
zena
case ErrorCodeConfigurationError
#
zena
case ErrorCodeInternalError(value: Option<String>)
#

Fields

zena
resource class Fields extends Resource
Extends Resource
Re-exported from wit:packages/stdlib/zena/wit#wasi:http/types

WIT resource fields.

Constructors
zena
new(handle: i32)
#
Methods
zena
static create(): Own<Fields>
#
zena
static fromList(entries: Array<(String, FixedArray<u8>)>): inline Result<Own<Fields>, HeaderError>
#
zena
get(name: String): Array<FixedArray<u8>>
#
zena
has(name: String): boolean
#
zena
set(name: String, value: Array<FixedArray<u8>>): inline Result<void, HeaderError>
#
zena
delete(name: String): inline Result<void, HeaderError>
#
zena
getAndDelete(name: String): inline Result<Array<FixedArray<u8>>, HeaderError>
#
zena
append(name: String, value: FixedArray<u8>): inline Result<void, HeaderError>
#
zena
copyAll(): Array<(String, FixedArray<u8>)>
#
zena
clone(): Own<Fields>
#

Request

zena
resource class Request extends Resource
Extends Resource
Re-exported from zena:http/request.zena

Represents an incoming HTTP request.

Provides typed access to the method, URL, headers, and body stream, as well as a mutable path property used by routers and prefix mounting.

A resource class, held as Own<Request>: a handler owns the request it is given and hands it on with next(req), so whoever holds it last reads or releases its body. Reading the body consumes the request (text, bytes, body); read anything else you need from it first. A request dropped with its body unread releases the wire request, and with it the body the host holds.

Constructors
zena
new(url: URL, method: String = 'GET', headers: HashMap<String, GrowableArray<String>> = new HashMap<String, GrowableArray<String>>(), bodyStream: Stream<u8> | null = null)
#

Constructs a Request with explicit parameters.

zena
new fromUrl(urlString: String, method: String = 'GET', headers: Map<String, String> | null = null, bodyStream: Stream<u8> | null = null)
#

Constructs a Request from a string URL and optional headers.

zena
new fromWire(wire: Own<WireRequest>)
#

Constructs a Request over an incoming wasi:http request, which it reads from as its members are asked for.

Properties
zena
var bodyLimit: i64
#

The most bytes text() and bytes() read of the body, or -1 for no limit. A body over it is refused with an HttpError of 413, which App answers: one whose Content-Length is over it before anything is read, and one that does not say once it passes it. A server sets it before its handlers read, and a handler that takes more raises it.

zena
method: String { get; }
#

The HTTP method in uppercase ('GET', 'POST', 'PUT', etc.).

zena
url: URL { get; }
#

The request URL.

zena
path: String { get; set; }
#

The request path, defaults to url.pathname or '/'.

Middleware like mount() or routers can rewrite path to represent the current subpath within a mounted handler hierarchy.

zena
origin: String { get; }
#

The origin of the request URL (e.g. "https://example.com:8080").

zena
protocol: String { get; }
#

The protocol of the request URL without the trailing colon (e.g. "http", "https").

zena
host: String { get; }
#

The Host of the request.

zena
query: String { get; }
#

The query string including the leading '?', or empty if none.

Methods
zena
getHeader(name: String): String | null
#

Returns the first value of the header with the given name, or null if absent.

zena
getHeaders(name: String): Array<String>
#

Returns all values of the header with the given name.

zena
hasHeader(name: String): boolean
#

Returns true if the header with the given name is present.

zena
headerNames(): Array<String>
#

Returns all header names present in the request.

zena
body(): Stream<u8>
#

The body stream. Consumes the request.

zena
text(): Future<String>
#

Reads and decodes the full request body as text, within bodyLimit. Consumes the request.

zena
bytes(): Future<FixedArray<u8>>
#

Reads the full request body as bytes, within bodyLimit. Consumes the request.

Response

zena
class Response
Re-exported from zena:http/response.zena

Represents an HTTP response being built by server middleware.

Defaults to status code 404 until a body or status code is set. Setting body automatically updates statusCode to 200 if it was not explicitly set beforehand.

Properties
zena
hasCustomHeaders: boolean { get; }
#

True if custom headers (other than the fast-path content-type) have been set.

zena
contentTypeHeader: String | null { get; }
#

Fast-path content-type header value if set without custom multi-value headers.

zena
statusCode: i32 { get; set; }
#

The HTTP status code.

zena
statusCodeSet: boolean { get; }
#

Whether the status code was explicitly set.

zena
body: ResponseBody { get; set; }
#

The response body.

zena
type: String | null { get; set; }
#

The Content-Type header.

zena
length: Option<i32> { get; set; }
#

The Content-Length header as an integer, or none if absent.

Methods
zena
setHeader(name: String, value: String): void
#

Sets a response header, replacing any previous values for this header.

zena
appendHeader(name: String, value: String): void
#

Appends a value to a response header without removing previous values.

zena
setCookie(name: String, value: String, options: CookieOptions = {}): void
#

Sets the cookie name to value, with the attributes options gives, in a Set-Cookie header of its own (serializeCookie).

zena
clearCookie(name: String, path: String = '/', domain: String | null = null): void
#

Tells the browser to drop the cookie name: an empty value that expires at once. path and domain must be the ones it was set with, or the browser keeps it.

zena
getHeader(name: String): String | null
#

Returns the first value of a response header, or null if absent.

zena
getHeaders(name: String): Array<String>
#

Returns all values of a response header.

zena
hasHeader(name: String): boolean
#

Returns true if the response header is present.

zena
removeHeader(name: String): void
#

Removes a response header.

zena
headerNames(): Array<String>
#

Returns all header names currently set on this response.

zena
forEachHeader(fn: (name: String, value: String) => void): void
#

Calls fn(name, value) for each custom header entry on this response.

zena
setLength(value: i32): void
#

Sets Content-Length header.

zena
redirect(url: String, alt: String = '/'): void
#

Performs an HTTP redirect.

Sets the Location header to url. If the current status code is not a 3xx redirect status (300-399), it defaults to 302.

HttpError

zena
class HttpError extends Error
Extends Error
Re-exported from zena:http/error.zena

An Error class for HTTP errors that includes a status code and an optional private message for server-side logging.

Constructors
zena
new(message: String | null = null)
#
Properties
zena
status: i32
#
zena
privateMessage: String | null
#
2 inherited members
From Error
Properties
zena
message: String
#
Methods
zena
getStackTrace(): String | null
#

Router

zena
class Router
Re-exported from zena:http/router.zena

A router that matches requests by HTTP method and URL path pattern.

Supports named parameters (:id) and wildcards (*).

Examples ​

zena
let router = new Router();

router.get('/users', async (req, res, next, params) => {
  res.body = 'Users list';
});

router.get('/users/:id', async (req, res, next, params) => {
  let id = params['id'] ?? 'unknown';
  res.body = 'User ' + id;
});

app.use(router.routes());
Methods
zena
all(pattern: String, handler: RouteHandler): void
#

Registers a route for any HTTP method.

zena
get(pattern: String, handler: RouteHandler): void
#

Registers a GET route.

zena
post(pattern: String, handler: RouteHandler): void
#

Registers a POST route.

zena
put(pattern: String, handler: RouteHandler): void
#

Registers a PUT route.

zena
delete(pattern: String, handler: RouteHandler): void
#

Registers a DELETE route.

zena
patch(pattern: String, handler: RouteHandler): void
#

Registers a PATCH route.

zena
routes(): Middleware
#

Returns a Middleware function that dispatches matching routes.

Server

zena
resource class Server extends Resource
Extends Resource
Re-exported from zena:http/server.zena

A running HTTP server.

A resource class, held as Own<Server>: its owner closes it when it leaves scope, so the server runs for as long as something holds it. await server.done holds it until it closes. keepOpen() trades the owner for a handle that keeps it running until close(), which an ordinary object can store.

Constructors
zena
new(app: App, port: u16)
#

Binds the listener; start runs the accept loop.

Properties
zena
port: u16 { get; }
#

The port this server is listening on.

zena
isOpen: boolean { get; }
#

True if the server is still open.

zena
done: Future<void> { get; }
#

Future that completes when the server is closed or stops running.

zena
isDone: boolean { get; }
#

True if the server has finished running and is closed.

Methods
zena
close(): void
#

Closes the server and releases its socket.

zena
keepOpen(): Unmanaged<Server>
#

Keeps the server running after its owner's scope ends: the handle this returns never closes it implicitly, and an ordinary class or record can store it. The server then runs until close(), or until the scope it was started in is cancelled.

zena
start(): void
#

Runs the accept loop in the background, once.

HTMLPartial

zena
final class HTMLPartial implements AsyncIterable<String>
Implements AsyncIterable<String>
Re-exported from zena:http/html.zena

Represents a partial HTML template result that can be rendered with interpolated values. It supports indentation, nested templates, iterables of values, futures, and HTML escaping of values.

The toString() method returns the rendered HTML as a string, propagating the indentation level. If the template contains a Future, toString() throws AsyncInSyncIteration; consume async templates with for await, collectResult, pipeToStream, or htmlStream.

To support streaming HTTP and hybrid sync/async iteration, HTMLPartial is an AsyncIterable<String> whose iterator yields Ready steps synchronously for string chunks and Pending steps only when awaiting a Future.

Constructors
zena
new()
#
Properties
zena
strings: TemplateStringsArray
#
zena
values: FixedArray<TemplateValue>
#
Methods
zena
toString(indent: i32 = 0): String
#
zena
appendTo(sb: StringBuilder, indent: i32 = 0): void
#

HTMLIterator

zena
final class HTMLIterator implements AsyncIterator<String>
Implements AsyncIterator<String>
Re-exported from zena:http/html.zena

Hybrid sync/async iterator over an HTMLPartial that yields AsyncStep<String>: Ready (1, chunk, _) synchronously for strings, Pending (2, _, future) when awaiting an interpolated Future<TemplateValue>, and Done (0, _, _) when exhausted.

Constructors
zena
new(partial: HTMLPartial)
#
Methods
zena
next(): AsyncStep<String>
#

UnsafeHTML

zena
final class UnsafeHTML
Re-exported from zena:http/html.zena

Represents a value that should be rendered as raw HTML without escaping.

Constructors
zena
new()
#
Properties
zena
value: String
#

Type aliases

ResponseBody

zena
type ResponseBody = String | FixedArray<u8> | Stream<u8> | HTMLPartial | null
Re-exported from zena:http/response.zena

Valid body representations for a response.

Middleware

zena
type Middleware = (req: Own<Request>, res: Response, next: NextFunction) => Future<void>
Re-exported from zena:http/middleware.zena

A middleware function handling an HTTP request and response pair.

The middleware owns the request: it hands it on with next(req), or answers itself and drops it. After next(req) the request is the downstream middleware's, so read what you need from it first; a second next(req), or any use of req after it, is a compile error.

NextFunction

zena
type NextFunction = (req: Own<Request>) => Future<void>
Re-exported from zena:http/middleware.zena

A callback function invoked by middleware to pass control, and the request, to the downstream middleware.

RouteHandler

zena
type RouteHandler = (req: Own<Request>, res: Response, next: NextFunction, params: Map<String, String>) => Future<void>
Re-exported from zena:http/router.zena

Route handler callback receiving the request, response, downstream next function, and extracted path parameters. The handler owns the request, as a middleware does: next(req) hands it to the next matching route.

SendOptions

zena
type SendOptions = {root?: String, index?: String | null, maxAge?: Duration, immutable?: boolean, hidden?: boolean, brotli?: boolean, gzip?: boolean, format?: boolean, extensions?: Array<String>, notFound?: String, setHeaders?: (res: Response, path: String, stat: FileStat) => void}
Re-exported from zena:http/static.zena

Options for send and serve. Every field is optional.

CookieOptions

zena
type CookieOptions = {maxAge?: Duration, path?: String, domain?: String, secure?: boolean, httpOnly?: boolean, sameSite?: String}
Re-exported from zena:http/cookie.zena

A cookie's attributes, for serializeCookie and Response.setCookie.

CorsOptions

zena
type CorsOptions = {origin?: Origin, allowMethods?: String | Iterable<String> | null, allowHeaders?: String | Iterable<String>, secureContext?: boolean, exposeHeaders?: String | Iterable<String>, maxAge?: Duration, credentials?: boolean, credentialsFor?: CredentialsFn}
Re-exported from zena:http/cors.zena

Options for cors. Every field is optional.

Origin

zena
type Origin = String | null | OriginFn
Re-exported from zena:http/cors.zena

An origin specification: a static origin string, null to disable CORS, or a per-request callback.

OriginFn

zena
type OriginFn = (req: Borrow<Request>) => String | null | Future<String | null>
Re-exported from zena:http/cors.zena

Callback returning the allowed origin for a request, or null to disable CORS for that request. May return synchronously or as a Future. It borrows the request, so an async callback reads it before its first await.

CredentialsFn

zena
type CredentialsFn = SyncCredentialsFn | AsyncCredentialsFn
Re-exported from zena:http/cors.zena

Callback deciding whether credentials are allowed for a request.

SyncCredentialsFn

zena
type SyncCredentialsFn = (req: Borrow<Request>) => boolean
Re-exported from zena:http/cors.zena

Synchronous callback deciding whether credentials are allowed for a request.

AsyncCredentialsFn

zena
type AsyncCredentialsFn = (req: Borrow<Request>) => Future<boolean>
Re-exported from zena:http/cors.zena

Asynchronous callback deciding whether credentials are allowed for a request.

TemplateValue

zena
type TemplateValue = String | HTMLPartial | UnsafeHTML | null | Iterable<TemplateValue> | Future<TemplateValue>
Re-exported from zena:http/html.zena

Values that may be interpolated into an html template.

PipeOptions

zena
type PipeOptions = {flushSize?: i32}
Re-exported from zena:http/html.zena

Options for pipeToStream.

Functions

fromWireRequest

zena
function fromWireRequest(wire: Own<WireRequest>): Own<Request>
Re-exported from zena:http/wasi.zena

Creates a Request from a low-level WASI HTTP Request resource.

toWireResponse

zena
function toWireResponse(res: Response): Own<WireResponse>
Re-exported from zena:http/wasi.zena

Converts a Response into a low-level WASI WireResponse resource.

handleWireRequest

zena
async function handleWireRequest(app: App, wire: Own<WireRequest>): Future<Result<Own<WireResponse>, ErrorCode>>
Re-exported from zena:http/wasi.zena

Dispatches an incoming WASI wire request through an App's middleware pipeline.

textResponse

zena
function textResponse(body: String, status: i32 = 200, contentType: String = 'text/plain; charset=utf-8'): Own<WireResponse>
Re-exported from zena:http/wasi.zena

Builds a low-level wire response carrying body as text.

requestText

zena
async function requestText(request: Own<WireRequest>): Future<String>
Re-exported from zena:http/wasi.zena

Reads a wire request's body to the end and decodes it as text.

bytesStream

zena
function bytesStream(bytes: FixedArray<u8>): Stream<u8>
Re-exported from zena:stream/index.zena

A byte stream carrying bytes, then end-of-stream: a response or request body, or a file's new contents, built from bytes in hand.

compose

zena
function compose(middleware: Array<Middleware>): Middleware
Re-exported from zena:http/middleware.zena

Composes an array of middleware functions into a single middleware.

Middleware executes in the order given, unwinding in reverse order as downstream futures resolve (the onion model).

mount

zena
function mount(prefix: String, middleware: Middleware): Middleware
Re-exported from zena:http/middleware.zena

Mounts middleware at a URL path prefix.

If req.path starts with prefix, req.path is rewritten to the matched subpath before middleware runs, and restored when it passes the request on with next(req). If req.path does not start with prefix, middleware is bypassed and next(req) is called.

matchPath

zena
function matchPath(prefix: String, path: String): String | null
Re-exported from zena:http/middleware.zena

Checks if path starts with prefix and returns the subpath.

Returns null if path does not start with prefix.

Examples ​

zena
matchPath('/prefix', '/prefix')       // => '/'
matchPath('/prefix/', '/prefix')      // => null
matchPath('/prefix', '/prefix/users') // => '/users'
matchPath('/prefix/', '/prefix/users')// => '/users'
matchPath('/prefix', '/other')        // => null

statusText

zena
function statusText(status: i32): String
Re-exported from zena:http/error.zena

Standard HTTP status code text lookup.

send

zena
function send(req: Borrow<Request>, res: Response, path: String, options: SendOptions = {}): Future<String | null>
Re-exported from zena:http/static.zena

The directory files are served from. The working directory if absent. serve takes the root as its own argument and ignores this one.

The file to serve for a path naming a directory. None if absent for send; index.html if absent for serve. Null turns it off.

Cache-Control max-age. Zero if absent.

Add immutable to Cache-Control: the file at this URL never changes. Off if absent.

Serve paths with a segment that starts with a dot. Off if absent: such paths are passed over, as if missing.

Serve <file>.br with Content-Encoding: br when it exists and the client accepts brotli. On if absent.

Serve <file>.gz likewise, for gzip. On if absent.

Serve the index file for a directory named without a trailing slash, as well as with one. On if absent.

Extensions to try, in order, for a path whose last segment has no extension: ['html'] serves /about from about.html. None if absent.

The file under root to serve with status 404 when serve finds no matching file and next leaves the response unhandled. Ignored by send.

Called with the response, the file's path and its metadata before the default headers are set, so headers it sets win.

Sends the file at path, relative to options.root, as the response: sets the status, Content-Type, Content-Length, Last-Modified, ETag, Cache-Control and X-Content-Type-Options, and the file as the body. Answers a matching If-None-Match with 304 and a HEAD request without a body.

Returns the path served, relative to the preopen it is under, or null when nothing was sent: a hidden path, or a directory with no index to serve. A missing file throws HttpError(404), and a path that climbs out of the root throws HttpError(403).

Examples ​

zena
app.use(async (req, res, next) => {
  if (req.path == '/hello') {
    await send(req, res, 'hello.html', {root: 'pages'});
  } else {
    await next(req);
  }
});

serve

zena
function serve(root: String, options: SendOptions = {}): Middleware
Re-exported from zena:http/static.zena

Middleware that serves the files under root for GET and HEAD requests, at req.path (so under mount, at the path below the mount point). A request it does not answer — another method, a missing or hidden file — goes on to next. When options.notFound is set and next leaves a GET or HEAD request unhandled, serves that file under root with status 404.

Examples ​

zena
let app = new App();
app.use(serve('public', {notFound: '404.html'}));
app.use(mount('/assets', serve('dist', {maxAge: milliseconds(86400000)})));

httpDate

zena
function httpDate(epochSeconds: i64): String
Re-exported from zena:http/static.zena

An HTTP date (RFC 9110 IMF-fixdate) for seconds since the Unix epoch: Tue, 13 Oct 2026 15:16:23 GMT. Times before the epoch are given as the epoch.

mimeType

zena
function mimeType(path: String): String | null
Re-exported from zena:http/mime.zena

The Content-Type for a file, from its extension (case-insensitive), or null for an extension not listed. Text types carry charset=utf-8.

Examples ​

zena
mimeType('index.html')    // 'text/html; charset=utf-8'
mimeType('logo.SVG')      // 'image/svg+xml'
mimeType('archive.xyz')   // null

parseCookies

zena
function parseCookies(header: String | null): HashMap<String, String>
Re-exported from zena:http/cookie.zena

How long the browser keeps the cookie, in whole seconds (Max-Age). Absent: until the browser's session ends.

The paths the browser sends it for (Path). The host and subdomains it is sent to (Domain). Absent: the origin's host only. Sent only over HTTPS (Secure). Hidden from the page's script (HttpOnly). Strict, Lax or None (SameSite).

The cookies in a Cookie header, by name. A value in double quotes loses them; values are otherwise as sent, with no decoding. When a name comes twice, the first wins: browsers send the cookie with the longest path first. Pairs without = are skipped.

serializeCookie

zena
function serializeCookie(name: String, value: String, options: CookieOptions = {}): String
Re-exported from zena:http/cookie.zena

A Set-Cookie header's value: name=value and the attributes options gives. Throws when name is not a token, value has a byte a cookie may not, or an attribute would break the header, so that nothing a caller passes can add an attribute of its own.

cors

zena
function cors(options: CorsOptions = {}): Middleware
Re-exported from zena:http/cors.zena

Middleware that sets Cross-Origin Resource Sharing (CORS) headers on responses and answers preflight OPTIONS requests.

Examples ​

zena
let app = new App();
app.use(cors());

html

zena
function html(strings: TemplateStringsArray, values: FixedArray<TemplateValue>): HTMLPartial
Re-exported from zena:http/html.zena

A template tag function that accepts an HTML string.

Interpolated values are escaped by default so that they are not interpreted as HTML. To interpolate a value as raw HTML, use unsafeHTML.

unsafeHTML

zena
function unsafeHTML(s: String): UnsafeHTML
Re-exported from zena:http/html.zena

Wraps a string in an UnsafeHTML object, which indicates that the string should be rendered as raw HTML without escaping.

escape

zena
function escape(str: String): String
Re-exported from zena:http/html.zena

Replaces characters which have special meaning in HTML (&<>"') with escaped HTML entities (&amp;, &lt;, &gt;, &quot;, &apos;).

pipeToStream

zena
async function pipeToStream(partial: HTMLPartial, writer: StreamWriter<u8>, options: PipeOptions = {}): Future<void>
Re-exported from zena:http/html.zena

Writes an HTMLPartial to a StreamWriter<u8>.

If flushSize is positive, small string chunks are buffered until at least flushSize bytes have accumulated, at which point they are written to the stream. Buffered chunks are always flushed before awaiting a Future, so the reader receives the HTML prefix immediately while async work is pending.

Does not call writer.close() when done, matching Zipadee's pipeToWritable.

htmlStream

zena
function htmlStream(partial: HTMLPartial, flushSize: i32 = 1024): Stream<u8>
Re-exported from zena:http/html.zena

Creates a Stream<u8> that streams the rendered bytes of partial.

Uses a default flushSize of 1024 bytes (slightly below typical Ethernet MTU) and always flushes before awaiting any embedded Future.

collectResult

zena
async function collectResult(result: AsyncIterable<String>): Future<String>
Re-exported from zena:http/html.zena

Joins an AsyncIterable<String> (such as an HTMLPartial) into a single String, awaiting any pending chunks.