How to serve static files
View Sourcelivery_static:handler/1,2 serves a directory of files (assets, a
built SPA, downloads) over HTTP, with correct Content-Type,
conditional GET, and Range support, and without exposing anything
outside the directory. You need it when you want to ship a folder of
files rather than write a handler per asset.
Mount it on a wildcard route
Mount the handler on a router wildcard route. The *path segment
captures the rest of the URL, which the handler maps to a file under
the root:
Router = livery_router:add(
'_', <<"/assets/*path">>, livery_static:handler("priv/assets"), #{}, Router0
).GET /assets/css/app.css serves priv/assets/css/app.css with
Content-Type: text/css, an ETag, and (if the client sends Range)
partial content.
Serve it without the router
If you are not using the router, configure a prefix to strip from the
request path:
{livery_static, never} %% NB: it is a handler, not middleware
%% as a service handler:
livery:start_listener(h1, #{
port => 8080,
handler => livery_static:handler("public", #{prefix => <<"/">>})
}).Options
livery_static:handler("priv/assets", #{
binding => <<"path">>, %% router binding name (default)
prefix => <<"/assets/">>, %% fallback when there is no binding
index => <<"index.html">>, %% served for a directory; false to disable
cache_control => [{max_age, 3600}, public], %% optional Cache-Control
etag => true, %% weak ETag from size+mtime (default)
range => true %% honor Range requests (default)
}).Behaviour
Content-Typeis inferred from the file extension (text types get; charset=utf-8), defaulting toapplication/octet-stream.- A weak
ETag(W/"size-mtime") is emitted; a matchingIf-None-Matchreturns304 Not Modified. Range: bytes=...returns206 Partial Content; an unsatisfiable range returns416.HEADreturns headers (includingContent-Length) with no body.- Only
GET/HEADare served; other methods get405withAllow. - A directory request serves
indexif present, else404(no directory listing).
Notes
- The sub-path is percent-decoded and then confined: any
..segment, absolute path, control byte, or bad escape is rejected with404, so a request can never traverse out of the root. - Only regular files are served (directories and symlinks yield
404), so a symlink inside the root cannot be used to escape it.
See also
- Reference:
livery_static,livery_resp(file/2,3) - Guide: Add HTTP caching
- Guide: Serve a file