diff --git a/Makefile b/Makefile index a80d1f9..eaa242a 100644 --- a/Makefile +++ b/Makefile @@ -89,6 +89,9 @@ conformance-local: @$(RUN_LOCAL) examples/fastify-basic.ts 8081 \ sh -c 'npx artillery run --target http://localhost:8081 --config $(TEST_KIT)/configs/conformance.yml $(TEST_KIT)/scenarios/core/conformance.yml && \ npx artillery run --target http://localhost:8081 --config $(TEST_KIT)/configs/conformance.yml $(TEST_KIT)/scenarios/s3proxy/error-contract.yml' + @echo "Running key-addressed (fetchWebKey) conformance against examples/hono-basic.ts on :8083..." + @$(RUN_LOCAL) examples/hono-basic.ts 8083 \ + npx artillery run --target http://localhost:8083 --config $(TEST_KIT)/configs/conformance.yml $(TEST_KIT)/scenarios/s3proxy/key-addressed.yml .PHONY: validation-local validation-local: diff --git a/examples/hono-basic.ts b/examples/hono-basic.ts index 2654250..0c7e40a 100644 --- a/examples/hono-basic.ts +++ b/examples/hono-basic.ts @@ -30,6 +30,22 @@ app.get('/health', async (c) => { app.get('/', (c) => c.redirect('/index.html')); +// fetchWebKey() names the S3 key explicitly — the URL does NOT select the key. +// This alias map stands in for a real lookup (a DB row, a signed-token resolver, +// a per-tenant prefix): the public id is decoupled from the storage key, and the +// key is served verbatim, so keys with reserved characters (%, spaces, +, ...) +// need no URL-encoding contortions — the exact failure fetchWeb's URL path can't +// avoid. `special` points at an object whose key is a pile of reserved chars. +const KEY_ALIASES: Record = { + home: 'index.html', + special: 'specialCharacters!-_.*\'()&$@=;:+ ,?\\{^}%`]">[~<#|.', +}; +app.get('/download/:id', (c) => { + const key = KEY_ALIASES[c.req.param('id')]; + if (key === undefined) return new Response('unknown id', { status: 404 }); + return proxy.fetchWebKey(key, c.req.raw); +}); + // fetchWeb adapts the Web `Request` -> `Response` in one line, so nothing here // re-encodes the library's HttpRequest shape or the stream conversion. It throws // the typed S3ProxyError on 404/403/416, which the app's onError below renders. diff --git a/package-lock.json b/package-lock.json index a69f4e2..746a55e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,7 +14,7 @@ "devDependencies": { "@aws-sdk/client-s3": "^3.832.0", "@biomejs/biome": "^2.0.4", - "@forkzero/s3-website-test-kit": "^0.4.0", + "@forkzero/s3-website-test-kit": "^0.5.0", "@hono/node-server": "^2.0.0", "@types/debug": "^4.1.12", "@types/express": "^5.0.3", @@ -2021,9 +2021,9 @@ } }, "node_modules/@forkzero/s3-website-test-kit": { - "version": "0.4.0", - "resolved": "https://registry.npmjs.org/@forkzero/s3-website-test-kit/-/s3-website-test-kit-0.4.0.tgz", - "integrity": "sha512-UziHuWnDFfniSl7+TFz6XxLG78TEma39kT3KLhs6BnOx47LC6Vy+O5HvrOkhvf9aRtFMkpqaNKRE6kkjNE5ulg==", + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/@forkzero/s3-website-test-kit/-/s3-website-test-kit-0.5.0.tgz", + "integrity": "sha512-/XKwCG/E9kFfpKJ1VDpPSK8rl3dchyj3F50J+VMRxFZa6E56ggNiLkYBb+42rScZghUTUYOdi91hi3JhRonVUQ==", "dev": true, "license": "Apache-2.0", "bin": { diff --git a/package.json b/package.json index 181cac1..cc25703 100644 --- a/package.json +++ b/package.json @@ -18,7 +18,7 @@ "devDependencies": { "@aws-sdk/client-s3": "^3.832.0", "@biomejs/biome": "^2.0.4", - "@forkzero/s3-website-test-kit": "^0.4.0", + "@forkzero/s3-website-test-kit": "^0.5.0", "@hono/node-server": "^2.0.0", "@types/debug": "^4.1.12", "@types/express": "^5.0.3",