Skip to content

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

@zfowed

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

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions