node-formidable / formidable

The most used, flexible, fast and streaming parser for multipart form data. Supports uploading to serverless environments, AWS S3, Azure, GCP or the filesystem. Used in production.
MIT License
7k stars 680 forks source link

maxFiles options doesn't work #901

Closed bottom-up-ai closed 12 months ago

bottom-up-ai commented 1 year ago

Support plan

Context

What are you trying to achieve or the steps to reproduce?

I try to limit the maxFiles option to 1, but when I upload 3 files, the 3 get uploaded in the corresponding folder.

const form = formidable({
        uploadDir: `${__dirname}/uploads`,
        maxFiles: 1
});

form.parse(req, (err, fields, files) => {
        console.log('ERR', err)
        console.log('FIELDS', fields)
        console.log('FILES', files)
});

What was the result you got?

3 files uploaded in folder

What result did you expect?

1 file uploaded in folder

bottom-up-ai commented 1 year ago

Temporary fix :

let countFileUploaded = 0;

const form = formidable({
        uploadDir: `${__dirname}/uploads`,
        keepExtensions: true,
        // maxFiles: 1,
        filter: () => {
            if (countFileUploaded === 1) return false;

            countFileUploaded += 1;

            return true;
        }
});
GrosSacASac commented 1 year ago

Try again with version 3

bottom-up-ai commented 1 year ago

It breaks my application with version 3, as I'm using CommonJS instead of ESModule.

Will you add support for both CJS & ESM ?

EDIT :

I created another project for testing purposes.

It doesn't seem to work perfectly though.

Scenario 1 :

const form = formidable({
        uploadDir: `./uploads`,
        maxFiles: 1
});

I try to upload 4 files, only 1 gets uploaded : Success.

Scenario 2 :

const form = formidable({
        uploadDir: `./uploads`,
        maxFiles: 2
});

I try to upload 4 files, only 1 gets uploaded : Failure.

Scenario 3 :

const form = formidable({
        uploadDir: `./uploads`,
        maxFiles: 3
});

I try to upload 4 files, only 2 get uploaded : Failure.

Scenario 4 :

const form = formidable({
        uploadDir: `./uploads`,
        maxFiles: 4
});

I try to upload 4 files, only 4 get uploaded : Success.

Scenario 5 :

const form = formidable({
        uploadDir: `./uploads`,
        maxFiles: 5
});

I try to upload 5 files, only 4 get uploaded : Failure.

tunnckoCore commented 1 year ago

@bottom-up-ai ha, that looks very weird, definitely.

As about CJS support... I don't want to, but unfortunately seems like we should and we will...

GrosSacASac commented 12 months ago

If the number of files uploaded is greater than the max, the whole form is going to error. By the time that happens there maybe a lower number of files written to disk. The files that are ongoing are cancelled.

That is why Scenario 2 :

const form = formidable({ uploadDir: ./uploads, maxFiles: 2 });

I try to upload 4 files, only 1 gets uploaded : Failure. When formidable received the 3rd file the second one still being written to disk is cancelled.

As for scenario 5 I was not able to reproduce it. Please provide a repro case.

GrosSacASac commented 12 months ago

To make formidable not error use the filter option instead. If it does not error it will not cancel ongoing write operations, which means you will have exactly the maximum files uploaded