X-Git-Url: https://git.piment-noir.org/?a=blobdiff_plain;f=src%2Fcharging-station%2Fui-server%2FUIWebSocketServer.ts;h=cc00db13f233af42975062331f054992135ce510;hb=4c3c0d59f56be4d58e906e938c00390b41e0ca7f;hp=60a4e3c186221f9c00556744e68110ec123cfa1b;hpb=03eacbe58030b56149284730a0af0367a01383cd;p=e-mobility-charging-stations-simulator.git diff --git a/src/charging-station/ui-server/UIWebSocketServer.ts b/src/charging-station/ui-server/UIWebSocketServer.ts index 60a4e3c1..cc00db13 100644 --- a/src/charging-station/ui-server/UIWebSocketServer.ts +++ b/src/charging-station/ui-server/UIWebSocketServer.ts @@ -1,20 +1,22 @@ -import type { IncomingMessage } from 'http'; -import type internal from 'stream'; +import type { IncomingMessage } from 'node:http'; +import type { Duplex } from 'node:stream'; import { StatusCodes } from 'http-status-codes'; import WebSocket, { type RawData, WebSocketServer } from 'ws'; -import type { UIServerConfiguration } from '../../types/ConfigurationData'; -import type { ProtocolRequest, ProtocolResponse } from '../../types/UIProtocol'; -import { WebSocketCloseEventStatusCode } from '../../types/WebSocket'; -import logger from '../../utils/Logger'; -import Utils from '../../utils/Utils'; import { AbstractUIServer } from './AbstractUIServer'; import { UIServerUtils } from './UIServerUtils'; +import { + type ProtocolRequest, + type ProtocolResponse, + type UIServerConfiguration, + WebSocketCloseEventStatusCode, +} from '../../types'; +import { Constants, Utils, logger } from '../../utils'; const moduleName = 'UIWebSocketServer'; -export default class UIWebSocketServer extends AbstractUIServer { +export class UIWebSocketServer extends AbstractUIServer { private readonly webSocketServer: WebSocketServer; public constructor(protected readonly uiServerConfiguration: UIServerConfiguration) { @@ -47,12 +49,7 @@ export default class UIWebSocketServer extends AbstractUIServer { } const [requestId] = request as ProtocolRequest; this.responseHandlers.set(requestId, ws); - this.uiServices - .get(version) - .requestHandler(request) - .catch(() => { - /* Error caught by AbstractUIService */ - }); + this.uiServices.get(version)?.requestHandler(request).catch(Constants.EMPTY_FUNCTION); }); ws.on('error', (error) => { logger.error(`${this.logPrefix(moduleName, 'start.ws.onerror')} WebSocket error:`, error); @@ -68,21 +65,35 @@ export default class UIWebSocketServer extends AbstractUIServer { ); }); }); - this.httpServer.on( - 'upgrade', - (req: IncomingMessage, socket: internal.Duplex, head: Buffer): void => { - this.authenticate(req, (err) => { - if (err) { - socket.write(`HTTP/1.1 ${StatusCodes.UNAUTHORIZED} Unauthorized\r\n\r\n`); - socket.destroy(); - return; - } + // eslint-disable-next-line @typescript-eslint/no-unused-vars + this.httpServer.on('connect', (req: IncomingMessage, socket: Duplex, head: Buffer) => { + if (req.headers?.connection !== 'Upgrade' || req.headers?.upgrade !== 'websocket') { + socket.write(`HTTP/1.1 ${StatusCodes.BAD_REQUEST} Bad Request\r\n\r\n`); + socket.destroy(); + } + }); + this.httpServer.on('upgrade', (req: IncomingMessage, socket: Duplex, head: Buffer): void => { + this.authenticate(req, (err) => { + if (err) { + socket.write(`HTTP/1.1 ${StatusCodes.UNAUTHORIZED} Unauthorized\r\n\r\n`); + socket.destroy(); + return; + } + try { this.webSocketServer.handleUpgrade(req, socket, head, (ws: WebSocket) => { this.webSocketServer.emit('connection', ws, req); }); - }); - } - ); + } catch (error) { + logger.error( + `${this.logPrefix( + moduleName, + 'start.httpServer.on.upgrade' + )} Error at handling connection upgrade:`, + error + ); + } + }); + }); this.startHttpServer(); } @@ -128,14 +139,16 @@ export default class UIWebSocketServer extends AbstractUIServer { } } - public logPrefix(modName?: string, methodName?: string, prefixSuffix?: string): string { + public logPrefix = (modName?: string, methodName?: string, prefixSuffix?: string): string => { const logMsgPrefix = prefixSuffix ? `UI WebSocket Server ${prefixSuffix}` : 'UI WebSocket Server'; const logMsg = - modName && methodName ? ` ${logMsgPrefix} | ${modName}.${methodName}:` : ` ${logMsgPrefix} |`; + Utils.isNotEmptyString(modName) && Utils.isNotEmptyString(methodName) + ? ` ${logMsgPrefix} | ${modName}.${methodName}:` + : ` ${logMsgPrefix} |`; return Utils.logPrefix(logMsg); - } + }; private broadcastToClients(message: string): void { for (const client of this.webSocketServer.clients) {