site/wrangler.jsonc puts site/dist/ behind bench.12vectors.com as static
assets. No `main`: the site is files, and a Worker with no script is the
cheapest correct way to serve them.
html_handling force-trailing-slash, so /x redirects to /x/ — the
url the pages link and rel=canonical names. One
page, one address; no url ends in .html.
not_found_handling 404-page, so an unknown path gets dist/404.html
with a 404 status rather than the landing page
with a 200.
routes bench.12vectors.com as a custom domain. Cloudflare
takes the hostname at the zone level and makes the
DNS record; nothing else on 12vectors.com moves.
site/root/_headers carries the response policy. HTML revalidates on
every view, so a deploy is visible on the next reload without anyone
clearing a cache; /static/* is kept for a year and never re-checked,
which is safe because the stylesheet and icon urls carry a hash of their
contents. The general rule is written first and the specific one second,
so a host that merged the two instead of overriding would still land on
max-age=0 — the safe side. Alongside it the baseline a public page owes:
nosniff, a referrer policy, a year of HSTS without preload,
X-Frame-Options, and a default-src 'none' CSP that makes "no analytics,
no third-party anything" something the browser enforces rather than
something a test asserted once.
Deploys are run by hand, as releases already are — no Cloudflare token
in repository secrets, no first deploy pipeline. site/README.md names
the account, the Worker, the route and the four-command sequence, plus
the four things to check after a deploy that no test here can reach.
The tests cover everything before Cloudflare: that the config says what
the site needs, that the build writes the files it names, and that
wrangler.jsonc, pages.json and README.md cannot drift apart about which
domain this is. A live response is not among them.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
43 lines
2.3 KiB
Plaintext
43 lines
2.3 KiB
Plaintext
# Response headers for bench.12vectors.com.
|
|
#
|
|
# Read by Cloudflare Workers static assets at deploy time — the file is
|
|
# consumed, never served — and copied here from site/root/ by
|
|
# site/build.py, because the host looks for it at the root of the build
|
|
# and nowhere else.
|
|
#
|
|
# Rules apply in order and a later rule wins on a header it repeats. The
|
|
# two blocks below are written so that even a host that merged them
|
|
# instead would land on the safe side: HTML would still revalidate.
|
|
|
|
# Everything, so that no page can ever forget one of these.
|
|
#
|
|
# nosniff a text/plain file must not become a script
|
|
# Referrer-Policy a full url is never sent to another origin
|
|
# HSTS one year, this host and anything below it. No
|
|
# `preload`: that is a submission to browser
|
|
# vendors and a commitment this card did not make
|
|
# X-Frame-Options nothing here is meant to be framed
|
|
# CSP the runtime form of the site's own promise —
|
|
# no analytics, no font CDN, no third-party
|
|
# anything. `default-src 'none'` means an asset
|
|
# must be named below to load at all, and no
|
|
# 'unsafe-inline' anywhere means an injected
|
|
# <script> does not run
|
|
# Cache-Control HTML revalidates on every view, so a deploy is
|
|
# visible on the next reload. The ETag makes that
|
|
# a 304 rather than a re-download
|
|
/*
|
|
X-Content-Type-Options: nosniff
|
|
Referrer-Policy: strict-origin-when-cross-origin
|
|
Strict-Transport-Security: max-age=31536000; includeSubDomains
|
|
X-Frame-Options: DENY
|
|
Content-Security-Policy: default-src 'none'; style-src 'self'; font-src 'self'; img-src 'self'; connect-src 'self'; base-uri 'none'; form-action 'none'; frame-ancestors 'none'
|
|
Cache-Control: public, max-age=0, must-revalidate
|
|
|
|
# The stylesheet and the icon are linked with a ?v=<hash> of their own
|
|
# contents (site/build.py, stamp()), and the fonts never change under a
|
|
# given filename. All of it is safe to keep for a year and never check:
|
|
# a deploy that changes the stylesheet changes the url that asks for it.
|
|
/static/*
|
|
Cache-Control: public, max-age=31536000, immutable
|