node-opcua-packet-assembler 2.66.0 → 2.74.0

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.
package/LICENSE CHANGED
@@ -1,6 +1,8 @@
1
1
  The MIT License (MIT)
2
2
 
3
- Copyright (c) 2014-2021 Etienne Rossignon
3
+ Copyright (c) 2022 Sterfive SAS - 833264583 RCS ORLEANS - France (https://www.sterfive.com)
4
+
5
+ Copyright (c) 2014-2022 Etienne Rossignon
4
6
 
5
7
  Permission is hereby granted, free of charge, to any person obtaining a copy of
6
8
  this software and associated documentation files (the "Software"), to deal in
@@ -1,4 +1,5 @@
1
1
  /// <reference types="node" />
2
+ /// <reference types="node" />
2
3
  import { EventEmitter } from "events";
3
4
  /***
4
5
  * @class PacketAssembler
@@ -14,16 +15,33 @@ export interface PacketInfo {
14
15
  messageHeader: MessageHeader;
15
16
  extra: string;
16
17
  }
17
- export declare type ReadMessageFuncType = (data: Buffer) => PacketInfo;
18
+ export declare type ReadChunkFuncType = (data: Buffer) => PacketInfo;
18
19
  export interface PacketAssemblerOptions {
19
- readMessageFunc: ReadMessageFuncType;
20
+ readChunkFunc: ReadChunkFuncType;
20
21
  minimumSizeInBytes: number;
22
+ maxChunkSize: number;
23
+ }
24
+ export declare enum PacketAssemblerErrorCode {
25
+ ChunkSizeExceeded = 1,
26
+ ChunkTooSmall = 2
21
27
  }
28
+ export interface PacketAssembler {
29
+ on(eventName: "startChunk", eventHandler: (packetInfo: PacketInfo, partial: Buffer) => void): this;
30
+ on(eventName: "chunk", eventHandler: (chunk: Buffer) => void): this;
31
+ on(eventName: "error", eventHandler: (err: Error, errCode: PacketAssemblerErrorCode) => void): this;
32
+ }
33
+ /**
34
+ * this class is used to assemble partial data from the tranport layer
35
+ * into message chunks
36
+ */
22
37
  export declare class PacketAssembler extends EventEmitter {
38
+ static defaultMaxChunkCount: number;
39
+ static defaultMaxMessageSize: number;
23
40
  private readonly _stack;
24
41
  private expectedLength;
25
42
  private currentLength;
26
- private readonly readMessageFunc;
43
+ private maxChunkSize;
44
+ private readonly readChunkFunc;
27
45
  private readonly minimumSizeInBytes;
28
46
  private packetInfo?;
29
47
  constructor(options: PacketAssemblerOptions);
@@ -1,18 +1,33 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.PacketAssembler = void 0;
3
+ exports.PacketAssembler = exports.PacketAssemblerErrorCode = void 0;
4
4
  const events_1 = require("events");
5
5
  const node_opcua_assert_1 = require("node-opcua-assert");
6
+ const node_opcua_debug_1 = require("node-opcua-debug");
6
7
  const doDebug = false;
8
+ const warningLog = (0, node_opcua_debug_1.make_warningLog)("PacketAssembler");
9
+ var PacketAssemblerErrorCode;
10
+ (function (PacketAssemblerErrorCode) {
11
+ PacketAssemblerErrorCode[PacketAssemblerErrorCode["ChunkSizeExceeded"] = 1] = "ChunkSizeExceeded";
12
+ PacketAssemblerErrorCode[PacketAssemblerErrorCode["ChunkTooSmall"] = 2] = "ChunkTooSmall";
13
+ })(PacketAssemblerErrorCode = exports.PacketAssemblerErrorCode || (exports.PacketAssemblerErrorCode = {}));
14
+ /**
15
+ * this class is used to assemble partial data from the tranport layer
16
+ * into message chunks
17
+ */
7
18
  class PacketAssembler extends events_1.EventEmitter {
8
19
  constructor(options) {
9
20
  super();
10
21
  this._stack = [];
11
22
  this.expectedLength = 0;
12
23
  this.currentLength = 0;
13
- this.readMessageFunc = options.readMessageFunc;
24
+ this.readChunkFunc = options.readChunkFunc;
14
25
  this.minimumSizeInBytes = options.minimumSizeInBytes || 8;
15
- (0, node_opcua_assert_1.assert)(typeof this.readMessageFunc === "function", "packet assembler requires a readMessageFunc");
26
+ (0, node_opcua_assert_1.assert)(typeof this.readChunkFunc === "function", "packet assembler requires a readChunkFunc");
27
+ // istanbul ignore next
28
+ (0, node_opcua_assert_1.assert)(options.maxChunkSize === undefined || options.maxChunkSize !== 0);
29
+ this.maxChunkSize = options.maxChunkSize || PacketAssembler.defaultMaxMessageSize;
30
+ (0, node_opcua_assert_1.assert)(this.maxChunkSize >= this.minimumSizeInBytes);
16
31
  }
17
32
  feed(data) {
18
33
  let messageChunk;
@@ -25,11 +40,20 @@ class PacketAssembler extends events_1.EventEmitter {
25
40
  }
26
41
  // we can extract the expected length here
27
42
  this.packetInfo = this._readPacketInfo(data);
28
- this.expectedLength = this.packetInfo.length;
29
43
  (0, node_opcua_assert_1.assert)(this.currentLength === 0);
30
- (0, node_opcua_assert_1.assert)(this.expectedLength > 0);
44
+ if (this.packetInfo.length < this.minimumSizeInBytes) {
45
+ this.emit("error", new Error("chunk is too small "), PacketAssemblerErrorCode.ChunkTooSmall);
46
+ return;
47
+ }
48
+ if (this.packetInfo.length > this.maxChunkSize) {
49
+ const message = `maximum chunk size exceeded (maxChunkSize=${this.maxChunkSize} current chunk size = ${this.packetInfo.length})`;
50
+ warningLog(message);
51
+ this.emit("error", new Error(message), PacketAssemblerErrorCode.ChunkSizeExceeded);
52
+ return;
53
+ }
31
54
  // we can now emit an event to signal the start of a new packet
32
- this.emit("newMessage", this.packetInfo, data);
55
+ this.emit("startChunk", this.packetInfo, data);
56
+ this.expectedLength = this.packetInfo.length;
33
57
  }
34
58
  if (this.expectedLength === 0 || this.currentLength + data.length < this.expectedLength) {
35
59
  this._stack.push(data);
@@ -48,7 +72,7 @@ class PacketAssembler extends events_1.EventEmitter {
48
72
  // reset
49
73
  this.currentLength = 0;
50
74
  this.expectedLength = 0;
51
- this.emit("message", messageChunk);
75
+ this.emit("chunk", messageChunk);
52
76
  }
53
77
  else {
54
78
  // there is more data in this chunk than expected...
@@ -65,7 +89,7 @@ class PacketAssembler extends events_1.EventEmitter {
65
89
  }
66
90
  }
67
91
  _readPacketInfo(data) {
68
- return this.readMessageFunc(data);
92
+ return this.readChunkFunc(data);
69
93
  }
70
94
  _buildData(data) {
71
95
  if (data && this._stack.length === 0) {
@@ -83,4 +107,6 @@ class PacketAssembler extends events_1.EventEmitter {
83
107
  }
84
108
  }
85
109
  exports.PacketAssembler = PacketAssembler;
110
+ PacketAssembler.defaultMaxChunkCount = 777;
111
+ PacketAssembler.defaultMaxMessageSize = 1024 * 64 - 7;
86
112
  //# sourceMappingURL=packet_assembler.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"packet_assembler.js","sourceRoot":"","sources":["../source/packet_assembler.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"packet_assembler.js","sourceRoot":"","sources":["../source/packet_assembler.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "node-opcua-packet-assembler",
3
- "version": "2.66.0",
3
+ "version": "2.74.0",
4
4
  "description": "pure nodejs OPCUA SDK - module -packet-assembler",
5
5
  "main": "./dist/index.js",
6
6
  "types": "./dist/index.d.ts",
@@ -12,7 +12,8 @@
12
12
  "author": "Etienne Rossignon",
13
13
  "license": "MIT",
14
14
  "dependencies": {
15
- "node-opcua-assert": "2.66.0"
15
+ "node-opcua-assert": "2.74.0",
16
+ "node-opcua-debug": "2.74.0"
16
17
  },
17
18
  "devDependencies": {
18
19
  "should": "^13.2.3"
@@ -30,5 +31,5 @@
30
31
  "internet of things"
31
32
  ],
32
33
  "homepage": "http://node-opcua.github.io/",
33
- "gitHead": "97f47e2e242a1fd737495fd64cb65e8fb7a9964b"
34
+ "gitHead": "003ee041795f3b737afaaef5721045ee31ea9f77"
34
35
  }
@@ -1,7 +1,9 @@
1
1
  import { EventEmitter } from "events";
2
2
  import { assert } from "node-opcua-assert";
3
+ import { make_warningLog } from "node-opcua-debug";
3
4
 
4
5
  const doDebug = false;
6
+ const warningLog = make_warningLog("PacketAssembler");
5
7
 
6
8
  /***
7
9
  * @class PacketAssembler
@@ -20,20 +22,39 @@ export interface PacketInfo {
20
22
  extra: string;
21
23
  }
22
24
 
23
- export type ReadMessageFuncType = (data: Buffer) => PacketInfo;
25
+ export type ReadChunkFuncType = (data: Buffer) => PacketInfo;
24
26
 
25
27
  export interface PacketAssemblerOptions {
26
- readMessageFunc: ReadMessageFuncType;
27
-
28
- // the minimum number of bytes that need to be received before the readMessageFunc can be called
28
+ readChunkFunc: ReadChunkFuncType;
29
+ // the minimum number of bytes that need to be received before the readChunkFunc can be called
29
30
  minimumSizeInBytes: number;
31
+ maxChunkSize: number;
30
32
  }
31
33
 
34
+ export enum PacketAssemblerErrorCode {
35
+ ChunkSizeExceeded = 1,
36
+ ChunkTooSmall = 2
37
+ }
38
+ export interface PacketAssembler {
39
+ on(eventName: "startChunk", eventHandler: (packetInfo: PacketInfo, partial: Buffer) => void): this;
40
+ on(eventName: "chunk", eventHandler: (chunk: Buffer) => void): this;
41
+ on(eventName: "error", eventHandler: (err: Error, errCode: PacketAssemblerErrorCode) => void): this;
42
+ }
43
+ /**
44
+ * this class is used to assemble partial data from the tranport layer
45
+ * into message chunks
46
+ */
32
47
  export class PacketAssembler extends EventEmitter {
48
+ public static defaultMaxChunkCount = 777;
49
+ public static defaultMaxMessageSize = 1024 * 64 - 7;
50
+
33
51
  private readonly _stack: Buffer[];
34
52
  private expectedLength: number;
35
53
  private currentLength: number;
36
- private readonly readMessageFunc: ReadMessageFuncType;
54
+
55
+ private maxChunkSize: number;
56
+
57
+ private readonly readChunkFunc: ReadChunkFuncType;
37
58
  private readonly minimumSizeInBytes: number;
38
59
  private packetInfo?: PacketInfo;
39
60
 
@@ -42,9 +63,15 @@ export class PacketAssembler extends EventEmitter {
42
63
  this._stack = [];
43
64
  this.expectedLength = 0;
44
65
  this.currentLength = 0;
45
- this.readMessageFunc = options.readMessageFunc;
66
+ this.readChunkFunc = options.readChunkFunc;
46
67
  this.minimumSizeInBytes = options.minimumSizeInBytes || 8;
47
- assert(typeof this.readMessageFunc === "function", "packet assembler requires a readMessageFunc");
68
+ assert(typeof this.readChunkFunc === "function", "packet assembler requires a readChunkFunc");
69
+
70
+ // istanbul ignore next
71
+ assert(options.maxChunkSize === undefined || options.maxChunkSize !== 0);
72
+
73
+ this.maxChunkSize = options.maxChunkSize || PacketAssembler.defaultMaxMessageSize;
74
+ assert(this.maxChunkSize >= this.minimumSizeInBytes);
48
75
  }
49
76
 
50
77
  public feed(data: Buffer) {
@@ -60,12 +87,22 @@ export class PacketAssembler extends EventEmitter {
60
87
 
61
88
  // we can extract the expected length here
62
89
  this.packetInfo = this._readPacketInfo(data);
63
- this.expectedLength = this.packetInfo.length;
90
+
64
91
  assert(this.currentLength === 0);
65
- assert(this.expectedLength > 0);
92
+ if (this.packetInfo.length < this.minimumSizeInBytes) {
93
+ this.emit("error", new Error("chunk is too small "), PacketAssemblerErrorCode.ChunkTooSmall);
94
+ return;
95
+ }
66
96
 
97
+ if (this.packetInfo.length > this.maxChunkSize) {
98
+ const message = `maximum chunk size exceeded (maxChunkSize=${this.maxChunkSize} current chunk size = ${this.packetInfo.length})`;
99
+ warningLog(message);
100
+ this.emit("error", new Error(message), PacketAssemblerErrorCode.ChunkSizeExceeded);
101
+ return;
102
+ }
67
103
  // we can now emit an event to signal the start of a new packet
68
- this.emit("newMessage", this.packetInfo, data);
104
+ this.emit("startChunk", this.packetInfo, data);
105
+ this.expectedLength = this.packetInfo.length;
69
106
  }
70
107
 
71
108
  if (this.expectedLength === 0 || this.currentLength + data.length < this.expectedLength) {
@@ -87,7 +124,7 @@ export class PacketAssembler extends EventEmitter {
87
124
  this.currentLength = 0;
88
125
  this.expectedLength = 0;
89
126
 
90
- this.emit("message", messageChunk);
127
+ this.emit("chunk", messageChunk);
91
128
  } else {
92
129
  // there is more data in this chunk than expected...
93
130
  // the chunk need to be split
@@ -104,10 +141,10 @@ export class PacketAssembler extends EventEmitter {
104
141
  }
105
142
 
106
143
  private _readPacketInfo(data: Buffer) {
107
- return this.readMessageFunc(data);
144
+ return this.readChunkFunc(data);
108
145
  }
109
146
 
110
- private _buildData(data: Buffer) {
147
+ private _buildData(data: Buffer): Buffer {
111
148
  if (data && this._stack.length === 0) {
112
149
  return data;
113
150
  }