Skip to content

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

Description

@zfowed

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 });
            });

        });


    };

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions