#StackBounty: #javascript #node.js #stream #multipartform-data #uwebsockets Reading multipartform-data stream correctly (NodeJS)

Bounty: 50

I’m trying to receive a multipartform-data stream which might include various files and fields and to write the files to a directory (uWebsockets.js server).
I have this code:

    let boundary = null;
    let fields = [];
    let streams = [];
    let keep = false;
    res.onData((chunk, isLast) => {
        const buff = Buffer.concat([Buffer.from(chunk)]).toString('binary').split('rn');
        if (!boundary) {
            boundary = buff[0];
        }
        for (let i = 0; i < buff.length; i++) {

            const line = buff[i];
            if (i > 0 && i < buff.length - 1 && line == '') {
                keep = true;
                continue;
            }
            if (line == boundary || line == boundary + '--') {
                keep = false;
                if (streams[fields.length - 1]) {
                    streams[fields.length - 1].end();
                }
            }
            if (line == boundary) {
                fields[fields.length] = {};
            }

            if (line.includes('Content-Disposition')) {
                if (line.includes('filename="')) {
                    fields[fields.length - 1].filename = getFilename(line);
                    fields[fields.length - 1].type = 'file';
                    fields[fields.length - 1].path = path.resolve(options.uploadPath + fields[fields.length - 1].filename);
                    streams[fields.length - 1] = fs.createWriteStream(
                        path.resolve(options.uploadPath + fields[fields.length - 1].filename)
                    );
                } else {
                    fields[fields.length - 1].type = 'field';
                }
                fields[fields.length - 1].name = getField(line);
            }
            if (line.includes('Content-Type')) {
                fields[fields.length - 1].contentType = line.split('Content-Type: ')[1];
            }

            if (keep == true) {
                if (fields[fields.length - 1].filename) {
                    streams[streams.length - 1].write(Buffer.from(line + "rn", 'binary'));
                } else {
                    fields[fields.length - 1].value += line;
                }
            }
        }

        if (isLast) {
            console.log(fields);
        }
    });

It works except that uploaded images are corrupted and are cut in randomly (Not the same in every image, some are totally corrupted and some are perfectly fine).
Could someone point out what is wrong with it?

Thanks in advance 🙂


Get this bounty!!!

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.