Ensure relay close handler is called

This commit is contained in:
Alex Gleason 2025-03-07 12:34:47 -06:00
parent f8eb4fc79c
commit 5162e051ad
No known key found for this signature in database
GPG key ID: 7211D1F99744FBB7

View file

@ -60,7 +60,7 @@ function connectStream(socket: WebSocket, ip: string | undefined, opts: ConnectS
.reduce((acc, limiter) => Math.min(acc, limiter.client(ip).remaining), Infinity); .reduce((acc, limiter) => Math.min(acc, limiter.client(ip).remaining), Infinity);
if (remaining < 0) { if (remaining < 0) {
socket.close(1008, 'Rate limit exceeded'); closeSocket(1008, 'Rate limit exceeded');
return; return;
} }
} }
@ -74,7 +74,7 @@ function connectStream(socket: WebSocket, ip: string | undefined, opts: ConnectS
if (rateLimited(limiters.msg)) return; if (rateLimited(limiters.msg)) return;
if (typeof e.data !== 'string') { if (typeof e.data !== 'string') {
socket.close(1003, 'Invalid message'); closeSocket(1003, 'Invalid message');
return; return;
} }
@ -95,13 +95,24 @@ function connectStream(socket: WebSocket, ip: string | undefined, opts: ConnectS
}; };
socket.onclose = () => { socket.onclose = () => {
handleSocketClose();
};
// HACK: Due to a bug in Deno, we need to call the close handler manually.
// https://github.com/denoland/deno/issues/27924
function closeSocket(code?: number, reason?: string): void {
socket.close(code, reason);
handleSocketClose();
}
function handleSocketClose() {
connections.delete(socket); connections.delete(socket);
relayConnectionsGauge.set(connections.size); relayConnectionsGauge.set(connections.size);
for (const controller of controllers.values()) { for (const controller of controllers.values()) {
controller.abort(); controller.abort();
} }
}; }
function rateLimited(limiter: Pick<RateLimiter, 'client'>): boolean { function rateLimited(limiter: Pick<RateLimiter, 'client'>): boolean {
if (ip) { if (ip) {
@ -109,7 +120,7 @@ function connectStream(socket: WebSocket, ip: string | undefined, opts: ConnectS
try { try {
client.hit(); client.hit();
} catch { } catch {
socket.close(1008, 'Rate limit exceeded'); closeSocket(1008, 'Rate limit exceeded');
return true; return true;
} }
} }