diff --git a/apps/relay/src/tunnel.ts b/apps/relay/src/tunnel.ts index 9eeaac1ce00..bf112e63d96 100644 --- a/apps/relay/src/tunnel.ts +++ b/apps/relay/src/tunnel.ts @@ -2,7 +2,7 @@ import { createApiClient } from "./api-client"; import type { TunnelHttpResponse, TunnelRequest } from "./types"; type WsSocket = { - send: (data: string) => void; + send: (data: string | ArrayBuffer | Uint8Array) => void; readyState: number; close: (code?: number, reason?: string) => void; }; @@ -173,8 +173,15 @@ export class TunnelManager { pending.resolve(msg as unknown as TunnelHttpResponse); } } else if (msg.type === "ws:frame") { + if (typeof msg.data !== "string") return; const clientWs = tunnel.activeChannels.get(msg.id as string); - if (clientWs?.readyState === 1) clientWs.send(msg.data as string); + if (clientWs?.readyState === 1) { + if (msg.encoding === "base64") { + clientWs.send(Buffer.from(msg.data, "base64")); + } else { + clientWs.send(msg.data); + } + } } else if (msg.type === "ws:close") { const clientWs = tunnel.activeChannels.get(msg.id as string); if (clientWs) { diff --git a/packages/host-service/src/tunnel/tunnel-client.ts b/packages/host-service/src/tunnel/tunnel-client.ts index 42d0e46771e..20a0268239e 100644 --- a/packages/host-service/src/tunnel/tunnel-client.ts +++ b/packages/host-service/src/tunnel/tunnel-client.ts @@ -191,9 +191,22 @@ export class TunnelClient { } const localWs = new WebSocket(wsUrl.toString()); + localWs.binaryType = "arraybuffer"; localWs.onmessage = (event) => { - this.send({ type: "ws:frame", id: request.id, data: String(event.data) }); + const data = event.data; + if (typeof data === "string") { + this.send({ type: "ws:frame", id: request.id, data }); + return; + } + if (data instanceof ArrayBuffer) { + this.send({ + type: "ws:frame", + id: request.id, + data: Buffer.from(data).toString("base64"), + encoding: "base64", + }); + } }; localWs.onclose = (event) => { diff --git a/packages/shared/src/tunnel-protocol.ts b/packages/shared/src/tunnel-protocol.ts index bb199865089..7bafd07dba7 100644 --- a/packages/shared/src/tunnel-protocol.ts +++ b/packages/shared/src/tunnel-protocol.ts @@ -20,6 +20,7 @@ export interface TunnelWsFrame { type: "ws:frame"; id: string; data: string; + encoding?: "base64"; } export interface TunnelWsClose {