From 8270e00d5b865278d136a4d349b344cbc2b38dc5 Mon Sep 17 00:00:00 2001 From: Damien Arrachequesne Date: Wed, 2 Aug 2023 01:32:38 +0200 Subject: [PATCH] fix(webtransport): honor the binaryType attribute The Node.js client will now properly receive binary data as Buffers instead of ArrayBuffers, when connecting with WebTransport. Browser clients will still receive ArrayBuffers though (or Blobs, if `socket.binaryType` is set to "blob"). --- lib/socket.ts | 3 ++- lib/transports/websocket.ts | 4 +--- lib/transports/webtransport.ts | 3 +-- test/webtransport.mjs | 23 ++++++++++++++++++++++- 4 files changed, 26 insertions(+), 7 deletions(-) diff --git a/lib/socket.ts b/lib/socket.ts index 1c387235f..81b974821 100644 --- a/lib/socket.ts +++ b/lib/socket.ts @@ -7,6 +7,7 @@ import { Emitter } from "@socket.io/component-emitter"; import { protocol } from "engine.io-parser"; import type { Packet, BinaryType, PacketType, RawData } from "engine.io-parser"; import { CloseDetails, Transport } from "./transport.js"; +import { defaultBinaryType } from "./transports/websocket-constructor.js"; const debug = debugModule("engine.io-client:socket"); // debug() @@ -253,7 +254,7 @@ export class Socket extends Emitter< > { public id: string; public transport: Transport; - public binaryType: BinaryType; + public binaryType: BinaryType = defaultBinaryType; public readyState: SocketState; public writeBuffer: Packet[] = []; diff --git a/lib/transports/websocket.ts b/lib/transports/websocket.ts index 33d78724d..45bc47d1e 100644 --- a/lib/transports/websocket.ts +++ b/lib/transports/websocket.ts @@ -1,9 +1,7 @@ import { Transport } from "../transport.js"; -import { encode } from "../contrib/parseqs.js"; import { yeast } from "../contrib/yeast.js"; import { pick } from "../util.js"; import { - defaultBinaryType, nextTick, usingBrowserWebSocket, WebSocket, @@ -84,7 +82,7 @@ export class WS extends Transport { return this.emitReserved("error", err); } - this.ws.binaryType = this.socket.binaryType || defaultBinaryType; + this.ws.binaryType = this.socket.binaryType; this.addEventListeners(); } diff --git a/lib/transports/webtransport.ts b/lib/transports/webtransport.ts index 9f411a636..7996a2f05 100644 --- a/lib/transports/webtransport.ts +++ b/lib/transports/webtransport.ts @@ -43,8 +43,7 @@ export class WT extends Transport { this.transport.createBidirectionalStream().then((stream) => { const decoderStream = createPacketDecoderStream( Number.MAX_SAFE_INTEGER, - // TODO expose binarytype - "arraybuffer" + this.socket.binaryType ); const reader = stream.readable.pipeThrough(decoderStream).getReader(); diff --git a/test/webtransport.mjs b/test/webtransport.mjs index 1ff7b917b..69d92d808 100644 --- a/test/webtransport.mjs +++ b/test/webtransport.mjs @@ -260,12 +260,14 @@ describe("WebTransport", () => { }); }); - it("should send some binary data (server to client)", (done) => { + it("should send some binary data (server to client) (as ArrayBuffer)", (done) => { setup({}, ({ engine, h3Server, certificate }) => { const socket = createSocket(h3Server.port, certificate, { transports: ["webtransport"], }); + socket.binaryType = "arraybuffer"; + engine.on("connection", (serverSocket) => { serverSocket.send(Uint8Array.from([1, 2, 3])); }); @@ -278,4 +280,23 @@ describe("WebTransport", () => { }); }); }); + + it("should send some binary data (server to client) (as Buffer)", (done) => { + setup({}, ({ engine, h3Server, certificate }) => { + const socket = createSocket(h3Server.port, certificate, { + transports: ["webtransport"], + }); + + engine.on("connection", (serverSocket) => { + serverSocket.send(Uint8Array.from([1, 2, 3])); + }); + + socket.on("message", (data) => { + expect(Buffer.isBuffer(data)).to.be(true); + expect(data).to.eql(Uint8Array.of(1, 2, 3)); + + success(engine, h3Server, done); + }); + }); + }); });