Skip to content

Commit 5983205

Browse files
author
Bret Ambrose
committed
Merge branch 'JsMqtt-9-5' into JsMqtt-10-ManualAck
2 parents aded3c9 + e94749a commit 5983205

4 files changed

Lines changed: 42 additions & 57 deletions

File tree

lib/browser/mqtt5.spec.ts

Lines changed: 4 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -335,40 +335,17 @@ function createOperationFailureClient() : mqtt5.IMqtt5Client {
335335
return new mqtt5.Mqtt5Client(createWsIotCoreClientConfig());
336336
}
337337

338-
/* Variant of the shared version that doesn't expect the stop call to throw */
339-
async function testDisconnectValidationFailure(client : mqtt5.Mqtt5Client, sessionExpiry: number) {
340-
let connectionSuccess = once(client, mqtt5.Mqtt5Client.CONNECTION_SUCCESS);
341-
let disconnection = once(client, mqtt5.Mqtt5Client.DISCONNECTION);
342-
343-
client.start();
344-
345-
await connectionSuccess;
346-
347-
client.stop({
348-
reasonCode: mqtt5.DisconnectReasonCode.NormalDisconnection,
349-
sessionExpiryIntervalSeconds: sessionExpiry
350-
});
351-
352-
// even though validation fails, we should still see the connection drop (on failure result handler)
353-
await disconnection;
354-
355-
let stopped = once(client, mqtt5.Mqtt5Client.STOPPED);
356-
357-
client.stop();
358-
await stopped;
359-
360-
client.close();
361-
}
362-
363338
test_utils.conditional_test(test_utils.ClientEnvironmentalConfig.hasIotCoreEnvironment())('Disconnection failure - session expiry underflow', async () => {
364339
await retry.networkTimeoutRetryWrapper( async () => {
365-
await testDisconnectValidationFailure(createOperationFailureClient() as mqtt5.Mqtt5Client, -5);
340+
// @ts-ignore
341+
await test_utils.testDisconnectValidationFailure(createOperationFailureClient() as mqtt5.Mqtt5Client, -5);
366342
})
367343
});
368344

369345
test_utils.conditional_test(test_utils.ClientEnvironmentalConfig.hasIotCoreEnvironment())('Disconnection failure - session expiry overflow', async () => {
370346
await retry.networkTimeoutRetryWrapper( async () => {
371-
await testDisconnectValidationFailure(createOperationFailureClient() as mqtt5.Mqtt5Client, 4294967296);
347+
// @ts-ignore
348+
await test_utils.testDisconnectValidationFailure(createOperationFailureClient() as mqtt5.Mqtt5Client, 4294967296);
372349
})
373350
});
374351

lib/browser/mqtt5.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ import {CrtError} from "./error";
2121
import * as ws from "./ws";
2222
import * as mqtt_shared from "../common/mqtt_shared";
2323
import * as auth from "./auth";
24+
import * as validate from "./mqtt_internal/validate";
2425

2526
export * from "../common/mqtt5";
2627
export * from '../common/mqtt5_packet';
@@ -374,6 +375,13 @@ export class Mqtt5Client extends BufferedEventEmitter implements mqtt5.IMqtt5Cli
374375
* @param disconnectPacket (optional) properties of a DISCONNECT packet to send as part of the shutdown process
375376
*/
376377
stop(disconnectPacket?: mqtt5_packet.DisconnectPacket) {
378+
// maintain backwards comaptibility with previous implementation which let validation errors
379+
// trump the stop request
380+
if (disconnectPacket) {
381+
disconnectPacket.type = mqtt5_packet.PacketType.Disconnect;
382+
validate.validateInitialOutboundPacket(disconnectPacket, internal_mqtt_client.ProtocolMode.Mqtt5);
383+
}
384+
377385
this.internalClient.stop(disconnectPacket);
378386
}
379387

lib/browser/mqtt_internal/client.ts

Lines changed: 6 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -246,30 +246,6 @@ function buildClientConfigLogString(prefix: string, config: ClientConfig) : stri
246246
return result;
247247
}
248248

249-
function validateUnsignedInteger(value: number, fieldName: string) {
250-
if (!Number.isInteger(value) || value < 0) {
251-
throw new CrtError(`Field "${fieldName}" with value "${value}" is not a valid unsigned integer`);
252-
}
253-
}
254-
255-
function validateOptionalUnsignedInteger(value: number | undefined, fieldName: string) {
256-
if (value === undefined) {
257-
return;
258-
}
259-
260-
validateUnsignedInteger(value, fieldName);
261-
}
262-
263-
function validateOptionalPositiveU32(value: number | undefined, fieldName: string) {
264-
if (value === undefined) {
265-
return;
266-
}
267-
268-
if (!Number.isInteger(value) || value <= 0 || value > (256 * 256 * 256 * 256 - 1)) {
269-
throw new CrtError(`Field "${fieldName}" with value "${value}" is not a valid positive 32 bit integer`);
270-
}
271-
}
272-
273249
function validateConnectOptions(options : ConnectOptions, mode : ProtocolMode) {
274250
if (options.connectPacketTransformer && (typeof options.connectPacketTransformer !== "function")) {
275251
throw new CrtError("connectPacketTransformer must be a function");
@@ -291,7 +267,7 @@ function validateConnectOptions(options : ConnectOptions, mode : ProtocolMode) {
291267
validate.validateU16(options.receiveMaximum, "receiveMaximum");
292268
}
293269

294-
validateOptionalPositiveU32(options.maximumPacketSizeBytes, "maximumPacketSizeBytes");
270+
validate.validateOptionalPositiveU32(options.maximumPacketSizeBytes, "maximumPacketSizeBytes");
295271
validate.validateOptionalU32(options.willDelayIntervalSeconds, "willDelayIntervalSeconds");
296272

297273
if (options.will !== undefined) {
@@ -312,21 +288,21 @@ function validateConfig(config: ClientConfig) {
312288

313289
validateConnectOptions(config.connectOptions, config.protocolVersion);
314290

315-
validateOptionalUnsignedInteger(config.pingTimeoutMillis, "pingTimeoutMillis");
291+
validate.validateOptionalUnsignedInteger(config.pingTimeoutMillis, "pingTimeoutMillis");
316292

317293
if (!config.connectionFactory || (typeof config.connectionFactory !== "function")) {
318294
throw new CrtError("connectionFactory must be a valid function");
319295
}
320296

321-
validateUnsignedInteger(config.connectTimeoutMillis, "connectTimeoutMillis");
297+
validate.validateUnsignedInteger(config.connectTimeoutMillis, "connectTimeoutMillis");
322298

323299
if (config.retryJitterMode !== undefined && mqtt5.RetryJitterType[config.retryJitterMode] == undefined) {
324300
throw new CrtError("Invalid value for retryJitterMode");
325301
}
326302

327-
validateOptionalUnsignedInteger(config.minReconnectDelayMs, "minReconnectDelayMs");
328-
validateOptionalUnsignedInteger(config.maxReconnectDelayMs, "maxReconnectDelayMs");
329-
validateOptionalUnsignedInteger(config.resetConnectionFailureCountMillis, "resetConnectionFailureCountMillis");
303+
validate.validateOptionalUnsignedInteger(config.minReconnectDelayMs, "minReconnectDelayMs");
304+
validate.validateOptionalUnsignedInteger(config.maxReconnectDelayMs, "maxReconnectDelayMs");
305+
validate.validateOptionalUnsignedInteger(config.resetConnectionFailureCountMillis, "resetConnectionFailureCountMillis");
330306

331307
if (config.resubscribeMode !== undefined && ResubscribeModeType[config.resubscribeMode] == undefined) {
332308
throw new CrtError("Invalid value for resubscribeMode");

lib/browser/mqtt_internal/validate.ts

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,30 @@ function validateOptionalVli(value: number | undefined, fieldName: string) {
170170
}
171171
}
172172

173+
export function validateUnsignedInteger(value: number, fieldName: string) {
174+
if (!Number.isInteger(value) || value < 0) {
175+
throw new CrtError(`Field "${fieldName}" with value "${value}" is not a valid unsigned integer`);
176+
}
177+
}
178+
179+
export function validateOptionalUnsignedInteger(value: number | undefined, fieldName: string) {
180+
if (value === undefined) {
181+
return;
182+
}
183+
184+
validateUnsignedInteger(value, fieldName);
185+
}
186+
187+
export function validateOptionalPositiveU32(value: number | undefined, fieldName: string) {
188+
if (value === undefined) {
189+
return;
190+
}
191+
192+
if (!Number.isInteger(value) || value <= 0 || value > (256 * 256 * 256 * 256 - 1)) {
193+
throw new CrtError(`Field "${fieldName}" with value "${value}" is not a valid positive 32 bit integer`);
194+
}
195+
}
196+
173197
// we don't validate length here because we don't know encoding length without doing a utf-8 conversion.
174198
// This means we validate string length in the internal validators which checks ArrayBuffer lengths.
175199
function validateString(value: any, fieldName: string) {

0 commit comments

Comments
 (0)