diff --git a/CHANGES.md b/CHANGES.md index 422fa9972..4c4dbfd46 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -8,6 +8,14 @@ Version 2.0.4 To be released. +### @fedify/fastify + + - Fixed the default `onNotAcceptable` handler in `@fedify/fastify` to + create a fresh `Response` for each request instead of reusing a shared + singleton instance. [[#612] by Lee Dogeon] + +[#612]: https://github.com/fedify-dev/fedify/pull/612 + Version 2.0.3 ------------- diff --git a/packages/fastify/src/index.test.ts b/packages/fastify/src/index.test.ts index 3c58cc24e..a2f68c7e6 100644 --- a/packages/fastify/src/index.test.ts +++ b/packages/fastify/src/index.test.ts @@ -129,6 +129,43 @@ test("Fedify should handle notAcceptable and return 406", async () => { await fastify.close(); }); +test("Fedify should create a fresh 406 response for each request", async () => { + const fastify = Fastify({ logger: false }); + const federation = createFederation({ kv: new MemoryKvStore() }); + + federation.setActorDispatcher( + "/users/{identifier}", + (_ctx: RequestContext, identifier: string) => { + return new Person({ + id: new URL(`https://example.com/users/${identifier}`), + preferredUsername: identifier, + name: `User ${identifier}`, + }); + }, + ); + + await fastify.register(fedifyPlugin, { federation }); + await fastify.ready(); + + const firstResponse = await fastify.inject({ + method: "GET", + url: "/users/alice", + headers: { "Accept": "text/html" }, + }); + const secondResponse = await fastify.inject({ + method: "GET", + url: "/users/alice", + headers: { "Accept": "text/html" }, + }); + + assert.equal(firstResponse.statusCode, 406); + assert.equal(firstResponse.body, "Not Acceptable"); + assert.equal(secondResponse.statusCode, 406); + assert.equal(secondResponse.body, "Not Acceptable"); + + await fastify.close(); +}); + test("Fedify should handle notAcceptable with custom error handler", async () => { const fastify = Fastify({ logger: false }); const federation = createFederation({ kv: new MemoryKvStore() }); diff --git a/packages/fastify/src/index.ts b/packages/fastify/src/index.ts index 0d922a0cc..36f4b6370 100644 --- a/packages/fastify/src/index.ts +++ b/packages/fastify/src/index.ts @@ -76,7 +76,7 @@ const fedifyPluginCore: FastifyPluginAsync> = ( const response = await federation.fetch(webRequest, { contextData, - onNotAcceptable: () => defaultNotAcceptableResponse, + onNotAcceptable: createDefaultNotAcceptableResponse, onNotFound: () => dummyNotFoundResponse, ...errorHandlers, }); @@ -101,10 +101,11 @@ const fedifyPlugin: FastifyPluginAsync> = fp( ); const dummyNotFoundResponse = new Response("", { status: 404 }); -const defaultNotAcceptableResponse = new Response("Not Acceptable", { - status: 406, - headers: { "Content-Type": "text/plain", Vary: "Accept" }, -}); +const createDefaultNotAcceptableResponse = () => + new Response("Not Acceptable", { + status: 406, + headers: { "Content-Type": "text/plain", Vary: "Accept" }, + }); /** * Convert Fastify request to Web API Request.