all files / modules/multipart/ parseContent.js

89.19% Statements 33/37
78.57% Branches 11/14
83.33% Functions 5/6
89.19% Lines 33/37
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70                     32× 31× 31×     32× 32×   32× 32× 31×     32× 32×   32× 53×     32×   32× 32× 32×   32×     32×   32×           32× 32× 32× 32×           32×        
const Stream = require("bufferedstream");
const MaxLengthExceededError = require("../utils/MaxLengthExceededError");
const resolveProperties = require("../utils/resolveProperties");
const Promise = require("../utils/Promise");
const Parser = require("./Parser");
const R = require("ramda");
 
function defaultPartHandler(part) {
    return part.parseContent();
}
 
/**
 * Parses a multipart message and returns a promise for an object of
 * the parts it contains, keyed by the name of that part. The partHandler
 * argument is a function that should be used to resolve the value of
 * a part. It defaults to collecting all the content in a buffer.
 */
function parseContent(content, boundary, maxLength, partHandler) {
    if (typeof maxLength === "function") {
        partHandler = maxLength;
        maxLength = null;
    }
 
    partHandler = partHandler || defaultPartHandler;
    maxLength = maxLength || Infinity;
 
    return new Promise(function (resolve, reject) {
        if (!R.is(Stream, content)) {
            content = new Stream(content);
        }
 
        const parts = {};
        let contentLength = 0;
 
        const parser = new Parser(boundary, function (part) {
            parts[part.name] = partHandler(part);
        });
 
        content.on("error", reject);
 
        content.on("data", function (chunk) {
            const length = chunk.length;
            contentLength += length;
 
            Iif (maxLength && contentLength > maxLength) {
                reject(new MaxLengthExceededError(maxLength));
            } else {
                const parsedLength = parser.execute(chunk);
 
                Iif (parsedLength !== length) {
                    reject(new Error(`Error parsing multipart body: ${parsedLength} of ${length} bytes parsed`));
                }
            }
        });
 
        content.on("end", function () {
            try {
                parser.finish();
                resolve(resolveProperties(parts));
            } catch (error) {
                reject(new Error(`Error parsing multipart body: ${error.message}`));
            }
        });
 
        content.resume();
    });
}
 
module.exports = parseContent;