sgapps-server
Version:
SGApps Network Server
706 lines (624 loc) • 31.8 kB
HTML
<html lang="en">
<head>
<meta charset="utf-8">
<title>prototypes/server/extend/request-postdata.js - SGApps Server - Framework</title>
<meta name="description" content="SGApps Server for high performance results" />
<meta name="keywords" content="javascript, js, application-prototype, prototype" />
<meta name="keyword" content="javascript, js, application-prototype, prototype" />
<meta property="og:title" content="SGApps Server - Framework"/>
<meta property="og:type" content="website"/>
<meta property="og:image" content=""/>
<meta property="og:url" content="https://labs.sgapps.io/open-source/sgapps-server"/>
<script src="scripts/prettify/prettify.js"></script>
<script src="scripts/prettify/lang-css.js"></script>
<!--[if lt IE 9]>
<script src="//html5shiv.googlecode.com/svn/trunk/html5.js"></script>
<![endif]-->
<link type="text/css" rel="stylesheet" href="styles/prettify.css">
<link type="text/css" rel="stylesheet" href="styles/jsdoc.css">
<script src="scripts/nav.js" defer></script>
<meta name="viewport" content="width=device-width, initial-scale=1.0">
</head>
<body>
<input type="checkbox" id="nav-trigger" class="nav-trigger" />
<label for="nav-trigger" class="navicon-button x">
<div class="navicon"></div>
</label>
<label for="nav-trigger" class="overlay"></label>
<nav class="wrap">
<input type="text" id="nav-search" placeholder="Search" />
<h2><a href="index.html">Home</a></h2><h2><a href="https://labs.sgapps.io/open-source/sgapps-server" target="_blank" class="menu-item" id="website_link" >Project Page ( Git Lab )</a></h2><h2><a href="http://gordienco.net/" target="_blank" class="menu-item" id="website_link" >About Me</a></h2><h2><a href="https://labs.sgapps.io/open-source/sgapps-server" target="_blank" class="menu-item" id="github_link" >GitHub</a></h2><h3>Classes</h3><ul><li><a href="AccessLogger.html">AccessLogger</a><ul class='methods'><li data-type='method' style='display: none;'><a href="AccessLogger.html#formattedDate">formattedDate</a></li><li data-type='method' style='display: none;'><a href="AccessLogger.html#getProtocol">getProtocol</a></li><li data-type='method' style='display: none;'><a href="AccessLogger.html#getReferer">getReferer</a></li><li data-type='method' style='display: none;'><a href="AccessLogger.html#getRemoteIp">getRemoteIp</a></li><li data-type='method' style='display: none;'><a href="AccessLogger.html#getSize">getSize</a></li><li data-type='method' style='display: none;'><a href="AccessLogger.html#getUsername">getUsername</a></li><li data-type='method' style='display: none;'><a href="AccessLogger.html#logRequest">logRequest</a></li></ul></li><li><a href="FaceboxTemplate.html">FaceboxTemplate</a><ul class='methods'><li data-type='method' style='display: none;'><a href="FaceboxTemplate.html#render">render</a></li><li data-type='method' style='display: none;'><a href="FaceboxTemplate.html#renderCode">renderCode</a></li><li data-type='method' style='display: none;'><a href="FaceboxTemplate.html#renderFile">renderFile</a></li></ul></li><li><a href="FSLibrary.html">FSLibrary</a></li><li><a href="LoggerBuilder.html">LoggerBuilder</a><ul class='methods'><li data-type='method' style='display: none;'><a href="LoggerBuilder.html#decorateGlobalLogger">decorateGlobalLogger</a></li><li data-type='method' style='display: none;'><a href="LoggerBuilder.html#error">error</a></li><li data-type='method' style='display: none;'><a href="LoggerBuilder.html#info">info</a></li><li data-type='method' style='display: none;'><a href="LoggerBuilder.html#log">log</a></li><li data-type='method' style='display: none;'><a href="LoggerBuilder.html#prettyCli">prettyCli</a></li><li data-type='method' style='display: none;'><a href="LoggerBuilder.html#prompt">prompt</a></li><li data-type='method' style='display: none;'><a href="LoggerBuilder.html#warn">warn</a></li></ul></li><li><a href="SGAppsServer.html">SGAppsServer</a><ul class='methods'><li data-type='method' style='display: none;'><a href="SGAppsServer.html#all">all</a></li><li data-type='method' style='display: none;'><a href="SGAppsServer.html#connect">connect</a></li><li data-type='method' style='display: none;'><a href="SGAppsServer.html#delete">delete</a></li><li data-type='method' style='display: none;'><a href="SGAppsServer.html#Email">Email</a></li><li data-type='method' style='display: none;'><a href="SGAppsServer.html#finalHandler">finalHandler</a></li><li data-type='method' style='display: none;'><a href="SGAppsServer.html#get">get</a></li><li data-type='method' style='display: none;'><a href="SGAppsServer.html#handle">handle</a></li><li data-type='method' style='display: none;'><a href="SGAppsServer.html#handleErrorRequest">handleErrorRequest</a></li><li data-type='method' style='display: none;'><a href="SGAppsServer.html#handlePostData">handlePostData</a></li><li data-type='method' style='display: none;'><a href="SGAppsServer.html#handleRequest">handleRequest</a></li><li data-type='method' style='display: none;'><a href="SGAppsServer.html#handleStaticRequest">handleStaticRequest</a></li><li data-type='method' style='display: none;'><a href="SGAppsServer.html#head">head</a></li><li data-type='method' style='display: none;'><a href="SGAppsServer.html#options">options</a></li><li data-type='method' style='display: none;'><a href="SGAppsServer.html#patch">patch</a></li><li data-type='method' style='display: none;'><a href="SGAppsServer.html#post">post</a></li><li data-type='method' style='display: none;'><a href="SGAppsServer.html#put">put</a></li><li data-type='method' style='display: none;'><a href="SGAppsServer.html#server">server</a></li><li data-type='method' style='display: none;'><a href="SGAppsServer.html#trace">trace</a></li><li data-type='method' style='display: none;'><a href="SGAppsServer.html#use">use</a></li></ul></li><li><a href="SGAppsServer.NodeJsMvc.html">NodeJsMvc</a></li><li class="level-hide"><a href="SGAppsServer.NodeJsMvc.Controller.html">Controller</a><ul class='methods'><li data-type='method' style='display: none;'><a href="SGAppsServer.NodeJsMvc.Controller.html#actionExists">actionExists</a></li><li data-type='method' style='display: none;'><a href="SGAppsServer.NodeJsMvc.Controller.html#addAction">addAction</a></li><li data-type='method' style='display: none;'><a href="SGAppsServer.NodeJsMvc.Controller.html#addView">addView</a></li><li data-type='method' style='display: none;'><a href="SGAppsServer.NodeJsMvc.Controller.html#getAction">getAction</a></li><li data-type='method' style='display: none;'><a href="SGAppsServer.NodeJsMvc.Controller.html#getView">getView</a></li><li data-type='method' style='display: none;'><a href="SGAppsServer.NodeJsMvc.Controller.html#removeAction">removeAction</a></li><li data-type='method' style='display: none;'><a href="SGAppsServer.NodeJsMvc.Controller.html#removeView">removeView</a></li><li data-type='method' style='display: none;'><a href="SGAppsServer.NodeJsMvc.Controller.html#render">render</a></li><li data-type='method' style='display: none;'><a href="SGAppsServer.NodeJsMvc.Controller.html#viewExists">viewExists</a></li></ul></li><li class="level-hide"><a href="SGAppsServer.NodeJsMvc.Controller.Action.html">Action</a><ul class='methods'><li data-type='method' style='display: none;'><a href="SGAppsServer.NodeJsMvc.Controller.Action.html#run">run</a></li></ul></li><li><a href="SGAppsServerDecoratorsLibrary.html">SGAppsServerDecoratorsLibrary</a><ul class='methods'><li data-type='method' style='display: none;'><a href="SGAppsServerDecoratorsLibrary.html#.AccessLoggerDecorator">AccessLoggerDecorator</a></li><li data-type='method' style='display: none;'><a href="SGAppsServerDecoratorsLibrary.html#.NodeJsMvcDecorator">NodeJsMvcDecorator</a></li></ul></li><li><a href="SGAppsServerDictionary.html">SGAppsServerDictionary</a><ul class='methods'><li data-type='method' style='display: none;'><a href="SGAppsServerDictionary.html#generatePathKey">generatePathKey</a></li><li data-type='method' style='display: none;'><a href="SGAppsServerDictionary.html#push">push</a></li><li data-type='method' style='display: none;'><a href="SGAppsServerDictionary.html#run">run</a></li></ul></li><li><a href="SGAppsServerEmail.html">SGAppsServerEmail</a><ul class='methods'><li data-type='method' style='display: none;'><a href="SGAppsServerEmail.html#.from">from</a></li><li data-type='method' style='display: none;'><a href="SGAppsServerEmail.html#.isValidAddress">isValidAddress</a></li><li data-type='method' style='display: none;'><a href="SGAppsServerEmail.html#.timeout">timeout</a></li><li data-type='method' style='display: none;'><a href="SGAppsServerEmail.html#send">send</a></li><li data-type='method' style='display: none;'><a href="SGAppsServerEmail.html#valid">valid</a></li></ul></li><li><a href="SGAppsServerRequest.html">SGAppsServerRequest</a><ul class='methods'><li data-type='method' style='display: none;'><a href="SGAppsServerRequest.html#_parseDeepFieldName">_parseDeepFieldName</a></li><li data-type='method' style='display: none;'><a href="SGAppsServerRequest.html#getMountUpdatedUrl">getMountUpdatedUrl</a></li></ul></li><li><a href="SGAppsServerRequestCookie.html">SGAppsServerRequestCookie</a><ul class='methods'><li data-type='method' style='display: none;'><a href="SGAppsServerRequestCookie.html#get">get</a></li><li data-type='method' style='display: none;'><a href="SGAppsServerRequestCookie.html#set">set</a></li></ul></li><li><a href="SGAppsServerRequestSession.html">SGAppsServerRequestSession</a><ul class='methods'><li data-type='method' style='display: none;'><a href="SGAppsServerRequestSession.html#destroy">destroy</a></li></ul></li><li><a href="SGAppsServerResponse.html">SGAppsServerResponse</a><ul class='methods'><li data-type='method' style='display: none;'><a href="SGAppsServerResponse.html#pipeFile">pipeFile</a></li><li data-type='method' style='display: none;'><a href="SGAppsServerResponse.html#pipeFileStatic">pipeFileStatic</a></li><li data-type='method' style='display: none;'><a href="SGAppsServerResponse.html#redirect">redirect</a></li><li data-type='method' style='display: none;'><a href="SGAppsServerResponse.html#send">send</a></li><li data-type='method' style='display: none;'><a href="SGAppsServerResponse.html#sendError">sendError</a></li><li data-type='method' style='display: none;'><a href="SGAppsServerResponse.html#sendStatusCode">sendStatusCode</a></li></ul></li><li><a href="SGAppsServerShared.html">SGAppsServerShared</a></li><li><a href="SGAppsSessionManager.html">SGAppsSessionManager</a><ul class='methods'><li data-type='method' style='display: none;'><a href="SGAppsSessionManager.html#handleRequest">handleRequest</a></li><li data-type='method' style='display: none;'><a href="SGAppsSessionManager.html#removeExpiredSessions">removeExpiredSessions</a></li></ul></li><li><a href="TemplateManager.html">TemplateManager</a><ul class='methods'><li data-type='method' style='display: none;'><a href="TemplateManager.html#add">add</a></li><li data-type='method' style='display: none;'><a href="TemplateManager.html#addList">addList</a></li><li data-type='method' style='display: none;'><a href="TemplateManager.html#get">get</a></li><li data-type='method' style='display: none;'><a href="TemplateManager.html#remove">remove</a></li><li data-type='method' style='display: none;'><a href="TemplateManager.html#render">render</a></li><li data-type='method' style='display: none;'><a href="TemplateManager.html#templateExists">templateExists</a></li></ul></li><li><a href="TemplateManagerViewer.html">TemplateManagerViewer</a><ul class='methods'><li data-type='method' style='display: none;'><a href="TemplateManagerViewer.html#render">render</a></li><li data-type='method' style='display: none;'><a href="TemplateManagerViewer.html#renderCode">renderCode</a></li></ul></li></ul><h3>Global</h3><ul><li><a href="global.html#LoggerBuilderPrompt">LoggerBuilderPrompt</a></li><li><a href="global.html#MountUpdatedURL">MountUpdatedURL</a></li><li><a href="global.html#RequestHandler">RequestHandler</a></li><li><a href="global.html#RequestPathStructure">RequestPathStructure</a></li><li><a href="global.html#RequestPathStructureMap">RequestPathStructureMap</a></li><li><a href="global.html#RequestSessionDecorator">RequestSessionDecorator</a></li><li><a href="global.html#ResourcesExtensions">ResourcesExtensions</a></li><li><a href="global.html#routeMatch">routeMatch</a></li><li><a href="global.html#SGAppsServerDecorator">SGAppsServerDecorator</a></li><li><a href="global.html#SGAppsServerDictionaryRunCallBack">SGAppsServerDictionaryRunCallBack</a></li><li><a href="global.html#SGAppsServerErrorCallBack">SGAppsServerErrorCallBack</a></li><li><a href="global.html#SGAppsServerErrorOnlyCallback">SGAppsServerErrorOnlyCallback</a></li><li><a href="global.html#SGAppsServerHandlerPostData">SGAppsServerHandlerPostData</a></li><li><a href="global.html#SGAppsServerOptions">SGAppsServerOptions</a></li><li><a href="global.html#SGAppsServerRequestFile">SGAppsServerRequestFile</a></li><li><a href="global.html#SGAppsServerRequestPostDataItem">SGAppsServerRequestPostDataItem</a></li><li><a href="global.html#SGAppsServerRequestSessionCache">SGAppsServerRequestSessionCache</a></li><li><a href="global.html#SGAppsSessionManagerOptions">SGAppsSessionManagerOptions</a></li><li><a href="global.html#TemplateManagerRenderOptions">TemplateManagerRenderOptions</a></li><li><a href="global.html#TemplateManagerTemplate">TemplateManagerTemplate</a></li></ul>
</nav>
<div id="main">
<h1 class="page-title">prototypes/server/extend/request-postdata.js</h1>
<section>
<article>
<pre class="prettyprint source linenums"><code>const ePrototype = require("application-prototype/constructors/extensions/prototype");
const Busboy = require("busboy");
const { ServerResponse } = require("http");
const { Stream, Readable } = require("stream");
/**
* @private
* @method RequestUrlDecorator
* @param {SGAppsServerRequest} request
* @param {SGAppsServerResponse} response
* @param {SGAppsServer} server
* @param {function} callback
*/
module.exports = function RequestUrlDecorator(request, response, server, callback) {
if (request === null || response === null) {
callback();
return;
}
/**
* post data buffer cache
* @memberof SGAppsServerRequest#
* @name _postDataBuffer
* @type {Buffer}
*/
request._postDataBuffer = Buffer.from('', 'binary');
/**
* @typedef {object} SGAppsServerRequestFile
* @property {string} fieldName field's name
* @property {object} data
* @property {string} data.fileName file's name `[duplicate]`
* @property {string} data.encoding file's encoding
* @property {Readable} data.fileStream () => fileStream
* @property {Buffer} data.fileData
* @property {number} data.fileSize size in bytes
* @property {string} data.contentType file's mimeType
* @property {boolean} data.loaded indicate if file is fully loaded into `fileData`
*/
/**
* @typedef {object} SGAppsServerRequestPostDataItem
* @property {string} fieldName field's name
* @property {object} data
* @property {string} data.value
* @property {string} data.encoding file's encoding
* @property {string} data.valTruncated
* @property {Buffer} data.fieldNameTruncated
* @property {string} data.mimeType file's mimeType
*/
let _body = {};
let _bodyItems = [];
/**
* @memberof SGAppsServerRequest#
* @name body
* @type {object}
*/
Object.defineProperty(request, 'body', {
get: () => _body,
set: () => server.logger.warn("[Request.body] is not configurable"),
enumerable: true,
configurable: true
});
/**
* @memberof SGAppsServerRequest#
* @name bodyItems
* @type {SGAppsServerRequestPostDataItem[]}
*/
Object.defineProperty(request, 'bodyItems', {
get: () => _bodyItems,
set: () => server.logger.warn("[Request.bodyItems] is not configurable"),
enumerable: true,
configurable: true
});
/**
* @memberof SGAppsServerRequest#
* @name files
* @type {Object<string,SGAppsServerRequestFile[]>}
*/
let _files = {};
Object.defineProperty(request, 'files', {
get: () => _files,
set: () => server.logger.warn("[Request.files] is not configurable"),
enumerable: true,
configurable: true
});
/**
* @memberof SGAppsServerRequest#
* @name fileItems
* @type {SGAppsServerRequestFile[]}
*/
let _fileItems = [];
Object.defineProperty(request, 'fileItems', {
get: () => _fileItems,
set: () => server.logger.warn("[Request.fileItems] is not configurable"),
enumerable: true,
configurable: true
});
/**
* Automatically used procedure for parsing formData field name if option `server._options._REQUEST_FORM_PARAMS_DEEP_PARSE = true`. it's by default enabled but can be disabled when needed
* @memberof SGAppsServerRequest#
* @method _parseDeepFieldName
* @param {object} container
* @param {string} fieldName
* @param {any} fieldData
* @param {object} [options]
* @param {boolean} [options.transform2ArrayOnDuplicate=false]
* @example
* paramsContainer = {};
* request._parseDeepFieldName(paramsContainer, 'test[arr][data]', 2);
* request._parseDeepFieldName(paramsContainer, 'test[arr][]', new Date());
* request._parseDeepFieldName(paramsContainer, 'test[arr][]', 2);
* request._parseDeepFieldName(paramsContainer, 'test[data]', 2);
* // if _debug enabled warns will be emitted
* // [Warn] [Request._parseDeepFieldName] Writing Array field "test[arr][]" into a object
* // [Warn] [Request._parseDeepFieldName] Overwriting field "test[data]" value
* console.log(paramsContainer)
* {
* "test": {
* "arr": {
* "1": "2021-02-12T21:23:01.913Z",
* "2": 2,
* "data": 2
* },
* "data": 2
* }
* }
* @example
* paramsContainer = {};
* request._parseDeepFieldName(paramsContainer, 'test[arr][]', new Date());
* request._parseDeepFieldName(paramsContainer, 'test[arr][]', 2);
* request._parseDeepFieldName(paramsContainer, 'test[arr][data]', 2);
* request._parseDeepFieldName(paramsContainer, 'test[data]', 2);
* // if _debug enabled warns will be emitted
* // [Warn] [Request._parseDeepFieldName] Converting array to object due incorrect field "test[arr][data]" name
* console.log(paramsContainer)
* {
* "test": {
* "arr": {
* "0": "2021-02-12T21:34:47.359Z",
* "1": 2,
* "data": 2
* },
* "data": 2
* }
* }
* @example
* paramsContainer = {};
* request._parseDeepFieldName(paramsContainer, 'test[arr][]', new Date());
* request._parseDeepFieldName(paramsContainer, 'test[arr][]', 2);
* request._parseDeepFieldName(paramsContainer, 'test[data]', 2);
* console.log(paramsContainer)
* {
* "test": {
* "arr": [
* "2021-02-12T21:26:43.766Z",
* 2
* ],
* "data": 2
* }
* }
*/
request._parseDeepFieldName = (container, fieldName, fieldData, options) => {
if (!fieldName[0] || fieldName[0] === '[') {
console.warn(
`[Warn] [Request._parseDeepFieldName] Unable to parse fieldName without base`, {
container,
fieldName,
fieldData
}
);
return;
}
let fieldNamePrefix = fieldName.replace(/\[.*$/, '');
container[fieldNamePrefix] = container[fieldNamePrefix] || {};
let p = container[fieldNamePrefix];
let pPrev = container;
const _debug = server.logger._debug;
const parts = fieldName
.match(/\[[^\[]*\]/g);
if (!parts) {
if (fieldNamePrefix in container) {
if (_debug) {
server.logger.warn(
`[Warn] [Request._parseDeepFieldName] Overwriting field "${fieldName}" value`, {
container,
fieldName,
fieldData
}
);
}
}
container[fieldNamePrefix] = fieldData;
return;
}
parts
.map(v => v.replace(/^\[([^\]]*)\]$/, '$1'))
.forEach((k, i, a) => {
if (p && typeof (p) === "object") {
if (i === a.length - 1) {
if (k === '') {
if (pPrev) {
const prevIndex = i ? a[i - 1] : fieldNamePrefix;
if (!Array.isArray(pPrev[prevIndex])) {
if (prevIndex in pPrev) {
if (pPrev[prevIndex] && typeof (pPrev[prevIndex]) === "object") {
const index = Object.keys(pPrev[prevIndex]).length;
if (index === 0) {
pPrev[prevIndex] = [];
pPrev[prevIndex].push(fieldData);
} else {
if (_debug) {
server.logger.warn(
`[Warn] [Request._parseDeepFieldName] Writing Array field "${fieldName}" into a object`, {
container,
fieldName,
fieldData
}
);
}
if (index in pPrev[prevIndex]) {
if (_debug) {
server.logger.warn(
`[Warn] [Request._parseDeepFieldName] Overwriting field "${fieldName}" value`, {
container,
fieldName,
fieldData
}
);
}
}
pPrev[prevIndex][index] = fieldData;
}
} else {
pPrev[prevIndex] = [];
pPrev[prevIndex].push(fieldData);
}
} else {
pPrev[prevIndex] = [];
pPrev[prevIndex].push(fieldData);
}
} else {
pPrev[prevIndex].push(fieldData);
}
} else {
if (_debug) {
console.warn(
`[Warn] [Request._parseDeepFieldName] Unable to parse intermediary array index "[]"`, {
container,
fieldName,
fieldData
}
);
}
p = null;
}
} else {
if (k in p) {
if (_debug) {
console.warn(
`[Warn] [Request._parseDeepFieldName] Overwriting field "${fieldName}" value`, {
container,
fieldName,
fieldData
}
);
}
} else {
if (Array.isArray(p)) {
if (k.match(/^\d+$/)) {
if (p[k] === undefined) {
p[k] = fieldData;
} else {
if (_debug) {
server.logger.warn(
`[Warn] [Request._parseDeepFieldName] Overwriting field "${fieldName}" value`, {
container,
fieldName,
fieldData
}
);
}
p[k] = fieldData;
}
} else {
if (_debug) {
server.logger.warn(
`[Warn] [Request._parseDeepFieldName] Converting array to object due incorrect field "${fieldName}" name`, {
container,
fieldName,
fieldData
}
);
}
const prevIndex = i ? a[i - 1] : fieldNamePrefix;
pPrev[prevIndex] = Object.assign({}, p);
pPrev[prevIndex][k] = fieldData;
}
} else {
p[k] = fieldData;
}
}
}
} else {
if (k === '') {
if (_debug) {
server.logger.warn(
`[Warn] [Request._parseDeepFieldName] Unable to parse intermediary array index "[]"`, {
container,
fieldName,
fieldData
}
);
}
p = null;
} else {
p[k] = p[k] || {};
pPrev = p;
p = p[k];
}
}
} else {
if (p !== null) {
p = null;
if (_debug) {
server.logger.warn(
`[Warn] [Request._parseDeepFieldName] Unable to parse Request params. Setting field "${fieldName}" in structure`, {
container,
fieldName,
fieldData
}
);
}
}
}
});
};
/**
* request's post received data
* @memberof SGAppsServerRequest#
* @name postData
* @type {Promise<Buffer>}
*/
let _postData = null;
Object.defineProperty(
request,
'postData',
{
get: () => {
if (_postData) return _postData;
_postData = new Promise(function (resolve, reject) {
let _postDataSize = 0;
let _canceled = false;
request.request.on("data", function (chunk) {
if (_canceled) return;
if (request.request.aborted) return;
var dataLimit = request.MAX_POST_SIZE;
if (dataLimit < _postDataSize) {
_canceled = true;
const err = Error('[Request.MAX_POST_SIZE] exceeded');
server.logger.error(err);
reject(err);
return;
}
request._postDataBuffer = Buffer.concat([request._postDataBuffer, chunk]);
_postDataSize += chunk.length;
});
request.request.once("error", function (err) {
if (_canceled) return;
server.logger.error(err);
_canceled = true;
reject(err);
});
request.request.once("abort", function () {
if (_canceled) return;
const err = Error('[Request] aborted');
server.logger.error(err);
_canceled = true;
reject(err);
});
request.request.once('end', function () {
if (_canceled) return;
if (
(
request.request.headers['content-type'] || ''
).indexOf('multipart/form-data') === 0
) {
let Readable = require('stream').Readable;
let readable = new Readable();
readable._read = () => {}; // _read is required but you can noop it
readable.push(request._postDataBuffer);
readable.push(null);
var detectedBoundary = (
request._postDataBuffer
.slice(0, 1024).toString()
.match(/^\-\-(\-{4,}[A-Za-z0-9]{4,}\-*)(\r|)\n/) || []
)[1] || null;
if (detectedBoundary) {
var calculatedHeader = 'multipart/form-data; boundary=' + detectedBoundary;
if (
calculatedHeader !== request.request.headers['content-type']
) {
server.logger.warn(
"Multipart Form Data: boundary replaced from ",
request.request.headers['content-type'],
calculatedHeader
);
}
request.request.headers['content-type'] = calculatedHeader;
}
/**
* @private
* @type {Readable}
*/
//@ts-ignore
const busboy = new Busboy({
headers: request.request.headers,
limits: {
fieldNameSize: 255,
fieldSize: request.MAX_POST_SIZE,
fileSize: request.MAX_POST_SIZE
}
});
busboy.on(
'file',
/**
* @inner
* @param {string} fieldName
* @param {Readable} fileStream
* @param {string} fileName
* @param {string} encoding
* @param {string} mimeType
*/
function (
fieldName,
fileStream,
fileName,
encoding,
mimeType
) {
const file = {
fieldName: fieldName,
data: {
fileName: fileName,
encoding: encoding,
fileStream: () => fileStream,
fileData: null,
fileSize: 0,
contentType: mimeType,
loaded: false
}
};
//@ts-ignore
_fileItems.push(file);
if (server._options._REQUEST_FORM_PARAMS_DEEP_PARSE) {
request._parseDeepFieldName(
_files, fieldName, file
);
} else {
if (!(fieldName in _files)) _files[fieldName] = [];
//@ts-ignore
_files[fieldName].push(file);
}
fileStream.on('data', function (data) {
file.data.fileData.push(data);
file.data.fileSize += data.length;
});
fileStream.on('error', function (err) {
file.data.error = err;
server.logger.error(err);
});
fileStream.on('end', function () {
file.data.fileData = Buffer.concat(file.data.fileData);
if (!file.data.error)
file.data.loaded = true;
});
}
);
busboy.on('field', function (fieldName, value, fieldNameTruncated, valTruncated, encoding, mimeType) {
// console.warn("BusBoy Field", arguments);
_bodyItems.push({
fieldName: fieldName,
data: {
value: value,
fieldNameTruncated: fieldNameTruncated,
valTruncated: valTruncated,
encoding: encoding,
mimeType: mimeType
}
});
if (server._options._REQUEST_FORM_PARAMS_DEEP_PARSE) {
request._parseDeepFieldName(
_body, fieldName, value
);
} else {
_body[fieldName] = value;
}
});
busboy.on('error', function (err) {
server.logger.error(err);
reject(err);
});
busboy.on('finish', function () {
resolve(request._postDataBuffer);
var err;
try {
readable.destroy();
} catch (err) {};
try {
busboy.destroy();
} catch (err) {};
});
//@ts-ignore
readable.pipe(busboy); // consume the Stream
} else {
if (
(
(
request.request.headers['content-type'] || ''
) || ''
).indexOf('application/json') === 0
) {
const data = request._postDataBuffer.toString('utf-8', 0, request._postDataBuffer.length);
try {
const jsonData = JSON.parse(data);
if (jsonData && typeof(jsonData) === "object") {
Object.assign(_body, jsonData);
}
} catch (err) {
if (server.logger._debug) {
server.logger.warn(`[Request._body] Unable to parse JSON data`);
}
}
} else if (
(
(
request.request.headers['content-type'] || ''
) || ''
).indexOf('application/x-www-form-urlencoded') === 0
) {
const data = request._postDataBuffer.toString('utf-8', 0, request._postDataBuffer.length);
//@ts-ignore
try {
const formData = data.parseUrlVars(true);
if (formData && typeof(formData) === "object") {
Object.assign(_body, formData);
}
} catch (err) {
if (server.logger._debug) {
server.logger.warn(`[Request._body] Unable to parse URL Formed Data data`);
}
}
}
resolve(request._postDataBuffer);
}
});
});
return _postData;
},
set: (v) => {
server.logger.warn('[Request.postData] is not writeable');
}
}
);
// response._destroy.push(function () {
// _postData = null;
// _body = null;
// _bodyItems = null;
// _fileItems = null;
// _files = null;
// delete request._parseDeepFieldName;
// delete request._postDataBuffer;
// delete request.postData;
// });
callback();
};
</code></pre>
</article>
</section>
</div>
<br class="clear">
<footer>
Documentation generated by <a href="https://github.com/jsdoc3/jsdoc">JSDoc 3.6.5</a> using the <a href="https://github.com/clenemt/docdash">docdash</a> theme.
</footer>
<script>prettyPrint();</script>
<script src="scripts/polyfill.js"></script>
<script src="scripts/linenumber.js"></script>
<script src="scripts/search.js" defer></script>
<script src="scripts/collapse.js" defer></script>
<script src="https://sgapps.io/components/sgapps-labs-examples/toolbar/loader.js"></script>
</body>
</html>