opensource
opensource copied to clipboard
Anyways to set the file size limit for the `multipart/form-data`?
I see there is a common problem with formidable, just want to know is there a way to deal with file size limitation by the bytesReceived
from form.progress
?
Don't know what you mean. What problem? And what you're want to do? Is it just a question as I may be more familiar with formidable, or it is something formidable-related bug?
My bad, I just want to know is that a way to do the file size limitation from multipart/form-data
?
Anyway, I have made some dirty hack for my project. But what I want is to throw an error and close the connection when the user's upload file exceed certain limit.
Got it. Hm... I'll think, but why not just pass IncomingForm
instance? And before that add listener on the file
event, than you can just throw.
Something like that, could you try?
var form = new formidable.IncomingForm()
form.on('file', function (name, file) {
if (file.size > myAppConfig.maxFileSize) {
throw new Error('file sieze exceeded: ', JSON.stringify(file))
}
})
app.use(body({
multipart: true,
IncomingForm: form
}))
That was the reason behind v2 and v3, decoupling.
edit: That fileLimit
is a bit good idea. If something around above doesn't work, I can think to implement something. We can add check that checks file.size
against opts.textLimit
?
I opened and feature issue for that (it make sense and cost nothing), but you can still try my snippet.
Um... I tried that before and I know it works, but plain throw new error
are not a good way for my project since what I want is error propagation. I want to return a JSON result with error message, thus I got to:
- Modify the context, or
- Error that can be catch by koa instance
I was thinking about using form.on('progress')
event listener. Which is something like this:
form.on('progress', function(byteReceived, byteExpected) {
if (byteReceived > options.fileLimit) {
fields = buff && buff.length
? utils.extend({}, utils.parseQs(buff.slice(0, -1), options), fields)
: fields
throw new Error('Exceed file size limit')
// or
fields['_ERROR'] = 'too big'
done(null, {
fields: fields,
files: files
})
}
it can check from the byteReceived
which is more precise. Just my two cents.
Hm. I think to implement it in some way. Listening on progress
event is good idea, but it is for fields too, so i would be more tricky.
So i think to add a check in file
event that checks file.size
against options.fileLimit
and if so, add an object with error
property instead of a file object. So you can access it again by name, but if there is .error
so you can throw or do what you want.
form.on('file', (name, file) => {
if (file.size > options.fileLimit) {
files.push({ error: new Error('Exceed file size limit') }
} else {
files.push(file)
}
})
form.on('end', () => {
done({
fields: fields,
files: files
})
})
so later in the middlewares you can
app.use((ctx, next) => {
ctx.request.files.forEach(file => {
if (file.error) return ctx.throw(file.error.message);
console.log("file:", file);
});
});