From 21ebeea43939b61e4f1d01aa30021dd5294bd9a4 Mon Sep 17 00:00:00 2001 From: scarry1992 Date: Tue, 19 Mar 2019 12:18:05 +0300 Subject: [PATCH] user properties with same names --- parser.js | 12 ++++++++++- test.js | 52 ++++++++++++++++++++++++++++++++++++++++++++++++ writeToStream.js | 22 +++++++++++++++++--- 3 files changed, 82 insertions(+), 4 deletions(-) diff --git a/parser.js b/parser.js index 2ae985c..b9ac7b8 100644 --- a/parser.js +++ b/parser.js @@ -597,7 +597,17 @@ Parser.prototype._parseProperties = function () { result[name] = {} } var currentUserProperty = this._parseByType(constants.propertiesTypes[name]) - result[name][currentUserProperty.name] = currentUserProperty.value + if (result[name][currentUserProperty.name]) { + if (Array.isArray(result[name][currentUserProperty.name])) { + result[name][currentUserProperty.name].push(currentUserProperty.value) + } else { + var currentValue = result[name][currentUserProperty.name] + result[name][currentUserProperty.name] = [currentValue] + result[name][currentUserProperty.name].push(currentUserProperty.value) + } + } else { + result[name][currentUserProperty.name] = currentUserProperty.value + } continue } result[name] = this._parseByType(constants.propertiesTypes[name]) diff --git a/test.js b/test.js index d115b22..c87cfec 100644 --- a/test.js +++ b/test.js @@ -780,6 +780,58 @@ testParseGenerate('connack MQTT5 with properties', { 22, 0, 4, 1, 2, 3, 4 // authenticationData ]), { protocolVersion: 5 }) +testParseGenerate('connack MQTT5 with properties and doubled user properties', { + cmd: 'connack', + retain: false, + qos: 0, + dup: false, + length: 100, + sessionPresent: false, + reasonCode: 0, + properties: { + sessionExpiryInterval: 1234, + receiveMaximum: 432, + maximumQoS: 2, + retainAvailable: true, + maximumPacketSize: 100, + assignedClientIdentifier: 'test', + topicAliasMaximum: 456, + reasonString: 'test', + userProperties: { + 'test': ['test', 'test'] + }, + wildcardSubscriptionAvailable: true, + subscriptionIdentifiersAvailable: true, + sharedSubscriptionAvailable: false, + serverKeepAlive: 1234, + responseInformation: 'test', + serverReference: 'test', + authenticationMethod: 'test', + authenticationData: Buffer.from([1, 2, 3, 4]) + } +}, Buffer.from([ + 32, 100, 0, 0, + 97, // properties length + 17, 0, 0, 4, 210, // sessionExpiryInterval + 33, 1, 176, // receiveMaximum + 36, 2, // Maximum qos + 37, 1, // retainAvailable + 39, 0, 0, 0, 100, // maximumPacketSize + 18, 0, 4, 116, 101, 115, 116, // assignedClientIdentifier + 34, 1, 200, // topicAliasMaximum + 31, 0, 4, 116, 101, 115, 116, // reasonString + 38, 0, 4, 116, 101, 115, 116, 0, 4, 116, 101, 115, 116, + 38, 0, 4, 116, 101, 115, 116, 0, 4, 116, 101, 115, 116, // userProperties + 40, 1, // wildcardSubscriptionAvailable + 41, 1, // subscriptionIdentifiersAvailable + 42, 0, // sharedSubscriptionAvailable + 19, 4, 210, // serverKeepAlive + 26, 0, 4, 116, 101, 115, 116, // responseInformation + 28, 0, 4, 116, 101, 115, 116, // serverReference + 21, 0, 4, 116, 101, 115, 116, // authenticationMethod + 22, 0, 4, 1, 2, 3, 4 // authenticationData +]), { protocolVersion: 5 }) + testParseGenerate('connack with return code 0 session present bit set', { cmd: 'connack', retain: false, diff --git a/writeToStream.js b/writeToStream.js index 4cc0702..f7732d7 100644 --- a/writeToStream.js +++ b/writeToStream.js @@ -926,7 +926,15 @@ function getProperties (stream, properties) { return false } length += Object.getOwnPropertyNames(value).reduce(function (result, name) { - result += 1 + 2 + Buffer.byteLength(name.toString()) + 2 + Buffer.byteLength(value[name].toString()) + var currentValue = value[name] + if (Array.isArray(currentValue)) { + result += currentValue.reduce((currentLength, value) => { + currentLength += 1 + 2 + Buffer.byteLength(name.toString()) + 2 + Buffer.byteLength(value.toString()) + return currentLength + }, 0) + } else { + result += 1 + 2 + Buffer.byteLength(name.toString()) + 2 + Buffer.byteLength(value[name].toString()) + } return result }, 0) break @@ -1019,8 +1027,16 @@ function writeProperties (stream, properties, propertiesLength) { } case 'pair': { Object.getOwnPropertyNames(value).forEach(function (name) { - stream.write(Buffer.from([protocol.properties[propName]])) - writeStringPair(stream, name.toString(), value[name].toString()) + var currentValue = value[name] + if (Array.isArray(currentValue)) { + currentValue.forEach(function (value) { + stream.write(Buffer.from([protocol.properties[propName]])) + writeStringPair(stream, name.toString(), value.toString()) + }) + } else { + stream.write(Buffer.from([protocol.properties[propName]])) + writeStringPair(stream, name.toString(), currentValue.toString()) + } }) break }