Sign in

    http-server-mbt

    Download zip
    Author
    Version
    0.4.2
    License
    MIT
    Last updated
    10 days ago
    Downloads
    21

    Dependencies

    #🚀 http-server-mbt

    A blazing fast, zero-dependency, high-performance static HTTP server written in MoonBit.

    MoonBit mooncakes.io Candidate acceptance License: MIT Platform Native Speed

    #đŸ–Ĩī¸ Platform Support Matrix

    The CI badge above tracks the latest master push to Candidate acceptance, including all three platform jobs and the artifact gate. Open a run below for each platform's result, commit, logs and candidate artifacts.

    PlatformCI ArchActions Runner / JobCore I/O & Transfer Mechanism
    Windowsx86_64native (windows-2025)Win32 TransmitFile + IOCP
    Linuxx86_64native (ubuntu-24.04)sendfile(2) explicit-offset path + epoll
    macOSarm64native (macos-15)Darwin sendfile + kqueue

    All three jobs run Native tests, resource/sanitizer checks, Full/Thin builds, external consumers and Node 22/24 candidate installation. Linux also verifies the four container variants. The final artifact gate checks platform coverage, commit, version and hashes; see the workflow for the current checks.

    The badge reports the whole workflow, not an individual job or a published release. For a released version, consult its release run and artifact manifests. macOS x86_64 is not currently covered by this CI matrix. Outstanding work remains tracked in the task list.


    #đŸ”Ĩ Major Extensions & Enhancements over Original Node.js http-server

    http-server-mbt re-architects and significantly expands upon the classic Node.js http-party/http-server (baseline commit 0d3b7bb5):

    DimensionOriginal Node.js http-serverhttp-server-mbt (MoonBit)Value & Advantage
    Underlying I/O & TransferRelies on Node.js/V8 streams and libuv with userland buffer copying; prone to GC pausesPer-platform kernel zero-copy: Win32 TransmitFile (Windows) / sendfile + epoll (Linux) / Darwin sendfile + kqueue (macOS); static files and Range byte slices pushed directly from kernel DMA to network socketMaximum throughput, minimal CPU & context switching overhead; 100ms timeout protection & bounded buffer fallback
    SPA & Custom FallbackBasic --spa only (blindly rewrites 404 to index.html), potentially masking authentication and permission errorsBoth --spa and --try-files <file>; core state machine strictly preserves 401 Unauthorized and 403 ForbiddenProduction-ready SPA routing; eliminates security bypass vulnerabilities; flexible --base-url / --base-dir path mounting
    Pre-compressed AssetsBasic check for .gz / .br filename presence without content validationBrotli (.br) prioritized negotiation, built-in gzip magic number validation (0x1F 0x8B), forceContentEncoding modePrevents serving corrupted or fake compressed files; validates and gracefully falls back to raw asset transfer
    WebSocket ProxyRelies on third-party http-proxy module; unhandled socket dropouts cause connection and handle leaksNative full-duplex WebSocket proxy with built-in Upgrade handshake, transparent bi-directional pipes & cancellation drainingCompletely eliminates IOCP read-blocking deadlocks; verified 0 handle leaks across long-running connections
    Dynamic File Mutation DefenseNo protection against files being modified or truncated mid-transfer; client receives corrupted slicesD-17 dynamic mutation defense: tracks open file handles; aborts response immediately on detected mutation / truncationStrictly prevents partial-write corruption, ensuring deterministic static asset distribution
    Fault Injection ResilienceLacks automated defense testing against malformed packet fragments or Slowloris read attacksBuilt-in T-034 fault injection testing: single-byte split writes, truncated header storms, Slowloris backpressureExtreme resilience against chaotic network conditions; stop_and_drain barrier synchronization ensures zero hangs
    Runtime & Deployment FootprintRequires heavy Node.js runtime and hundreds of node_modules dependencies; slow startupStandalone native machine binary compiled via MoonBit; no Node.js/V8/Python runtimeA single-file deployment shape with platform runtime dependencies recorded per target


    #✨ Features

    • Blazing Fast: Native machine code generated by MoonBit, with kernel zero-copy file transfer on all three platforms — Windows (TransmitFile), Linux (sendfile), macOS (Darwin sendfile).
    • Standalone Native CLI: No Node.js, V8, or Python runtime is required. Platform system DLLs remain part of the native runtime contract.
    • Modern Routing: BaseURL path mounting prefix, SPA fallback, and custom --try-files fallback strategy.
    • Smart Pre-compression: Dual Brotli / gzip content negotiation with gzip magic number validation.
    • Full-Duplex Proxy: Reverse HTTP proxy for unhandled (404) requests and WebSocket protocol upgrade bidirectional proxy.
    • Enterprise-Grade Security: Path traversal defense (.., \, NUL bytes and cross-drive boundaries), constant-time HTTP Basic Auth, strict 401/403 isolation.
    • Clean Directory Listing: Auto-generated modern HTML directory browser with file sizes, companion file folding, and natural sorting.
    • Graceful Lifecycle: Clean Ctrl+C interrupt handling, bounded connection draining, and 0 handle leaks under stress.


    #đŸ“Ļ Installation

    The recommended installation method is using the MoonBit package manager to compile and install directly from source:

    # Full version (with TLS and reverse proxy support) moon install unmbt/http-server-mbt/cmd/http-server-mbt http-server-mbt -v # Or Thin version (plaintext static server without TLS, proxy, MbedTLS or PSA) moon install unmbt/http-server-mbt/cmd/http-server-mbt-thin http-server-mbt-thin -v

    moon install places the executable in ~/.moon/bin. Make sure that directory is included in your PATH.

    #Pre-compiled Binary

    If you prefer not to build from source, use the installation script for your system to download the standalone executable directly from the latest GitHub Release:

    Two editions are available:
    • Full (Default): Full-featured static server with TLS 1.2/1.3 (HTTPS) via embedded MbedTLS and reverse/WebSocket proxy (http-server-mbt).
    • Thin: Plaintext static server without TLS/proxy/MbedTLS/PSA dependencies. On the measured Windows release build it is 1,602,560 bytes versus Full 3,884,544 bytes, a 58.75% reduction; the build still imports the generic runtime bcrypt.dll capability on Windows.

    #Linux & macOS

    # Full version (Default) curl -fsSL https://raw.githubusercontent.com/unmbt/http-server-mbt/master/scripts/install.sh | bash # Thin version (Lightweight plaintext variant without TLS/proxy) curl -fsSL https://raw.githubusercontent.com/unmbt/http-server-mbt/master/scripts/install.sh | bash -s -- --thin

    #Windows (PowerShell)

    # Full version (Default) irm https://raw.githubusercontent.com/unmbt/http-server-mbt/master/scripts/install.ps1 | iex # Thin version (Lightweight plaintext variant without TLS/proxy) & ([scriptblock]::Create((irm https://raw.githubusercontent.com/unmbt/http-server-mbt/master/scripts/install.ps1))) -Thin

    Note: Pre-compiled binary scripts install to ~/.unmbt (or $HOME\.unmbt) and automatically configure your PATH. Both editions install the primary executable as http-server-mbt (installing with --thin / -Thin also creates an http-server-mbt-thin symlink/copy). Restart your terminal for PATH updates to take effect.

    #C ABI SDK for Native Embedding

    If you are embedding http-server-mbt as a shared library (.so / .dylib / .dll) or static archive (.a / .lib) into C, C++, Rust, Zig, Go, or Python, download the pre-packaged http-server-cabi-<platform>-<arch>.tar.gz (or .zip for Windows) from the GitHub Releases page. It contains http_server.h, both thin and full library binaries, and runnable integration examples. See the C ABI Integration Guide for complete details.


    #🚀 Usage

    Run directly from your terminal:

    http-server-mbt [root] [options]

    #CLI Options

    OptionDescriptionDefault
    [root]Filesystem root directory to serve.
    -p, --port <port>TCP port to listen on (or via PORT environment variable)8080
    --base-url <url>Mount URL prefix (e.g. /docs/)/
    --base-dir <dir>Alias for --base-url/
    --spaEnable SPA mode: fallback missing paths to index.html (preserves 401/403)Disabled
    --try-files <file>Custom fallback file relative to root (preserves 401/403)None
    -c, --cache <time>Cache-Control duration in seconds or max-age=...3600
    -i, --autoIndex / --no-autoIndexAutomatically display default index.html on directory requestsEnabled (true)
    -d, --showDir / --no-showDirShow HTML directory listings when no index file is presentEnabled (true)
    --corsEnable CORS headers via Access-Control-Allow-OriginDisabled
    -a, --auth <user:pass>HTTP Basic Auth credentialsDisabled
    -P, --proxy <url>Fallback proxy URL for unhandled requestsDisabled
    --proxy-all <url>Proxy all incoming requests unconditionally to target URLDisabled
    --proxy-config <file>JSON route-based proxy configuration file or inline JSONDisabled
    --cert <file>TLS certificate chain file (PEM) — enables HTTPS serving (vendored MbedTLS 4.2.0)Disabled
    --key <file>TLS private key file (PEM)None
    --key-passphrase <pass>Passphrase for encrypted TLS keys (or TLS_KEY_PASSPHRASE env)None
    -l, --log-ipLog client IP address to terminal outputDisabled
    -s, --silentSuppress log messages in terminalDisabled
    -h, --helpShow command-line help and exit-
    -v, --versionShow version information and exit-


    #💡 Examples

    #1. Basic Static Serving

    Serve the ./public directory on port 3000:
    http-server-mbt ./public -p 3000

    #2. Single Page Application (SPA) Serving

    Serve frontend dist directory with SPA fallback, CORS enabled, and caching disabled:
    http-server-mbt ./dist -p 8080 --spa --cors -c -1

    #3. Path Prefix & Basic Auth

    Serve assets under /app/ prefix protected by username and password:
    http-server-mbt ./site -p 8000 --base-url /app/ -a admin:secret123

    Terminal Output:
    Starting up http-server, serving ./public http-server version: 0.1.5 http-server settings: CORS: true Cache: 3600 seconds Connection Timeout: 120 seconds Directory Listings: visible AutoIndex: visible Serve GZIP Files: false Serve Brotli Files: false Default File Extension: none Available on: http://127.0.0.1:8080 http://192.168.1.10:8080 Hit CTRL-C to stop the server


    #đŸ› ī¸ Build from Source

    Ensure you have the MoonBit toolchain installed.

    # Clone repository git clone https://github.com/unmbt/http-server-mbt.git cd http-server-mbt # Update dependencies and typecheck moon update moon check --target native # Run the complete Native test suite moon test --target native # Build release executable moon build --target native --release

    The compiled binary will be located at _build/native/release/build/cmd/http-server-mbt/http-server-mbt.exe (same commands and artifact name on Windows, Linux, and macOS).


    #📄 License

    Developer navigation: documentation, scripts, tests.

    This project is licensed under the MIT License. The underlying asynchronous networking library moonbitlang/async is licensed under Apache-2.0.

    ServerError

    pub suberror ServerError {
    InvalidRequest(String)
    Forbidden(String)
    Io(String)
    FileChanged(String)
    Closed
    Busy
    Overloaded
    }

    ServerError::forbidden

    fn ServerError::forbidden(message : String) -> ServerError

    ServerError::invalid_request

    fn ServerError::invalid_request(message : String) -> ServerError

    ServerError::io

    fn ServerError::io(message : String) -> ServerError

    HandleResult

    pub(all) enum HandleResult {
    Handled(Response)
    Next
    Error(ServerError)
    }

    Response

    pub struct Response {
    status : Int
    headers : Map[String, String]
    // private fields
    }

    Response::body_length

    fn Response::body_length(self : Response) -> Int64

    Response::check

    async fn Response::check(self : Response) -> Unit

    Revalidate the representation immediately before committing response headers.

    Response::close

    async fn Response::close(self : Response) -> Unit

    Response::content_length

    fn Response::content_length(self : Response) -> Int64?

    None denotes a streaming body whose length is not precomputed.

    Response::read

    async fn Response::read(self : Response, max_len? : Int) -> Bytes

    Read the next bounded chunk. Only successful EOF returns empty bytes.

    Response::send_to

    async fn Response::send_to(self : Response, tcp :
    Tcp
    ) -> Unit

    Send the remaining file through the socket's kernel transfer path, falling back from the exact current offset when the platform reports unsupported operation.

    Response::to_bytes

    async fn Response::to_bytes(self : Response, max_bytes~ : Int) -> Bytes

    Explicitly bounded convenience collection; normal server paths stream instead.

    Response::write_to

    async fn Response::write_to(self : Response, writer : &
    Writer
    , chunked? : Bool) -> Unit

    Write a body through a bounded writer; chunked is HTTP/1.1 framing only.

    StaticEngine

    pub struct StaticEngine {
    config :
    Config

    // private fields
    }

    StaticEngine::close

    async fn StaticEngine::close(self : StaticEngine) -> Unit

    StaticEngine::handle

    StaticEngine::open

    Open and validate a Native static engine. Pair with async close, or prefer with_engine.

    escape_html

    fn escape_html(s : String) -> String

    Escape characters for safe HTML rendering.

    get_handle_count

    fn get_handle_count() -> UInt

    Process handle count for Native resource probes.

    render_directory_listing_html

    fn render_directory_listing_html(title_path : String, entry_names : Array[(String, Bool)], raw_query? : String?, host? : String) -> String

    Pure HTML directory listing renderer for testing and embedding (AD-05).

    with_engine

    async fn[T] with_engine(config :
    Config
    , handler : async (StaticEngine) -> T) -> T

    Powered by MoonBit

    Site sourceReport issuePackagesBuild queueSkillsStatistics

    Š 2026 mooncakes.io