node-opcua-transport
Advanced tools
Comparing version 2.128.0 to 2.129.0
@@ -0,1 +1,2 @@ | ||
/// <reference types="node" /> | ||
import { ErrorCallback } from "node-opcua-status-code"; | ||
@@ -2,0 +3,0 @@ import { TCP_transport } from "./tcp_transport"; |
@@ -121,4 +121,2 @@ "use strict"; | ||
connect(endpointUrl, callback) { | ||
(0, node_opcua_assert_1.assert)(arguments.length === 2); | ||
(0, node_opcua_assert_1.assert)(typeof callback === "function"); | ||
const ep = (0, tools_1.parseEndpointUrl)(endpointUrl); | ||
@@ -158,2 +156,3 @@ this.endpointUrl = endpointUrl; | ||
*/ | ||
console.log("connection_break", endpointUrl); | ||
this.emit("connection_break"); | ||
@@ -160,0 +159,0 @@ } |
@@ -0,1 +1,3 @@ | ||
/// <reference types="node" /> | ||
/// <reference types="node" /> | ||
/** | ||
@@ -7,3 +9,3 @@ * @module node-opcua-transport | ||
import { SequenceHeader } from "node-opcua-chunkmanager"; | ||
import { MessageHeader, PacketAssembler, PacketInfo } from "node-opcua-packet-assembler"; | ||
import { MessageHeader, PacketInfo } from "node-opcua-packet-assembler"; | ||
import { StatusCode } from "node-opcua-status-code"; | ||
@@ -67,2 +69,3 @@ export declare function readRawMessageHeader(data: Buffer): PacketInfo; | ||
export declare class MessageBuilderBase extends EventEmitter { | ||
#private; | ||
static defaultMaxChunkCount: number; | ||
@@ -76,3 +79,2 @@ static defaultMaxMessageSize: number; | ||
readonly options: MessageBuilderBaseOptions; | ||
readonly _packetAssembler: PacketAssembler; | ||
channelId: number; | ||
@@ -87,7 +89,2 @@ totalMessageSize: number; | ||
protected messageHeader?: MessageHeader; | ||
private _securityDefeated; | ||
private _hasReceivedError; | ||
private blocks; | ||
private readonly _expectedChannelId; | ||
private offsetBodyStart; | ||
constructor(options?: MessageBuilderBaseOptions); | ||
@@ -105,11 +102,2 @@ dispose(): void; | ||
protected _report_error(statusCode: StatusCode, errorMessage: string): false; | ||
private _init_new; | ||
/** | ||
* append a message chunk | ||
* @method _append | ||
* @param chunk | ||
* @private | ||
*/ | ||
private _append; | ||
private _feed_messageChunk; | ||
} |
"use strict"; | ||
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) { | ||
if (kind === "m") throw new TypeError("Private method is not writable"); | ||
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); | ||
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); | ||
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; | ||
}; | ||
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) { | ||
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); | ||
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); | ||
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); | ||
}; | ||
var _MessageBuilderBase_instances, _MessageBuilderBase__packetAssembler, _MessageBuilderBase__securityDefeated, _MessageBuilderBase__hasReceivedError, _MessageBuilderBase_blocks, _MessageBuilderBase__expectedChannelId, _MessageBuilderBase_offsetBodyStart, _MessageBuilderBase__init_new, _MessageBuilderBase__append, _MessageBuilderBase__feed_messageChunk; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.MessageBuilderBase = void 0; | ||
exports.readRawMessageHeader = readRawMessageHeader; | ||
exports.MessageBuilderBase = exports.readRawMessageHeader = void 0; | ||
/** | ||
@@ -30,2 +41,3 @@ * @module node-opcua-transport | ||
} | ||
exports.readRawMessageHeader = readRawMessageHeader; | ||
/** | ||
@@ -43,9 +55,16 @@ * @class MessageBuilderBase | ||
super(); | ||
_MessageBuilderBase_instances.add(this); | ||
_MessageBuilderBase__packetAssembler.set(this, void 0); | ||
_MessageBuilderBase__securityDefeated.set(this, void 0); | ||
_MessageBuilderBase__hasReceivedError.set(this, void 0); | ||
_MessageBuilderBase_blocks.set(this, void 0); | ||
_MessageBuilderBase__expectedChannelId.set(this, void 0); | ||
_MessageBuilderBase_offsetBodyStart.set(this, void 0); | ||
this.id = ""; | ||
this._tick0 = 0; | ||
this._tick1 = 0; | ||
this._hasReceivedError = false; | ||
this.blocks = []; | ||
__classPrivateFieldSet(this, _MessageBuilderBase__hasReceivedError, false, "f"); | ||
__classPrivateFieldSet(this, _MessageBuilderBase_blocks, [], "f"); | ||
this.messageChunks = []; | ||
this._expectedChannelId = 0; | ||
__classPrivateFieldSet(this, _MessageBuilderBase__expectedChannelId, 0, "f"); | ||
options = options || { | ||
@@ -61,9 +80,9 @@ maxMessageSize: 0, | ||
this.options = options; | ||
this._packetAssembler = new node_opcua_packet_assembler_1.PacketAssembler({ | ||
__classPrivateFieldSet(this, _MessageBuilderBase__packetAssembler, new node_opcua_packet_assembler_1.PacketAssembler({ | ||
minimumSizeInBytes: 8, | ||
maxChunkSize: this.maxChunkSize, | ||
readChunkFunc: readRawMessageHeader | ||
}); | ||
this._packetAssembler.on("chunk", (messageChunk) => this._feed_messageChunk(messageChunk)); | ||
this._packetAssembler.on("startChunk", (info, data) => { | ||
}), "f"); | ||
__classPrivateFieldGet(this, _MessageBuilderBase__packetAssembler, "f").on("chunk", (messageChunk) => __classPrivateFieldGet(this, _MessageBuilderBase_instances, "m", _MessageBuilderBase__feed_messageChunk).call(this, messageChunk)); | ||
__classPrivateFieldGet(this, _MessageBuilderBase__packetAssembler, "f").on("startChunk", (info, data) => { | ||
if (doPerfMonitoring) { | ||
@@ -75,13 +94,13 @@ // record tick 0: when the first data is received | ||
}); | ||
this._packetAssembler.on("error", (err) => { | ||
__classPrivateFieldGet(this, _MessageBuilderBase__packetAssembler, "f").on("error", (err) => { | ||
warningLog("packet assembler ", err.message); | ||
return this._report_error(status_codes_1.StatusCodes2.BadTcpMessageTooLarge, "packet assembler: " + err.message); | ||
}); | ||
this._securityDefeated = false; | ||
__classPrivateFieldSet(this, _MessageBuilderBase__securityDefeated, false, "f"); | ||
this.totalBodySize = 0; | ||
this.totalMessageSize = 0; | ||
this.channelId = 0; | ||
this.offsetBodyStart = 0; | ||
__classPrivateFieldSet(this, _MessageBuilderBase_offsetBodyStart, 0, "f"); | ||
this.sequenceHeader = null; | ||
this._init_new(); | ||
__classPrivateFieldGet(this, _MessageBuilderBase_instances, "m", _MessageBuilderBase__init_new).call(this); | ||
} | ||
@@ -97,4 +116,4 @@ dispose() { | ||
feed(data) { | ||
if (!this._securityDefeated && !this._hasReceivedError) { | ||
this._packetAssembler.feed(data); | ||
if (!__classPrivateFieldGet(this, _MessageBuilderBase__securityDefeated, "f") && !__classPrivateFieldGet(this, _MessageBuilderBase__hasReceivedError, "f")) { | ||
__classPrivateFieldGet(this, _MessageBuilderBase__packetAssembler, "f").feed(data); | ||
} | ||
@@ -108,7 +127,7 @@ } | ||
this.messageHeader = (0, node_opcua_chunkmanager_1.readMessageHeader)(binaryStream); | ||
(0, node_opcua_assert_1.assert)(binaryStream.length === 8, "expecting message header to be 8 bytes"); | ||
// assert(binaryStream.length === 8, "expecting message header to be 8 bytes"); | ||
this.channelId = binaryStream.readUInt32(); | ||
(0, node_opcua_assert_1.assert)(binaryStream.length === 12); | ||
// assert(binaryStream.length === 12); | ||
// verifying secure ChannelId | ||
if (this._expectedChannelId && this.channelId !== this._expectedChannelId) { | ||
if (__classPrivateFieldGet(this, _MessageBuilderBase__expectedChannelId, "f") && this.channelId !== __classPrivateFieldGet(this, _MessageBuilderBase__expectedChannelId, "f")) { | ||
return this._report_error(status_codes_1.StatusCodes2.BadTcpSecureChannelUnknown, "Invalid secure channel Id"); | ||
@@ -125,3 +144,3 @@ } | ||
// the connection can probably continue | ||
this._hasReceivedError = false; /// | ||
__classPrivateFieldSet(this, _MessageBuilderBase__hasReceivedError, false, "f"); /// | ||
this.emit("abandon", sequenceHeader.requestId); | ||
@@ -131,4 +150,4 @@ return false; | ||
_report_error(statusCode, errorMessage) { | ||
this._hasReceivedError = true; | ||
debugLog("Error ", this.id, errorMessage); | ||
__classPrivateFieldSet(this, _MessageBuilderBase__hasReceivedError, true, "f"); | ||
errorLog("Error ", this.id, errorMessage); | ||
// xx errorLog(new Error()); | ||
@@ -138,113 +157,105 @@ this.emit("error", new Error(errorMessage), statusCode, this.sequenceHeader?.requestId || null); | ||
} | ||
_init_new() { | ||
this._securityDefeated = false; | ||
this._hasReceivedError = false; | ||
this.totalBodySize = 0; | ||
this.totalMessageSize = 0; | ||
this.blocks = []; | ||
this.messageChunks = []; | ||
} | ||
exports.MessageBuilderBase = MessageBuilderBase; | ||
_MessageBuilderBase__packetAssembler = new WeakMap(), _MessageBuilderBase__securityDefeated = new WeakMap(), _MessageBuilderBase__hasReceivedError = new WeakMap(), _MessageBuilderBase_blocks = new WeakMap(), _MessageBuilderBase__expectedChannelId = new WeakMap(), _MessageBuilderBase_offsetBodyStart = new WeakMap(), _MessageBuilderBase_instances = new WeakSet(), _MessageBuilderBase__init_new = function _MessageBuilderBase__init_new() { | ||
__classPrivateFieldSet(this, _MessageBuilderBase__securityDefeated, false, "f"); | ||
__classPrivateFieldSet(this, _MessageBuilderBase__hasReceivedError, false, "f"); | ||
this.totalBodySize = 0; | ||
this.totalMessageSize = 0; | ||
__classPrivateFieldSet(this, _MessageBuilderBase_blocks, [], "f"); | ||
this.messageChunks = []; | ||
}, _MessageBuilderBase__append = function _MessageBuilderBase__append(chunk) { | ||
if (__classPrivateFieldGet(this, _MessageBuilderBase__hasReceivedError, "f")) { | ||
// the message builder is in error mode and further message chunks should be discarded. | ||
return false; | ||
} | ||
/** | ||
* append a message chunk | ||
* @method _append | ||
* @param chunk | ||
* @private | ||
*/ | ||
_append(chunk) { | ||
if (this._hasReceivedError) { | ||
// the message builder is in error mode and further message chunks should be discarded. | ||
return false; | ||
} | ||
if (this.messageChunks.length + 1 > this.maxChunkCount) { | ||
return this._report_error(status_codes_1.StatusCodes2.BadTcpMessageTooLarge, `max chunk count exceeded: ${this.maxChunkCount}`); | ||
} | ||
this.messageChunks.push(chunk); | ||
this.totalMessageSize += chunk.length; | ||
if (this.totalMessageSize > this.maxMessageSize) { | ||
return this._report_error(status_codes_1.StatusCodes2.BadTcpMessageTooLarge, `max message size exceeded: ${this.maxMessageSize} : total message size ${this.totalMessageSize}`); | ||
} | ||
const binaryStream = new node_opcua_binary_stream_1.BinaryStream(chunk); | ||
if (!this._read_headers(binaryStream)) { | ||
return this._report_error(status_codes_1.StatusCodes2.BadTcpInternalError, `Invalid message header detected`); | ||
} | ||
(0, node_opcua_assert_1.assert)(binaryStream.length >= 12); | ||
// verify message chunk length | ||
if (this.messageHeader.length !== chunk.length) { | ||
// tslint:disable:max-line-length | ||
return this._report_error(status_codes_1.StatusCodes2.BadTcpInternalError, `Invalid messageChunk size: the provided chunk is ${chunk.length} bytes long but header specifies ${this.messageHeader.length}`); | ||
} | ||
// the start of the message body block | ||
const offsetBodyStart = binaryStream.length; | ||
// the end of the message body block | ||
const offsetBodyEnd = binaryStream.buffer.length; | ||
this.totalBodySize += offsetBodyEnd - offsetBodyStart; | ||
this.offsetBodyStart = offsetBodyStart; | ||
// add message body to a queue | ||
// note : Buffer.slice create a shared memory ! | ||
// use Buffer.clone | ||
const sharedBuffer = chunk.subarray(this.offsetBodyStart, offsetBodyEnd); | ||
const clonedBuffer = (0, node_opcua_buffer_utils_1.createFastUninitializedBuffer)(sharedBuffer.length); | ||
sharedBuffer.copy(clonedBuffer, 0, 0); | ||
this.blocks.push(clonedBuffer); | ||
return true; | ||
if (this.messageChunks.length + 1 > this.maxChunkCount) { | ||
return this._report_error(status_codes_1.StatusCodes2.BadTcpMessageTooLarge, `max chunk count exceeded: ${this.maxChunkCount}`); | ||
} | ||
_feed_messageChunk(chunk) { | ||
(0, node_opcua_assert_1.assert)(chunk); | ||
const messageHeader = (0, node_opcua_chunkmanager_1.readMessageHeader)(new node_opcua_binary_stream_1.BinaryStream(chunk)); | ||
this.emit("chunk", chunk); | ||
if (messageHeader.isFinal === "F") { | ||
if (messageHeader.msgType === "ERR") { | ||
const binaryStream = new node_opcua_binary_stream_1.BinaryStream(chunk); | ||
binaryStream.length = 8; | ||
const errorCode = (0, node_opcua_basic_types_1.decodeStatusCode)(binaryStream); | ||
const message = (0, node_opcua_basic_types_1.decodeString)(binaryStream); | ||
this._report_error(errorCode, message || "Error message not specified"); | ||
return true; | ||
} | ||
else { | ||
this._append(chunk); | ||
// last message | ||
if (this._hasReceivedError) { | ||
return false; | ||
} | ||
const fullMessageBody = this.blocks.length === 1 ? this.blocks[0] : Buffer.concat(this.blocks); | ||
if (doPerfMonitoring) { | ||
// record tick 1: when a complete message has been received ( all chunks assembled) | ||
this._tick1 = (0, node_opcua_utils_1.get_clock_tick)(); | ||
} | ||
this.emit("full_message_body", fullMessageBody); | ||
const messageOk = this._decodeMessageBody(fullMessageBody); | ||
// be ready for next block | ||
this._init_new(); | ||
return messageOk; | ||
} | ||
this.messageChunks.push(chunk); | ||
this.totalMessageSize += chunk.length; | ||
if (this.totalMessageSize > this.maxMessageSize) { | ||
return this._report_error(status_codes_1.StatusCodes2.BadTcpMessageTooLarge, `max message size exceeded: ${this.maxMessageSize} : total message size ${this.totalMessageSize}`); | ||
} | ||
const binaryStream = new node_opcua_binary_stream_1.BinaryStream(chunk); | ||
if (!this._read_headers(binaryStream)) { | ||
return false; // error already reported | ||
} | ||
(0, node_opcua_assert_1.assert)(binaryStream.length >= 12); | ||
// verify message chunk length | ||
if (this.messageHeader.length !== chunk.length) { | ||
// tslint:disable:max-line-length | ||
return this._report_error(status_codes_1.StatusCodes2.BadTcpInternalError, `Invalid messageChunk size: the provided chunk is ${chunk.length} bytes long but header specifies ${this.messageHeader.length}`); | ||
} | ||
// the start of the message body block | ||
const offsetBodyStart = binaryStream.length; | ||
// the end of the message body block | ||
const offsetBodyEnd = binaryStream.buffer.length; | ||
this.totalBodySize += offsetBodyEnd - offsetBodyStart; | ||
__classPrivateFieldSet(this, _MessageBuilderBase_offsetBodyStart, offsetBodyStart, "f"); | ||
// add message body to a queue | ||
// note : Buffer.slice create a shared memory ! | ||
// use Buffer.clone | ||
const sharedBuffer = chunk.subarray(__classPrivateFieldGet(this, _MessageBuilderBase_offsetBodyStart, "f"), offsetBodyEnd); | ||
const clonedBuffer = (0, node_opcua_buffer_utils_1.createFastUninitializedBuffer)(sharedBuffer.length); | ||
sharedBuffer.copy(clonedBuffer, 0, 0); | ||
__classPrivateFieldGet(this, _MessageBuilderBase_blocks, "f").push(clonedBuffer); | ||
return true; | ||
}, _MessageBuilderBase__feed_messageChunk = function _MessageBuilderBase__feed_messageChunk(chunk) { | ||
(0, node_opcua_assert_1.assert)(chunk); | ||
const messageHeader = (0, node_opcua_chunkmanager_1.readMessageHeader)(new node_opcua_binary_stream_1.BinaryStream(chunk)); | ||
this.emit("chunk", chunk); | ||
if (messageHeader.isFinal === "F") { | ||
if (messageHeader.msgType === "ERR") { | ||
const binaryStream = new node_opcua_binary_stream_1.BinaryStream(chunk); | ||
binaryStream.length = 8; | ||
const errorCode = (0, node_opcua_basic_types_1.decodeStatusCode)(binaryStream); | ||
const message = (0, node_opcua_basic_types_1.decodeString)(binaryStream); | ||
this._report_error(errorCode, message || "Error message not specified"); | ||
return true; | ||
} | ||
else if (messageHeader.isFinal === "A") { | ||
try { | ||
// only valid for MSG, according to spec | ||
const stream = new node_opcua_binary_stream_1.BinaryStream(chunk); | ||
(0, node_opcua_chunkmanager_1.readMessageHeader)(stream); | ||
(0, node_opcua_assert_1.assert)(stream.length === 8); | ||
// instead of | ||
// const securityHeader = new SymmetricAlgorithmSecurityHeader(); | ||
// securityHeader.decode(stream); | ||
const channelId = stream.readUInt32(); | ||
const tokenId = (0, node_opcua_basic_types_1.decodeUInt32)(stream); | ||
const sequenceHeader = new node_opcua_chunkmanager_1.SequenceHeader(); | ||
sequenceHeader.decode(stream); | ||
return this._report_abandon(channelId, tokenId, sequenceHeader); | ||
else { | ||
__classPrivateFieldGet(this, _MessageBuilderBase_instances, "m", _MessageBuilderBase__append).call(this, chunk); | ||
// last message | ||
if (__classPrivateFieldGet(this, _MessageBuilderBase__hasReceivedError, "f")) { | ||
return false; | ||
} | ||
catch (err) { | ||
warningLog((0, node_opcua_debug_1.hexDump)(chunk)); | ||
warningLog("Cannot interpret message chunk: ", err.message); | ||
return this._report_error(status_codes_1.StatusCodes2.BadTcpInternalError, "Error decoding message header " + err.message); | ||
const fullMessageBody = __classPrivateFieldGet(this, _MessageBuilderBase_blocks, "f").length === 1 ? __classPrivateFieldGet(this, _MessageBuilderBase_blocks, "f")[0] : Buffer.concat(__classPrivateFieldGet(this, _MessageBuilderBase_blocks, "f")); | ||
if (doPerfMonitoring) { | ||
// record tick 1: when a complete message has been received ( all chunks assembled) | ||
this._tick1 = (0, node_opcua_utils_1.get_clock_tick)(); | ||
} | ||
this.emit("full_message_body", fullMessageBody); | ||
const messageOk = this._decodeMessageBody(fullMessageBody); | ||
// be ready for next block | ||
__classPrivateFieldGet(this, _MessageBuilderBase_instances, "m", _MessageBuilderBase__init_new).call(this); | ||
return messageOk; | ||
} | ||
else if (messageHeader.isFinal === "C") { | ||
return this._append(chunk); | ||
} | ||
else if (messageHeader.isFinal === "A") { | ||
try { | ||
// only valid for MSG, according to spec | ||
const stream = new node_opcua_binary_stream_1.BinaryStream(chunk); | ||
(0, node_opcua_chunkmanager_1.readMessageHeader)(stream); | ||
(0, node_opcua_assert_1.assert)(stream.length === 8); | ||
// instead of | ||
// const securityHeader = new SymmetricAlgorithmSecurityHeader(); | ||
// securityHeader.decode(stream); | ||
const channelId = stream.readUInt32(); | ||
const tokenId = (0, node_opcua_basic_types_1.decodeUInt32)(stream); | ||
const sequenceHeader = new node_opcua_chunkmanager_1.SequenceHeader(); | ||
sequenceHeader.decode(stream); | ||
return this._report_abandon(channelId, tokenId, sequenceHeader); | ||
} | ||
return false; | ||
catch (err) { | ||
warningLog((0, node_opcua_debug_1.hexDump)(chunk)); | ||
warningLog("Cannot interpret message chunk: ", err.message); | ||
return this._report_error(status_codes_1.StatusCodes2.BadTcpInternalError, "Error decoding message header " + err.message); | ||
} | ||
} | ||
} | ||
exports.MessageBuilderBase = MessageBuilderBase; | ||
else if (messageHeader.isFinal === "C") { | ||
return __classPrivateFieldGet(this, _MessageBuilderBase_instances, "m", _MessageBuilderBase__append).call(this, chunk); | ||
} | ||
return false; | ||
}; | ||
MessageBuilderBase.defaultMaxChunkCount = 1000; | ||
@@ -251,0 +262,0 @@ MessageBuilderBase.defaultMaxMessageSize = 1024 * 64 * 1024; // 64Mo |
@@ -0,1 +1,2 @@ | ||
/// <reference types="node" /> | ||
import { ErrorCallback } from "node-opcua-status-code"; | ||
@@ -2,0 +3,0 @@ import { ISocketLike, TCP_transport } from "./tcp_transport"; |
@@ -6,4 +6,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.ServerTCP_transport = void 0; | ||
exports.adjustLimitsWithParameters = adjustLimitsWithParameters; | ||
exports.ServerTCP_transport = exports.adjustLimitsWithParameters = void 0; | ||
/** | ||
@@ -74,2 +73,3 @@ * @module node-opcua-transport | ||
} | ||
exports.adjustLimitsWithParameters = adjustLimitsWithParameters; | ||
const defaultAdjustLimits = (hello) => adjustLimitsWithParameters(hello, defaultTransportParameters); | ||
@@ -76,0 +76,0 @@ /** |
@@ -0,1 +1,3 @@ | ||
/// <reference types="node" /> | ||
/// <reference types="node" /> | ||
/** | ||
@@ -64,4 +66,10 @@ * @module node-opcua-transport | ||
export declare class TCP_transport extends EventEmitter { | ||
#private; | ||
private static registry; | ||
/** | ||
* the size of the header in bytes | ||
* @default 8 | ||
*/ | ||
static readonly headerSize = 8; | ||
/** | ||
* indicates the version number of the OPCUA protocol used | ||
@@ -81,14 +89,2 @@ * @default 0 | ||
_socket: ISocketLike | null; | ||
private _closedEmitted; | ||
/** | ||
* the size of the header in bytes | ||
* @default 8 | ||
*/ | ||
private readonly headerSize; | ||
private _timerId; | ||
private _theCallback?; | ||
private _on_error_during_one_time_message_receiver; | ||
private packetAssembler?; | ||
private _timeout; | ||
private _isDisconnecting; | ||
protected _theCloseError: Error | null; | ||
@@ -124,3 +120,2 @@ constructor(); | ||
protected _write_chunk(messageChunk: Buffer, callback?: (err?: Error) => void | undefined): void; | ||
protected _install_packetAssembler(): void; | ||
protected _install_socket(socket: ISocketLike): void; | ||
@@ -127,0 +122,0 @@ sendErrorMessage(statusCode: StatusCode, extraErrorDescription: string | null): void; |
"use strict"; | ||
var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (receiver, state, value, kind, f) { | ||
if (kind === "m") throw new TypeError("Private method is not writable"); | ||
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a setter"); | ||
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it"); | ||
return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value; | ||
}; | ||
var __classPrivateFieldGet = (this && this.__classPrivateFieldGet) || function (receiver, state, kind, f) { | ||
if (kind === "a" && !f) throw new TypeError("Private accessor was defined without a getter"); | ||
if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot read private member from an object whose class did not declare it"); | ||
return kind === "m" ? f : kind === "a" ? f.call(receiver) : f ? f.value : state.get(receiver); | ||
}; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
}; | ||
var _TCP_transport_instances, _a, _TCP_transport__closedEmitted, _TCP_transport__timerId, _TCP_transport__theCallback, _TCP_transport__on_error_during_one_time_message_receiver, _TCP_transport_packetAssembler, _TCP_transport__timeout, _TCP_transport__isDisconnecting, _TCP_transport__install_packetAssembler; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.TCP_transport = void 0; | ||
exports.setFakeTransport = setFakeTransport; | ||
exports.getFakeTransport = getFakeTransport; | ||
exports.TCP_transport = exports.getFakeTransport = exports.setFakeTransport = void 0; | ||
/* eslint-disable @typescript-eslint/ban-types */ | ||
@@ -59,2 +69,3 @@ /** | ||
} | ||
exports.setFakeTransport = setFakeTransport; | ||
function getFakeTransport() { | ||
@@ -67,2 +78,3 @@ if (fakeSocket.invalid) { | ||
} | ||
exports.getFakeTransport = getFakeTransport; | ||
let counter = 0; | ||
@@ -73,11 +85,17 @@ // tslint:disable:class-name | ||
super(); | ||
this._closedEmitted = undefined; | ||
this._isDisconnecting = false; | ||
_TCP_transport_instances.add(this); | ||
_TCP_transport__closedEmitted.set(this, undefined); | ||
_TCP_transport__timerId.set(this, void 0); | ||
_TCP_transport__theCallback.set(this, void 0); | ||
_TCP_transport__on_error_during_one_time_message_receiver.set(this, void 0); | ||
_TCP_transport_packetAssembler.set(this, void 0); | ||
_TCP_transport__timeout.set(this, void 0); | ||
_TCP_transport__isDisconnecting.set(this, false); | ||
this._theCloseError = null; | ||
this.name = this.constructor.name + counter; | ||
counter += 1; | ||
this._timerId = null; | ||
this._timeout = 5000; // 5 seconds timeout | ||
this._socket = null; | ||
this.headerSize = 8; | ||
__classPrivateFieldSet(this, _TCP_transport__timerId, null, "f"); | ||
__classPrivateFieldSet(this, _TCP_transport__timeout, 5000, "f"); // 5 seconds timeout | ||
__classPrivateFieldSet(this, _TCP_transport__theCallback, undefined, "f"); | ||
this.maxMessageSize = 0; | ||
@@ -90,6 +108,5 @@ this.maxChunkCount = 0; | ||
this.bytesRead = 0; | ||
this._theCallback = undefined; | ||
this.chunkWrittenCount = 0; | ||
this.chunkReadCount = 0; | ||
TCP_transport.registry.register(this); | ||
_a.registry.register(this); | ||
} | ||
@@ -108,3 +125,3 @@ toString() { | ||
str += " chunkReadCount.... = " + this.chunkReadCount + "\n"; | ||
str += " closeEmitted ? ....= " + this._closedEmitted + "\n"; | ||
str += " closeEmitted ? ....= " + __classPrivateFieldGet(this, _TCP_transport__closedEmitted, "f") + "\n"; | ||
return str; | ||
@@ -128,15 +145,15 @@ } | ||
// reinstall packetAssembler with correct limits | ||
this._install_packetAssembler(); | ||
__classPrivateFieldGet(this, _TCP_transport_instances, "m", _TCP_transport__install_packetAssembler).call(this); | ||
} | ||
get timeout() { | ||
return this._timeout; | ||
return __classPrivateFieldGet(this, _TCP_transport__timeout, "f"); | ||
} | ||
set timeout(value) { | ||
(0, node_opcua_assert_1.assert)(!this._timerId); | ||
(0, node_opcua_assert_1.assert)(!__classPrivateFieldGet(this, _TCP_transport__timerId, "f")); | ||
debugLog("Setting socket " + this.name + " timeout = ", value); | ||
this._timeout = value; | ||
__classPrivateFieldSet(this, _TCP_transport__timeout, value, "f"); | ||
} | ||
dispose() { | ||
this._cleanup_timers(); | ||
(0, node_opcua_assert_1.assert)(!this._timerId); | ||
(0, node_opcua_assert_1.assert)(!__classPrivateFieldGet(this, _TCP_transport__timerId, "f")); | ||
if (this._socket) { | ||
@@ -155,3 +172,3 @@ const gracefully = true; | ||
} | ||
TCP_transport.registry.unregister(this); | ||
_a.registry.unregister(this); | ||
} | ||
@@ -173,3 +190,3 @@ /** | ||
isDisconnecting() { | ||
return !this._socket || this._isDisconnecting; | ||
return !this._socket || __classPrivateFieldGet(this, _TCP_transport__isDisconnecting, "f"); | ||
} | ||
@@ -186,4 +203,4 @@ /** | ||
(0, node_opcua_assert_1.assert)(typeof callback === "function", "expecting a callback function, but got " + callback); | ||
if (!this._socket || this._isDisconnecting) { | ||
if (!this._isDisconnecting) { | ||
if (!this._socket || __classPrivateFieldGet(this, _TCP_transport__isDisconnecting, "f")) { | ||
if (!__classPrivateFieldGet(this, _TCP_transport__isDisconnecting, "f")) { | ||
this.dispose(); | ||
@@ -194,3 +211,3 @@ } | ||
} | ||
this._isDisconnecting = true; | ||
__classPrivateFieldSet(this, _TCP_transport__isDisconnecting, true, "f"); | ||
this._cleanup_timers(); | ||
@@ -222,27 +239,2 @@ this._socket.prependOnceListener("close", () => { | ||
} | ||
_install_packetAssembler() { | ||
if (this.packetAssembler) { | ||
this.packetAssembler.removeAllListeners(); | ||
this.packetAssembler = undefined; | ||
} | ||
// install packet assembler ... | ||
this.packetAssembler = new node_opcua_packet_assembler_1.PacketAssembler({ | ||
readChunkFunc: message_builder_base_1.readRawMessageHeader, | ||
minimumSizeInBytes: this.headerSize, | ||
maxChunkSize: this.receiveBufferSize //Math.max(this.receiveBufferSize, this.sendBufferSize) | ||
}); | ||
this.packetAssembler.on("chunk", (chunk) => this._on_message_chunk_received(chunk)); | ||
this.packetAssembler.on("error", (err, code) => { | ||
let statusCode = status_codes_1.StatusCodes2.BadTcpMessageTooLarge; | ||
switch (code) { | ||
case node_opcua_packet_assembler_1.PacketAssemblerErrorCode.ChunkSizeExceeded: | ||
statusCode = status_codes_1.StatusCodes2.BadTcpMessageTooLarge; | ||
break; | ||
default: | ||
statusCode = status_codes_1.StatusCodes2.BadTcpInternalError; | ||
} | ||
this.sendErrorMessage(statusCode, err.message); | ||
this.prematureTerminate(new Error("Packet Assembler : " + err.message), statusCode); | ||
}); | ||
} | ||
_install_socket(socket) { | ||
@@ -253,5 +245,5 @@ // note: it is possible that a transport may be recycled and re-used again after a connection break | ||
this._socket = socket; | ||
this._closedEmitted = undefined; | ||
__classPrivateFieldSet(this, _TCP_transport__closedEmitted, undefined, "f"); | ||
this._theCloseError = null; | ||
(0, node_opcua_assert_1.assert)(this._closedEmitted === undefined, "TCP Transport has already been closed !"); | ||
(0, node_opcua_assert_1.assert)(__classPrivateFieldGet(this, _TCP_transport__closedEmitted, "f") === undefined, "TCP Transport has already been closed !"); | ||
this._socket.setKeepAlive(true); | ||
@@ -266,3 +258,3 @@ // Setting true for noDelay will immediately fire off data each time socket.write() is called. | ||
doDebug && debugLog(" TCP_transport#_install_socket ", this.name); | ||
this._install_packetAssembler(); | ||
__classPrivateFieldGet(this, _TCP_transport_instances, "m", _TCP_transport__install_packetAssembler).call(this); | ||
this._socket | ||
@@ -319,3 +311,3 @@ .on("data", (data) => this._on_socket_data(data)) | ||
_install_one_time_message_receiver(callback) { | ||
(0, node_opcua_assert_1.assert)(!this._theCallback, "callback already set"); | ||
(0, node_opcua_assert_1.assert)(!__classPrivateFieldGet(this, _TCP_transport__theCallback, "f"), "callback already set"); | ||
(0, node_opcua_assert_1.assert)(typeof callback === "function"); | ||
@@ -325,7 +317,7 @@ this._start_one_time_message_receiver(callback); | ||
_fulfill_pending_promises(err, data) { | ||
if (!this._theCallback) | ||
if (!__classPrivateFieldGet(this, _TCP_transport__theCallback, "f")) | ||
return false; | ||
doDebugFlow && errorLog("_fulfill_pending_promises from", new Error().stack); | ||
const callback = this._theCallback; | ||
this._theCallback = undefined; | ||
const callback = __classPrivateFieldGet(this, _TCP_transport__theCallback, "f"); | ||
__classPrivateFieldSet(this, _TCP_transport__theCallback, undefined, "f"); | ||
callback(err, data); | ||
@@ -346,14 +338,14 @@ return true; | ||
_cleanup_timers() { | ||
if (this._timerId) { | ||
clearTimeout(this._timerId); | ||
this._timerId = null; | ||
if (__classPrivateFieldGet(this, _TCP_transport__timerId, "f")) { | ||
clearTimeout(__classPrivateFieldGet(this, _TCP_transport__timerId, "f")); | ||
__classPrivateFieldSet(this, _TCP_transport__timerId, null, "f"); | ||
} | ||
} | ||
_start_one_time_message_receiver(callback) { | ||
(0, node_opcua_assert_1.assert)(!this._timerId && !this._on_error_during_one_time_message_receiver, "timer already started"); | ||
(0, node_opcua_assert_1.assert)(!__classPrivateFieldGet(this, _TCP_transport__timerId, "f") && !__classPrivateFieldGet(this, _TCP_transport__on_error_during_one_time_message_receiver, "f"), "timer already started"); | ||
const _cleanUp = () => { | ||
this._cleanup_timers(); | ||
if (this._on_error_during_one_time_message_receiver) { | ||
this._socket?.removeListener("close", this._on_error_during_one_time_message_receiver); | ||
this._on_error_during_one_time_message_receiver = undefined; | ||
if (__classPrivateFieldGet(this, _TCP_transport__on_error_during_one_time_message_receiver, "f")) { | ||
this._socket?.removeListener("close", __classPrivateFieldGet(this, _TCP_transport__on_error_during_one_time_message_receiver, "f")); | ||
__classPrivateFieldSet(this, _TCP_transport__on_error_during_one_time_message_receiver, undefined, "f"); | ||
} | ||
@@ -367,26 +359,26 @@ }; | ||
// Setup timeout detection timer .... | ||
this._timerId = setTimeout(() => { | ||
this._timerId = null; | ||
__classPrivateFieldSet(this, _TCP_transport__timerId, setTimeout(() => { | ||
__classPrivateFieldSet(this, _TCP_transport__timerId, null, "f"); | ||
onTimeout(); | ||
}, this.timeout); | ||
}, this.timeout), "f"); | ||
// also monitored | ||
if (this._socket) { | ||
// to do = intercept socket error as well | ||
this._on_error_during_one_time_message_receiver = (hadError) => { | ||
__classPrivateFieldSet(this, _TCP_transport__on_error_during_one_time_message_receiver, (hadError) => { | ||
const err = new Error(`ERROR in waiting for data on socket ( timeout was = ${this.timeout} ms) hadError` + hadError); | ||
this._emitClose(err); | ||
this._fulfill_pending_promises(err); | ||
}; | ||
this._socket.prependOnceListener("close", this._on_error_during_one_time_message_receiver); | ||
}, "f"); | ||
this._socket.prependOnceListener("close", __classPrivateFieldGet(this, _TCP_transport__on_error_during_one_time_message_receiver, "f")); | ||
} | ||
const _callback = callback; | ||
this._theCallback = (err, data) => { | ||
__classPrivateFieldSet(this, _TCP_transport__theCallback, (err, data) => { | ||
_cleanUp(); | ||
this._theCallback = undefined; | ||
__classPrivateFieldSet(this, _TCP_transport__theCallback, undefined, "f"); | ||
_callback(err, data); | ||
}; | ||
}, "f"); | ||
} | ||
_on_socket_data(data) { | ||
// istanbul ignore next | ||
if (!this.packetAssembler) { | ||
if (!__classPrivateFieldGet(this, _TCP_transport_packetAssembler, "f")) { | ||
throw new Error("internal Error"); | ||
@@ -396,3 +388,3 @@ } | ||
if (data.length > 0) { | ||
this.packetAssembler.feed(data); | ||
__classPrivateFieldGet(this, _TCP_transport_packetAssembler, "f").feed(data); | ||
} | ||
@@ -406,3 +398,3 @@ } | ||
this.dispose(); | ||
if (this._theCallback) | ||
if (__classPrivateFieldGet(this, _TCP_transport__theCallback, "f")) | ||
return; | ||
@@ -419,4 +411,4 @@ // if (hadError) { | ||
doDebugFlow && warningLog("_emitClose ", err?.message || "", "from", new Error().stack); | ||
if (!this._closedEmitted) { | ||
this._closedEmitted = err || "noError"; | ||
if (!__classPrivateFieldGet(this, _TCP_transport__closedEmitted, "f")) { | ||
__classPrivateFieldSet(this, _TCP_transport__closedEmitted, err || "noError", "f"); | ||
this.emit("close", err || null); | ||
@@ -430,6 +422,6 @@ // if (this._theCallback) { | ||
else { | ||
debugLog("Already emitted close event", this._closedEmitted.message); | ||
debugLog("Already emitted close event", __classPrivateFieldGet(this, _TCP_transport__closedEmitted, "f").message); | ||
debugLog("err = ", err?.message); | ||
debugLog(""); | ||
debugLog("Already emitted close event", this._closedEmitted); | ||
debugLog("Already emitted close event", __classPrivateFieldGet(this, _TCP_transport__closedEmitted, "f")); | ||
debugLog("err = ", err?.message, err); | ||
@@ -465,3 +457,33 @@ } | ||
exports.TCP_transport = TCP_transport; | ||
_a = TCP_transport, _TCP_transport__closedEmitted = new WeakMap(), _TCP_transport__timerId = new WeakMap(), _TCP_transport__theCallback = new WeakMap(), _TCP_transport__on_error_during_one_time_message_receiver = new WeakMap(), _TCP_transport_packetAssembler = new WeakMap(), _TCP_transport__timeout = new WeakMap(), _TCP_transport__isDisconnecting = new WeakMap(), _TCP_transport_instances = new WeakSet(), _TCP_transport__install_packetAssembler = function _TCP_transport__install_packetAssembler() { | ||
if (__classPrivateFieldGet(this, _TCP_transport_packetAssembler, "f")) { | ||
__classPrivateFieldGet(this, _TCP_transport_packetAssembler, "f").removeAllListeners(); | ||
__classPrivateFieldSet(this, _TCP_transport_packetAssembler, undefined, "f"); | ||
} | ||
// install packet assembler ... | ||
__classPrivateFieldSet(this, _TCP_transport_packetAssembler, new node_opcua_packet_assembler_1.PacketAssembler({ | ||
readChunkFunc: message_builder_base_1.readRawMessageHeader, | ||
minimumSizeInBytes: _a.headerSize, | ||
maxChunkSize: this.receiveBufferSize //Math.max(this.receiveBufferSize, this.sendBufferSize) | ||
}), "f"); | ||
__classPrivateFieldGet(this, _TCP_transport_packetAssembler, "f").on("chunk", (chunk) => this._on_message_chunk_received(chunk)); | ||
__classPrivateFieldGet(this, _TCP_transport_packetAssembler, "f").on("error", (err, code) => { | ||
let statusCode = status_codes_1.StatusCodes2.BadTcpMessageTooLarge; | ||
switch (code) { | ||
case node_opcua_packet_assembler_1.PacketAssemblerErrorCode.ChunkSizeExceeded: | ||
statusCode = status_codes_1.StatusCodes2.BadTcpMessageTooLarge; | ||
break; | ||
default: | ||
statusCode = status_codes_1.StatusCodes2.BadTcpInternalError; | ||
} | ||
this.sendErrorMessage(statusCode, err.message); | ||
this.prematureTerminate(new Error("Packet Assembler : " + err.message), statusCode); | ||
}); | ||
}; | ||
TCP_transport.registry = new node_opcua_object_registry_1.ObjectRegistry(); | ||
/** | ||
* the size of the header in bytes | ||
* @default 8 | ||
*/ | ||
TCP_transport.headerSize = 8; | ||
//# sourceMappingURL=tcp_transport.js.map |
@@ -0,1 +1,3 @@ | ||
/// <reference types="node" /> | ||
/// <reference types="node" /> | ||
/** | ||
@@ -2,0 +4,0 @@ * @module node-opcua-transport |
@@ -6,7 +6,3 @@ "use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.decodeMessage = decodeMessage; | ||
exports.packTcpMessage = packTcpMessage; | ||
exports.parseEndpointUrl = parseEndpointUrl; | ||
exports.is_valid_endpointUrl = is_valid_endpointUrl; | ||
exports.writeTCPMessageHeader = writeTCPMessageHeader; | ||
exports.writeTCPMessageHeader = exports.is_valid_endpointUrl = exports.parseEndpointUrl = exports.packTcpMessage = exports.decodeMessage = void 0; | ||
/** | ||
@@ -49,2 +45,3 @@ * @module node-opcua-transport | ||
} | ||
exports.decodeMessage = decodeMessage; | ||
function packTcpMessage(msgType, encodableObject) { | ||
@@ -58,2 +55,3 @@ (0, node_opcua_assert_1.assert)(is_valid_msg_type(msgType)); | ||
} | ||
exports.packTcpMessage = packTcpMessage; | ||
// opc.tcp://hostname:51210/UA/SampleServer | ||
@@ -85,2 +83,3 @@ function parseEndpointUrl(endpointUrl) { | ||
} | ||
exports.parseEndpointUrl = parseEndpointUrl; | ||
function is_valid_endpointUrl(endpointUrl) { | ||
@@ -90,2 +89,3 @@ const e = parseEndpointUrl(endpointUrl); | ||
} | ||
exports.is_valid_endpointUrl = is_valid_endpointUrl; | ||
function writeTCPMessageHeader(msgType, chunkType, totalLength, stream) { | ||
@@ -104,2 +104,3 @@ if (stream instanceof Buffer) { | ||
} | ||
exports.writeTCPMessageHeader = writeTCPMessageHeader; | ||
function encodeMessage(msgType, messageContent, stream) { | ||
@@ -106,0 +107,0 @@ // the length of the message, in bytes. (includes the 8 bytes of the message header) |
@@ -0,1 +1,4 @@ | ||
/// <reference types="node" /> | ||
/// <reference types="node" /> | ||
/// <reference types="node" /> | ||
import { EventEmitter } from "events"; | ||
@@ -2,0 +5,0 @@ import net from "net"; |
@@ -0,1 +1,3 @@ | ||
/// <reference types="node" /> | ||
/// <reference types="node" /> | ||
import { EventEmitter } from "events"; | ||
@@ -2,0 +4,0 @@ import { ISocketLike } from "../source"; |
@@ -0,1 +1,2 @@ | ||
/// <reference types="node" /> | ||
import { HalfComChannel } from "./half_com_channel"; | ||
@@ -2,0 +3,0 @@ import { ITransportPair } from "./ITransportPair"; |
@@ -0,1 +1,2 @@ | ||
/// <reference types="node" /> | ||
import net from "net"; | ||
@@ -2,0 +3,0 @@ import { ISocketLike } from "../source"; |
@@ -0,1 +1,2 @@ | ||
/// <reference types="node" /> | ||
export declare const helloMessage1: Buffer; | ||
@@ -2,0 +3,0 @@ export declare const altered_helloMessage1: Buffer; |
{ | ||
"name": "node-opcua-transport", | ||
"version": "2.128.0", | ||
"version": "2.129.0", | ||
"description": "pure nodejs OPCUA SDK - module transport", | ||
@@ -20,3 +20,3 @@ "main": "./dist/source/index.js", | ||
"node-opcua-buffer-utils": "2.128.0", | ||
"node-opcua-chunkmanager": "2.128.0", | ||
"node-opcua-chunkmanager": "2.129.0", | ||
"node-opcua-debug": "2.128.0", | ||
@@ -47,3 +47,3 @@ "node-opcua-factory": "2.128.0", | ||
"homepage": "http://node-opcua.github.io/", | ||
"gitHead": "67a73af6b831d8651a0e66ceb295f159cab4386b", | ||
"gitHead": "8a1754350fb95a764e278d37a289f0c48ccb8c9d", | ||
"files": [ | ||
@@ -50,0 +50,0 @@ "dist", |
@@ -169,13 +169,8 @@ /** | ||
public connect(endpointUrl: string, callback: ErrorCallback): void { | ||
assert(arguments.length === 2); | ||
assert(typeof callback === "function"); | ||
const ep = parseEndpointUrl(endpointUrl); | ||
this.endpointUrl = endpointUrl; | ||
this.serverUri = "urn:" + gHostname + ":Sample"; | ||
/* istanbul ignore next */ | ||
doDebug && debugLog(chalk.cyan("ClientTCP_transport#connect(endpointUrl = " + endpointUrl + ")")); | ||
let socket: ISocketLike | null = null; | ||
@@ -214,2 +209,3 @@ try { | ||
*/ | ||
console.log("connection_break", endpointUrl); | ||
this.emit("connection_break"); | ||
@@ -216,0 +212,0 @@ } |
@@ -103,3 +103,2 @@ /** | ||
public readonly options: MessageBuilderBaseOptions; | ||
public readonly _packetAssembler: PacketAssembler; | ||
public channelId: number; | ||
@@ -118,7 +117,8 @@ public totalMessageSize: number; | ||
private _securityDefeated: boolean; | ||
private _hasReceivedError: boolean; | ||
private blocks: Buffer[]; | ||
private readonly _expectedChannelId: number; | ||
private offsetBodyStart: number; | ||
readonly #_packetAssembler: PacketAssembler; | ||
#_securityDefeated: boolean; | ||
#_hasReceivedError: boolean; | ||
#blocks: Buffer[]; | ||
readonly #_expectedChannelId: number; | ||
#offsetBodyStart: number; | ||
@@ -132,6 +132,6 @@ constructor(options?: MessageBuilderBaseOptions) { | ||
this._tick1 = 0; | ||
this._hasReceivedError = false; | ||
this.blocks = []; | ||
this.#_hasReceivedError = false; | ||
this.#blocks = []; | ||
this.messageChunks = []; | ||
this._expectedChannelId = 0; | ||
this.#_expectedChannelId = 0; | ||
@@ -152,3 +152,3 @@ options = options || { | ||
this._packetAssembler = new PacketAssembler({ | ||
this.#_packetAssembler = new PacketAssembler({ | ||
minimumSizeInBytes: 8, | ||
@@ -159,5 +159,5 @@ maxChunkSize: this.maxChunkSize, | ||
this._packetAssembler.on("chunk", (messageChunk) => this._feed_messageChunk(messageChunk)); | ||
this.#_packetAssembler.on("chunk", (messageChunk) => this.#_feed_messageChunk(messageChunk)); | ||
this._packetAssembler.on("startChunk", (info, data) => { | ||
this.#_packetAssembler.on("startChunk", (info, data) => { | ||
if (doPerfMonitoring) { | ||
@@ -170,3 +170,3 @@ // record tick 0: when the first data is received | ||
this._packetAssembler.on("error", (err) => { | ||
this.#_packetAssembler.on("error", (err) => { | ||
warningLog("packet assembler ", err.message); | ||
@@ -176,9 +176,9 @@ return this._report_error(StatusCodes2.BadTcpMessageTooLarge, "packet assembler: " + err.message); | ||
this._securityDefeated = false; | ||
this.#_securityDefeated = false; | ||
this.totalBodySize = 0; | ||
this.totalMessageSize = 0; | ||
this.channelId = 0; | ||
this.offsetBodyStart = 0; | ||
this.#offsetBodyStart = 0; | ||
this.sequenceHeader = null; | ||
this._init_new(); | ||
this.#_init_new(); | ||
} | ||
@@ -196,4 +196,4 @@ | ||
public feed(data: Buffer): void { | ||
if (!this._securityDefeated && !this._hasReceivedError) { | ||
this._packetAssembler.feed(data); | ||
if (!this.#_securityDefeated && !this.#_hasReceivedError) { | ||
this.#_packetAssembler.feed(data); | ||
} | ||
@@ -206,12 +206,11 @@ } | ||
protected _read_headers(binaryStream: BinaryStream): boolean { | ||
protected _read_headers(binaryStream: BinaryStream): boolean { | ||
try { | ||
this.messageHeader = readMessageHeader(binaryStream); | ||
assert(binaryStream.length === 8, "expecting message header to be 8 bytes"); | ||
// assert(binaryStream.length === 8, "expecting message header to be 8 bytes"); | ||
this.channelId = binaryStream.readUInt32(); | ||
assert(binaryStream.length === 12); | ||
// assert(binaryStream.length === 12); | ||
// verifying secure ChannelId | ||
if (this._expectedChannelId && this.channelId !== this._expectedChannelId) { | ||
if (this.#_expectedChannelId && this.channelId !== this.#_expectedChannelId) { | ||
return this._report_error(StatusCodes2.BadTcpSecureChannelUnknown, "Invalid secure channel Id"); | ||
@@ -228,3 +227,3 @@ } | ||
// the connection can probably continue | ||
this._hasReceivedError = false; /// | ||
this.#_hasReceivedError = false; /// | ||
this.emit("abandon", sequenceHeader.requestId); | ||
@@ -235,4 +234,4 @@ return false; | ||
protected _report_error(statusCode: StatusCode, errorMessage: string): false { | ||
this._hasReceivedError = true; | ||
debugLog("Error ", this.id, errorMessage); | ||
this.#_hasReceivedError = true; | ||
errorLog("Error ", this.id, errorMessage); | ||
// xx errorLog(new Error()); | ||
@@ -243,8 +242,8 @@ this.emit("error", new Error(errorMessage), statusCode, this.sequenceHeader?.requestId || null); | ||
private _init_new() { | ||
this._securityDefeated = false; | ||
this._hasReceivedError = false; | ||
#_init_new() { | ||
this.#_securityDefeated = false; | ||
this.#_hasReceivedError = false; | ||
this.totalBodySize = 0; | ||
this.totalMessageSize = 0; | ||
this.blocks = []; | ||
this.#blocks = []; | ||
this.messageChunks = []; | ||
@@ -259,4 +258,4 @@ } | ||
*/ | ||
private _append(chunk: Buffer): boolean { | ||
if (this._hasReceivedError) { | ||
#_append(chunk: Buffer): boolean { | ||
if (this.#_hasReceivedError) { | ||
// the message builder is in error mode and further message chunks should be discarded. | ||
@@ -280,3 +279,3 @@ return false; | ||
if (!this._read_headers(binaryStream)) { | ||
return this._report_error(StatusCodes2.BadTcpInternalError, `Invalid message header detected`); | ||
return false; // error already reported | ||
} | ||
@@ -291,4 +290,3 @@ | ||
StatusCodes2.BadTcpInternalError, | ||
`Invalid messageChunk size: the provided chunk is ${chunk.length} bytes long but header specifies ${ | ||
this.messageHeader!.length | ||
`Invalid messageChunk size: the provided chunk is ${chunk.length} bytes long but header specifies ${this.messageHeader!.length | ||
}` | ||
@@ -305,3 +303,3 @@ ); | ||
this.totalBodySize += offsetBodyEnd - offsetBodyStart; | ||
this.offsetBodyStart = offsetBodyStart; | ||
this.#offsetBodyStart = offsetBodyStart; | ||
@@ -311,7 +309,7 @@ // add message body to a queue | ||
// use Buffer.clone | ||
const sharedBuffer = chunk.subarray(this.offsetBodyStart, offsetBodyEnd); | ||
const sharedBuffer = chunk.subarray(this.#offsetBodyStart, offsetBodyEnd); | ||
const clonedBuffer = createFastUninitializedBuffer(sharedBuffer.length); | ||
sharedBuffer.copy(clonedBuffer, 0, 0); | ||
this.blocks.push(clonedBuffer); | ||
this.#blocks.push(clonedBuffer); | ||
@@ -321,3 +319,3 @@ return true; | ||
private _feed_messageChunk(chunk: Buffer): boolean { | ||
#_feed_messageChunk(chunk: Buffer): boolean { | ||
assert(chunk); | ||
@@ -336,9 +334,9 @@ const messageHeader = readMessageHeader(new BinaryStream(chunk)); | ||
} else { | ||
this._append(chunk); | ||
this.#_append(chunk); | ||
// last message | ||
if (this._hasReceivedError) { | ||
if (this.#_hasReceivedError) { | ||
return false; | ||
} | ||
const fullMessageBody: Buffer = this.blocks.length === 1 ? this.blocks[0] : Buffer.concat(this.blocks); | ||
const fullMessageBody: Buffer = this.#blocks.length === 1 ? this.#blocks[0] : Buffer.concat(this.#blocks); | ||
@@ -353,3 +351,3 @@ if (doPerfMonitoring) { | ||
// be ready for next block | ||
this._init_new(); | ||
this.#_init_new(); | ||
return messageOk; | ||
@@ -366,3 +364,3 @@ } | ||
// securityHeader.decode(stream); | ||
const channelId = stream.readUInt32(); | ||
@@ -373,3 +371,3 @@ const tokenId = decodeUInt32(stream); | ||
sequenceHeader.decode(stream); | ||
return this._report_abandon(channelId, tokenId, sequenceHeader); | ||
@@ -385,3 +383,3 @@ } catch (err) { | ||
} else if (messageHeader.isFinal === "C") { | ||
return this._append(chunk); | ||
return this.#_append(chunk); | ||
} | ||
@@ -388,0 +386,0 @@ return false; |
@@ -141,2 +141,7 @@ /* eslint-disable @typescript-eslint/ban-types */ | ||
private static registry = new ObjectRegistry(); | ||
/** | ||
* the size of the header in bytes | ||
* @default 8 | ||
*/ | ||
public static readonly headerSize = 8; | ||
@@ -160,15 +165,10 @@ /** | ||
public _socket: ISocketLike | null; | ||
private _closedEmitted: Error | string | undefined = undefined; | ||
#_closedEmitted: Error | string | undefined = undefined; | ||
/** | ||
* the size of the header in bytes | ||
* @default 8 | ||
*/ | ||
private readonly headerSize: 8; | ||
private _timerId: NodeJS.Timeout | null; | ||
private _theCallback?: (err?: Error | null, data?: Buffer) => void; | ||
private _on_error_during_one_time_message_receiver: ((hadError: boolean) => void) | undefined; | ||
private packetAssembler?: PacketAssembler; | ||
private _timeout: number; | ||
private _isDisconnecting = false; | ||
#_timerId: NodeJS.Timeout | null; | ||
#_theCallback?: (err?: Error | null, data?: Buffer) => void; | ||
#_on_error_during_one_time_message_receiver: ((hadError: boolean) => void) | undefined; | ||
#packetAssembler?: PacketAssembler; | ||
#_timeout: number; | ||
#_isDisconnecting = false; | ||
protected _theCloseError: Error | null = null; | ||
@@ -182,7 +182,8 @@ | ||
this._timerId = null; | ||
this._timeout = 5000; // 5 seconds timeout | ||
this._socket = null; | ||
this.headerSize = 8; | ||
this.#_timerId = null; | ||
this.#_timeout = 5000; // 5 seconds timeout | ||
this.#_theCallback = undefined; | ||
this.maxMessageSize = 0; | ||
@@ -197,3 +198,2 @@ this.maxChunkCount = 0; | ||
this._theCallback = undefined; | ||
this.chunkWrittenCount = 0; | ||
@@ -217,3 +217,3 @@ this.chunkReadCount = 0; | ||
str += " chunkReadCount.... = " + this.chunkReadCount + "\n"; | ||
str += " closeEmitted ? ....= " + this._closedEmitted + "\n"; | ||
str += " closeEmitted ? ....= " + this.#_closedEmitted + "\n"; | ||
return str; | ||
@@ -254,12 +254,12 @@ } | ||
// reinstall packetAssembler with correct limits | ||
this._install_packetAssembler(); | ||
this.#_install_packetAssembler(); | ||
} | ||
public get timeout(): number { | ||
return this._timeout; | ||
return this.#_timeout; | ||
} | ||
public set timeout(value: number) { | ||
assert(!this._timerId); | ||
assert(!this.#_timerId); | ||
debugLog("Setting socket " + this.name + " timeout = ", value); | ||
this._timeout = value; | ||
this.#_timeout = value; | ||
} | ||
@@ -269,3 +269,3 @@ | ||
this._cleanup_timers(); | ||
assert(!this._timerId); | ||
assert(!this.#_timerId); | ||
if (this._socket) { | ||
@@ -302,3 +302,3 @@ const gracefully = true; | ||
public isDisconnecting(): boolean { | ||
return !this._socket || this._isDisconnecting; | ||
return !this._socket || this.#_isDisconnecting; | ||
} | ||
@@ -315,4 +315,4 @@ /** | ||
assert(typeof callback === "function", "expecting a callback function, but got " + callback); | ||
if (!this._socket || this._isDisconnecting) { | ||
if (!this._isDisconnecting) { | ||
if (!this._socket || this.#_isDisconnecting) { | ||
if (!this.#_isDisconnecting) { | ||
this.dispose(); | ||
@@ -323,3 +323,3 @@ } | ||
} | ||
this._isDisconnecting = true; | ||
this.#_isDisconnecting = true; | ||
@@ -356,18 +356,18 @@ this._cleanup_timers(); | ||
protected _install_packetAssembler() { | ||
if (this.packetAssembler) { | ||
this.packetAssembler.removeAllListeners(); | ||
this.packetAssembler = undefined; | ||
#_install_packetAssembler() { | ||
if (this.#packetAssembler) { | ||
this.#packetAssembler.removeAllListeners(); | ||
this.#packetAssembler = undefined; | ||
} | ||
// install packet assembler ... | ||
this.packetAssembler = new PacketAssembler({ | ||
this.#packetAssembler = new PacketAssembler({ | ||
readChunkFunc: readRawMessageHeader, | ||
minimumSizeInBytes: this.headerSize, | ||
minimumSizeInBytes: TCP_transport.headerSize, | ||
maxChunkSize: this.receiveBufferSize //Math.max(this.receiveBufferSize, this.sendBufferSize) | ||
}); | ||
this.packetAssembler.on("chunk", (chunk: Buffer) => this._on_message_chunk_received(chunk)); | ||
this.#packetAssembler.on("chunk", (chunk: Buffer) => this._on_message_chunk_received(chunk)); | ||
this.packetAssembler.on("error", (err, code) => { | ||
this.#packetAssembler.on("error", (err, code) => { | ||
let statusCode = StatusCodes2.BadTcpMessageTooLarge; | ||
@@ -392,5 +392,5 @@ switch (code) { | ||
this._socket = socket; | ||
this._closedEmitted = undefined; | ||
this.#_closedEmitted = undefined; | ||
this._theCloseError = null; | ||
assert(this._closedEmitted === undefined, "TCP Transport has already been closed !"); | ||
assert(this.#_closedEmitted === undefined, "TCP Transport has already been closed !"); | ||
@@ -408,3 +408,3 @@ this._socket.setKeepAlive(true); | ||
this._install_packetAssembler(); | ||
this.#_install_packetAssembler(); | ||
@@ -468,3 +468,3 @@ this._socket | ||
protected _install_one_time_message_receiver(callback: CallbackWithData): void { | ||
assert(!this._theCallback, "callback already set"); | ||
assert(!this.#_theCallback, "callback already set"); | ||
assert(typeof callback === "function"); | ||
@@ -475,6 +475,6 @@ this._start_one_time_message_receiver(callback); | ||
private _fulfill_pending_promises(err: Error | null, data?: Buffer): boolean { | ||
if (!this._theCallback) return false; | ||
if (!this.#_theCallback) return false; | ||
doDebugFlow && errorLog("_fulfill_pending_promises from", new Error().stack); | ||
const callback = this._theCallback; | ||
this._theCallback = undefined; | ||
const callback = this.#_theCallback; | ||
this.#_theCallback = undefined; | ||
callback(err, data); | ||
@@ -497,5 +497,5 @@ return true; | ||
private _cleanup_timers() { | ||
if (this._timerId) { | ||
clearTimeout(this._timerId); | ||
this._timerId = null; | ||
if (this.#_timerId) { | ||
clearTimeout(this.#_timerId); | ||
this.#_timerId = null; | ||
} | ||
@@ -505,9 +505,9 @@ } | ||
private _start_one_time_message_receiver(callback: CallbackWithData) { | ||
assert(!this._timerId && !this._on_error_during_one_time_message_receiver, "timer already started"); | ||
assert(!this.#_timerId && !this.#_on_error_during_one_time_message_receiver, "timer already started"); | ||
const _cleanUp = () => { | ||
this._cleanup_timers(); | ||
if (this._on_error_during_one_time_message_receiver) { | ||
this._socket?.removeListener("close", this._on_error_during_one_time_message_receiver); | ||
this._on_error_during_one_time_message_receiver = undefined; | ||
if (this.#_on_error_during_one_time_message_receiver) { | ||
this._socket?.removeListener("close", this.#_on_error_during_one_time_message_receiver); | ||
this.#_on_error_during_one_time_message_receiver = undefined; | ||
} | ||
@@ -524,4 +524,4 @@ }; | ||
// Setup timeout detection timer .... | ||
this._timerId = setTimeout(() => { | ||
this._timerId = null; | ||
this.#_timerId = setTimeout(() => { | ||
this.#_timerId = null; | ||
onTimeout(); | ||
@@ -533,3 +533,3 @@ }, this.timeout); | ||
// to do = intercept socket error as well | ||
this._on_error_during_one_time_message_receiver = (hadError: boolean) => { | ||
this.#_on_error_during_one_time_message_receiver = (hadError: boolean) => { | ||
const err = new Error( | ||
@@ -541,9 +541,9 @@ `ERROR in waiting for data on socket ( timeout was = ${this.timeout} ms) hadError` + hadError | ||
}; | ||
this._socket.prependOnceListener("close", this._on_error_during_one_time_message_receiver); | ||
this._socket.prependOnceListener("close", this.#_on_error_during_one_time_message_receiver); | ||
} | ||
const _callback = callback; | ||
this._theCallback = (err?: Error | null, data?: Buffer) => { | ||
this.#_theCallback = (err?: Error | null, data?: Buffer) => { | ||
_cleanUp(); | ||
this._theCallback = undefined; | ||
this.#_theCallback = undefined; | ||
_callback(err!, data); | ||
@@ -555,3 +555,3 @@ }; | ||
// istanbul ignore next | ||
if (!this.packetAssembler) { | ||
if (!this.#packetAssembler) { | ||
throw new Error("internal Error"); | ||
@@ -561,3 +561,3 @@ } | ||
if (data.length > 0) { | ||
this.packetAssembler.feed(data); | ||
this.#packetAssembler.feed(data); | ||
} | ||
@@ -572,3 +572,3 @@ } | ||
this.dispose(); | ||
if (this._theCallback) return; | ||
if (this.#_theCallback) return; | ||
// if (hadError) { | ||
@@ -586,4 +586,4 @@ // if (this._socket) { | ||
if (!this._closedEmitted) { | ||
this._closedEmitted = err || "noError"; | ||
if (!this.#_closedEmitted) { | ||
this.#_closedEmitted = err || "noError"; | ||
this.emit("close", err || null); | ||
@@ -596,6 +596,6 @@ // if (this._theCallback) { | ||
} else { | ||
debugLog("Already emitted close event", (this._closedEmitted as any).message); | ||
debugLog("Already emitted close event", (this.#_closedEmitted as any).message); | ||
debugLog("err = ", err?.message); | ||
debugLog(""); | ||
debugLog("Already emitted close event", this._closedEmitted); | ||
debugLog("Already emitted close event", this.#_closedEmitted); | ||
debugLog("err = ", err?.message, err); | ||
@@ -602,0 +602,0 @@ } |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
License Policy Violation
LicenseThis package is not allowed per your license policy. Review the package's license to ensure compliance.
Found 1 instance in 1 package
367220
75
5064
+ Addednode-opcua-chunkmanager@2.129.0(transitive)
- Removednode-opcua-chunkmanager@2.128.0(transitive)