cdp: send a going-away close frame (1001) on pending terminate

Previously tick() tore the connection down without a WebSocket close
frame, so clients saw an abnormal closure (1006). Safe to send from
tick(): the worker thread is the sole writer of the socket.
This commit is contained in:
Pierre Tachoire
2026-07-16 09:09:49 +02:00
parent 9ff4fc2705
commit fc45c0980f
2 changed files with 25 additions and 0 deletions

View File

@@ -246,6 +246,11 @@ pub fn tick(self: *CDP) !bool {
// so the flag can't be a stale leftover here. Exit.
if (self.browser.env.terminatePending()) {
log.warn(.cdp, "closing connection", .{ .reason = "pending terminate" });
// The worker thread is the sole writer of this socket, so sending the
// close frame here can't interleave with another write.
self.conn.send(&WS.CLOSE_GOING_AWAY) catch |err| {
log.warn(.app, "CDP terminate close", .{ .err = err });
};
return false;
}
@@ -1435,6 +1440,25 @@ test "cdp: disconnect latches so the worker keeps exiting" {
try testing.expectError(error.ClientDisconnected, client.tick(0));
}
test "cdp: tick sends a close frame on pending terminate" {
var ctx = try testing.context();
defer ctx.deinit();
const cdp = ctx.cdp();
cdp.browser.env.requestTerminate();
// Clear the pending terminate so deinit's V8 calls don't trip over the
// terminating-state asserts.
defer cdp.browser.env.cancelTerminate();
try testing.expectEqual(false, try cdp.tick());
// The client should receive a close frame (code 1001, going away), not
// just an abrupt socket close.
var buf: [WS.CLOSE_GOING_AWAY.len]u8 = undefined;
const n = try posix.read(ctx.socket, &buf);
try testing.expectEqualSlices(u8, &WS.CLOSE_GOING_AWAY, buf[0..n]);
}
test "cdp: syncRequest short-circuits after disconnect" {
var ctx = try testing.context();
defer ctx.deinit();

View File

@@ -26,6 +26,7 @@ pub const EMPTY_PONG = [_]u8{ 138, 0 };
// CLOSE, 2 length, code
pub const CLOSE_NORMAL = [_]u8{ 136, 2, 3, 232 }; // code: 1000
pub const CLOSE_GOING_AWAY = [_]u8{ 136, 2, 3, 233 }; // code: 1001
pub const CLOSE_TOO_BIG = [_]u8{ 136, 2, 3, 241 }; // 1009
pub const CLOSE_PROTOCOL_ERROR = [_]u8{ 136, 2, 3, 234 }; //code: 1002