/** * Handlers for servers, service tunnels, virtual hosts, proxy port, lookup, pingTunnel. * Context: holesailManager, debugLog */ function register(deps) { const { holesailManager, debugLog } = deps; return [ { type: 'startServer', handle: async (payload, reply) => { debugLog('startServer: payload=', JSON.stringify(payload)); const result = await holesailManager.startServer(payload); debugLog('startServer: result=', JSON.stringify(result)); reply(result); } }, { type: 'stopServer', handle: async (payload, reply) => { debugLog('stopServer: payload=', JSON.stringify(payload)); const result = await holesailManager.stopServer(payload); debugLog('stopServer: result=', JSON.stringify(result)); reply(result); } }, { type: 'startServiceTunnel', handle: async (payload, reply) => { debugLog('startServiceTunnel: payload=', JSON.stringify(payload)); const result = await holesailManager.startServiceTunnel(payload); debugLog('startServiceTunnel: result=', JSON.stringify(result)); reply(result); } }, { type: 'updateServiceTunnel', handle: async (payload, reply) => { debugLog('updateServiceTunnel: payload=', JSON.stringify(payload)); await holesailManager.stopServiceTunnel({ tunnelId: payload.tunnelId }).catch(() => {}); const result = await holesailManager.startServiceTunnel(payload); debugLog('updateServiceTunnel: result=', JSON.stringify(result)); reply(result); } }, { type: 'stopServiceTunnel', handle: async (payload, reply) => { debugLog('stopServiceTunnel: payload=', JSON.stringify(payload)); const result = await holesailManager.stopServiceTunnel(payload); debugLog('stopServiceTunnel: result=', JSON.stringify(result)); reply(result); } }, { type: 'getServiceTunnels', handle: async (payload, reply) => reply({ ok: true, tunnels: holesailManager.getServiceTunnels() }) }, { type: 'getVirtualHosts', handle: async (payload, reply) => { const hosts = holesailManager.getVirtualHosts(); debugLog('getVirtualHosts: count=', hosts.length); reply({ ok: true, hosts }); } }, { type: 'setVirtualHost', handle: async (payload, reply) => { debugLog('setVirtualHost: payload=', JSON.stringify(payload)); const result = await holesailManager.setVirtualHost(payload); debugLog('setVirtualHost: result=', JSON.stringify(result)); reply(result); } }, { type: 'removeVirtualHost', handle: async (payload, reply) => { debugLog('removeVirtualHost: payload=', JSON.stringify(payload)); const result = await holesailManager.removeVirtualHost(payload); debugLog('removeVirtualHost: result=', JSON.stringify(result)); reply(result); } }, { type: 'getProxyPort', handle: async (payload, reply) => { const port = holesailManager.getProxyPort(); debugLog('getProxyPort: port=', port); reply({ ok: true, port }); } }, { type: 'lookup', handle: async (payload, reply) => { debugLog('lookup: payload=', JSON.stringify(payload)); const result = await holesailManager.lookup(payload); debugLog('lookup: result=', JSON.stringify(result)); reply(result); } }, { type: 'pingTunnel', handle: async (payload, reply) => { const pingHost = payload.host || '127.0.0.1'; const pingPort = typeof payload.port === 'number' ? payload.port : null; if (!pingPort) { reply({ ok: false, error: 'port required' }); return; } const tcp = require('bare-tcp'); const t0 = Date.now(); const sock = tcp.connect(pingPort, pingHost); const pingTimeout = setTimeout(() => { try { sock.destroy(); } catch (_) {} reply({ ok: false, error: 'timeout' }); }, 3000); sock.on('connect', () => { clearTimeout(pingTimeout); const latencyMs = Date.now() - t0; try { sock.destroy(); } catch (_) {} reply({ ok: true, latencyMs }); }); sock.on('error', (err) => { clearTimeout(pingTimeout); try { sock.destroy(); } catch (_) {} reply({ ok: false, error: err.message }); }); } } ]; } module.exports = { register };