Log inGet started

httpServer

The httpServer namespace — the engine's Luau API reference for httpServer.

The httpServer namespace — 7 functions.

globals/httpServer/address

httpServer.address(path: string) -> (string?, string?)

The URL a path answers on — scheme, host, port and the /app mount, ready to be fetched or printed for someone to open. Takes the same path spelling route does, and reads the interface and port from the socket routes answer on: the address listen opened while one is open, and the engine's own server otherwise.

Parameters

  • path string — Path under the /app mount, e.g. "/status".

Returns (string?, string?) — The URL, or nil plus the reason there is none — this engine holds no address, or the path is not one a route can be registered at.

print(httpServer.address("/status")) --> http://127.0.0.1:7607/app/status

globals/httpServer/listen

httpServer.listen(target: string) -> (HttpListener?, string?)

Hold an interface and port of this world's own, and answer content routes on it.

The host in target is the interface bound, and the whole of what decides who can reach those routes: "127.0.0.1:8080" answers programs on this machine, "0.0.0.0:8080" answers any host that routes to this machine on that port — a phone on the same wifi, and whatever else the network lets through. Bind loopback unless you want that. A port of 0 asks the operating system for a free one, which the returned record reports, and http:// may be spelled out in front.

This address serves the routes registered under the /app mount. The engine's own /engine/* tree answers on the loopback server it booted with, whose interface stays what the boot bound.

The address belongs to the chunk that opened it and is released when that chunk runs again, so an edited module holds the address its current source names. Asking for the address already held is the same address back.

Parameters

  • target string — Interface and port to hold, e.g. "0.0.0.0:8080".

Returns (HttpListener?, string?) — The listener record, or nil plus the reason the target or the bind was refused.

local l = assert(httpServer.listen("0.0.0.0:8080"))

globals/httpServer/route

httpServer.route(method: string, path: string, handler: HttpHandler, options: HttpRouteOptions?) -> (number?, string?)

Serve one method and path from this engine, answering each matching request with handler.

The path is relative to the /app mount, and a trailing /* segment matches the rest of the path — "/files/*" answers /app/files/a/b, with "a/b" in request.wildcard. An exact path answers ahead of a wildcard, and among wildcards the longest one wins.

One method and path is served by one handler. Registering an address another chunk serves returns nil and a reason naming the handle and the chunk holding it; httpServer.routes() finds that handle and httpServer.unroute frees the address. Registering an address this same chunk already serves takes it back and releases the handler it replaces, so a chunk that runs twice serves the handler it just built.

The handler runs on the script thread. Raising inside it answers 500 and writes the error to the engine log; returning something that is not a response table or a string answers 500 saying what arrived.

Parameters

  • method string — HTTP verb, e.g. "GET" or "POST".
  • path string — Path under the /app mount, e.g. "/status" or "/files/*".
  • handler HttpHandler — Called with the request table; returns a response table or a body string.
  • options HttpRouteOptions (optional){ timeoutMs? } — how long a request waits for this handler.

Returns (number?, string?) — The route handle, or nil plus the reason it was not registered.

local h = httpServer.route("GET", "/status", function(req)

globals/httpServer/routes

httpServer.routes() -> { HttpRoute }

Every route this engine currently serves, in registration order — handle, method, registered path, the address it answers on, its full URL, the chunk that registered it, and how long a request for it waits.

Returns { HttpRoute } — An array of route records.

for _, r in ipairs(httpServer.routes()) do print(r.method, r.url, r.owner) end

globals/httpServer/status

httpServer.status() -> HttpServerStatus

Whether this engine serves content routes, on which interface, port and mount, who can reach them, and how many routes and waiting requests it holds. host, port, url and reach are read from the socket routes answer on — the one listen opened while one is open, and the engine's own server otherwise — and listeners carries every address, each with its own reach. When supported is false, reason says why: a browser tab answers HTTP requests and holds no address of its own.

Returns HttpServerStatus{ supported, reason?, host?, port?, url?, reach?, prefix, routeCount, pending, listeners }.

local s = httpServer.status(); print(s.url, s.reach)

globals/httpServer/unlisten

httpServer.unlisten() -> boolean

Release the address listen opened. Returns once the socket is free, so the same port binds again straight after.

Returns boolean — True when an address was held.

httpServer.unlisten()

globals/httpServer/unroute

httpServer.unroute(handle: number) -> boolean

Stop serving a route and release its handler. The address is free for another registration once this returns true.

Parameters

  • handle number — The handle httpServer.route returned.

Returns boolean — True when a route with this handle was registered.

httpServer.unroute(h)
  • api
  • reference