@@ -222,14 +297,16 @@
diff --git a/packages/node_modules/@node-red/nodes/core/network/31-tcpin.js b/packages/node_modules/@node-red/nodes/core/network/31-tcpin.js
index 2f59227c8..24e6abf7e 100644
--- a/packages/node_modules/@node-red/nodes/core/network/31-tcpin.js
+++ b/packages/node_modules/@node-red/nodes/core/network/31-tcpin.js
@@ -16,13 +16,46 @@
module.exports = function(RED) {
"use strict";
- var reconnectTime = RED.settings.socketReconnectTime||10000;
- var socketTimeout = RED.settings.socketTimeout||null;
+ let reconnectTime = RED.settings.socketReconnectTime || 10000;
+ let socketTimeout = RED.settings.socketTimeout || null;
const msgQueueSize = RED.settings.tcpMsgQueueSize || 1000;
const Denque = require('denque');
- var net = require('net');
+ const net = require('net');
+ const tls = require('tls');
- var connectionPool = {};
+ let connectionPool = {};
+
+ function normalizeConnectArgs(listArgs) {
+ const args = net._normalizeArgs(listArgs);
+ const options = args[0];
+ const cb = args[1];
+
+ // If args[0] was options, then normalize dealt with it.
+ // If args[0] is port, or args[0], args[1] is host, port, we need to
+ // find the options and merge them in, normalize's options has only
+ // the host/port/path args that it knows about, not the tls options.
+ // This means that options.host overrides a host arg.
+ if (listArgs[1] !== null && typeof listArgs[1] === 'object') {
+ ObjectAssign(options, listArgs[1]);
+ } else if (listArgs[2] !== null && typeof listArgs[2] === 'object') {
+ ObjectAssign(options, listArgs[2]);
+ }
+
+ return cb ? [options, cb] : [options];
+ }
+
+ function getAllowUnauthorized() {
+ const allowUnauthorized = process.env.NODE_TLS_REJECT_UNAUTHORIZED === '0';
+
+ if (allowUnauthorized) {
+ process.emitWarning(
+ 'Setting the NODE_TLS_REJECT_UNAUTHORIZED ' +
+ 'environment variable to \'0\' makes TLS connections ' +
+ 'and HTTPS requests insecure by disabling ' +
+ 'certificate verification.');
+ }
+ return allowUnauthorized;
+ }
/**
* Enqueue `item` in `queue`
@@ -53,13 +86,14 @@ module.exports = function(RED) {
this.topic = n.topic;
this.stream = (!n.datamode||n.datamode=='stream'); /* stream,single*/
this.datatype = n.datatype||'buffer'; /* buffer,utf8,base64 */
- this.newline = (n.newline||"").replace("\\n","\n").replace("\\r","\r");
+ this.newline = (n.newline||"").replace("\\n","\n").replace("\\r","\r").replace("\\t","\t");
this.base64 = n.base64;
this.server = (typeof n.server == 'boolean')?n.server:(n.server == "server");
this.closing = false;
this.connected = false;
var node = this;
var count = 0;
+ if (n.tls) { var tlsNode = RED.nodes.getNode(n.tls); }
if (!node.server) {
var buffer = null;
@@ -70,13 +104,25 @@ module.exports = function(RED) {
node.log(RED._("tcpin.status.connecting",{host:node.host,port:node.port}));
node.status({fill:"grey",shape:"dot",text:"common.status.connecting"});
var id = RED.util.generateId();
- client = net.connect(node.port, node.host, function() {
- buffer = (node.datatype == 'buffer') ? Buffer.alloc(0) : "";
- node.connected = true;
- node.log(RED._("tcpin.status.connected",{host:node.host,port:node.port}));
- node.status({fill:"green",shape:"dot",text:"common.status.connected",_session:{type:"tcp",id:id}});
- });
- client.setKeepAlive(true,120000);
+ var connOpts = {host: node.host};
+ if (n.tls) {
+ var connOpts = tlsNode.addTLSOptions({host: node.host});
+ client = tls.connect(node.port, connOpts, function() {
+ buffer = (node.datatype == 'buffer') ? Buffer.alloc(0) : "";
+ node.connected = true;
+ node.log(RED._("status.connected", {host: node.host, port: node.port}));
+ node.status({fill:"green",shape:"dot",text:"common.status.connected",_session:{type:"tcp",id:id}});
+ });
+ }
+ else {
+ client = net.connect(node.port, node.host, function() {
+ buffer = (node.datatype == 'buffer') ? Buffer.alloc(0) : "";
+ node.connected = true;
+ node.log(RED._("tcpin.status.connected",{host:node.host,port:node.port}));
+ node.status({fill:"green",shape:"dot",text:"common.status.connected",_session:{type:"tcp",id:id}});
+ });
+ }
+ client.setKeepAlive(true, 120000);
connectionPool[id] = client;
client.on('data', function (data) {
@@ -89,7 +135,7 @@ module.exports = function(RED) {
buffer = buffer+data;
var parts = buffer.split(node.newline);
for (var i = 0; i
{
try {
if (typeof result === 'object') {
- msg.should.have.properties(Object.assign({}, result, {payload: Buffer.from(result.payload)}));
+ if (flow[0].ret === "string") {
+ msg.should.have.properties(Object.assign({}, result, {payload: result.payload}));
+ } else {
+ msg.should.have.properties(Object.assign({}, result, {payload: Buffer.from(result.payload)}));
+ }
} else {
- msg.should.have.property('payload', Buffer.from(result));
+ if (flow[0].ret === "string") {
+ msg.should.have.property('payload', result);
+ } else {
+ msg.should.have.property('payload', Buffer.from(result));
+ }
}
done();
} catch(err) {
@@ -245,10 +253,41 @@ describe('TCP Request Node', function() {
}, done);
});
+ it('should send & receive, then keep connection, and not split return strings', function(done) {
+ var flow = [{id:"n1", type:"tcp request", server:"localhost", port:port, out:"sit", ret:"string", newline:"", wires:[["n2"]] },
+ {id:"n2", type:"helper"}];
+ testTCPMany(flow, [{
+ payload: "foo",
+ topic: 'boo'
+ }, {
+ payload: "bar\nfoo",
+ topic: 'boo'
+ }], {
+ payload: "ACK:foobar\nfoo",
+ topic: 'boo'
+ }, done);
+ });
+
+ it('should send & receive, then keep connection, and split return strings', function(done) {
+ var flow = [{id:"n1", type:"tcp request", server:"localhost", port:port, out:"sit", ret:"string", newline:"\\n", wires:[["n2"]] },
+ {id:"n2", type:"helper"}];
+ testTCPMany(flow, [{
+ payload: "foo",
+ topic: 'boo'
+ }, {
+ payload: "bar\nfoo",
+ topic: 'boo'
+ }], {
+ payload: "ACK:foobar",
+ topic: 'boo'
+ }, done);
+ });
+
it('should send & recv data to/from server:port from msg', function(done) {
var flow = [{id:"n1", type:"tcp request", server:"", port:"", out:"time", splitc: "0", wires:[["n2"]] },
{id:"n2", type:"helper"}];
- testTCPMany(flow, [{
+ testTCPMany(flow, [
+ {
payload: "f",
host: "localhost",
port: port