Minimal static HTTP file server, implemented in pure MoonBit withmoonbitlang/async@0.22.9. Run the latest published releasewith MoonX:
moonx cli/serve@latest -- public
Version: cli/serve@0.1.3, reporting serve 0.1.3 with --version.This version keeps successful file-response connections available for reuse.The immutable 0.1.2 release closes those connections; the earlier 0.1.1 packageincorrectly reports version 0.1.0.
Usage: serve [--host ADDRESS] [-p PORT|--port PORT] [DIRECTORY].The directory defaults to ., the address to 127.0.0.1, and the port to 8000.Use a numeric IPv4/IPv6 address; port 0 selects an available port. The actualaddress is printed to stderr. --port=8000 and -p8000 are also accepted,each option may be supplied once, and -- ends option parsing. Use -h or--help for usage and -V or --version for version information. Metadatarequests exit without reading stdin or starting a listener. Argument syntaxerrors print the standard parser diagnostic with usage to stderr and exit 1.
GET streams regular files with Content-Length and an extension-based MIME type;HEAD sends the same headers without a body. Unknown extensions useapplication/octet-stream; responses disable MIME sniffing. Directories serveindex.html, redirecting to a trailing slash when needed; absent files/indexesreturn 404. Other methods return 405.There is no directory listing, SPA fallback, upload, range, cache, compressionor TLS support. Every readable file under the selected root, including hiddenfiles, is eligible for serving.
Paths are percent-decoded once as UTF-8; queries do not select files. Traversalsegments, malformed escapes, control bytes, backslashes, drive/stream colonsand Windows device/alias names are rejected with 400 on all platforms. Canonicaltargets must remain under the canonical root, including symlink targets andindex.html; forbidden/unreadable/nonregular targets return 404. Symlinkswithin the root are permitted. Open files stream through @http'sfixed-length body path in 64 KiB chunks, with at most 64 simultaneousconnections. moonbitlang/async@0.22.9 writes large fixed-length chunksdirectly to the socket, so successful GET/HEAD file responses keep theconnection open; redirects and error responses also keep it open. Filesshould remain stable while served; a shortened file aborts its response, andappended bytes are excluded.
Wasm policy adds process permissions; it is supplied by the launcher, notinstalled by this command. For example, save serve-policy.json beside publicand launch from that parent directory:
moonx --experimental-policy serve-policy.json cli/serve@latest -- public
Keep write/process/network-connect permissions absent. Neither path-basedchecks nor the current host policy establish race-free confinement againsthostile concurrent filesystem replacement. Serve a trusted, stable directory;descriptor-relative confined opening on Wasm is the missing unlock condition.See compatibility and thefilesystem decision.