diff --git a/lib/reply.js b/lib/reply.js index bee18b3fa3..51bfc1b55e 100644 --- a/lib/reply.js +++ b/lib/reply.js @@ -457,7 +457,7 @@ function sendStream (payload, res, reply) { eos(payload, { readable: true, writable: false }, function (err) { sourceOpen = false if (err != null) { - if (res.headersSent) { + if (res.headersSent || reply.request.raw.aborted === true) { if (!errorLogged) { errorLogged = true logStreamError(reply.log, err, res) diff --git a/test/stream.test.js b/test/stream.test.js index 95f440ef02..da36519d85 100644 --- a/test/stream.test.js +++ b/test/stream.test.js @@ -694,3 +694,51 @@ test('should mark reply as sent before pumping the payload stream into response fastify.close() }) }) + +test('reply.send handles aborted requests', t => { + t.plan(2) + + const spyLogger = { + level: 'error', + fatal: () => { }, + error: () => { + t.fail('should not log an error') + }, + warn: () => { }, + info: () => { }, + debug: () => { }, + trace: () => { }, + child: () => { return spyLogger } + } + const fastify = Fastify({ + logger: spyLogger + }) + + fastify.get('/', (req, reply) => { + setTimeout(() => { + const stream = new Readable({ + read: function () { + this.push(null) + } + }) + reply.send(stream) + }, 6) + }) + + fastify.listen({ port: 0 }, err => { + t.error(err) + fastify.server.unref() + + const port = fastify.server.address().port + const http = require('http') + const req = http.get(`http://localhost:${port}`) + .on('error', (err) => { + t.equal(err.code, 'ECONNRESET') + fastify.close() + }) + + setTimeout(() => { + req.abort() + }, 1) + }) +})