UNPKG

@zimic/interceptor

Version:

Next-gen TypeScript-first HTTP intercepting and mocking

92 lines (69 loc) 2.41 kB
import { PossiblePromise } from '@zimic/utils/types'; import { Server as HttpServer, IncomingMessage } from 'http'; import ClientSocket from 'isomorphic-ws'; import { closeServerSocket } from '@/utils/webSocket'; import { WebSocketControlMessage } from './constants'; import { WebSocketSchema } from './types'; import WebSocketHandler from './WebSocketHandler'; const { WebSocketServer: ServerSocket } = ClientSocket; export type WebSocketServerAuthenticate = ( socket: ClientSocket, request: IncomingMessage, ) => PossiblePromise<{ isValid: true } | { isValid: false; message: string }>; interface WebSocketServerOptions { httpServer: HttpServer; socketTimeout?: number; messageTimeout?: number; authenticate?: WebSocketServerAuthenticate; } class WebSocketServer<Schema extends WebSocketSchema> extends WebSocketHandler<Schema> { private webSocketServer?: InstanceType<typeof ServerSocket>; private httpServer: HttpServer; private authenticate?: WebSocketServerOptions['authenticate']; constructor(options: WebSocketServerOptions) { super({ socketTimeout: options.socketTimeout, messageTimeout: options.messageTimeout, }); this.httpServer = options.httpServer; this.authenticate = options.authenticate; } get isRunning() { return this.webSocketServer !== undefined; } start() { if (this.isRunning) { return; } const webSocketServer = new ServerSocket({ server: this.httpServer }); webSocketServer.on('error', (error) => { console.error(error); }); webSocketServer.on('connection', async (socket, request) => { if (this.authenticate) { const result = await this.authenticate(socket, request); if (!result.isValid) { socket.close(1008, result.message); return; } } try { await super.registerSocket(socket); socket.send('socket:auth:valid' satisfies WebSocketControlMessage); } catch (error) { webSocketServer.emit('error', error); } }); this.webSocketServer = webSocketServer; } async stop() { if (!this.webSocketServer || !this.isRunning) { return; } super.offAny(); await super.closeClientSockets(); await closeServerSocket(this.webSocketServer, { timeout: this.socketTimeout }); this.webSocketServer = undefined; } } export default WebSocketServer;