diff --git a/packages/node_modules/@node-red/nodes/core/network/21-httpin.html b/packages/node_modules/@node-red/nodes/core/network/21-httpin.html
index f828077a1..6d478c29e 100644
--- a/packages/node_modules/@node-red/nodes/core/network/21-httpin.html
+++ b/packages/node_modules/@node-red/nodes/core/network/21-httpin.html
@@ -23,6 +23,9 @@
+
+
+
diff --git a/packages/node_modules/@node-red/nodes/core/network/21-httpin.js b/packages/node_modules/@node-red/nodes/core/network/21-httpin.js
index 22e83b411..bb7967d35 100644
--- a/packages/node_modules/@node-red/nodes/core/network/21-httpin.js
+++ b/packages/node_modules/@node-red/nodes/core/network/21-httpin.js
@@ -171,9 +171,18 @@ module.exports = function(RED) {
if (RED.settings.httpNodeCors) {
corsHandler = cors(RED.settings.httpNodeCors);
- RED.httpNode.options("*",corsHandler);
}
+ RED.httpNode.options("*", function(req,res,next) {
+ //see if any routes for this path exist & call next() otherwise call corsHandler
+ const routes = RED.httpNode._router.stack.filter(e => e.route && e.route.path == req.path && e.route.methods.options === true);
+ if(routes.length > 0) {
+ next();
+ return
+ }
+ corsHandler(req,res,next);
+ });
+
function HTTPIn(n) {
RED.nodes.createNode(this,n);
if (RED.settings.httpNodeRoot !== false) {
@@ -197,8 +206,9 @@ module.exports = function(RED) {
res.sendStatus(500);
};
- this.callback = function(req,res) {
- var msgid = RED.util.generateId();
+ this.callback = function (req, res, next) {
+ const msgid = RED.util.generateId();
+ const resWrap = createResponseWrapper(node, res);
res._msgid = msgid;
// Since Node 15, req.headers are lazily computed and the property
// marked as non-enumerable.
@@ -210,11 +220,19 @@ module.exports = function(RED) {
enumerable: true
})
if (node.method.match(/^(post|delete|put|options|patch)$/)) {
- node.send({_msgid:msgid,req:req,res:createResponseWrapper(node,res),payload:req.body});
+ node.send({ _msgid: msgid, req: req, res: resWrap, payload: req.body });
} else if (node.method == "get") {
- node.send({_msgid:msgid,req:req,res:createResponseWrapper(node,res),payload:req.query});
+ node.send({ _msgid: msgid, req: req, res: resWrap, payload: req.query });
+ } else if (node.method == "trace") {
+ // https://httpwg.org/specs/rfc7231.html#rfc.section.4.3.8
+ res.set('Content-Type', 'message/http')
+ // Add REQ string to body (e.g. TRACE / HTTP/1.1)
+ let pl = `TRACE ${req.path} ${req.protocol.toUpperCase()}/${req.httpVersion}\n`;
+ // Add REQ headers to body
+ pl += Object.entries(req.headers).map(e => e.join(": ")).join("\n");
+ node.send({ _msgid: msgid, req: req, res: resWrap, payload: pl });
} else {
- node.send({_msgid:msgid,req:req,res:createResponseWrapper(node,res)});
+ node.send({ _msgid: msgid, req: req, res: resWrap });
}
};
@@ -262,6 +280,8 @@ module.exports = function(RED) {
if (this.method == "get") {
RED.httpNode.get(this.url,cookieParser(),httpMiddleware,corsHandler,metricsHandler,this.callback,this.errorHandler);
+ } else if (this.method == "head") { // https://httpwg.org/specs/rfc7231.html#rfc.section.4.3.2
+ RED.httpNode.head(this.url,cookieParser(),httpMiddleware,corsHandler,metricsHandler,this.callback,this.errorHandler);
} else if (this.method == "post") {
RED.httpNode.post(this.url,cookieParser(),httpMiddleware,corsHandler,metricsHandler,jsonParser,urlencParser,multipartParser,rawBodyParser,this.callback,this.errorHandler);
} else if (this.method == "put") {
@@ -270,6 +290,10 @@ module.exports = function(RED) {
RED.httpNode.patch(this.url,cookieParser(),httpMiddleware,corsHandler,metricsHandler,jsonParser,urlencParser,rawBodyParser,this.callback,this.errorHandler);
} else if (this.method == "delete") {
RED.httpNode.delete(this.url,cookieParser(),httpMiddleware,corsHandler,metricsHandler,jsonParser,urlencParser,rawBodyParser,this.callback,this.errorHandler);
+ } else if (this.method == "options") { // https://httpwg.org/specs/rfc7231.html#rfc.section.4.3.7
+ RED.httpNode.options(this.url,cookieParser(),httpMiddleware,metricsHandler,jsonParser,urlencParser,rawBodyParser,this.callback,this.errorHandler);
+ } else if (this.method == "trace") { // https://httpwg.org/specs/rfc7231.html#rfc.section.4.3.8
+ RED.httpNode.trace(this.url,cookieParser(),httpMiddleware,corsHandler,metricsHandler,this.callback,this.errorHandler);
}
this.on("close",function() {
diff --git a/packages/node_modules/@node-red/nodes/locales/en-US/network/21-httpin.html b/packages/node_modules/@node-red/nodes/locales/en-US/network/21-httpin.html
index d3f1984c4..ef38c8429 100644
--- a/packages/node_modules/@node-red/nodes/locales/en-US/network/21-httpin.html
+++ b/packages/node_modules/@node-red/nodes/locales/en-US/network/21-httpin.html
@@ -19,8 +19,18 @@
Outputs
- payload
- - For a GET request, contains an object of any query string parameters.
- Otherwise, contains the body of the HTTP request.
+ -
+
+ GET
- payload
contains an object of any query string parameters passed in the HTTP Request
+ POST
- payload
contains the body of the HTTP Request
+ PUT
- payload
contains the body of the HTTP Request
+ DELETE
- payload
contains the body of the HTTP Request
+ PATCH
- payload
contains the body of the HTTP Request
+ HEAD
- payload
the HEAD method has no payload
+ OPTIONS
- payload
contains the body of the HTTP Request
+ TRACE
- payload
contains the details of the HTTP Request in the body
+
+
- reqobject
- An HTTP request object. This object contains multiple properties that
provide information about the request.