node package manager

http2server

🕸

http2server 🕸

HTTP/2 webserver for static files

  • Single page app fallback handling for client side routing.
  • Auto-generated HTTPS certificate for localhost development.
  • Data compression with Brotli, Zopfli (Gzip), and Deflate.
  • Server Push for round-trip elimination.
  • Cache Digests to only push changed files.
  • CORS for 3rd party embedding, static JSON APIs, etc.
  • Service-Worker-Allowed header to enable Service Workers on any path.
  • Redirects HTTP to HTTPS URLs.
  • Immutable extension for the cache-control header for revved files.
  • Multi-process cluster operation for scalable performance.
  • Supports Node.js 8+ native HTTP/2 with fallback for older Node.js.

Installation

npm i -g http2server

CLI

http2server <path> [options]

Where <path> is the directory to serve. Defaults to ./public if it exists, otherwise the current directory.

Options

-f, --fallback

HTML fallback for single page apps. This path is either absolute, or relative to <path>. Default: ./index.html

-i, --include

Files to push alongside the fallback. Default: **/*

-e, --exclude

Files not to push. Default: **/*.map

-p, --port

Port to listen on. Defaults to process.env.PORT if the PORT environment variable is set, otherwise 8443.

-C, --cert

Path to ssl cert file. Default: cert.pem See: HTTPS Certificate

-K, --key

Path to ssl key file. Default: key.pem See: HTTPS Certificate

--ca

One or more intermadiate certificates. Default: ca.pem See: HTTPS Certificate

--immutable

One or more regular expressions to match file paths of assets that never change. Default: hex emoji See: Caching Policy

--worker

Service worker source files. These are not pushed with the fallback. Default: **/service-worker/**/*

--scope

Set the value of the Service-Worker-Allowed header. Default: /

--cors

Set Access-Control-Allow-Origin. Default: false

-o

Open browser window after starting the server. Default: false

-s, --silent

Suppress log messages from output. Default: false

-v, --version

Show version number

-h, --help

Show help

Server Push with Cache Digests

Page load time is a largely function of latency (round trip time × delays) and aggregate volume (number × size of assets).

Latency is minimised by using HTTP/2 Server Push to deliver any necessary assets to the browser alongside the HTML. When the browser parses the HTML it does not need to make a round trip request to fetch styles, scripts, and other assets. They are already in its cache or actively being pushed by the server as quickly as network conditions allow.

Volume is reduced by using strong compression (HPACK, Brotli, etc), and by avoiding sending redundant data.

If all assets were pushed every time, a large amount of bandwidth would be wasted. HTTP/1 asset concatenation makes a tradeoff between reducing round trips (good) and re-transferring invalidated, large files (bad). For example having to re-tranfer an entire spritesheet or JavaScript bundle because of one little change.

The HTTP/1 approach was to use file signatures (Etags) and timestamps to invalidate cached responses. This requires many expensive round trips where the browser checks with the server if any files have been modified.

Cache Digests to the rescue! Using a clever technique, called Golomb-Rice Coded Bloom Filters, a compressed list of cached responses is sent by the browser to the server. Now the server can avoid pushing assets that are fresh in the browser's cache.

With Server Push and Cache Digests the best practice is to have many small files that can be cached and updated atomically, instead of large, concatenated blobs.

Browsers do not yet support cache digests natively so Service Workers and the Cache API are used to implement them. A cookie-based fallback is available for browsers that lack Service Worker support.

HTTPS Certificate

While the HTTP/2 specification allows unencrypted connections, web browsers strictly enforce HTTPS.

If no certificate and key are provided, one pair will be auto-generated. The generated certificate is only valid for localhost. It is stored in ~/.http2server. As a developer convenience, the certificate is added as trusted to the operating system so browsers will accept the certificate. A password dialog may appear to confirm. This is currently only supported on macOS and Linux.

In production use Let's Encrypt or any other trusted, signed certificate.

Intermediate certificates are stapled to the OCSP response to speed up the TLS handshake.

Caching Policy

By default files are served with the header cache-control: public, must-revalidate.

File paths that match the patterns set by the --immutable option are considered to never, ever change their contents. They are served with the header cache-control: public, max-age=31536000, immutable. This tells browsers never to revalidate these resources.

The default immutable patterns are:

  • hex — Matches hexadecimal hash revved files. Example: unicorn-d41d8cd98f.css
  • emoji — Matches emoji revved files. Example: app.⚽️.js

See Also

  • Unbundle — Build tool for front-end JavaScript applications, designed for HTTP/2 Server Push and Cache Digests.
  • Push Demo — Shows how to use this tool through a practical example.

Colophon

Made with ❤️ by Sebastiaan Deckers in Venice 🇮🇹 at a Legalese workation, in San Francisco 🇺🇸 for SFNode, and in Singapore 🇸🇬 for JSConf.Asia.