// import type { RegisterServerOptions } from '@peertube/peertube-types' // import type { IncomingMessage } from 'http' // import type { Duplex } from 'stream' // import { WebSocketServer, WebSocket } from 'ws' // import { Socket } from 'net' // FIXME: this method should not be necessary anymore, it was a proof of concept. // interface ProxyLogger { // debug: (s: string) => void // info: (s: string) => void // error: (s: string) => void // } // let xmppWsProxyServer: XMPPWsProxyServer | undefined // class XMPPWsProxyServer { // private readonly logger: ProxyLogger // private readonly options: RegisterServerOptions // private readonly wsProxyServer: WebSocketServer // private prosodyPort: number | undefined // private readonly connections: Map = new Map() // constructor (options: RegisterServerOptions) { // const logger = options.peertubeHelpers.logger // this.logger = { // debug: s => logger.debug('XMPP-WS-PROXY: ' + s), // info: s => logger.info('XMPP-WS-PROXY: ' + s), // error: s => logger.error('XMPP-WS-PROXY: ' + s) // } // this.options = options // this.wsProxyServer = new WebSocketServer({ noServer: true, perMessageDeflate: false }) // } // public handleUpgrade (request: IncomingMessage, incomingSocket: Duplex, head: Buffer): void { // this.wsProxyServer.handleUpgrade(request, incomingSocket, head, ws => { // this.handleUpgradeCallback(ws).then(() => {}, () => {}) // }) // } // public async handleUpgradeCallback (ws: WebSocket): Promise { // this.logger.debug('Opening a Websocket Proxy connection') // const port = await this.getProsodyPort() // if (!port) { // this.logger.error('No port configured for Prosody, closing the websocket stream') // ws.close() // FIXME: add a code and error message // return // } // // Opening a tcp connection to local Prosody: // const prosodySocket = new Socket() // this.connections.set(ws, prosodySocket) // prosodySocket.connect(port, 'localhost', () => { // // TODO: write the remote IP in the header line. // prosodySocket.write('LIVECHAT-WS-PROXY\n') // }) // prosodySocket.on('close', () => { // ws.close() // }) // prosodySocket.on('data', (data) => { // ws.send(data) // }) // ws.on('message', (data) => { // // TODO: remove this log // this.logger.debug('Receiving raw data') // if (Array.isArray(data)) { // data.forEach(chunck => { // prosodySocket.write(chunck) // }) // } else if (data instanceof ArrayBuffer) { // prosodySocket.write(Buffer.from(data)) // } else { // prosodySocket.write(data) // } // }) // ws.on('close', () => { // this.logger.debug('Websocket connection is closed, closing socket') // prosodySocket.end() // }) // } // private async getProsodyPort (): Promise { // if (this.prosodyPort) { // return this.prosodyPort // } // const port = await this.options.settingsManager.getSetting('prosody-port') as string // this.prosodyPort = parseInt(port) // return this.prosodyPort // } // private async closeConnections (): Promise { // this.logger.debug('Closing XMPPWsProxyServer connections...') // this.connections.forEach((socket, _ws) => { // socket.end() // // ws.terminate() // not necessary, socket close event should be called // }) // // FIXME: wait for all connections to be closed... // } // static singleton (options: RegisterServerOptions): XMPPWsProxyServer { // if (!xmppWsProxyServer) { // xmppWsProxyServer = new XMPPWsProxyServer(options) // } // return xmppWsProxyServer // } // static async destroySingleton (): Promise { // if (!xmppWsProxyServer) { return } // const server = xmppWsProxyServer // xmppWsProxyServer = undefined // await server.closeConnections() // } // } // export { // XMPPWsProxyServer // }