diff --git a/README.md b/README.md index 930fc43c..2fd661a8 100644 --- a/README.md +++ b/README.md @@ -380,6 +380,20 @@ the `content-length` header. } ``` +`onResponse` may also be async when you need to read the upstream response +before sending a replacement body: + +```js +{ + async onResponse (request, reply, res) { + const data = await new Response(res.stream).json() + reply.send({ ...data, proxied: true }) + } +} +``` + +Handle errors inside async `onResponse` callbacks before replying. + **Note**: `onResponse` is called after headers have already been sent. If you want to modify response headers, use the `rewriteHeaders` hook. #### `onError(reply, error)` diff --git a/test/onResponse.test.js b/test/onResponse.test.js index b442a71d..f3213ea4 100644 --- a/test/onResponse.test.js +++ b/test/onResponse.test.js @@ -40,3 +40,38 @@ t.test('onResponse', async (t) => { t.assert.strictEqual(result.statusCode, 200) t.assert.strictEqual(await result.body.text(), 'hello world') }) + +t.test('async onResponse', async (t) => { + t.plan(6) + + const instance = Fastify() + instance.register(From) + t.after(() => instance.close()) + + const target = http.createServer((req, res) => { + t.assert.ok('request proxied') + t.assert.strictEqual(req.method, 'GET') + res.statusCode = 200 + res.end('hello world') + }) + + instance.get('/async', (request1, reply) => { + reply.from(`http://localhost:${target.address().port}`, { + async onResponse (request2, reply, res) { + await Promise.resolve() + t.assert.strictEqual(res.statusCode, 200) + t.assert.strictEqual(request1.raw, request2.raw) + reply.send(res.stream) + } + }) + }) + + t.after(() => target.close()) + + await instance.listen({ port: 0 }) + await new Promise(resolve => target.listen({ port: 0 }, resolve)) + + const result = await request(`http://localhost:${instance.server.address().port}/async`) + t.assert.strictEqual(result.statusCode, 200) + t.assert.strictEqual(await result.body.text(), 'hello world') +}) diff --git a/types/index.d.ts b/types/index.d.ts index 6a8fb272..c806ba28 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -75,7 +75,7 @@ declare namespace fastifyReplyFrom { request: FastifyRequest, reply: FastifyReply, res: RawServerResponse - ) => void; + ) => void | Promise; onError?: ( reply: FastifyReply, error: { error: Error } diff --git a/types/index.tst.ts b/types/index.tst.ts index 5e2bf6f8..d544bbd8 100644 --- a/types/index.tst.ts +++ b/types/index.tst.ts @@ -89,6 +89,16 @@ app.get('/v3', (_request, reply) => { }) }) +app.get('/async-on-response', (_request, reply) => { + reply.from('/async-on-response', { + async onResponse (request, reply, res) { + expect(request).type.toBe>() + expect(reply).type.toBe>() + expect(res).type.toBe>() + } + }) +}) + app.get('/http2', (_request, reply) => { reply.from('/', { method: 'POST',