From f1478e9e82f141a6c6aca11725c0759efa5d6a34 Mon Sep 17 00:00:00 2001 From: Anna Henningsen Date: Wed, 22 Mar 2017 07:17:05 +0100 Subject: [PATCH 1/2] dgram: support Uint8Array input to send() Fixes: https://github.com/nodejs/node/issues/11954 Refs: https://github.com/nodejs/node/pull/11961 --- doc/api/dgram.md | 16 ++++++++++------ lib/dgram.js | 16 ++++++++++------ test/parallel/test-dgram-send-default-host.js | 2 +- 3 files changed, 21 insertions(+), 13 deletions(-) diff --git a/doc/api/dgram.md b/doc/api/dgram.md index 6a9a885491653f..58fdad2a3d0206 100644 --- a/doc/api/dgram.md +++ b/doc/api/dgram.md @@ -245,20 +245,23 @@ chained. -* `msg` {Buffer|string|array} Message to be sent +* `msg` {Buffer|Uint8Array|string|array} Message to be sent * `offset` {number} Integer. Optional. Offset in the buffer where the message starts. * `length` {number} Integer. Optional. Number of bytes in the message. * `port` {number} Integer. Destination port. @@ -269,7 +272,8 @@ Broadcasts a datagram on the socket. The destination `port` and `address` must be specified. The `msg` argument contains the message to be sent. -Depending on its type, different behavior can apply. If `msg` is a `Buffer`, +Depending on its type, different behavior can apply. If `msg` is a `Buffer` +or `Uint8Array`, the `offset` and `length` specify the offset within the `Buffer` where the message begins and the number of bytes in the message, respectively. If `msg` is a `String`, then it is automatically converted to a `Buffer` @@ -299,7 +303,7 @@ the error is emitted as an `'error'` event on the `socket` object. Offset and length are optional, but if you specify one you would need to specify the other. Also, they are supported only when the first -argument is a `Buffer`. +argument is a `Buffer` or `Uint8Array`. Example of sending a UDP packet to a random port on `localhost`; diff --git a/lib/dgram.js b/lib/dgram.js index f39487ba1b298d..0104d962b1b81d 100644 --- a/lib/dgram.js +++ b/lib/dgram.js @@ -29,6 +29,7 @@ const UV_UDP_REUSEADDR = process.binding('constants').os.UV_UDP_REUSEADDR; const UDP = process.binding('udp_wrap').UDP; const SendWrap = process.binding('udp_wrap').SendWrap; +const { isUint8Array } = process.binding('util'); const BIND_STATE_UNBOUND = 0; const BIND_STATE_BINDING = 1; @@ -266,10 +267,12 @@ Socket.prototype.sendto = function(buffer, function sliceBuffer(buffer, offset, length) { - if (typeof buffer === 'string') + if (typeof buffer === 'string') { buffer = Buffer.from(buffer); - else if (!(buffer instanceof Buffer)) - throw new TypeError('First argument must be a buffer or string'); + } else if (!isUint8Array(buffer)) { + throw new TypeError('First argument must be a Buffer, ' + + 'Uint8Array or string'); + } offset = offset >>> 0; length = length >>> 0; @@ -285,7 +288,7 @@ function fixBufferList(list) { var buf = list[i]; if (typeof buf === 'string') newlist[i] = Buffer.from(buf); - else if (!(buf instanceof Buffer)) + else if (!isUint8Array(buf)) return null; else newlist[i] = buf; @@ -359,8 +362,9 @@ Socket.prototype.send = function(buffer, if (!Array.isArray(buffer)) { if (typeof buffer === 'string') { list = [ Buffer.from(buffer) ]; - } else if (!(buffer instanceof Buffer)) { - throw new TypeError('First argument must be a buffer or a string'); + } else if (!isUint8Array(buffer)) { + throw new TypeError('First argument must be a Buffer, ' + + 'Uint8Array or string'); } else { list = [ buffer ]; } diff --git a/test/parallel/test-dgram-send-default-host.js b/test/parallel/test-dgram-send-default-host.js index 6472e5bb0d74e4..c6306439ec1d45 100644 --- a/test/parallel/test-dgram-send-default-host.js +++ b/test/parallel/test-dgram-send-default-host.js @@ -16,7 +16,7 @@ const received = []; client.on('listening', common.mustCall(() => { const port = client.address().port; client.send(toSend[0], 0, toSend[0].length, port); - client.send(toSend[1], port); + client.send(new Uint8Array([...toSend[1]]), port); client.send([toSend[2]], port); client.send(toSend[3], 0, toSend[3].length, port); })); From bd033bb33432462b8ce5b1b96b64e82ada986f63 Mon Sep 17 00:00:00 2001 From: Anna Henningsen Date: Fri, 24 Mar 2017 20:03:43 +0100 Subject: [PATCH 2/2] [squash] duplicate tests instead of modifying one of them --- test/parallel/test-dgram-send-default-host.js | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/test/parallel/test-dgram-send-default-host.js b/test/parallel/test-dgram-send-default-host.js index c6306439ec1d45..4e2541783d2c34 100644 --- a/test/parallel/test-dgram-send-default-host.js +++ b/test/parallel/test-dgram-send-default-host.js @@ -15,23 +15,30 @@ const received = []; client.on('listening', common.mustCall(() => { const port = client.address().port; + client.send(toSend[0], 0, toSend[0].length, port); - client.send(new Uint8Array([...toSend[1]]), port); + client.send(toSend[1], port); client.send([toSend[2]], port); client.send(toSend[3], 0, toSend[3].length, port); + + client.send(new Uint8Array(toSend[0]), 0, toSend[0].length, port); + client.send(new Uint8Array(toSend[1]), port); + client.send([new Uint8Array(toSend[2])], port); + client.send(new Uint8Array(Buffer.from(toSend[3])), + 0, toSend[3].length, port); })); client.on('message', common.mustCall((buf, info) => { received.push(buf.toString()); - if (received.length === toSend.length) { + if (received.length === toSend.length * 2) { // The replies may arrive out of order -> sort them before checking. received.sort(); - const expected = toSend.map(String).sort(); + const expected = toSend.concat(toSend).map(String).sort(); assert.deepStrictEqual(received, expected); client.close(); } -}, toSend.length)); +}, toSend.length * 2)); client.bind(0);