Different file size limitation based on file type
I have an endpoint to upload files. I would like to have different file size limits depending on the file type. Images size limit =< .5 MB and PDF size limit =< 2MB.
The limits.fileSize options only allows for one value, and I can't do it in the fileFilter property either... So how could I do it?
I think you should be able to do it with the fileFilter property?
function fileFilter (req, file, cb) {
if (file.mimetype === 'application/pdf' && file. size > 2 * 1014 * 1024) {
return cb(new Error('File too large'))
}
cb(null, true)
}
@LinusU , I can't get 'size' from file inside fileFilter(), other fields are: { fieldname: 'xxxx', originalname: 'xxxx-xxxx.jpg', encoding: '7bit', mimetype: 'image/jpeg' }
version: "multer": "^1.3.0"
Ah, I see 🤔
Right, I remember now, yeah the length is not given prior to consuming the stream...
Hmm, this is currently unsupported, any suggestions on how an API might look?
Also, in the 2.0 alpha you should be able to do this fairly easy:
(req, res, next) => {
switch (req.file.detectedMimeType) {
case 'image/jpeg':
case 'image/png':
case 'image/gif':
if (req.file.size > 512 * 1024) {
return next(new Error('File too large'))
}
break
case 'application/pdf':
if (req.file.size > 2 * 1024 * 1024) {
return next(new Error('File too large'))
}
break
default:
return next(new Error('Unspported file type'))
}
// Use `req.file` here
}
Considering https://github.com/expressjs/multer/issues/568 this will not remove the temp file and file handle will not be closed.
@ecmel They should be unlinked as soon as they are opened, which should happen regardless of whether you read the file or not:
https://github.com/expressjs/multer/blob/c4b223efc4730611f7c6bfe9608bfd4048e3754d/lib/middleware.js#L24-L32
That issue was originally opened about an EPERM error...
But as far as I understand, if there is an error and next is called with an error the file will never be opened and never removed from temp
Am I wrong?
The file will be opened shortly after the call to createReadStream so the temporary file will be removed. This should be easy to confirm as well.
However, I just realized that there is an FD leak going on when ReadStream is garbage collected... made some comments about it here: #570
Hi @LinusU
I have the same problem on Multer 1.4.2. I need to limit the file size on base of the file type for my project. It would be really nice, if that would be possible inside the file filter function.
Or can you expect when there will be a stable release for Multer 2.0?
there is size of file in req.rawHeaders(it a array) in my request last item is size of file so I used (req.rawHeaders.slice(-1)[0]) ,after that I write a logic in fileFilter based on type file, It's work to me, multer should be .any
in this logic, size of .pdf < 1 Mb and .png,.jpeg,.jpg < 4 Mb
const multer = require('multer');
const { v4: uuid } = require("uuid");
const TYPE_IMAGE = {
'image/png': 'png',
'image/jpeg': 'jpeg',
'image/jpg': 'jpg'
};
const TYPE_File = {
'application/pdf': 'pdf',
};
const fileUpload =
multer({
limits: 500000,
storage: multer.diskStorage({
destination: (req, file, cb) => {
cb(null, 'uploads/images');
},
filename: (req, file, cb) => {
const ext = (TYPE_IMAGE[file.mimetype]) ? TYPE_IMAGE[file.mimetype] : TYPE_File[file.mimetype];
cb(null, uuid() + '.' + ext);
}
}),
fileFilter: (req, file, cb) => {
let size = +req.rawHeaders.slice(-1)[0]
let isValid =false;
if(!!TYPE_IMAGE[file.mimetype] && size < 4 * 1024 * 1024 ){
isValid = true
}
if(!!TYPE_File[file.mimetype] && size < 1 * 1024 * 1024 ){
isValid = true
}
let error = isValid ? null : new Error('Invalid mime type!');
cb(error, isValid);
}
}).any();
module.exports = fileUpload;
+req.rawHeaders.slice(-1)[0] is giving size of full content we are uploading , if we are passig an array of fiels and wants to validate size of each file inside array then this solution is not helping.
is there any other solution thrugh which we can get size of each file of array inside filefilter ?