Description
Support plan
- Which support plan is this issue covered by? (Community, Sponsor, Enterprise): Community
- Currently blocking your project/work? (yes/no): no
- Affecting a production system? (yes/no): no
Context
- Node.js version: 18.20.4
- Release Line of Formidable (Legacy, Current, Next): latest
- Formidable exact version: 3.5.2
- Environment (node, browser, native, OS): node
- Used with (popular names of modules):
What are you trying to achieve or the steps to reproduce?
I am setting options.maxFiles to 1 to ensure that only 1 file is received per request. When I am testing this, I find that if the request carries more files than options.maxFiles, some file handles created by formidable are not released until the nodejs process is terminated.
import express from 'express'
import formidable from 'formidable'
import fs from 'fs'
const app = express()
app.post('/', (req, res, next) => {
const form = formidable({
maxFiles: 1,
uploadDir: './uploads',
keepExtensions: true,
})
const filePaths = []
form.on('fileBegin', (_, file) => {
filePaths.push(file.filepath)
})
form.parse(req)
.then(() => res.json('success'), err => res.json(err.message))
.then(() => {
setImmediate(() => {
filePaths.forEach(path => {
fs.promises.unlink(path)
.then(() => {
console.log(`unlink ${path}`)
}, console.log)
})
})
})
})
app.listen(8080)
Here's what I found.
The function _handlePart does thing like this:
- emit the fileBegin event
- open file (creating the write stream)
- push file to this.openedFiles
How the bug comes:
- files received and fileBegin event emitted, causing the maxFiles check to emit an error
- formidable destroys files in this.openedFiles due to the error
- _handlePart goes on and write streams are still opened even if there is an error occurred
- those file handles can never be closed
I think maybe the solution is checking this.error between emitting the fileBegin event and file.open() in _handlePart
What was the result you got?
Files are deleted but the file handles are not released until the termination of the nodejs process.
On windows, those files are still shown in the file explorer and can not be opened/deleted.
On linux, the result of "lsof" is something like:
1 /usr/local/bin/node 27 /usr/local/app/uploads/67656e2415a12ae1195c86f01.jpg (deleted)
What result did you expect?
Files handles are released when formidable finishes its job, with or without errors