Skip to content

Commit 64af152

Browse files
authored
Ggt debugger no binary (#2012)
1 parent 21fa421 commit 64af152

File tree

3 files changed

+91
-4
lines changed

3 files changed

+91
-4
lines changed

cspell.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
".direnv",
99
".envrc",
1010
".git",
11+
".vscode",
1112
"__fixtures__",
1213
"__generated__",
1314
"__snapshots__",

spec/commands/debugger.spec.ts

Lines changed: 86 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -468,6 +468,92 @@ describe("debugger", () => {
468468
testCtx.abort();
469469
await debuggerPromise;
470470
});
471+
472+
it("preserves text/binary framing end-to-end", async () => {
473+
const syncScenario = await makeSyncScenario({ localFiles: { ".gadget/": "" } });
474+
475+
// Remote mock WS server that records whether received frames are binary
476+
const wss = new WebSocketServer({ port: 0 });
477+
await new Promise<void>((resolve) => wss.once("listening", resolve));
478+
const remotePort = (wss.address() as any).port as number;
479+
480+
const remoteReceivedIsBinary: boolean[] = [];
481+
let remoteSocket!: WebSocket;
482+
483+
const remoteConnected = new Promise<void>((resolve) => {
484+
wss.on("connection", (ws) => {
485+
remoteSocket = ws;
486+
ws.on("message", (_data, isBinary) => {
487+
remoteReceivedIsBinary.push(isBinary);
488+
});
489+
resolve();
490+
});
491+
});
492+
493+
setupMockRemote(getSubdomain(syncScenario), `ws://localhost:${remotePort}`);
494+
495+
const debuggerPromise = debuggerCommand.run(testCtx, makeArgs(debuggerCommand.args));
496+
497+
await waitUntilUsed(9229);
498+
499+
const response = await fetch("http://127.0.0.1:9229/json/list");
500+
const result = (await response.json()) as any;
501+
const wsUrl = result[0].webSocketDebuggerUrl;
502+
503+
const clientWs = new WebSocket(wsUrl);
504+
505+
await remoteConnected; // ensure remote side is connected
506+
507+
// Track framing for messages coming back from remote to client
508+
const clientReceivedIsBinary: boolean[] = [];
509+
const clientGotTwo = new Promise<void>((resolve) => {
510+
clientWs.on("message", (_data, isBinary) => {
511+
clientReceivedIsBinary.push(isBinary);
512+
if (clientReceivedIsBinary.length === 2) {
513+
resolve();
514+
}
515+
});
516+
});
517+
518+
// Client -> Remote: send a text frame (string) and a binary frame (Buffer)
519+
clientWs.send(JSON.stringify({ hello: "world" }));
520+
clientWs.send(Buffer.from([1, 2, 3]), { binary: true });
521+
522+
// Wait until remote has received both messages
523+
await new Promise<void>((resolve, reject) => {
524+
const start = Date.now();
525+
const check = (): void => {
526+
if (remoteReceivedIsBinary.length >= 2) {
527+
resolve();
528+
return;
529+
}
530+
if (Date.now() - start > 5000) {
531+
reject(new Error("timeout waiting for remote messages"));
532+
return;
533+
}
534+
setTimeout(check, 25);
535+
};
536+
check();
537+
});
538+
539+
expect(remoteReceivedIsBinary).toEqual([false, true]);
540+
541+
// Remote -> Client: send a text frame and a binary frame and ensure client sees same framing
542+
remoteSocket.send(JSON.stringify({ ok: true }), { binary: false });
543+
remoteSocket.send(Buffer.from([9, 8, 7]), { binary: true });
544+
545+
await clientGotTwo;
546+
expect(clientReceivedIsBinary).toEqual([false, true]);
547+
548+
// Cleanup
549+
await new Promise<void>((resolve) => {
550+
clientWs.once("close", () => resolve());
551+
clientWs.close();
552+
});
553+
wss.close();
554+
testCtx.abort();
555+
await debuggerPromise;
556+
});
471557
});
472558

473559
describe("configuration", () => {

src/commands/debugger.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -489,7 +489,7 @@ class ClientConnection {
489489
this._ctx.log.trace("received message from client", { message: messageString });
490490

491491
if (this._remoteReady && this._remoteWs) {
492-
this._remoteWs.send(data);
492+
this._remoteWs.send(data, { binary: isBinary });
493493
} else {
494494
this._messageQueue.push({ data, isBinary });
495495
}
@@ -503,7 +503,7 @@ class ClientConnection {
503503
this._remoteWs.on("message", (data: RawData, isBinary: boolean) => {
504504
const messageString = isBinary ? "<binary data>" : String(data);
505505
this._ctx.log.trace("received message from remote debugger", { message: messageString });
506-
this._clientWs.send(data);
506+
this._clientWs.send(data, { binary: isBinary });
507507
});
508508

509509
this._remoteWs.on("error", (error: Error) => {
@@ -528,8 +528,8 @@ class ClientConnection {
528528
queueLength: this._messageQueue.length,
529529
});
530530

531-
for (const { data } of this._messageQueue) {
532-
this._remoteWs.send(data);
531+
for (const { data, isBinary } of this._messageQueue) {
532+
this._remoteWs.send(data, { binary: isBinary });
533533
}
534534
this._messageQueue.length = 0;
535535
}

0 commit comments

Comments
 (0)