gateway: auto-index directory paths for s3 records

silentmode.bch/tools/ was returning the Sia NoSuchKey XML because the
gateway only auto-appended index.html for the root path (/), not for
sub-directory paths (/tools/, /apps/, etc). Trailing-slash URLs now
resolve to <path>/index.html — matches Ariadne's bnsd.js which already
had the same rewrite on the client side.

Verified: /bns/silentmode.bch/tools/ returns 200 with the tools page
(was 404 NoSuchKey).

Fixes the user-reported "download link on silentmode.bch/tools/#theseus
shows an XML NoSuchKey error" — the browser was requesting /tools/
(trailing slash from the URL path), gateway looked up bucket key
bns/silentmode/tools/ which doesn't exist, forwarded the S3 error.

Deployed on the VPS (/opt/bns-gateway/) with the in-place edit path
that keeps the same-dir import shape there (repo has ../lib/, VPS has
./resolver-web.js — the two file layouts intentionally differ).
This commit is contained in:
Local Dev 2026-08-29 13:27:42 +02:00
parent f77c6558ee
commit 5b65be2483

View file

@ -171,7 +171,14 @@ async function serve(res, name, reqPath, baseHref) {
case "s3": {
const sub = subFolder(name);
let base = r.s3; if (base.endsWith("/") && sub) base += sub + "/";
const key = base.endsWith("/") ? base + (reqPath === "/" ? "index.html" : reqPath.slice(1)) : base;
// Auto-index directory paths. S3 has no dir listing, so `/tools/`
// would 404 (NoSuchKey) without this — matches how nginx handles
// `try_files … /index.html` and how Ariadne's bnsd.js rewrites the
// same URLs client-side.
const rel = reqPath === "/" ? "index.html"
: reqPath.endsWith("/") ? reqPath.slice(1) + "index.html"
: reqPath.slice(1);
const key = base.endsWith("/") ? base + rel : base;
const up = await aws.fetch(`${S3_ENDPOINT}/${key}`);
const buf = Buffer.from(await up.arrayBuffer());
let ct = up.headers.get("content-type"); if (!ct || ct === "application/octet-stream") ct = guess(key);