Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How can the server automatically interrupt the file transfer? #456

Closed
zfowed opened this issue Dec 24, 2017 · 4 comments
Closed

How can the server automatically interrupt the file transfer? #456

zfowed opened this issue Dec 24, 2017 · 4 comments

Comments

@zfowed
Copy link

zfowed commented Dec 24, 2017

Now I have a need, that is, you want to limit the number of customer-side upload files.

Assuming the server now want to limit the client can only upload a file, then it is possible to detect the client is the time to upload the first two files on the initiative to interrupt transmission ? This is just an example, as well as a single file size limit, file type, file extension, etc.

I read the API seems to filter only some of the files, although not stored in the file, but the client actually upload the file stream.

I was wondering if it was possible to take the initiative to throw a bit off the onprogress, onfileBegin, onfile, etc. interrupts the transfer and called onerror.

ps: Forgive me for not going to English, all Google Translate.

mart of my code:

    /** 初始默认配置 */
    const options = {
        dir: null,
        bytesExpected: 10 * 1024 * 1024,
        maxFieldsSize: 2 * 1024 * 1024,
        maxFields: 1000,
        multiples: false,
        hash: false,
        fileNum: 1,
        fileSize: 10 * 1024 * 1024,
        fileType: null,
        fileExt: null,
    };

    const getFormidable = async function (request, option) {
        return new Promise(async (resolve, reject) => {
            
            /** 初始化配置对象 */
            if (utils.lodash.isUndefined(option)) {
                option = {};
            }

            /** 检查配置对象 */
            if (!utils.lodash.isPlainObject(option)) {
                return throwError(new Error('${option} 必须是一个普通对象!'));
            }

            option = utils.lodash.merge(options, option);

            let error = checkOption(options);

            const throwError = function (err) {
                request.pause();
                error = err;
                return reject(err);
            };

            if (utils.lodash.isError(error)) {
                return throwError(error);
            }

            var form = new formidable.IncomingForm();

            if (form.bytesExpected > option.bytesExpected) {
                return throwError(new Error(`字节预期不可以超过${option.bytesExpected}字节!`));
            }

            form.encoding = 'utf-8';
            if (uploadDir) form.uploadDir = utils.rootJoin(uploadDir);
            form.keepExtensions = false;
            // form.type = 'multipart';
            form.maxFieldsSize = option.maxFieldsSize;
            form.maxFields = option.maxFields;
            form.multiples = option.multiples;
            form.hash = option.hash;

            let fileNum = 0;

            form.onPart = function (part) {
                if (option.fileNum) {
                    if (part.filename) { fileNum += 1; }
                    if (fileNum > option.fileNum) {
                        return throwError(new Error(`上传文件数量不可以超过${option.fileNum}个!`));
                    }
                }
                if (option.fileExt && !option.fileExt.includes(utils.path.extname(part.filename))) {
                    return throwError(new Error(`上传文件后缀名必须是(${option.fileExt})!`));
                }
                form.handlePart(part);
            };

            form.on('progress', function (bytesReceived, bytesExpected) {
                if (bytesExpected > option.bytesExpected) {
                    return throwError(new Error(`字节预期不可以超过${option.bytesExpected}字节!`));
                }
            });

            // form.on('field', function (name, value) { });
            
            form.on('fileBegin', function (name, file) {
                if (option.fileType && !option.fileType.includes(file.type)) {
                    return throwError(new Error(`上传文件类型必须是(${option.fileType})!`));
                }
            });

            form.on('file', function (name, file) {
                if (file.size > option.fileSize) {
                    return throwError(new Error(`上传文件大小不可以超过${option.fileSize}字节!`));
                }
            });

            form.on('error', function (err) {
                return throwError(err);
            });

            form.on('aborted', function () {
                return throwError(new Error(`当前请求被用户发出中止时!`));
            });

            // form.on('end', function () { });

            form.parse(request, function (err, fields, files) {
                if (err) return throwError(err);
                if (error) return throwError(error);
                return resolve({ fields, files });
            });

        });


    };
@DennisJames
Copy link

我最近也有个需求是,在formidable把文件存储到临时目录之前先判断文件的类型,不符合要求就终止上传,例如可执行文件就不能让formidable存储到临时目录上,应该跟你描述的有相同之处,有解决方案吗?

@zfowed
Copy link
Author

zfowed commented May 1, 2018

@DennisJames 我上面的代码就可以啊,这是我实际项目上传中的部分核心代码,可以限制上传的字节预期,文件数量,文件后缀名,文件数量,文件类型,文件大小,

@xarguments
Copy link
Collaborator

Seems to be related with this feature request #471. Can you confirm that?
P.S. @DennisJames, @zfowed, Please write in English. Your comments may be useful, but they are not readable.

@GrosSacASac
Copy link
Contributor

Try https://github.com/node-formidable/formidable/tree/filter-upload and use the filter function

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants