mirror of https://github.com/node-red/node-red.git
refactor: update rawBody label to skipBodyParsing and adjust related UI elements
parent
8543c88f2b
commit
16d095397c
|
@ -33,9 +33,9 @@
|
|||
<input type="checkbox" id="node-input-upload" style="margin-right: 5%; margin-bottom: 5%;">
|
||||
<label for="node-input-upload" style="text-wrap: nowrap;" data-i18n="httpin.label.upload"></label>
|
||||
</div>
|
||||
<div id="form-row-http-in-rawdata" class="hide" style="display: flex;">
|
||||
<input type="checkbox" id="node-input-includeRawBody" style="margin-right: 5%; margin-bottom: 5%;">
|
||||
<label for="node-input-includeRawBody" style="text-wrap: nowrap;" data-i18n="httpin.label.rawBody"></label>
|
||||
<div id="form-row-http-in-parsing" class="hide" style="display: flex;">
|
||||
<input type="checkbox" id="node-input-skipBodyParsing" style="margin-right: 5%; margin-bottom: 5%;">
|
||||
<label for="node-input-skipBodyParsing" style="text-wrap: nowrap;" data-i18n="httpin.label.parsing"></label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -85,7 +85,7 @@
|
|||
label:RED._("node-red:httpin.label.url")},
|
||||
method: {value:"get",required:true},
|
||||
upload: {value:false},
|
||||
includeRawBody: {value:false},
|
||||
skipBodyParsing: {value:false},
|
||||
swaggerDoc: {type:"swagger-doc", required:false}
|
||||
},
|
||||
inputs:0,
|
||||
|
@ -130,14 +130,14 @@
|
|||
var method = $(this).val();
|
||||
if(["post", "put", "patch","delete"].includes(method)){
|
||||
$("#form-reqBody-http-in-controller").show();
|
||||
$("#form-row-http-in-rawdata").show();
|
||||
$("#form-row-http-in-parsing").show();
|
||||
if (method === "post") {
|
||||
$("#form-row-http-in-upload").show();
|
||||
} else {
|
||||
$("#form-row-http-in-upload").hide();
|
||||
}
|
||||
} else {
|
||||
$("#form-row-http-in-rawdata").hide();
|
||||
$("#form-row-http-in-parsing").hide();
|
||||
$("#form-row-http-in-upload").hide();
|
||||
$("#form-reqBody-http-in-controller").hide();
|
||||
}
|
||||
|
|
|
@ -37,11 +37,15 @@ module.exports = function(RED) {
|
|||
* @param {import('express').NextFunction} next
|
||||
* @returns
|
||||
*/
|
||||
function rawBodyParser(req, _res, next) {
|
||||
if (!req._nodeRedReqStream) {
|
||||
return next();
|
||||
}
|
||||
var isText = true, checkUTF = false;
|
||||
function rawBodyParser(req, res, next) {
|
||||
if (req.skipRawBodyParser) { next(); } // don't parse this if told to skip
|
||||
if (req._body) { return next(); }
|
||||
req.body = "";
|
||||
req._body = true;
|
||||
|
||||
var isText = true;
|
||||
var checkUTF = false;
|
||||
|
||||
if (req.headers['content-type']) {
|
||||
var contentType = typer.parse(req.headers['content-type'])
|
||||
if (contentType.type) {
|
||||
|
@ -57,26 +61,23 @@ module.exports = function(RED) {
|
|||
&& (parsedType.subtype !== "x-protobuf")) {
|
||||
checkUTF = true;
|
||||
} else {
|
||||
// application/octet-stream or application/cbor
|
||||
isText = false;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
getBody(req._nodeRedReqStream, {
|
||||
getBody(req, {
|
||||
length: req.headers['content-length'],
|
||||
encoding: isText ? "utf8" : null
|
||||
}, function (err, buf) {
|
||||
if (err) {
|
||||
return next(err);
|
||||
}
|
||||
if (err) { return next(err); }
|
||||
if (!isText && checkUTF && isUtf8(buf)) {
|
||||
buf = buf.toString()
|
||||
}
|
||||
Object.defineProperty(req, "rawRequestBody", {
|
||||
value: buf,
|
||||
enumerable: true
|
||||
});
|
||||
return next();
|
||||
req.body = buf;
|
||||
next();
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -115,49 +116,23 @@ module.exports = function(RED) {
|
|||
var routeKey = getRouteKey({ method: req.method, url: req._parsedUrl.pathname });
|
||||
// Check if routeKey exist in rawDataRoutes
|
||||
if (rawDataRoutes.has(routeKey)) {
|
||||
|
||||
// Create a PassThrough stream to capture the request body
|
||||
var cloneStream = new PassThrough();
|
||||
|
||||
// Function to handle 'data' event
|
||||
function onData(chunk) {
|
||||
// Safely call clone stream write
|
||||
if (cloneStream.writable) {
|
||||
cloneStream.write(chunk);
|
||||
}
|
||||
}
|
||||
|
||||
// Function to handle 'end' or 'error' events
|
||||
function onEnd(err) {
|
||||
// Convert the request stream to buffer
|
||||
getBody(req, {
|
||||
length: req.headers['content-length'],
|
||||
encoding: typer.parse(req).parameters.charset
|
||||
}, function (err, buf) {
|
||||
if (err) {
|
||||
// Safely call clone stream destroy method
|
||||
if (!cloneStream.destroyed) {
|
||||
cloneStream.destroy(err);
|
||||
}
|
||||
} else {
|
||||
// Safely call clone stream end method
|
||||
if (cloneStream.writable) {
|
||||
cloneStream.end();
|
||||
}
|
||||
return next(err);
|
||||
}
|
||||
}
|
||||
|
||||
// Attach event listeners to the request stream
|
||||
req.on('data', onData)
|
||||
.once('end', onEnd)
|
||||
.once('error', onEnd)
|
||||
// Remove listeners once the request is closed
|
||||
.once('close', () => {
|
||||
req.removeListener('data', onData);
|
||||
});
|
||||
|
||||
// Attach the clone stream to the request
|
||||
Object.defineProperty(req, "_nodeRedReqStream", {
|
||||
value: cloneStream
|
||||
});
|
||||
req.body = buf;
|
||||
// Skip the body parsing
|
||||
req.skipRawBodyParser = true;
|
||||
req._body = true;
|
||||
next();
|
||||
})
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
// Proceed to the next middleware
|
||||
return next();
|
||||
}
|
||||
|
||||
if(typeof RED.httpNode === 'function' && (rootApp = getRootApp(RED.httpNode))) {
|
||||
|
@ -283,14 +258,14 @@ module.exports = function(RED) {
|
|||
}
|
||||
this.method = n.method;
|
||||
this.upload = n.upload;
|
||||
this.includeRawBody = n.includeRawBody;
|
||||
this.skipBodyParsing = n.skipBodyParsing;
|
||||
this.swaggerDoc = n.swaggerDoc;
|
||||
|
||||
var node = this;
|
||||
var routeKey = getRouteKey({method: this.method, url: RED.httpNode.path() + this.url});
|
||||
|
||||
// If the user enables raw body, add it to the raw data routes.
|
||||
if(this.includeRawBody) {
|
||||
if(this.skipBodyParsing) {
|
||||
rawDataRoutes.add(routeKey);
|
||||
}
|
||||
|
||||
|
|
|
@ -451,7 +451,6 @@
|
|||
"upload": "Dateiuploads akzeptieren",
|
||||
"status": "Statuscode",
|
||||
"headers": "Kopfzeilen",
|
||||
"rawBody": "Rohdaten einbeziehen?",
|
||||
"other": "andere",
|
||||
"paytoqs": {
|
||||
"ignore": "Ignorieren",
|
||||
|
|
|
@ -515,7 +515,7 @@
|
|||
"doc": "Docs",
|
||||
"return": "Return",
|
||||
"upload": "Accept file uploads?",
|
||||
"rawBody": "Include Raw Data?",
|
||||
"parsing": "Skip body parsing?",
|
||||
"status": "Status code",
|
||||
"headers": "Headers",
|
||||
"other": "other",
|
||||
|
|
|
@ -518,7 +518,6 @@
|
|||
"status": "Código de estado",
|
||||
"headers": "Encabezados",
|
||||
"other": "otro",
|
||||
"rawBody": "¿Incluir datos sin procesar?",
|
||||
"paytoqs": {
|
||||
"ignore": "Ignorar",
|
||||
"query": "Agregar a los parámetros de la cadena de consulta",
|
||||
|
|
|
@ -518,7 +518,6 @@
|
|||
"status": "Code d'état",
|
||||
"headers": "En-têtes",
|
||||
"other": "Autre",
|
||||
"rawBody": "Inclure les données brutes ?",
|
||||
"paytoqs": {
|
||||
"ignore": "Ignorer",
|
||||
"query": "Joindre aux paramètres de chaîne de requête",
|
||||
|
|
|
@ -518,7 +518,6 @@
|
|||
"status": "ステータスコード",
|
||||
"headers": "ヘッダ",
|
||||
"other": "その他",
|
||||
"rawBody": "生データを含める?",
|
||||
"paytoqs": {
|
||||
"ignore": "無視",
|
||||
"query": "クエリパラメータに追加",
|
||||
|
|
|
@ -397,8 +397,7 @@
|
|||
"binaryBuffer": "바이너리 버퍼",
|
||||
"jsonObject": "JSON오브젝트",
|
||||
"authType": "종류별",
|
||||
"bearerToken": "토큰",
|
||||
"rawBody": "원시 데이터를 포함할까요?"
|
||||
"bearerToken": "토큰"
|
||||
},
|
||||
"setby": "- msg.method에 정의 -",
|
||||
"basicauth": "인증을 사용",
|
||||
|
|
|
@ -506,7 +506,6 @@
|
|||
"status": "Código de estado",
|
||||
"headers": "Cabeçalhos",
|
||||
"other": "outro",
|
||||
"rawBody": "Incluir dados brutos?",
|
||||
"paytoqs" : {
|
||||
"ignore": "Ignorar",
|
||||
"query": "Anexar aos parâmetros da cadeia de caracteres de consulta",
|
||||
|
|
|
@ -411,7 +411,6 @@
|
|||
"status": "Код состояния",
|
||||
"headers": "Заголовки",
|
||||
"other": "другое",
|
||||
"rawBody": "Включить необработанные данные?",
|
||||
"paytoqs": {
|
||||
"ignore": "Игнорировать",
|
||||
"query": "Добавлять к параметрам строки запроса",
|
||||
|
|
|
@ -508,7 +508,6 @@
|
|||
"status": "状态码",
|
||||
"headers": "头",
|
||||
"other": "其他",
|
||||
"rawBody": "包含原始数据?",
|
||||
"paytoqs": {
|
||||
"ignore": "忽略",
|
||||
"query": "附加到查询字符串参数",
|
||||
|
|
|
@ -416,8 +416,7 @@
|
|||
"binaryBuffer": "二進制buffer",
|
||||
"jsonObject": "解析的JSON對象",
|
||||
"authType": "類型",
|
||||
"bearerToken": "Token",
|
||||
"rawBody": "包含原始數據?"
|
||||
"bearerToken": "Token"
|
||||
},
|
||||
"setby": "- 用 msg.method 設定 -",
|
||||
"basicauth": "基本認證",
|
||||
|
|
Loading…
Reference in New Issue