diff --git a/src/index.js b/src/index.js index 2cad269f9..9e1151bc7 100644 --- a/src/index.js +++ b/src/index.js @@ -303,12 +303,18 @@ function fixResponseChunkedTransferBadEnding(request, errorCallback) { properLastChunkReceived = Buffer.compare(buf.slice(-3), LAST_CHUNK) === 0; }); - socket.prependListener('close', () => { + const onSocketClose = () => { if (!properLastChunkReceived) { const error = new Error('Premature close'); error.code = 'ERR_STREAM_PREMATURE_CLOSE'; errorCallback(error); } + }; + + socket.prependListener('close', onSocketClose); + + request.on('abort', () => { + socket.removeListener('close', onSocketClose); }); } }); diff --git a/test/main.js b/test/main.js index c50860e2f..a777cf583 100644 --- a/test/main.js +++ b/test/main.js @@ -684,6 +684,14 @@ describe('node-fetch', () => { }); }); + it('should follow redirect after empty chunked transfer-encoding', () => { + const url = `${base}redirect/chunked`; + return fetch(url).then(res => { + expect(res.status).to.equal(200); + expect(res.ok).to.be.true; + }); + }); + it('should handle DNS-error response', () => { const url = 'http://domain.invalid'; return expect(fetch(url)).to.eventually.be.rejected diff --git a/test/utils/server.js b/test/utils/server.js index b9ba35188..32aa070fe 100644 --- a/test/utils/server.js +++ b/test/utils/server.js @@ -297,6 +297,14 @@ export default class TestServer { res.socket.end('\r\n'); } + if (p === '/redirect/chunked') { + res.writeHead(301, { + Location: '/inspect', + 'Transfer-Encoding': 'chunked' + }); + setTimeout(() => res.end(), 10); + } + if (p === '/error/400') { res.statusCode = 400; res.setHeader('Content-Type', 'text/plain');