UNPKG

@cliz/inlets

Version:
100 lines (99 loc) 3.96 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const doreamon_1 = require("@zodash/doreamon"); const utils_1 = require("../../../utils"); const debug = require('debug')('inlets:tunnel:tcp'); const logger = doreamon_1.default.logger.getLogger('tunnel:http'); function createServer(ctx, options) { const domain = options.domain; const subDomainRe = new RegExp(`([^.]+).${domain}`); let requestCount = 0; const attach = (server) => { server.on('connection', (tcpSocket) => { const socketConfig = { tcpId: doreamon_1.default.uuid(), domain: null, subDomain: null, isWs: false, }; const request = async (tcpId, data, callback) => { var _a; requestCount += 1; if (socketConfig.isWs) { return; } if (!socketConfig.domain) { const req = new utils_1.Request(data); socketConfig.domain = req.get('host'); socketConfig.req = req; if (req.path === ctx.config.wsPath) { socketConfig.isWs = true; return; } if (socketConfig.domain) { const matched = socketConfig.domain.match(subDomainRe); if (matched) { socketConfig.subDomain = matched[1]; } } } const requestLog = `[${socketConfig.subDomain}.${domain}][request: ${requestCount}] ${(_a = socketConfig.req) === null || _a === void 0 ? void 0 : _a.getRequestLog()}`; if (!socketConfig.subDomain) { logger.info(`[404]${requestLog}`); return destroy(tcpSocket); } const wt = ctx.domainMappings.get(socketConfig.subDomain); let domainSocket = null; if (!!wt) { domainSocket = wt.wsSocket; wt.tcpSocket = tcpSocket; } debug('mapping:', socketConfig.domain, socketConfig.subDomain, !!domainSocket); if (!domainSocket) { logger.info(`[404]${requestLog}`); return destroy(tcpSocket); } logger.info(requestLog); const requestId = doreamon_1.default.uuid() + '@' + new Date().getTime(); const id = tcpId + ':' + requestId; const _data = await utils_1.dataProcessor.server.request(data); domainSocket.emit('request', { id, data: _data, }); ctx.callbackContainer.set(tcpId, requestId, callback); }; tcpSocket.on('data', data => { const _data = data.toString(); request(socketConfig.tcpId, _data, (data) => { if (tcpSocket.writable) { const buffer = Buffer.from(data, 'base64'); debug('response:', buffer.toString('utf8')); tcpSocket.write(buffer); } }); }); tcpSocket.on('close', () => { ctx.callbackContainer.remove(socketConfig.tcpId); }); }); }; return { attach, }; } exports.default = createServer; function destroy(tcpSocket) { const data = [ 'HTTP/1.1 404 Not Found', 'Content-Type: text/plain; charset=utf-8', 'Content-Length: 9', `Date: ${new Date().toUTCString()}`, 'Connection: keep-alive', 'Keep-Alive: timeout=5', '', 'Not Found' ]; tcpSocket.write(data.join('\r\n')); tcpSocket.destroy(); }