UNPKG

rjweb-server

Version:

Easy and Robust Way to create a Web Server with Many Easy-to-use Features in NodeJS

421 lines (420 loc) 22.6 kB
export default async function wsHandler({ context, custom, aborter }, ws, server, middlewares) { const route = context.route; context.elapsed(true); context.body.raw = Buffer.from(ws.message()); context.endFn = false; switch (ws.type()) { case "open": { const ctr = new context.global.classContexts.WsOpen(context, ws, aborter.signal); ctr["@"] = custom; for (let i = 0; i < middlewares.length; i++) { if (aborter.signal.aborted) return; const middleware = middlewares[i]; if (middleware.callbacks.wsOpen) { try { await Promise.resolve(middleware.callbacks.wsOpen(middleware.config, server, context, ctr, () => context.endFn = true)); } catch (err) { const error = context.handleError(err, `ws.handle.middleware.${i}.wsOpen`); if (context.global.errorHandlers.wsOpen) { try { await Promise.resolve(context.global.errorHandlers.wsOpen(ctr, error)); } catch (err) { context.global.logger.error(`An Error has occured on ${context.url.method} ${context.url.href}\n${error.toString()}`); } } else { context.global.logger.error(`An Error has occured on ${context.url.method} ${context.url.href}\n${error.toString()}`); } } if (context.endFn) break; } } if (!context.endFn) for (let i = 0; i < route.validators.length; i++) { const validator = route.validators[i]; for (let j = 0; j < validator.listeners.wsOpen.length; j++) { if (aborter.signal.aborted) return; const validate = validator.listeners.wsOpen[j]; try { await Promise.resolve(validate(ctr, () => context.endFn = true, validator.data)); } catch (err) { const error = context.handleError(err, `ws.handle.validator.${i}.listeners.${j}.wsOpen`); if (context.global.errorHandlers.wsOpen) { try { await Promise.resolve(context.global.errorHandlers.wsOpen(ctr, error)); } catch (err) { context.global.logger.error(`An Error has occured on ${context.url.method} ${context.url.href}\n${error.toString()}`); } } else { context.global.logger.error(`An Error has occured on ${context.url.method} ${context.url.href}\n${error.toString()}`); } } } } if (route.data.onOpen && !context.endFn && !aborter.signal.aborted) { try { await Promise.resolve(route.data.onOpen(ctr)); } catch (err) { const error = context.handleError(err, 'ws.handle.onOpen'); if (context.global.errorHandlers.wsOpen) { try { await Promise.resolve(context.global.errorHandlers.wsOpen(ctr, error)); } catch (err) { context.global.logger.error(`An Error has occured on ${context.url.method} ${context.url.href}\n${error.toString()}`); } } else { context.global.logger.error(`An Error has occured on ${context.url.method} ${context.url.href}\n${error.toString()}`); } } } for (let i = 0; i < middlewares.length; i++) { if (aborter.signal.aborted) return; const middleware = middlewares[i]; if (middleware.callbacks.wsOpen) { try { await Promise.resolve(middleware.callbacks.wsOpen(middleware.config, server, context, ctr, () => context.endFn = true)); } catch (err) { const error = context.handleError(err, `ws.handle.middleware.${i}.wsOpen`); if (context.global.errorHandlers.wsOpen) { try { await Promise.resolve(context.global.errorHandlers.wsOpen(ctr, error)); } catch (err) { context.global.logger.error(`An Error has occured on ${context.url.method} ${context.url.href}\n${error.toString()}`); } } else { context.global.logger.error(`An Error has occured on ${context.url.method} ${context.url.href}\n${error.toString()}`); } } if (context.endFn) break; } } for (let i = 0; i < middlewares.length; i++) { const middleware = middlewares[i]; if (middleware.finishCallbacks.wsOpen) { try { await Promise.resolve(middleware.finishCallbacks.wsOpen(middleware.config, server, context, ctr, context.elapsed())); } catch (err) { const error = context.handleError(err, `ws.handle.middleware.${i}.wsOpenFinish`); if (context.global.errorHandlers.wsOpen) { try { await Promise.resolve(context.global.errorHandlers.wsOpen(ctr, error)); } catch (err) { context.global.logger.error(`An Error has occured on ${context.url.method} ${context.url.href}\n${error.toString()}`); } } else { context.global.logger.error(`An Error has occured on ${context.url.method} ${context.url.href}\n${error.toString()}`); } } } } if (context.global.finishHandlers.wsOpen) try { await Promise.resolve(context.global.finishHandlers.wsOpen(ctr, context.elapsed())); } catch (err) { const error = context.handleError(err, 'ws.handle.onOpenFinish'); if (context.global.errorHandlers.wsOpen) { try { await Promise.resolve(context.global.errorHandlers.wsOpen(ctr, error)); } catch (err) { context.global.logger.error(`An Error has occured on ${context.url.method} ${context.url.href}\n${error.toString()}`); } } else { context.global.logger.error(`An Error has occured on ${context.url.method} ${context.url.href}\n${error.toString()}`); } } break; } case "message": { const ctr = new context.global.classContexts.WsMessage(context, ws, aborter.signal); ctr["@"] = custom; if (route.ratelimit && route.ratelimit.maxHits !== Infinity && route.ratelimit.timeWindow !== Infinity) { let data = context.global.rateLimits.get(`ws+${ctr.client.ip}-${route.ratelimit.sortTo}`, { hits: 0, end: Date.now() + route.ratelimit.timeWindow }); if (data.hits + 1 > route.ratelimit.maxHits && data.end > Date.now()) { if (data.hits === route.ratelimit.maxHits) data.end += route.ratelimit.penalty; context.endFn = true; if (context.global.rateLimitHandlers.wsMessage) { try { await Promise.resolve(context.global.rateLimitHandlers.wsMessage(ctr)); } catch (err) { const error = context.handleError(err, 'ws.handle.rateLimitHandlers.wsMessage'); if (context.global.errorHandlers.wsMessage) { try { await Promise.resolve(context.global.errorHandlers.wsMessage(ctr, error)); } catch (err) { context.global.logger.error(`An Error has occured on ${context.url.method} ${context.url.href}\n${error.toString()}`); } } else { context.global.logger.error(`An Error has occured on ${context.url.method} ${context.url.href}\n${error.toString()}`); } } } } else if (data.end < Date.now()) { context.global.rateLimits.delete(`ws+${ctr.client.ip}-${route.ratelimit.sortTo}`); data = { hits: 0, end: Date.now() + route.ratelimit.timeWindow }; } } for (let i = 0; i < middlewares.length; i++) { if (aborter.signal.aborted) return; const middleware = middlewares[i]; if (middleware.callbacks.wsMessage) { try { await Promise.resolve(middleware.callbacks.wsMessage(middleware.config, server, context, ctr, () => context.endFn = true)); } catch (err) { const error = context.handleError(err, `ws.handle.middleware.${i}.wsMessage`); if (context.global.errorHandlers.wsMessage) { try { await Promise.resolve(context.global.errorHandlers.wsMessage(ctr, error)); } catch (err) { context.global.logger.error(`An Error has occured on ${context.url.method} ${context.url.href}\n${error.toString()}`); } } else { context.global.logger.error(`An Error has occured on ${context.url.method} ${context.url.href}\n${error.toString()}`); } } if (context.endFn) break; } } if (!context.endFn) for (let i = 0; i < route.validators.length; i++) { const validator = route.validators[i]; for (let j = 0; j < validator.listeners.wsMessage.length; j++) { if (aborter.signal.aborted) return; const validate = validator.listeners.wsMessage[j]; try { await Promise.resolve(validate(ctr, () => context.endFn = true, validator.data)); } catch (err) { const error = context.handleError(err, `ws.handle.validator.${i}.listeners.${j}.wsMessage`); if (context.global.errorHandlers.wsMessage) { try { await Promise.resolve(context.global.errorHandlers.wsMessage(ctr, error)); } catch (err) { context.global.logger.error(`An Error has occured on ${context.url.method} ${context.url.href}\n${error.toString()}`); } } else { context.global.logger.error(`An Error has occured on ${context.url.method} ${context.url.href}\n${error.toString()}`); } } } } if (route.data.onMessage && !context.endFn && !aborter.signal.aborted) { try { await Promise.resolve(route.data.onMessage(ctr)); } catch (err) { const error = context.handleError(err, 'ws.handle.onMessage'); if (context.global.errorHandlers.wsMessage) { try { await Promise.resolve(context.global.errorHandlers.wsMessage(ctr, error)); } catch (err) { context.global.logger.error(`An Error has occured on ${context.url.method} ${context.url.href}\n${error.toString()}`); } } else { context.global.logger.error(`An Error has occured on ${context.url.method} ${context.url.href}\n${error.toString()}`); } } } for (let i = 0; i < middlewares.length; i++) { const middleware = middlewares[i]; if (middleware.finishCallbacks.wsMessage) { try { await Promise.resolve(middleware.finishCallbacks.wsMessage(middleware.config, server, context, ctr, context.elapsed())); } catch (err) { const error = context.handleError(err, `ws.handle.middleware.${i}.wsmessageFinish`); if (context.global.errorHandlers.wsMessage) { try { await Promise.resolve(context.global.errorHandlers.wsMessage(ctr, error)); } catch (err) { context.global.logger.error(`An Error has occured on ${context.url.method} ${context.url.href}\n${error.toString()}`); } } else { context.global.logger.error(`An Error has occured on ${context.url.method} ${context.url.href}\n${error.toString()}`); } } } } if (context.global.finishHandlers.wsMessage) try { await Promise.resolve(context.global.finishHandlers.wsMessage(ctr, context.elapsed())); } catch (err) { const error = context.handleError(err, 'ws.handle.onMessageFinish'); if (context.global.errorHandlers.wsMessage) { try { await Promise.resolve(context.global.errorHandlers.wsMessage(ctr, error)); } catch (err) { context.global.logger.error(`An Error has occured on ${context.url.method} ${context.url.href}\n${error.toString()}`); } } else { context.global.logger.error(`An Error has occured on ${context.url.method} ${context.url.href}\n${error.toString()}`); } } break; } case "close": { const ctr = new context.global.classContexts.WsClose(context); ctr["@"] = custom; for (let i = 0; i < middlewares.length; i++) { if (aborter.signal.aborted) return; const middleware = middlewares[i]; if (middleware.callbacks.wsClose) { try { await Promise.resolve(middleware.callbacks.wsClose(middleware.config, server, context, ctr, () => context.endFn = true)); } catch (err) { const error = context.handleError(err, `ws.handle.middleware.${i}.wsClose`); if (context.global.errorHandlers.wsClose) { try { await Promise.resolve(context.global.errorHandlers.wsClose(ctr, error)); } catch (err) { context.global.logger.error(`An Error has occured on ${context.url.method} ${context.url.href}\n${error.toString()}`); } } else { context.global.logger.error(`An Error has occured on ${context.url.method} ${context.url.href}\n${error.toString()}`); } } if (context.endFn) break; } } if (!context.endFn) for (let i = 0; i < route.validators.length; i++) { const validator = route.validators[i]; for (let j = 0; j < validator.listeners.wsClose.length; j++) { if (aborter.signal.aborted) return; const validate = validator.listeners.wsClose[j]; try { await Promise.resolve(validate(ctr, () => context.endFn = true, validator.data)); } catch (err) { const error = context.handleError(err, `ws.handle.validator.${i}.listeners.${j}.wsClose`); if (context.global.errorHandlers.wsClose) { try { await Promise.resolve(context.global.errorHandlers.wsClose(ctr, error)); } catch (err) { context.global.logger.error(`An Error has occured on ${context.url.method} ${context.url.href}\n${error.toString()}`); } } else { context.global.logger.error(`An Error has occured on ${context.url.method} ${context.url.href}\n${error.toString()}`); } } } } aborter.abort(); if (route.data.onClose && !context.endFn) { try { await Promise.resolve(route.data.onClose(ctr)); } catch (err) { const error = context.handleError(err, 'ws.handle.onClose'); if (context.global.errorHandlers.wsClose) { try { await Promise.resolve(context.global.errorHandlers.wsClose(ctr, error)); } catch (err) { context.global.logger.error(`An Error has occured on ${context.url.method} ${context.url.href}\n${error.toString()}`); } } else { context.global.logger.error(`An Error has occured on ${context.url.method} ${context.url.href}\n${error.toString()}`); } } } for (let i = 0; i < middlewares.length; i++) { const middleware = middlewares[i]; if (middleware.finishCallbacks.wsClose) { try { await Promise.resolve(middleware.finishCallbacks.wsClose(middleware.config, server, context, ctr, context.elapsed())); } catch (err) { const error = context.handleError(err, `ws.handle.middleware.${i}.wsCloseFinish`); if (context.global.errorHandlers.wsClose) { try { await Promise.resolve(context.global.errorHandlers.wsClose(ctr, error)); } catch (err) { context.global.logger.error(`An Error has occured on ${context.url.method} ${context.url.href}\n${error.toString()}`); } } else { context.global.logger.error(`An Error has occured on ${context.url.method} ${context.url.href}\n${error.toString()}`); } } } } if (context.global.finishHandlers.wsClose) try { await Promise.resolve(context.global.finishHandlers.wsClose(ctr, context.elapsed())); } catch (err) { const error = context.handleError(err, 'ws.handle.onCloseFinish'); if (context.global.errorHandlers.wsClose) { try { await Promise.resolve(context.global.errorHandlers.wsClose(ctr, error)); } catch (err) { context.global.logger.error(`An Error has occured on ${context.url.method} ${context.url.href}\n${error.toString()}`); } } else { context.global.logger.error(`An Error has occured on ${context.url.method} ${context.url.href}\n${error.toString()}`); } } break; } } }