From 0396988124a92d224e9500a79a5e2f62e454aaa5 Mon Sep 17 00:00:00 2001 From: Local Dev Date: Sun, 20 Sep 2026 17:31:49 +0200 Subject: [PATCH] fix(gateway): baseHref per current directory, not per site root MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The path-form handler injected `` on every page regardless of the sub-path being viewed. That meant a subdirectory page's relative-parent links resolved wrong: from /bns/theseus.x/extensions/ the page's `` was resolved against the base as /bns/plug-ins/ — dropping the name, giving a 404. Compute baseHref from the directory of the current sub-path instead (everything before the last "/" in rest, defaulting to "/"). Now: /bns/theseus.x/ → /bns/theseus.x/plug-ins/ → /bns/theseus.x/plug-ins/x.html → /bns/theseus.x/extensions/ → `../plug-ins/` from the extensions page now resolves correctly to /bns/theseus.x/plug-ins/, and `./` on a subdirectory page resolves to the subdirectory itself instead of the site root. Verified end-to-end: clicking Plug-ins from Extensions preserves the name in the URL. Assets loaded via `../assets/...` from any subdirectory still resolve correctly (they now go up exactly one level, to the site root). --- src/gateway/public-gateway.mjs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/gateway/public-gateway.mjs b/src/gateway/public-gateway.mjs index d3db881..1bd4d2a 100644 --- a/src/gateway/public-gateway.mjs +++ b/src/gateway/public-gateway.mjs @@ -1749,7 +1749,15 @@ const server = http.createServer(async (req, res) => { if (!m) { res.writeHead(400, { "content-type": "text/html" }); return res.end(`usage: ${MOUNT}/./`); } const name = m[1].toLowerCase(); const rest = m[2] || "/"; - return serve(res, name, rest, `${MOUNT}/${name}/`); + // baseHref must point at the CURRENT DIRECTORY, not the site root. + // If we injected `` on every page, then a + // relative link like `../plug-ins/` on a subdirectory page (e.g. + // /bns/theseus.x/extensions/) resolves against the base — landing on + // /bns/plug-ins/, dropping the name. Using the directory of `rest` + // makes `.`, `..`, `foo/`, `../bar/` all resolve as the browser would + // if the site were served from its own origin. + const restDir = rest.replace(/[^/]*$/, "") || "/"; + return serve(res, name, rest, `${MOUNT}/${name}${restDir}`); } catch (e) { res.writeHead(500); res.end("gateway error: " + e.message); } }); server.listen(PORT, "127.0.0.1", () => console.log(`bns public gateway on 127.0.0.1:${PORT} (path ${MOUNT}, subdomain *.${SUB_BASE})`));