Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -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:
Expand Down
16 changes: 16 additions & 0 deletions examples/hono-basic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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<string, string> = {
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.
Expand Down
8 changes: 4 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -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",
Expand Down
Loading