From c489c4b68884bc067e1982e457f07a6711ec6a0d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladimir=20Adami=C4=87?= Date: Mon, 15 Mar 2021 11:25:52 +0100 Subject: [PATCH] Test calling finished if one of the streams closes prematurely (#213) * Test calling finished if one of the streams closes prematurely * Simplify eos callback logic - remove callDoneOnNextEos and count --- index.js | 17 +-------- test/legacy/multipart.test.js | 72 +++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+), 16 deletions(-) diff --git a/index.js b/index.js index 1fc5624d..fb39b444 100644 --- a/index.js +++ b/index.js @@ -227,8 +227,6 @@ function fastifyMultipart (fastify, options, done) { const stream = busboy(busboyOptions) let completed = false let files = 0 - let count = 0 - let callDoneOnNextEos = false req.on('error', function (err) { stream.destroy() @@ -240,11 +238,9 @@ function fastifyMultipart (fastify, options, done) { stream.on('finish', function () { log.debug('finished receiving stream, total %d files', files) - if (!completed && count === files) { + if (!completed) { completed = true setImmediate(done) - } else { - callDoneOnNextEos = true } }) @@ -270,17 +266,6 @@ function fastifyMultipart (fastify, options, done) { if (err) { completed = true done(err) - return - } - - if (completed) { - return - } - - ++count - if (callDoneOnNextEos && count === files) { - completed = true - done() } } diff --git a/test/legacy/multipart.test.js b/test/legacy/multipart.test.js index 233ffdbe..54e58b39 100644 --- a/test/legacy/multipart.test.js +++ b/test/legacy/multipart.test.js @@ -139,6 +139,78 @@ test('should call finished when both files are pumped', { skip: process.platform }) }) +test('should call finished if one of the streams closes prematurely', { skip: process.platform === 'win32' }, function (t) { + t.plan(5) + + const fastify = Fastify({ + logger: { + level: 'debug' + } + }) + t.tearDown(fastify.close.bind(fastify)) + + fastify.register(multipart) + + fastify.post('/', function (req, reply) { + let fileCount = 0 + t.ok(req.isMultipart()) + + req.multipart(handler, function () { + t.equal(fileCount, 1) + reply.code(200).send() + }) + + function handler (field, file, filename, encoding, mimetype) { + const saveTo = path.join(os.tmpdir(), path.basename(filename)) + eos(file, function () { + fileCount++ + }) + + file.on('data', function () { + if (fileCount === 0) { + this.destroy() + } + }) + + pump(file, fs.createWriteStream(saveTo), () => {}) + } + }) + + fastify.listen(0, function () { + // request + const form = new FormData() + const opts = { + protocol: 'http:', + hostname: 'localhost', + port: fastify.server.address().port, + path: '/', + headers: form.getHeaders(), + method: 'POST' + } + + const stream1 = fs.createReadStream(filePath) + + const req = http.request(opts, (res) => { + t.equal(res.statusCode, 200) + res.resume() + res.on('end', () => { + t.pass('res ended successfully') + }) + }) + + form.append('upload1', stream1, { + filename: 'random-data1' + }) + form.append('upload2', stream1, { + filename: 'random-data2' + }) + + pump(form, req, function (err) { + t.error(err, 'client pump: no err') + }) + }) +}) + test('should error if it is not multipart', { skip: process.platform === 'win32' }, function (t) { t.plan(4)