user1272965 user1272965 - 29 days ago 19
Node.js Question

How to cleanup temp files using multer

My nodejs app accepts file uploads from users with permission that's enforced by express middleware, and it uses multer.

A typical route authenticates, checks if the user is permitted, then does the import, e.g.:

router.post('/:id/import', passport.authenticate('jwt', { session: false }), permit('admin'), function(req, res, next) {
MyClass.doImport(req.file.path).then(function(result) {
res.json(result);
}).catch(function(error) {
res.status(500).json(error);
});
});


When there's no error, this works great, and the import function deletes the file. But in the case of an error (like an invalid or non-permitted user), the uploaded file is created and remains on disk.

I'd like to not create any files on disk until all of the the permission middleware has run successfully. I've tried using multer as very end of the chain, i.e.:

var app = express();

app.use( // ...

app.use(passport.initialize());
app.use(multer({dest:'./tmp/'}).single('file'));


but on an auth error, I still end up with a file in tmp.

How can I avoid creating a file on disk until all other middleware passes?

If that's not possible, can I add a middleware function that runs only if there's a file attachment and there's an error upstream?

Answer

Move your multer middleware so that it gets executed only right before the relevant route handler(s). That way if any other middleware "rejects" the request, you do not have temporary files left over. For example:

function isLoggedIn(req, res, next) {
  if (req.isAuthenticated())
    return next();
  res.redirect('/');
}
var fileUpload = multer({dest:'./tmp/'}).single('file');

var app = express();
// ...
app.use(passport.initialize());
// ...
app.put('/upload', isLoggedIn, fileUpload, function(req, res) {
  // use `req.file`
});