Skip to content

Commit

Permalink
Fix forms (#91)
Browse files Browse the repository at this point in the history
Co-authored-by: Thierry Boileau <[email protected]>
  • Loading branch information
C​⁠‌​⁠⁠‌​​⁠‍‌‌​​‍‌yprien Q​⁠‌​⁠⁠‌​​⁠‍‌‌​​‍‌uilici and thboileau authored Jan 3, 2024
1 parent 3dc1f1c commit bfa5d18
Show file tree
Hide file tree
Showing 4 changed files with 782 additions and 194 deletions.
202 changes: 111 additions & 91 deletions lib/middleware/body-parser.js
Original file line number Diff line number Diff line change
@@ -1,139 +1,159 @@
'use strict'

var Dicer = require('dicer')
var querystring = require('querystring')
var typer = require('media-typer')
var util = require('../utils')

module.exports = function (req, res, next) {
req.bodyChunks = []

req.on('data', function (chunk) {
req.bodyChunks.push(chunk)
})

req.on('end', function () {
req.rawBody = Buffer.concat(req.bodyChunks)
req.body = req.rawBody.toString('utf8')
req.bodySize = req.rawBody.length
req.jsonBody = null
req.formBody = null
req.contentType = null
req.multiPartSimple = {}
var Dicer = require("dicer");
var querystring = require("querystring");
var contentTypeParser = require("content-type");
var util = require("../utils");

const parseContentType = (contentTypeHeader) => {
if (!contentTypeHeader) {
return { contentType: null };
}
var { type, parameters } = contentTypeParser.parse(contentTypeHeader);
return {
contentType: type.replace(/\+$/, ""),
parameters,
};
};

module.exports = (req, res, next) => {
req.bodyChunks = [];

req.on("data", (chunk) => {
req.bodyChunks.push(chunk);
});

req.on("end", () => {
req.rawBody = Buffer.concat(req.bodyChunks);
req.body = req.rawBody.toString("utf8");
req.bodySize = req.rawBody.length;
req.jsonBody = null;
req.formBody = null;
req.contentType = null;
req.multiPartSimple = {};

// parse Content-Type
var contentType = req.headers['content-type']

// @jgould-sonos
// 8 June 2022 - Updated to avoid error with unable to handle semicolon in content type
var type = contentType ? typer.parse(contentType.split(';')[0]) : null
var contentTypeHeader = req.headers["content-type"];
var { contentType, parameters } = parseContentType(contentTypeHeader);

if (type) {
req.contentType = [[type.type, type.subtype].join('/'), type.suffix].join('+').replace(/\+$/, '')
if (contentType) {
req.contentType = contentType;
}

// create HAR Object
req.har = util.createHar(req)
req.simple = util.createSimpleHar(req)
req.har = util.createHar(req);
req.simple = util.createSimpleHar(req);

// json
switch (req.contentType) {
case 'application/json':
case "application/json":
try {
req.jsonBody = JSON.parse(req.body)
} catch (exception) {}
req.jsonBody = JSON.parse(req.body);
} catch (exception) { }

next()
break
next();
break;

case 'application/x-www-form-urlencoded':
req.formBody = querystring.parse(req.body)
case "application/x-www-form-urlencoded":
req.formBody = querystring.parse(req.body);

// update HAR objects
req.simple.postData.params = req.formBody
req.har.log.entries[0].request.postData.params = util.objectToArray(req.formBody)
req.simple.postData.params = req.formBody;
req.har.log.entries[0].request.postData.params = util.objectToArray(
req.formBody,
);

next()
break
next();
break;

case 'multipart/mixed':
case 'multipart/related':
case 'multipart/form-data':
case 'multipart/alternate':
req.multiPartData = []
req.multiPartParams = []
case "multipart/mixed":
case "multipart/related":
case "multipart/form-data":
case "multipart/alternate":
req.multiPartData = [];
req.multiPartParams = [];

// parse a file upload
var dice = new Dicer({
boundary: type.parameters.boundary
})
boundary: parameters.boundary,
});

dice.on('part', function (part) {
part.on('data', function (data) {
req.multiPartData.push(data.toString('utf8'))
})
dice.on("part", (part) => {
part.on("data", (data) => {
req.multiPartData.push(data.toString("utf8"));
});

part.on('header', function (headers) {
var param = {}
part.on("header", (headers) => {
var param = {};

if (headers['content-disposition']) {
var disposition = typer.parse(headers['content-disposition'][0].replace('form-data', 'form-data/text') || 'form-data/text')
if (headers["content-disposition"]) {
var disposition = contentTypeParser.parse(
headers["content-disposition"][0].replace(
"form-data",
"form-data/text",
) || "form-data/text",
);

param.name = disposition.parameters.name
param.name = disposition.parameters.name;

if (disposition.parameters.filename) {
param.fileName = disposition.parameters.filename
param.fileName = disposition.parameters.filename;
}
}

if (headers['content-type']) {
var type = typer.parse(headers['content-type'][0] || 'application/octet-stream')
if (headers["content-type"]) {
var { contentType: partContentType } = parseContentType(
headers["content-type"][0] || "application/octet-stream",
);

param.contentType = [[type.type, type.subtype].join('/'), type.suffix].join('+').replace(/\+$/, '')
param.contentType = partContentType;
}

req.multiPartParams.push(param)
})
})
req.multiPartParams.push(param);
});
});

dice.on('finish', function () {
dice.on("finish", () => {
// createa a new simple object param
req.multiPart = req.multiPartParams.map(function (param, index) {
req.multiPart = req.multiPartParams.map((param, index) => {
// append value to pair
param.value = req.multiPartData[index]
param.value = req.multiPartData[index];

switch (typeof req.multiPartSimple[param.name]) {
case 'undefined':
req.multiPartSimple[param.name] = param.value
break
case "undefined":
req.multiPartSimple[param.name] = param.value;
break;

// array
case 'object':
req.multiPartSimple[param.name].push(param.value)
break
case "object":
req.multiPartSimple[param.name].push(param.value);
break;

case 'string':
case "string":
// this exists? must be an array, make it so
req.multiPartSimple[param.name] = [req.multiPartSimple[param.name]]
req.multiPartSimple[param.name].push(param.value)
break
req.multiPartSimple[param.name] = [
req.multiPartSimple[param.name],
];
req.multiPartSimple[param.name].push(param.value);
break;
}

return param
})
return param;
});

// update HAR objects
req.simple.postData.params = req.multiPartSimple ? req.multiPartSimple : []
req.har.log.entries[0].request.postData.params = req.multiPart ? req.multiPart : []
req.simple.postData.params = req.multiPartSimple
? req.multiPartSimple
: [];
req.har.log.entries[0].request.postData.params = req.multiPart
? req.multiPart
: [];

next()
})
next();
});

dice.write(req.body)
break
dice.write(req.body);
break;

default:
next()
next();
}
})
}
});
};
Loading

0 comments on commit bfa5d18

Please sign in to comment.