Aller au contenu
Français

Static files

Ce contenu n’est pas encore disponible dans votre langue.

Serve files without reaching for a backend-specific plugin. getFromFile serves one file; getFromDirectory maps a URL onto a directory tree; getFromBrowseableDirectory adds HTML listings.

import { concat, getFromFile, getFromBrowseableDirectory, path } from 'actor-ts/http';
const routes = concat(
path('logo.svg', getFromFile('./assets/logo.svg')),
getFromBrowseableDirectory('static', './public'), // mounts at /static
);

getFromDirectory([routePrefix,] fsRoot, options?) — with a routePrefix it mounts under it (e.g. /static/...), without one it mounts at the root.

Builder methodFieldDefault
withIndexFiles(...n)indexFiles['index.html'] ([] disables)
withBrowse(flag?)browsefalse
withCacheControl(v)cacheControlheader omitted
withEtag(flag)etagtrue (weak, size+mtime)
withLastModified(flag)lastModifiedtrue
withRanges(flag)rangestrue
withDotfiles('deny' | 'allow')dotfiles'deny'
withSymlinks('within-root' | 'follow')symlinks'within-root'
withContentTypes(map)contentTypes— (ext → type overrides)
withMaxFileSize(bytes)maxFileSize50 MiB (larger → 413)
  • Conditional requests — a weak ETag (size + mtime) and Last-Modified; matching If-None-Match / If-Modified-Since304.
  • Range — a single bytes= range → 206 (or 416 if unsatisfiable); Accept-Ranges: bytes is advertised.
  • Directories — a request without a trailing slash 301-redirects to add it (query preserved); with a slash, index files are tried in order, then a listing (if browsing) or 404.
  • HEAD — full headers, empty body, no file read.

Content-types come from contentTypeFor(pathOrExt, overrides?) — a small registry of ~45 common web types. Text-ish types get ; charset=utf-8; unknown extensions fall back to application/octet-stream. Override per-route with withContentTypes({ ext: 'type' }) or call contentTypeFor directly when building responses by hand.

The URL remainder is fully decoded before validation (peeling every encoding layer), then every path segment is rejected if it is .., empty, a NUL, a backslash, or a : segment (Windows drive / NTFS alternate data stream); absolute forms are refused, the joined path is confined to the root, and a symlink escaping the root is refused (within-root default). Dotfiles are denied by default. Every rejection is a uniform 404 — no information leak about what exists.

  • Route DSL — how directives compose.
  • HTML & XSS — the listing escapes filenames with the same helpers.
  • Security — the recommended stack.