@node-red/nodes 4.1.2 → 4.1.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -20,13 +20,15 @@ module.exports = function(RED) {
20
20
  function StatusNode(n) {
21
21
  RED.nodes.createNode(this,n);
22
22
  var node = this;
23
- this.scope = n.scope || [];
23
+ this.scope = n.scope;
24
24
 
25
25
  // auto-filter out any directly connected nodes to avoid simple loopback
26
- const w = this.wires.flat();
27
- for (let i=0; i < this.scope.length; i++) {
28
- if (w.includes(this.scope[i])) {
29
- this.scope.splice(i, 1);
26
+ if (Array.isArray(this.scope)) {
27
+ const w = this.wires.flat();
28
+ for (let i = 0; i < this.scope.length; i++) {
29
+ if (w.includes(this.scope[i])) {
30
+ this.scope.splice(i, 1);
31
+ }
30
32
  }
31
33
  }
32
34
 
@@ -159,7 +159,8 @@ module.exports = function(RED) {
159
159
  if (node.pauseType === "delay") {
160
160
  node.on("input", function(msg, send, done) {
161
161
  var id = ourTimeout(function() {
162
- node.idList.splice(node.idList.indexOf(id),1);
162
+ var idx = node.idList.indexOf(id);
163
+ if (idx !== -1) { node.idList.splice(idx, 1); }
163
164
  if (node.timeout > 1000) {
164
165
  node.status({fill:"blue",shape:"dot",text:node.idList.length});
165
166
  }
@@ -184,7 +185,8 @@ module.exports = function(RED) {
184
185
  }
185
186
  if (delayvar < 0) { delayvar = 0; }
186
187
  var id = ourTimeout(function() {
187
- node.idList.splice(node.idList.indexOf(id),1);
188
+ var idx = node.idList.indexOf(id);
189
+ if (idx !== -1) { node.idList.splice(idx, 1); }
188
190
  if (node.idList.length === 0) { node.status({}); }
189
191
  send(msg);
190
192
  if (delayvar >= 0) {
@@ -192,7 +194,8 @@ module.exports = function(RED) {
192
194
  }
193
195
  done();
194
196
  }, delayvar, () => done());
195
- node.idList.push(id);
197
+ if (Object.keys(msg).length === 2 && msg.hasOwnProperty("flush")) { id.clear(); }
198
+ else { node.idList.push(id); }
196
199
  if (msg.hasOwnProperty("reset")) { clearDelayList(true); }
197
200
  if (msg.hasOwnProperty("flush")) { flushDelayList(msg.flush); done(); }
198
201
  if (delayvar >= 0) {
@@ -206,7 +209,8 @@ module.exports = function(RED) {
206
209
  node.on("input", function(msg, send, done) {
207
210
  var wait = node.randomFirst + (node.diff * Math.random());
208
211
  var id = ourTimeout(function() {
209
- node.idList.splice(node.idList.indexOf(id),1);
212
+ var idx = node.idList.indexOf(id);
213
+ if (idx !== -1) { node.idList.splice(idx, 1); }
210
214
  send(msg);
211
215
  if (node.timeout >= 1000) {
212
216
  node.status({fill:"blue",shape:"dot",text:node.idList.length});
@@ -105,18 +105,26 @@ module.exports = function(RED) {
105
105
  }
106
106
  node.activeProcesses[child.pid] = child;
107
107
  child.stdout.on('data', function (data) {
108
- if (node.activeProcesses.hasOwnProperty(child.pid) && node.activeProcesses[child.pid] !== null) {
109
- // console.log('[exec] stdout: ' + data,child.pid);
110
- if (isUtf8(data)) { msg.payload = data.toString(); }
111
- else { msg.payload = data; }
112
- nodeSend([RED.util.cloneMessage(msg),null,null]);
108
+ try {
109
+ if (node.activeProcesses.hasOwnProperty(child.pid) && node.activeProcesses[child.pid] !== null) {
110
+ // console.log('[exec] stdout: ' + data,child.pid);
111
+ if (isUtf8(data)) { msg.payload = data.toString(); }
112
+ else { msg.payload = data; }
113
+ nodeSend([RED.util.cloneMessage(msg),null,null]);
114
+ }
115
+ } catch (err) {
116
+ node.error(err.toString());
113
117
  }
114
118
  });
115
119
  child.stderr.on('data', function (data) {
116
- if (node.activeProcesses.hasOwnProperty(child.pid) && node.activeProcesses[child.pid] !== null) {
117
- if (isUtf8(data)) { msg.payload = data.toString(); }
118
- else { msg.payload = data; }
119
- nodeSend([null,RED.util.cloneMessage(msg),null]);
120
+ try {
121
+ if (node.activeProcesses.hasOwnProperty(child.pid) && node.activeProcesses[child.pid] !== null) {
122
+ if (isUtf8(data)) { msg.payload = data.toString(); }
123
+ else { msg.payload = data; }
124
+ nodeSend([null,RED.util.cloneMessage(msg),null]);
125
+ }
126
+ } catch (err) {
127
+ node.error(err.toString());
120
128
  }
121
129
  });
122
130
  child.on('close', function (code,signal) {
@@ -167,12 +167,15 @@
167
167
  $("#tls-config-button-cert-clear").on("click", function() {
168
168
  clearNameData("cert");
169
169
  });
170
+ RED.popover.tooltip($("#tls-config-button-cert-clear"), RED._("common.label.delete"));
170
171
  $("#tls-config-button-key-clear").on("click", function() {
171
172
  clearNameData("key");
172
173
  });
174
+ RED.popover.tooltip($("#tls-config-button-key-clear"), RED._("common.label.delete"));
173
175
  $("#tls-config-button-ca-clear").on("click", function() {
174
176
  clearNameData("ca");
175
177
  });
178
+ RED.popover.tooltip($("#tls-config-button-ca-clear"), RED._("common.label.delete"));
176
179
 
177
180
  if (RED.settings.tlsConfigDisableLocalFiles) {
178
181
  $("#node-config-row-uselocalfiles").hide();
@@ -227,6 +227,7 @@ module.exports = function(RED) {
227
227
  * Handle the payload / packet recieved in MQTT In and MQTT Sub nodes
228
228
  */
229
229
  function subscriptionHandler(node, datatype ,topic, payload, packet) {
230
+ if (!packet) { packet = {}; }
230
231
  const msg = {topic:topic, payload:null, qos:packet.qos, retain:packet.retain};
231
232
  const v5 = (node && node.brokerConn)
232
233
  ? node.brokerConn.v5()
@@ -1074,12 +1075,16 @@ module.exports = function(RED) {
1074
1075
 
1075
1076
  if (!subscription.handler) {
1076
1077
  subscription.handler = function (mtopic, mpayload, mpacket) {
1077
- const sops = subscription.options ? subscription.options.properties : {}
1078
- const pops = mpacket.properties || {}
1079
- if (subIdsAvailable && pops.subscriptionIdentifier && sops.subscriptionIdentifier && (pops.subscriptionIdentifier !== sops.subscriptionIdentifier)) {
1080
- //do nothing as subscriptionIdentifier does not match
1081
- } else if (matchTopic(topic, mtopic)) {
1082
- subscription.callback && subscription.callback(mtopic, mpayload, mpacket)
1078
+ try {
1079
+ const sops = subscription.options ? subscription.options.properties : {}
1080
+ const pops = (mpacket && mpacket.properties) || {}
1081
+ if (subIdsAvailable && pops.subscriptionIdentifier && sops.subscriptionIdentifier && (pops.subscriptionIdentifier !== sops.subscriptionIdentifier)) {
1082
+ //do nothing as subscriptionIdentifier does not match
1083
+ } else if (matchTopic(topic, mtopic)) {
1084
+ subscription.callback && subscription.callback(mtopic, mpayload, mpacket)
1085
+ }
1086
+ } catch (err) {
1087
+ node.error("MQTT subscription handler error: " + err.toString());
1083
1088
  }
1084
1089
  }
1085
1090
  }
@@ -143,15 +143,6 @@ in your Node-RED user directory (${RED.settings.userDir}).
143
143
  });
144
144
  }
145
145
  }
146
- /**
147
- * @param {Object} headersObject
148
- * @param {string} name
149
- * @return {any} value
150
- */
151
- const getHeaderValue = (headersObject, name) => {
152
- const asLowercase = name.toLowercase();
153
- return headersObject[Object.keys(headersObject).find(k => k.toLowerCase() === asLowercase)];
154
- }
155
146
  this.count = 0;
156
147
  this.on("input",function(msg,nodeSend,nodeDone) {
157
148
  node.count++;
@@ -256,34 +247,42 @@ in your Node-RED user directory (${RED.settings.userDir}).
256
247
  opts.hooks = {
257
248
  beforeRequest: [
258
249
  options => {
259
- // Whilst HTTP headers are meant to be case-insensitive,
260
- // in the real world, there are servers that aren't so compliant.
261
- // GOT will lower case all headers given a chance, so we need
262
- // to restore the case of any headers the user has set.
263
- Object.keys(options.headers).forEach(h => {
264
- if (originalHeaderMap[h] && originalHeaderMap[h] !== h) {
265
- options.headers[originalHeaderMap[h]] = options.headers[h];
266
- delete options.headers[h];
250
+ try {
251
+ // Whilst HTTP headers are meant to be case-insensitive,
252
+ // in the real world, there are servers that aren't so compliant.
253
+ // GOT will lower case all headers given a chance, so we need
254
+ // to restore the case of any headers the user has set.
255
+ Object.keys(options.headers).forEach(h => {
256
+ if (originalHeaderMap[h] && originalHeaderMap[h] !== h) {
257
+ options.headers[originalHeaderMap[h]] = options.headers[h];
258
+ delete options.headers[h];
259
+ }
260
+ })
261
+ if (node.insecureHTTPParser) {
262
+ // Setting the property under _unixOptions as pretty
263
+ // much the only hack available to get got to apply
264
+ // a core http option it doesn't think we should be
265
+ // allowed to set
266
+ options._unixOptions = { ...options.unixOptions, insecureHTTPParser: true }
267
267
  }
268
- })
269
- if (node.insecureHTTPParser) {
270
- // Setting the property under _unixOptions as pretty
271
- // much the only hack available to get got to apply
272
- // a core http option it doesn't think we should be
273
- // allowed to set
274
- options._unixOptions = { ...options.unixOptions, insecureHTTPParser: true }
268
+ } catch (err) {
269
+ node.warn("Error in beforeRequest hook: " + err.message);
275
270
  }
276
271
  }
277
272
  ],
278
273
  beforeRedirect: [
279
274
  (options, response) => {
280
- let redirectInfo = {
281
- location: response.headers.location
282
- }
283
- if (response.headers.hasOwnProperty('set-cookie')) {
284
- redirectInfo.cookies = extractCookies(response.headers['set-cookie']);
275
+ try {
276
+ let redirectInfo = {
277
+ location: response.headers.location
278
+ }
279
+ if (response.headers.hasOwnProperty('set-cookie')) {
280
+ redirectInfo.cookies = extractCookies(response.headers['set-cookie']);
281
+ }
282
+ redirectList.push(redirectInfo)
283
+ } catch (err) {
284
+ node.warn("Error processing redirect: " + err.message);
285
285
  }
286
- redirectList.push(redirectInfo)
287
286
  }
288
287
  ]
289
288
  }
@@ -422,25 +421,30 @@ in your Node-RED user directory (${RED.settings.userDir}).
422
421
  let digestCreds = this.credentials;
423
422
  let sentCreds = false;
424
423
  opts.hooks.afterResponse = [(response, retry) => {
425
- if (response.statusCode === 401) {
426
- if (sentCreds) {
427
- return response
428
- }
429
- const requestUrl = new URL(response.request.requestUrl);
430
- const options = { headers: {} }
431
- const normalisedHeaders = {};
432
- Object.keys(response.headers).forEach(k => {
433
- normalisedHeaders[k.toLowerCase()] = response.headers[k]
434
- })
435
- if (normalisedHeaders['www-authenticate']) {
436
- let authHeader = buildDigestHeader(digestCreds.user,digestCreds.password, response.request.options.method, requestUrl.pathname + requestUrl.search, normalisedHeaders['www-authenticate'])
437
- options.headers.Authorization = authHeader;
424
+ try {
425
+ if (response.statusCode === 401) {
426
+ if (sentCreds) {
427
+ return response
428
+ }
429
+ const requestUrl = new URL(response.request.requestUrl);
430
+ const options = { headers: {} }
431
+ const normalisedHeaders = {};
432
+ Object.keys(response.headers).forEach(k => {
433
+ normalisedHeaders[k.toLowerCase()] = response.headers[k]
434
+ })
435
+ if (normalisedHeaders['www-authenticate']) {
436
+ let authHeader = buildDigestHeader(digestCreds.user,digestCreds.password, response.request.options.method, requestUrl.pathname + requestUrl.search, normalisedHeaders['www-authenticate'])
437
+ options.headers.Authorization = authHeader;
438
+ }
439
+ // response.request.options.merge(options)
440
+ sentCreds = true;
441
+ return retry(options);
438
442
  }
439
- // response.request.options.merge(options)
440
- sentCreds = true;
441
- return retry(options);
443
+ return response
444
+ } catch (err) {
445
+ node.warn("Digest authentication failed: " + err.message);
446
+ return response;
442
447
  }
443
- return response
444
448
  }];
445
449
  } else if (this.authType === "bearer") {
446
450
  opts.headers.Authorization = `Bearer ${this.credentials.password||""}`
@@ -688,6 +692,7 @@ in your Node-RED user directory (${RED.settings.userDir}).
688
692
  if (!sendErrorsToCatch) {
689
693
  nodeSend(msg);
690
694
  }
695
+ node.count--;
691
696
  nodeDone();
692
697
  });
693
698
  });
@@ -720,13 +725,29 @@ in your Node-RED user directory (${RED.settings.userDir}).
720
725
 
721
726
  function extractCookies(setCookie) {
722
727
  var cookies = {};
728
+ if (!Array.isArray(setCookie)) {
729
+ return cookies;
730
+ }
723
731
  setCookie.forEach(function(c) {
724
- var parsedCookie = cookie.parse(c);
725
- var eq_idx = c.indexOf('=');
726
- var key = c.substr(0, eq_idx).trim()
727
- parsedCookie.value = parsedCookie[key];
728
- delete parsedCookie[key];
729
- cookies[key] = parsedCookie;
732
+ try {
733
+ if (typeof c !== 'string') {
734
+ return;
735
+ }
736
+ var parsedCookie = cookie.parse(c);
737
+ var eq_idx = c.indexOf('=');
738
+ if (eq_idx === -1) {
739
+ return;
740
+ }
741
+ var key = c.substr(0, eq_idx).trim()
742
+ if (!key) {
743
+ return;
744
+ }
745
+ parsedCookie.value = parsedCookie[key];
746
+ delete parsedCookie[key];
747
+ cookies[key] = parsedCookie;
748
+ } catch (err) {
749
+ // Skip malformed cookies
750
+ }
730
751
  });
731
752
  return cookies;
732
753
  }
@@ -778,6 +799,9 @@ in your Node-RED user directory (${RED.settings.userDir}).
778
799
  }
779
800
 
780
801
  function buildDigestHeader(user, pass, method, path, authHeader) {
802
+ if (!authHeader || typeof authHeader !== 'string') {
803
+ throw new Error("Invalid or missing WWW-Authenticate header");
804
+ }
781
805
  var challenge = {}
782
806
  var re = /([a-z0-9_-]+)=(?:"([^"]+)"|([a-z0-9_-]+))/gi
783
807
  for (;;) {
@@ -787,6 +811,12 @@ in your Node-RED user directory (${RED.settings.userDir}).
787
811
  }
788
812
  challenge[match[1]] = match[2] || match[3]
789
813
  }
814
+ if (!challenge.nonce) {
815
+ throw new Error("Invalid digest challenge: missing nonce");
816
+ }
817
+ if (!challenge.realm) {
818
+ throw new Error("Invalid digest challenge: missing realm");
819
+ }
790
820
  var qop = /(^|,)\s*auth\s*($|,)/.test(challenge.qop) && 'auth'
791
821
  var nc = qop && '00000001'
792
822
  var cnonce = qop && uuid().replace(/-/g, '')
@@ -297,7 +297,11 @@ module.exports = function(RED) {
297
297
  }
298
298
  msg._session = {type:"websocket",id:id};
299
299
  for (var i = 0; i < this._inputNodes.length; i++) {
300
- this._inputNodes[i].send(msg);
300
+ try {
301
+ this._inputNodes[i].send(msg);
302
+ } catch (err) {
303
+ this.error(RED._("websocket.errors.send-error") + " " + err.toString());
304
+ }
301
305
  }
302
306
  }
303
307
 
@@ -127,32 +127,36 @@ module.exports = function(RED) {
127
127
  connectionPool[id] = client;
128
128
 
129
129
  client.on('data', function (data) {
130
- if (node.datatype != 'buffer') {
131
- data = data.toString(node.datatype);
132
- }
133
- if (node.stream) {
134
- var msg;
135
- if ((node.datatype) === "utf8" && node.newline !== "") {
136
- buffer = buffer+data;
137
- var parts = buffer.split(node.newline);
138
- for (var i = 0; i<parts.length-1; i+=1) {
139
- msg = {topic:node.topic, payload:parts[i]};
140
- if (node.trim == true) { msg.payload += node.newline; }
130
+ try {
131
+ if (node.datatype != 'buffer') {
132
+ data = data.toString(node.datatype);
133
+ }
134
+ if (node.stream) {
135
+ var msg;
136
+ if ((node.datatype) === "utf8" && node.newline !== "") {
137
+ buffer = buffer+data;
138
+ var parts = buffer.split(node.newline);
139
+ for (var i = 0; i<parts.length-1; i+=1) {
140
+ msg = {topic:node.topic, payload:parts[i]};
141
+ if (node.trim == true) { msg.payload += node.newline; }
142
+ msg._session = {type:"tcp",id:id};
143
+ node.send(msg);
144
+ }
145
+ buffer = parts[parts.length-1];
146
+ } else {
147
+ msg = {topic:node.topic, payload:data};
141
148
  msg._session = {type:"tcp",id:id};
142
149
  node.send(msg);
143
150
  }
144
- buffer = parts[parts.length-1];
145
151
  } else {
146
- msg = {topic:node.topic, payload:data};
147
- msg._session = {type:"tcp",id:id};
148
- node.send(msg);
149
- }
150
- } else {
151
- if ((typeof data) === "string") {
152
- buffer = buffer+data;
153
- } else {
154
- buffer = Buffer.concat([buffer,data],buffer.length+data.length);
152
+ if ((typeof data) === "string") {
153
+ buffer = buffer+data;
154
+ } else {
155
+ buffer = Buffer.concat([buffer,data],buffer.length+data.length);
156
+ }
155
157
  }
158
+ } catch (err) {
159
+ node.error(RED._("tcpin.errors.error",{error:err.toString()}));
156
160
  }
157
161
  });
158
162
  client.on('end', function() {
@@ -222,35 +226,39 @@ module.exports = function(RED) {
222
226
 
223
227
  var buffer = (node.datatype == 'buffer') ? Buffer.alloc(0) : "";
224
228
  socket.on('data', function (data) {
225
- if (node.datatype != 'buffer') {
226
- data = data.toString(node.datatype);
227
- }
228
- if (node.stream) {
229
- var msg;
230
- if ((typeof data) === "string" && node.newline !== "") {
231
- buffer = buffer+data;
232
- var parts = buffer.split(node.newline);
233
- for (var i = 0; i<parts.length-1; i+=1) {
234
- msg = {topic:node.topic, payload:parts[i], ip:socket.remoteAddress, port:socket.remotePort};
235
- if (node.trim == true) { msg.payload += node.newline; }
229
+ try {
230
+ if (node.datatype != 'buffer') {
231
+ data = data.toString(node.datatype);
232
+ }
233
+ if (node.stream) {
234
+ var msg;
235
+ if ((typeof data) === "string" && node.newline !== "") {
236
+ buffer = buffer+data;
237
+ var parts = buffer.split(node.newline);
238
+ for (var i = 0; i<parts.length-1; i+=1) {
239
+ msg = {topic:node.topic, payload:parts[i], ip:socket.remoteAddress, port:socket.remotePort};
240
+ if (node.trim == true) { msg.payload += node.newline; }
241
+ msg._session = {type:"tcp",id:id};
242
+ node.send(msg);
243
+ }
244
+ buffer = parts[parts.length-1];
245
+ } else {
246
+ msg = {topic:node.topic, payload:data, ip:socket.remoteAddress, port:socket.remotePort};
236
247
  msg._session = {type:"tcp",id:id};
237
248
  node.send(msg);
238
249
  }
239
- buffer = parts[parts.length-1];
240
- } else {
241
- msg = {topic:node.topic, payload:data, ip:socket.remoteAddress, port:socket.remotePort};
242
- msg._session = {type:"tcp",id:id};
243
- node.send(msg);
244
250
  }
245
- }
246
- else {
247
- if ((typeof data) === "string") {
248
- buffer = buffer+data;
249
- } else {
250
- buffer = Buffer.concat([buffer,data],buffer.length+data.length);
251
+ else {
252
+ if ((typeof data) === "string") {
253
+ buffer = buffer+data;
254
+ } else {
255
+ buffer = Buffer.concat([buffer,data],buffer.length+data.length);
256
+ }
257
+ fromi = socket.remoteAddress;
258
+ fromp = socket.remotePort;
251
259
  }
252
- fromi = socket.remoteAddress;
253
- fromp = socket.remotePort;
260
+ } catch (err) {
261
+ node.error(RED._("tcpin.errors.error",{error:err.toString()}));
254
262
  }
255
263
  });
256
264
  socket.on('end', function() {
@@ -678,117 +686,121 @@ module.exports = function(RED) {
678
686
  }
679
687
  var chunk = "";
680
688
  clients[connection_id].client.on('data', function(data) {
681
- if (node.out === "sit") { // if we are staying connected just send the buffer
682
- if (clients[connection_id]) {
683
- const msg = clients[connection_id].lastMsg || {};
684
- msg.payload = RED.util.cloneMessage(data);
685
- if (node.ret === "string") {
686
- try {
687
- if (node.newline && node.newline !== "" ) {
688
- chunk += msg.payload.toString();
689
- let parts = chunk.split(node.newline);
690
- for (var p=0; p<parts.length-1; p+=1) {
691
- let m = RED.util.cloneMessage(msg);
692
- m.payload = parts[p];
693
- if (node.trim == true) { m.payload += node.newline; }
694
- nodeSend(m);
689
+ try {
690
+ if (node.out === "sit") { // if we are staying connected just send the buffer
691
+ if (clients[connection_id]) {
692
+ const msg = clients[connection_id].lastMsg || {};
693
+ msg.payload = RED.util.cloneMessage(data);
694
+ if (node.ret === "string") {
695
+ try {
696
+ if (node.newline && node.newline !== "" ) {
697
+ chunk += msg.payload.toString();
698
+ let parts = chunk.split(node.newline);
699
+ for (var p=0; p<parts.length-1; p+=1) {
700
+ let m = RED.util.cloneMessage(msg);
701
+ m.payload = parts[p];
702
+ if (node.trim == true) { m.payload += node.newline; }
703
+ nodeSend(m);
704
+ }
705
+ chunk = parts[parts.length-1];
706
+ }
707
+ else {
708
+ msg.payload = msg.payload.toString();
709
+ nodeSend(msg);
695
710
  }
696
- chunk = parts[parts.length-1];
697
- }
698
- else {
699
- msg.payload = msg.payload.toString();
700
- nodeSend(msg);
701
711
  }
712
+ catch(e) { node.error(RED._("tcpin.errors.bad-string"), msg); }
702
713
  }
703
- catch(e) { node.error(RED._("tcpin.errors.bad-string"), msg); }
714
+ else { nodeSend(msg); }
704
715
  }
705
- else { nodeSend(msg); }
706
716
  }
707
- }
708
- // else if (node.splitc === 0) {
709
- // clients[connection_id].msg.payload = data;
710
- // node.send(clients[connection_id].msg);
711
- // }
712
- else {
713
- for (var j = 0; j < data.length; j++ ) {
714
- if (node.out === "time") {
715
- if (clients[connection_id]) {
716
- // do the timer thing
717
- if (clients[connection_id].timeout) {
718
- i += 1;
719
- buf[i] = data[j];
720
- }
721
- else {
722
- clients[connection_id].timeout = setTimeout(function () {
723
- if (clients[connection_id]) {
724
- clients[connection_id].timeout = null;
725
- const msg = clients[connection_id].lastMsg || {};
726
- msg.payload = Buffer.alloc(i+1);
727
- buf.copy(msg.payload,0,0,i+1);
728
- if (node.ret === "string") {
729
- try { msg.payload = msg.payload.toString(); }
730
- catch(e) { node.error("Failed to create string", msg); }
731
- }
732
- nodeSend(msg);
733
- if (clients[connection_id].client) {
734
- node.status({});
735
- clients[connection_id].client.destroy();
736
- delete clients[connection_id];
737
- }
738
- }
739
- }, node.splitc);
740
- i = 0;
741
- buf[0] = data[j];
742
- }
743
- }
744
- }
745
- // count bytes into a buffer...
746
- else if (node.out == "count") {
747
- buf[i] = data[j];
748
- i += 1;
749
- if ( i >= node.splitc) {
717
+ // else if (node.splitc === 0) {
718
+ // clients[connection_id].msg.payload = data;
719
+ // node.send(clients[connection_id].msg);
720
+ // }
721
+ else {
722
+ for (var j = 0; j < data.length; j++ ) {
723
+ if (node.out === "time") {
750
724
  if (clients[connection_id]) {
751
- const msg = clients[connection_id].lastMsg || {};
752
- msg.payload = Buffer.alloc(i);
753
- buf.copy(msg.payload,0,0,i);
754
- if (node.ret === "string") {
755
- try { msg.payload = msg.payload.toString(); }
756
- catch(e) { node.error("Failed to create string", msg); }
725
+ // do the timer thing
726
+ if (clients[connection_id].timeout) {
727
+ i += 1;
728
+ buf[i] = data[j];
757
729
  }
758
- nodeSend(msg);
759
- if (clients[connection_id].client) {
760
- node.status({});
761
- clients[connection_id].client.destroy();
762
- delete clients[connection_id];
730
+ else {
731
+ clients[connection_id].timeout = setTimeout(function () {
732
+ if (clients[connection_id]) {
733
+ clients[connection_id].timeout = null;
734
+ const msg = clients[connection_id].lastMsg || {};
735
+ msg.payload = Buffer.alloc(i+1);
736
+ buf.copy(msg.payload,0,0,i+1);
737
+ if (node.ret === "string") {
738
+ try { msg.payload = msg.payload.toString(); }
739
+ catch(e) { node.error("Failed to create string", msg); }
740
+ }
741
+ nodeSend(msg);
742
+ if (clients[connection_id].client) {
743
+ node.status({});
744
+ clients[connection_id].client.destroy();
745
+ delete clients[connection_id];
746
+ }
747
+ }
748
+ }, node.splitc);
749
+ i = 0;
750
+ buf[0] = data[j];
763
751
  }
764
- i = 0;
765
752
  }
766
753
  }
767
- }
768
- // look for a char
769
- else {
770
- buf[i] = data[j];
771
- i += 1;
772
- if (data[j] == node.splitc) {
773
- if (clients[connection_id]) {
774
- const msg = clients[connection_id].lastMsg || {};
775
- msg.payload = Buffer.alloc(i);
776
- buf.copy(msg.payload,0,0,i);
777
- if (node.ret === "string") {
778
- try { msg.payload = msg.payload.toString(); }
779
- catch(e) { node.error("Failed to create string", msg); }
754
+ // count bytes into a buffer...
755
+ else if (node.out == "count") {
756
+ buf[i] = data[j];
757
+ i += 1;
758
+ if ( i >= node.splitc) {
759
+ if (clients[connection_id]) {
760
+ const msg = clients[connection_id].lastMsg || {};
761
+ msg.payload = Buffer.alloc(i);
762
+ buf.copy(msg.payload,0,0,i);
763
+ if (node.ret === "string") {
764
+ try { msg.payload = msg.payload.toString(); }
765
+ catch(e) { node.error("Failed to create string", msg); }
766
+ }
767
+ nodeSend(msg);
768
+ if (clients[connection_id].client) {
769
+ node.status({});
770
+ clients[connection_id].client.destroy();
771
+ delete clients[connection_id];
772
+ }
773
+ i = 0;
780
774
  }
781
- nodeSend(msg);
782
- if (clients[connection_id].client) {
783
- node.status({});
784
- clients[connection_id].client.destroy();
785
- delete clients[connection_id];
775
+ }
776
+ }
777
+ // look for a char
778
+ else {
779
+ buf[i] = data[j];
780
+ i += 1;
781
+ if (data[j] == node.splitc) {
782
+ if (clients[connection_id]) {
783
+ const msg = clients[connection_id].lastMsg || {};
784
+ msg.payload = Buffer.alloc(i);
785
+ buf.copy(msg.payload,0,0,i);
786
+ if (node.ret === "string") {
787
+ try { msg.payload = msg.payload.toString(); }
788
+ catch(e) { node.error("Failed to create string", msg); }
789
+ }
790
+ nodeSend(msg);
791
+ if (clients[connection_id].client) {
792
+ node.status({});
793
+ clients[connection_id].client.destroy();
794
+ delete clients[connection_id];
795
+ }
796
+ i = 0;
786
797
  }
787
- i = 0;
788
798
  }
789
799
  }
790
800
  }
791
801
  }
802
+ } catch (err) {
803
+ node.error(RED._("tcpin.errors.error",{error:err.toString()}));
792
804
  }
793
805
  });
794
806
 
@@ -98,15 +98,19 @@ module.exports = function(RED) {
98
98
  });
99
99
 
100
100
  server.on('message', function (message, remote) {
101
- var msg;
102
- if (node.datatype =="base64") {
103
- msg = { payload:message.toString('base64'), fromip:remote.address+':'+remote.port, ip:remote.address, port:remote.port };
104
- } else if (node.datatype =="utf8") {
105
- msg = { payload:message.toString('utf8'), fromip:remote.address+':'+remote.port, ip:remote.address, port:remote.port };
106
- } else {
107
- msg = { payload:message, fromip:remote.address+':'+remote.port, ip:remote.address, port:remote.port };
101
+ try {
102
+ var msg;
103
+ if (node.datatype =="base64") {
104
+ msg = { payload:message.toString('base64'), fromip:remote.address+':'+remote.port, ip:remote.address, port:remote.port };
105
+ } else if (node.datatype =="utf8") {
106
+ msg = { payload:message.toString('utf8'), fromip:remote.address+':'+remote.port, ip:remote.address, port:remote.port };
107
+ } else {
108
+ msg = { payload:message, fromip:remote.address+':'+remote.port, ip:remote.address, port:remote.port };
109
+ }
110
+ node.send(msg);
111
+ } catch (err) {
112
+ node.error(RED._("udp.errors.error",{error:err.toString()}));
108
113
  }
109
- node.send(msg);
110
114
  });
111
115
 
112
116
  server.on('listening', function () {
@@ -2,7 +2,7 @@
2
2
  <script type="text/html" data-template-name="file">
3
3
  <div class="form-row node-input-filename">
4
4
  <label for="node-input-filename"><i class="fa fa-file"></i> <span data-i18n="file.label.filename"></span></label>
5
- <input id="node-input-filename" type="text">
5
+ <input id="node-input-filename" type="text" style="width: 100% !important;">
6
6
  <input type="hidden" id="node-input-filenameType">
7
7
  </div>
8
8
  <div class="form-row">
@@ -38,7 +38,7 @@
38
38
  <script type="text/html" data-template-name="file in">
39
39
  <div class="form-row">
40
40
  <label for="node-input-filename"><i class="fa fa-file"></i> <span data-i18n="file.label.filename"></span></label>
41
- <input id="node-input-filename" type="text">
41
+ <input id="node-input-filename" type="text" style="width: 100% !important;">
42
42
  <input type="hidden" id="node-input-filenameType">
43
43
  </div>
44
44
  <div class="form-row">
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@node-red/nodes",
3
- "version": "4.1.2",
3
+ "version": "4.1.4",
4
4
  "license": "Apache-2.0",
5
5
  "repository": {
6
6
  "type": "git",
@@ -18,7 +18,7 @@
18
18
  "acorn": "8.15.0",
19
19
  "acorn-walk": "8.3.4",
20
20
  "ajv": "8.17.1",
21
- "body-parser": "1.20.3",
21
+ "body-parser": "1.20.4",
22
22
  "cheerio": "1.0.0-rc.10",
23
23
  "content-type": "1.0.5",
24
24
  "cookie-parser": "1.4.7",