53 lines
1.7 KiB
TypeScript
53 lines
1.7 KiB
TypeScript
/**
|
|
* WebSocket upgrade routing.
|
|
*
|
|
* Routes incoming HTTP Upgrade requests to the appropriate WebSocket handler
|
|
* based on the request path and session/topic. Non-matching paths are
|
|
* destroyed immediately.
|
|
*
|
|
* Current routes (all LEGACY — browser HTML client):
|
|
* /ws → legacy browser client WebSocket endpoint
|
|
*
|
|
* Future routes (T-1.5):
|
|
* /sessions/:id/stream → binary ANSI stream per tmux session
|
|
*
|
|
* T-1.5 will extend createUpgradeHandler to accept a session registry and
|
|
* dispatch to per-session stream handlers.
|
|
*/
|
|
|
|
import type { IncomingMessage } from "node:http";
|
|
import type { Socket } from "node:net";
|
|
import type { WsClient, WsServer } from "./types.js";
|
|
|
|
/**
|
|
* Create the HTTP `upgrade` event handler.
|
|
*
|
|
* @param wss - WebSocket server instance.
|
|
* @param isAuthenticated - Predicate that checks token/session on the request.
|
|
* @returns A handler suitable for `httpServer.on("upgrade", handler)`.
|
|
*/
|
|
export function createUpgradeHandler(
|
|
wss: WsServer,
|
|
isAuthenticated: (req: IncomingMessage) => boolean,
|
|
): (request: IncomingMessage, socket: Socket, head: Buffer) => void {
|
|
return (request: IncomingMessage, socket: Socket, head: Buffer): void => {
|
|
const url = new URL(request.url ?? "/", "http://localhost");
|
|
|
|
if (url.pathname === "/ws") {
|
|
// LEGACY: browser HTML client WebSocket endpoint — auth guard
|
|
if (!isAuthenticated(request)) {
|
|
socket.write("HTTP/1.1 403 Forbidden\r\n\r\n");
|
|
socket.destroy();
|
|
return;
|
|
}
|
|
wss.handleUpgrade(request, socket, head, (ws: WsClient) => {
|
|
wss.emit("connection", ws, request);
|
|
});
|
|
return;
|
|
}
|
|
|
|
// Unknown upgrade path — reject
|
|
socket.destroy();
|
|
};
|
|
}
|