mirror of
https://github.com/node-red/node-red.git
synced 2025-03-01 10:36:34 +00:00
Refactor raw body capture middleware to use a Set for route management and improve code consistency
This commit is contained in:
parent
9a26ee3052
commit
caeb5d3538
@ -26,11 +26,9 @@ module.exports = function(RED) {
|
||||
var mediaTyper = require('media-typer');
|
||||
var isUtf8 = require('is-utf8');
|
||||
var hashSum = require("hash-sum");
|
||||
var PassThrough = require('stream').PassThrough
|
||||
var rootApp = getRootApp(RED.httpNode)
|
||||
|
||||
// Check if middleware already exists
|
||||
var isMiddlewareExists = rootApp._router.stack.some(layer => layer.name === 'setupRawBodyCapture')
|
||||
var PassThrough = require('stream').PassThrough;
|
||||
var rootApp = getRootApp(RED.httpNode);
|
||||
var rawDataRoutes = new Set();
|
||||
|
||||
/**
|
||||
* This middleware parses the raw body if the user enables it.
|
||||
@ -69,7 +67,7 @@ module.exports = function(RED) {
|
||||
encoding: isText ? "utf8" : null
|
||||
}, function (err, buf) {
|
||||
if (err) {
|
||||
return next(err)
|
||||
return next(err);
|
||||
}
|
||||
if (!isText && checkUTF && isUtf8(buf)) {
|
||||
buf = buf.toString()
|
||||
@ -77,7 +75,7 @@ module.exports = function(RED) {
|
||||
Object.defineProperty(req, "rawRequestBody", {
|
||||
value: buf,
|
||||
enumerable: true
|
||||
})
|
||||
});
|
||||
return next();
|
||||
});
|
||||
}
|
||||
@ -91,7 +89,7 @@ module.exports = function(RED) {
|
||||
if (typeof app.parent === 'undefined') {
|
||||
return app;
|
||||
}
|
||||
return getRootApp(app.parent)
|
||||
return getRootApp(app.parent);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -100,9 +98,9 @@ module.exports = function(RED) {
|
||||
* @returns
|
||||
*/
|
||||
function getRouteKey(obj) {
|
||||
var method = obj.method.toUpperCase()
|
||||
var method = obj.method.toUpperCase();
|
||||
// Normalize the URL by replacing double slashes with a single slash and removing the trailing slash
|
||||
var url = obj.url.replace(/\/{2,}/g, '/').replace(/\/$/, '')
|
||||
var url = obj.url.replace(/\/{2,}/g, '/').replace(/\/$/, '');
|
||||
return `${method}:${url}`;
|
||||
}
|
||||
|
||||
@ -114,17 +112,9 @@ module.exports = function(RED) {
|
||||
* @returns
|
||||
*/
|
||||
function setupRawBodyCapture(req, _res, next) {
|
||||
var routeKey = getRouteKey({method: req.method, url: req._parsedUrl.pathname})
|
||||
var httpInNodes = rootApp.get('httpInNodes')
|
||||
var routeKey = getRouteKey({ method: req.method, url: req._parsedUrl.pathname });
|
||||
// Check if settings for this ID exist
|
||||
if (httpInNodes.has(routeKey)) {
|
||||
// Get the httpInNode by routeId
|
||||
var httpInNode = httpInNodes.get(routeKey);
|
||||
|
||||
// If raw body inclusion is disabled, skip the processing
|
||||
if (!httpInNode.includeRawBody) {
|
||||
return next();
|
||||
}
|
||||
if (rawDataRoutes.has(routeKey)) {
|
||||
|
||||
// Create a PassThrough stream to capture the request body
|
||||
var cloneStream = new PassThrough();
|
||||
@ -159,7 +149,7 @@ module.exports = function(RED) {
|
||||
// Remove listeners once the request is closed
|
||||
.once('close', () => {
|
||||
req.removeListener('data', onData);
|
||||
})
|
||||
});
|
||||
|
||||
// Attach the clone stream to the request
|
||||
Object.defineProperty(req, "_nodeRedReqStream", {
|
||||
@ -172,14 +162,10 @@ module.exports = function(RED) {
|
||||
return next();
|
||||
}
|
||||
|
||||
if (!isMiddlewareExists) {
|
||||
// Initialize HTTP node storage
|
||||
rootApp.set('httpInNodes', new Map());
|
||||
// Add middleware to the stack
|
||||
rootApp.use(setupRawBodyCapture)
|
||||
// Move the router to top of the stack
|
||||
rootApp._router.stack.unshift(rootApp._router.stack.pop())
|
||||
}
|
||||
// Add middleware to the stack
|
||||
rootApp.use(setupRawBodyCapture);
|
||||
// Move the router to top of the stack
|
||||
rootApp._router.stack.unshift(rootApp._router.stack.pop());
|
||||
|
||||
function createRequestWrapper(node,req) {
|
||||
// This misses a bunch of properties (eg headers). Before we use this function
|
||||
@ -301,6 +287,12 @@ module.exports = function(RED) {
|
||||
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) {
|
||||
rawDataRoutes.add(routeKey);
|
||||
}
|
||||
|
||||
this.errorHandler = function(err,req,res,next) {
|
||||
node.warn(err);
|
||||
@ -383,14 +375,10 @@ module.exports = function(RED) {
|
||||
RED.httpNode.delete(this.url, cookieParser(), httpMiddleware, corsHandler, metricsHandler, jsonParser, urlencParser, rawBodyParser, this.callback, this.errorHandler);
|
||||
}
|
||||
|
||||
var routeKey = getRouteKey({method: this.method, url: RED.httpNode.path() + this.url})
|
||||
|
||||
var httpInNodes = rootApp.get('httpInNodes')
|
||||
|
||||
httpInNodes.set(routeKey, this);
|
||||
|
||||
this.on("close",function() {
|
||||
httpInNodes.delete(routeKey)
|
||||
// Remove it from the raw data routes if the node is closed
|
||||
rawDataRoutes.delete(routeKey);
|
||||
var node = this;
|
||||
RED.httpNode._router.stack.forEach(function(route,i,routes) {
|
||||
if (route.route && route.route.path === node.url && route.route.methods[node.method]) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user