http
js/net/http.ts
fino:net/http — public HTTP API barrel.
This module gathers the stable public HTTP APIs: server helpers (serve,
serveHttp), reusable clients (HttpClient, HttpSession, HttpResponse),
application routing (App), Server-Sent Events (EventSource), WebSockets
(WebSocket, WebSocketConnection), WebTransport, and raw request/response
parse and serialize helpers (parseRequest, serializeResponse, and the
Arena backing them). Fetch-compatible Headers, Request, and Response
are globals and are not re-exported here. Protocol drivers and implementation
modules live behind internal:net/http/*.
Import from this barrel when you want the ergonomic entry points without
reaching into a specific submodule; the same symbols are also available from
their home modules (fino:net/http/server, fino:net/http/client,
fino:net/http/app, and so on) when a narrower import is preferable. All the
named exports here are re-exports — the symbols are documented in the module
that defines them.
import { serveHttp, HttpClient, App } from 'fino:net/http';
// A minimal server: every request gets the same JSON response.
const server = serveHttp({ port: 3000 }, (request) =>
Response.json({ method: request.method, url: request.url }));
// A pooled client for making outbound requests.
const client = new HttpClient();
const res = await client.fetch('http://127.0.0.1:3000/health');
console.log(res.status, await res.json());
// A routed application when you need middleware and OpenAPI.
const app = new App({ name: 'Example' });
app.get('/hello').handle(() => new Response('hi'));
app.listen({ port: 3001 });
await server.close();
Learn more:
- Fetch: https://fetch.spec.whatwg.org/
- HTTP semantics: https://www.rfc-editor.org/rfc/rfc9110
- Server-Sent Events: https://html.spec.whatwg.org/multipage/server-sent-events.html
- WebSocket: https://websockets.spec.whatwg.org/
- WebTransport: https://w3c.github.io/webtransport/
Types
type HttpMethod = 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE' | 'HEAD' | 'OPTIONS'
Re-exported from app.HttpMethod.
type Middleware = (ctx: HttpContext) => HttpHandlerResult | void | Promise<HttpHandlerResult | void>
Re-exported from app.Middleware.
type LayerMiddleware = (
ctx: HttpContext,
next: (
) => Promise<HttpHandlerResult>
) => HttpHandlerResult | void | Promise<HttpHandlerResult | void>
Re-exported from app.LayerMiddleware.
type Handler = (ctx: HttpContext) => HttpHandlerResult | Promise<HttpHandlerResult>
Re-exported from app.Handler.
type WebSocketHandler = (socket: WebSocketConnection, ctx: WebSocketContext) => void | Promise<void>
Re-exported from app.WebSocketHandler.
type WebTransportHandler = (session: WebTransport, ctx: WebTransportContext) => void | Promise<void>
Re-exported from app.WebTransportHandler.
type SseHandler = (events: EventSourceWriter, ctx: SseContext) => void | Promise<void>
Re-exported from app.SseHandler.
type Producer = (ctx: HttpContext) => unknown | Promise<unknown>
Re-exported from app.Producer.
type HttpHandlerResult = Response | WebSocketConnection | WebTransport
Re-exported from js/net/http/server.HttpHandlerResult.
type HttpClientProtocol = 'http/1.1' | 'h2' | 'h3'
Re-exported from js/net/http/client.HttpClientProtocol.
type HttpClientTransport = 'tcp' | 'tls' | 'quic'
Re-exported from js/net/http/client.HttpClientTransport.
type HttpHeadersInit = Headers | string[][] | Record<string, string> | null | undefined
Re-exported from js/net/http/client.HttpHeadersInit.
type HttpSessionEvent = {
type: 'connecting';
session: HttpSession;
} | {
type: 'connected';
session: HttpSession;
connection: HttpConnectionInfo;
} | {
type: 'reconnecting';
session: HttpSession;
reason: unknown;
} | {
type: 'reconnected';
session: HttpSession;
connection: HttpConnectionInfo;
} | {
type: 'closed';
session: HttpSession;
reason?: unknown;
}
Re-exported from js/net/http/client.HttpSessionEvent.
type HttpProtocol = 'http/1.1' | 'h2' | 'h3'
Re-exported from js/net/http/server.HttpProtocol.
type HttpTransport = 'tcp' | 'tls' | 'quic'
Re-exported from js/net/http/server.HttpTransport.
type HttpRequestHandler = (
request: Request,
session: HttpSession
) => HttpHandlerResult | Promise<HttpHandlerResult>
Re-exported from js/net/http/server.HttpRequestHandler.
type HttpTlsPeerInfo = TlsPeerInfo
Re-exported from js/net/http/server.HttpTlsPeerInfo.
type IncomingHttp = IncomingHttpRequest | IncomingWebSocketRequest | IncomingWebTransportRequest
Re-exported from js/net/http/server.IncomingHttp.
type ServerAcceptHandler = (incoming: IncomingHttp, session: HttpSession) => void | Promise<void>
Re-exported from js/net/http/server.ServerAcceptHandler.
type WebTransportReceiveStream = ReadableStream<Uint8Array> & {
getStats(): Promise<WebTransportReceiveStreamStats>;
}
Re-exported from js/net/http/webtransport.WebTransportReceiveStream.
type WebTransportSendStream = WritableStream<Uint8Array> & {
sendGroup: string | null;
sendOrder: number | null;
getStats(): Promise<WebTransportSendStreamStats>;
}
Re-exported from js/net/http/webtransport.WebTransportSendStream.
Interfaces
interface HttpContext {
Re-exported from app.HttpContext.
interface WebSocketContext extends HttpContext {
Re-exported from app.WebSocketContext.
interface WebTransportContext extends HttpContext {
Re-exported from app.WebTransportContext.
interface SseContext extends HttpContext {
Re-exported from app.SseContext.
interface OperationMeta {
Re-exported from app.OperationMeta.
interface OpenApiOptions {
Re-exported from app.OpenApiOptions.
interface OpenApiParameter {
Re-exported from app.OpenApiParameter.
interface OpenApiRequestBody {
Re-exported from app.OpenApiRequestBody.
interface OpenApiResponse {
Re-exported from app.OpenApiResponse.
interface Session {
Re-exported from app.Session.
interface SessionStore {
Re-exported from app.SessionStore.
interface HttpClientOptions {
Re-exported from js/net/http/client.HttpClientOptions.
interface HttpRequestInit {
Re-exported from js/net/http/client.HttpRequestInit.
interface HttpSessionRequest extends HttpRequestInit {
Re-exported from js/net/http/client.HttpSessionRequest.
interface HttpSessionOptions {
Re-exported from js/net/http/client.HttpSessionOptions.
interface ReconnectOptions {
Re-exported from js/net/http/client.ReconnectOptions.
interface CloseOptions {
Re-exported from js/net/http/client.CloseOptions.
interface HttpRequestInfo {
Re-exported from js/net/http/client.HttpRequestInfo.
interface HttpConnectionInfo {
Re-exported from js/net/http/client.HttpConnectionInfo.
interface HttpResponseTiming {
Re-exported from js/net/http/client.HttpResponseTiming.
interface SseOptions extends EventSourceInit {
Re-exported from js/net/http/client.SseOptions.
interface HttpWebSocketOptions extends WebSocketConnectOptions {
Re-exported from js/net/http/client.HttpWebSocketOptions.
interface HttpWebTransportOptions extends WebTransportOptions {
Re-exported from js/net/http/client.HttpWebTransportOptions.
interface EventSourceInit {
Re-exported from eventsource.EventSourceInit.
interface ServeOptions {
Re-exported from js/net/http/server.ServeOptions.
interface ServeServer {
Re-exported from js/net/http/server.ServeServer.
interface IncomingBase<TKind extends string> {
Re-exported from js/net/http/server.IncomingBase.
interface IncomingHttpRequest extends IncomingBase<'request'> {
Re-exported from js/net/http/server.IncomingHttpRequest.
interface AcceptedHttpRequest {
Re-exported from js/net/http/server.AcceptedHttpRequest.
interface IncomingWebSocketRequest extends IncomingBase<'websocket'> {
Re-exported from js/net/http/server.IncomingWebSocketRequest.
interface IncomingWebTransportRequest extends IncomingBase<'webtransport'> {
Re-exported from js/net/http/server.IncomingWebTransportRequest.
interface WebSocketMessage {
Re-exported from js/net/http/websocket.WebSocketMessage.
interface WebSocketAcceptOptions {
Re-exported from js/net/http/websocket.WebSocketAcceptOptions.
interface WebSocketConnectOptions {
Re-exported from js/net/http/websocket.WebSocketConnectOptions.
interface WebTransportBidirectionalStream {
Re-exported from js/net/http/webtransport.WebTransportBidirectionalStream.
interface WebTransportCloseInfo {
Re-exported from js/net/http/webtransport.WebTransportCloseInfo.
interface WebTransportHash {
Re-exported from js/net/http/webtransport.WebTransportHash.
interface WebTransportOptions {
Re-exported from js/net/http/webtransport.WebTransportOptions.
interface WebTransportReceiveStreamStats {
Re-exported from js/net/http/webtransport.WebTransportReceiveStreamStats.
interface WebTransportSendStreamStats {
Re-exported from js/net/http/webtransport.WebTransportSendStreamStats.
interface WebTransportStats {
Re-exported from js/net/http/webtransport.WebTransportStats.
Classes
abstract class BuilderBranch<TSelf extends BuilderBranch<TSelf>> {
Re-exported from app.BuilderBranch.
abstract class RouterBase<TSelf> extends BuilderBranch<RouterBranch> {
Re-exported from app.RouterBase.
class RouterBranch extends BuilderBranch<RouterBranch> {
Re-exported from app.RouterBranch.
class App extends RouterBase<App> {
Re-exported from app.App.
class Router extends RouterBase<Router> {
Re-exported from app.Router.
class RouteBuilder extends BuilderBranch<RouteBuilder> {
Re-exported from app.RouteBuilder.
class MethodBuilder extends BuilderBranch<MethodBuilder> {
Re-exported from app.MethodBuilder.
class CookieJar {
Re-exported from cookie.CookieJar.
class HttpResponse {
Re-exported from js/net/http/client.HttpResponse.
class HttpSession {
Re-exported from js/net/http/client.HttpSession.
class HttpClient {
Re-exported from js/net/http/client.HttpClient.
class EventSource extends EventTarget {
Re-exported from eventsource.EventSource.
class CloseEvent extends Event {
Re-exported from js/net/http/websocket.CloseEvent.
class ErrorEvent extends Event {
Re-exported from js/net/http/websocket.ErrorEvent.
class WebSocketError extends DOMException {
Re-exported from js/net/http/websocket.WebSocketError.
class WebSocketConnection extends EventTarget implements ConnectionTakeover {
Re-exported from js/net/http/websocket.WebSocketConnection.
class WebSocket extends EventTarget {
Re-exported from js/net/http/websocket.WebSocket.
class WebTransport {
Re-exported from js/net/http/webtransport.WebTransport.
class WebTransportDatagramDuplexStream {
Re-exported from js/net/http/webtransport.WebTransportDatagramDuplexStream.
class Arena {
Bump allocator backed by a single ArrayBuffer.
Each alloc(n) returns a Uint8Array view at the current cursor, advances
the cursor by n, and never allocates a new backing store. reset() sets
the cursor back to zero, logically freeing all previous allocations in O(1).
Used to eliminate per-message allocations for HTTP/1.1 request and response
encoding. All bytes written into arena views are consumed by write(2)
before reset() is called, so there is no aliasing hazard. If the arena is
full, alloc() falls back to a regular new Uint8Array(n) — no failure
mode.
The FFI layer correctly handles the non-zero byteOffset of arena views
when they are passed to write(2) as buffer arguments.
const arena = new Arena(4096);
const bytes = arena.alloc(128);
arena.reset();
Constructors
constructor(size: number = 8192)
Create an arena with the requested backing-buffer size.
const arena = new Arena(65536);
Methods
alloc(n: number): Uint8Array
Allocate a Uint8Array view of n bytes.
If the arena has insufficient remaining space, this returns a standalone
Uint8Array instead of throwing. Previously returned arena views are
invalidated logically by reset() but not zeroed.
const header = arena.alloc(64);
reset(): void
Reset the allocation cursor to the beginning of the backing buffer.
Call this only after all views allocated from the arena have been consumed.
arena.reset();
Functions
function defineMiddleware<T extends Middleware | LayerMiddleware>(
fn: T,
meta: OperationMeta = {
}
): T
Re-exported from app.defineMiddleware.
function defineProducer<T extends Producer>(fn: T, meta: OperationMeta = {}): T
Re-exported from app.defineProducer.
function cookies(): Producer
Re-exported from app.cookies.
function memorySessionStore(): SessionStore
Re-exported from app.memorySessionStore.
function sessions(opts: {
store: SessionStore;
cookie?: string;
cookieOptions?: CookieOptions;
}): Producer
Re-exported from app.sessions.
function errorHandler(opts: {
expose?: boolean;
} = {}): LayerMiddleware
Re-exported from app.errorHandler.
function staticFiles(root: string, opts: {
index?: string;
prefix?: string;
} = {}): LayerMiddleware
Re-exported from app.staticFiles.
function serve(options: ServeOptions, handler: ServerAcceptHandler): ServeServer
Re-exported from js/net/http/server.serve.
function serveHttp(options: ServeOptions, handler: HttpRequestHandler): ServeServer
Re-exported from js/net/http/server.serveHttp.
async function parseRequest(source: AsyncIterable<Uint8Array | ArrayBuffer>): Promise<Request>
Parse an HTTP/1.x request from an async iterable of byte chunks.
The returned Request's url is constructed from the Host header and the
request path: "http://<host><path>". If no Host header is present, url
contains only the path.
Throws on malformed request lines, malformed headers, conflicting
Content-Length, invalid chunked framing, or premature EOF.
const req = await parseRequest(reader);
async function parseResponse(
source: AsyncIterable<Uint8Array | ArrayBuffer>,
method?: string
): Promise<Response>
Parse an HTTP response from a byte stream.
method is the original request method; pass 'HEAD' so the parser knows
the response must not expose a body even if framing headers are present.
Throws on malformed status lines, headers, or body framing.
const res = await parseResponse(reader, request.method);
async function* serializeRequest(req: Request, arena?: Arena): AsyncGenerator<Uint8Array>
Serialize a Request to an async iterable of Uint8Array chunks suitable for piping to a TCP connection: request-line + headers first, then body chunks.
Body framing:
- No body → no framing headers added.
- content-length already present → body emitted verbatim.
- Body without content-length → transfer-encoding: chunked injected.
Reading from the returned iterable consumes the request body. Passing an
Arena reuses its backing buffer for generated head and chunk framing bytes.
for await (const chunk of serializeRequest(req, new Arena())) {
await writer.write(chunk);
}
async function* serializeResponse(res: Response, arena?: Arena): AsyncGenerator<Uint8Array>
Serialize a Response to an async iterable of Uint8Array chunks suitable for piping to a TCP connection: status-line + headers first, then body chunks.
If outbound trailers are present, chunked transfer encoding is emitted and
content-length is removed from the wire headers. Reading from the returned
iterable consumes the response body.
for await (const chunk of serializeResponse(res, new Arena())) {
await writer.write(chunk);
}
Constants
const schema
Re-exported from app.schema.
const body
Re-exported from app.body.