httpd.execline
performs the business logic of a a static HTTP mirror. it is
implemented in execline, in the same
sense that you could implement the business logic of a static HTTP server in
POSIX sh(1)
, by wrangling Unix tools together which will actually perform the
useful tasks you want to get done. (the advantage of POSIX sh(1)
for this job
is that it is far less verbose.)
it takes a lot of inspiration from publicfile, while trying to allow some level of customization (custom error status pages, custom HTTP headers, file-extension/MIME-type mapping adjustments) without requiring you to edit code; here we use using a filesystem-driven configuration where the hierarchical file structure amounts to a simple structured key-value store.
this README is served as standalone HTML by an instance of httpd.execline at https://httpd-execline.cat.family/
you can download the latest release from the official website, currently version 1.0.2. the git repository is currently hosted on Gitlab
for the quickest install ensure you have systemwide installations of s6, execline, and s6-networking with TLS support.
visible-to-httpd
to a suitable webroot location, such
as /srv/httpd.execline
dependencies
(on linux, you might want to
run the musl chroot script) to render the runtime dependencies availabse in
the chroot jaildata/env
and log/data/env
files as
required(if you do not have systemwide installations of your dependencies, you could
try hacking the httpd service to use the binaries
folder from the chroot jail
as part of the PATH
…)
you are currently on your own.
if you’ve ever used the publicfile httpd
, then the setup is somewhat familiar:
httpd.execline
expects to be run in a directory where there is a subdirectory
matching every hostname the dæmon serves requests for; it will simply mirror the
contents of every file in that subdirectory it is allowed to read.
in short: if example.org
routed to your machine, then place a directory named
example.org/
in ./visible-to-httpd/supported_domains/
.
(you should consider ensuring httpd.execline
not have any write permissions
for the hostname-directories and their contents.)
if you’re using daemontools
-style process supervision (runit, daemontools, s6,
or the like), and you already have all the dependencies (see below), including
statically linked binaries in ./binaries
(see below), then adjust
paramaterized values in ./run.template
and rename it to ./run
, and drop this
directory into wherever your process supervision suite is looking for service
directories. (if you’re not using s6
, you should replace s6-log
in
`./log/run.)
i haven’t used systemd
for years, and as such, haven’t gotten around to
writing an equivalent unit file yet.
you will need a superserver to actually perform any networking; i use
s6-tlsserver
(which itself uses
s6-tcpserver
,
which you could use if you don’t need TLS), from
s6-networking
.
furthermore, we assume your kernel supports chroot
, and that you have
userspace-level access to the feature, like GNU coreutils chroot(1)
.
./visible-to-httpd/binaries
httpd.execline
normally chroots into the directory it runs from, making it
difficult to use dynamically linked versions of its hard dependencies. a
feasible configuration is to place statically linked dependencies into
./binaries
:
s6-applyuidgid
s6-echo
tr(1)
, read(1)
, urlencode(1)
wc(1)
,
date(1p)
, stat(1)
, cat(1)
, timeout(1)
, cksum(1)
(optional; used to
generate ETags)
tr(1)
is pending but seems to workgzip(1)
(optional; required for gzip
encoding)chroot(1)
note that if you build execline and s6-portable-utils with slashpackage
support, they will expect to find commands in /package
, and you will
need to somehow ensure it exists in the chroot directory.
the directory ./visible-to-httpd/configuration
has several subdirectories for
configuring headers and error status behavior.
./visible-to-httpd/configuration/Content-Type_table/
a key-value store for associating extensions
with Content-Type
s. for example, data/Content-Type_table/html
should probably contain the string text/html; charset=utf-8
.
this feature can be overriden on a per-file basis in two ways, the second overriding even the first.
${1}=${2}
; such files
will be served with a Content-Type
of {1}/${2}
(with colons in
${1}
or ${2}
converted to periods). for example, a file named
index.text=x:market
will always be served with a Content-Type
of
text/x.market
.overrides
folder (see below) to specify a
Content-Type
header explicitly (but not in the headers
subdirectory)../visible-to-httpd/configuration/default_headers/
a collection of key-value stores to specify headers to send for all
resources associated with a particular hostname, as well as a
-fallback
which takes effect if there is no store for that domain
(or that specific resource; see overrides
below).
in subfolders matching hostnames, files named after a header should
contain the contents of that header. a personal site heavily
associated with a mastodon account would perhaps add a file
X-Clacks-Overhead
, containing the contents GNU Natalie Nguyen
;
a Strict-Transport-Security
file is a good idea; if you find it
prudent to allow access as an onion service, an Onion-Location
file
is a good idea. and so on.
the hostname and requested resource for the current request will be
substituted for all instances of ${hostname}
and ${resource}
in
the header contents, which might prove useful for the Location
and
Onion-Location
headers.
\r
and newlines will be stripped from filenames and file contents to
prevent trivial mischevious configurations from breaking HTTP
responses; other than this, these HTTP header folders are not
validated syntactically or semantically.
./visible-to-httpd/configuration/error_response_pages/
this directory may contain a subdirectory named after each hostname,
each containing subdirectories for a numerical HTTP status code, each
containing a required message_body
file, an optional Content-Type
file (defaulting to application/xhtml+xml; charset=utf-8
), and an
optional headers
folder using the same scheme as the
default_headers
header specifications.
for example: if you wanted to handle 404s at my-cool-web.site
with
an HTML file, write the contents of said file at
./visible-to-httpd/configuration/error_response_pages/404/my-cool-web.site/message_body
,
and place text/html
in a file Content-Type
in the same folder.
the error response code has a generic fallback built into the script.
you can override this using a -fallback
domain folder, like with
domain-level default_headers
.
./visible-to-httpd/configuration/overrides/
this directory allows you to override the extra headers sent along
with a resource, and attach a status code other than 200 with them. a
folder named after the specific resource (including a prepended
hostname) should may contain a status_code
file containing a
numerical status code and optional textual message, a
headers
folder, which specifies headers using the default_headers
scheme, and a Content-Type
file, to override any other mechanism for
determining the Content-Type to send to the client.
Note that a Content-Type
file in the headers
folder is always
ignored. This is also true for the other required or recommended
HTTP 1.1 headers always sent by httpd.execline, namely
Content-Length
, Date
, and Last-Modified
.
a former official website for httpd-execline.eerie.garden
used to redirect to this github repository, thanks to
./visible-to-httpd/configuration/overrides/httpd-execline.eerie.garden/index.xhtml/status_code
containing the text 301 moved permanently
; and./visible-to-httpd/configuration/overrides/httpd-execline.eerie.garden/index.xhtml/headers/Location
containing https://github.com/single-right-quote/httpd.execline
httpd_execline_default_index
: the file to default to if a resource matches
a directory. defaults to index.html
HTTPD_EXECLINE_GZIP
: if set, use gzip(1)
to compress found resources.HTTPD_EXECLINE_GENERATE_ETAGS
: if set, use cksum(1)
to generate ETag
s
for all resources on the flyHTTPD_EXECLINE_MAX_AGE
: if HTTPD_EXECLINE_CACHE
is set, this variable
controls the max-age directive. defaults to 604800