UNPKG

@kloak-it/tq-proxy

Version:
214 lines (213 loc) 9.67 kB
"use strict"; /*! * Copyright 2018 CoNET Technology Inc. All Rights Reserved. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); const Compress = __importStar(require("./compressClient")); const Net = __importStar(require("net")); const res = __importStar(require("./res")); const Stream = __importStar(require("stream")); const Crypto = __importStar(require("crypto")); const log_1 = require("../GateWay/log"); const safe_1 = __importDefault(require("colors/safe")); const util_1 = require("util"); const Day = 1000 * 60 * 60 * 24; const otherRequestForNet = (path, host, port, UserAgent) => { if (path.length < 1024 + Math.round(Math.random() * 4000)) return `GET /${path} HTTP/1.1\r\n` + `Host: ${host}${port !== 80 ? ':' + port : ''}\r\n` + `Accept: */*\r\n` + `Accept-Language: en-ca\r\n` + `Connection: keep-alive\r\n` + `Accept-Encoding: gzip, deflate\r\n` + `User-Agent: ${UserAgent ? UserAgent : 'Mozilla/5.0'}\r\n\r\n`; return `POST /${Crypto.randomBytes(10 + Math.round(Math.random() * 1500)).toString('base64')} HTTP/1.1\r\n` + `Host: ${host}${port !== 80 ? ':' + port : ''}\r\n` + `User-Agent: ${UserAgent ? UserAgent : 'Mozilla/5.0'}\r\n\r\n` + `Content-Length: ${path.length}\r\n\r\n` + path + '\r\n\r\n'; }; class hostLookupResponse extends Stream.Writable { constructor(CallBack) { super(); this.CallBack = CallBack; } _write(chunk, enc, next) { //console.log ( `hostLookupResponse _write come [${ chunk.toString()}]`) const ns = chunk.toString('utf8'); try { const _ret = JSON.parse(ns); const ret = { expire: new Date().getTime() + Day, dns: _ret }; this.CallBack(null, ret); next(); return this.end(); } catch (e) { return next(e); } } } class gateWay { request(str, gateway) { return Buffer.from(otherRequestForNet(str, gateway.gateWayIpAddress, gateway.gateWayPort, this.userAgent)); } getCurrentGateway() { if (this.multipleGateway.length === 1) { return this.multipleGateway[0]; } if (++this.currentGatewayPoint > this.multipleGateway.length - 1) { this.currentGatewayPoint = 0; } return this.multipleGateway[this.currentGatewayPoint]; } constructor(multipleGateway, debug) { this.multipleGateway = multipleGateway; this.debug = debug; this.userAgent = null; this.currentGatewayPoint = 0; this.RemoteServerDistroyed = false; } hostLookup(hostName, userAgent, CallBack) { const _data = Buffer.from(JSON.stringify({ hostName: hostName })); const gateway = this.getCurrentGateway(); const id = safe_1.default.blue(`hostLookup`); const encrypt = new Compress.encryptStream(id, gateway.randomPassword, 3000, (str) => { return this.request(str, gateway); }, this.debug); const finish = new hostLookupResponse(CallBack); const httpBlock = new Compress.getDecryptClientStreamHttp(this.debug, id); const decrypt = new Compress.decryptStream(gateway.randomPassword, id, this.debug); (0, log_1.logger)(`try connect gateway server: [${gateway.gateWayIpAddress}:${gateway.gateWayPort}] password[${gateway.randomPassword}]`); const _socket = Net.createConnection(gateway.gateWayPort, gateway.gateWayIpAddress, () => { (0, log_1.logger)(`connected Gateway [${gateway.gateWayIpAddress}: ${gateway.gateWayPort}] doing encrypt.write ( _data )`); encrypt.write(_data); }); _socket.once('end', () => { //console.log ( `_socket.once end!` ) }); _socket.once('error', err => { return CallBack(err); }); httpBlock.once('error', err => { (0, log_1.logger)(`hostLookup httpBlock.on error`, err); _socket.end(res._HTTP_502); return CallBack(err); }); decrypt.once('err', err => { CallBack(err); }); encrypt.pipe(_socket).pipe(httpBlock).pipe(decrypt).pipe(finish); } requestGetWay(requestObj, uuuu, userAgent, socket) { // remote server was stoped if (this.RemoteServerDistroyed) { console.log(`requestGetWay this.RemoteServerDistroyed === true !`); return socket.end(res._HTTP_404); } this.userAgent = userAgent; const gateway = this.getCurrentGateway(); // remote gateway error if (!gateway) { return socket.end(res._HTTP_404); } let id = safe_1.default.yellow(`[${uuuu.uuid}]${uuuu.host}:${uuuu.port}->[Gateway ${gateway.gateWayIpAddress}:${gateway.gateWayPort}]`); const decrypt = new Compress.decryptStream(gateway.randomPassword, id, this.debug); const encrypt = new Compress.encryptStream(id, gateway.randomPassword, Math.random() * 500, (str) => { return this.request(str, gateway); }, this.debug); const httpBlock = new Compress.getDecryptClientStreamHttp(this.debug, id); httpBlock.once('error', err => { socket.end(res._HTTP_404); }); decrypt.once('error', err => { (0, log_1.logger)(safe_1.default.red(`requestGetWay decrypt [${id}] on error [${err.message}]`)); socket.end(res._HTTP_404); }); encrypt.once('end', () => { //console.log (`encrypt.once end` ) socket.end(res._HTTP_404); }); encrypt.once('error', err => { console.log(`requestGetWay [${id}] encrypt.once error`, err); socket.end(res._HTTP_404); }); if (this.debug) { (0, log_1.logger)(safe_1.default.red(`requestGetWay to [${gateway.gateWayIpAddress}:${gateway.gateWayPort}] for [${(0, util_1.inspect)(requestObj, false, 3, true)}]`)); (0, log_1.hexDebug)(Buffer.from(uuuu.buffer, 'base64')); } const connect = () => { if (!encrypt.writable) { return setTimeout(() => { (0, log_1.logger)(`!encrypt.writable waiting 200ms`, (0, util_1.inspect)(requestObj, false, 3, true)); return connect(); }, 200); } const _socket = Net.createConnection(gateway.gateWayPort || 80, gateway.gateWayIpAddress, () => { id = safe_1.default.blue(`[${_socket.localAddress}:${_socket.localPort}] `) + id; if (encrypt && encrypt.writable) { if (this.debug) { (0, log_1.logger)(safe_1.default.red(`${id} success to Gateway! send data now.`)); (0, log_1.hexDebug)(Buffer.from(uuuu.buffer, 'base64')); } return encrypt.write(Buffer.from(JSON.stringify(uuuu), 'utf8'), () => { socket.resume(); }); } (0, log_1.logger)(safe_1.default.red(`encryptStream writable false!`), (0, util_1.inspect)(requestObj, false, 3, true)); return socket.end(res._HTTP_404); }); _socket.once('error', err => { (0, log_1.logger)(safe_1.default.red(`Gateway server [${gateway.gateWayIpAddress}] on error ${safe_1.default.grey(err.message)}`)); socket.end(res._HTTP_404); }); _socket.once('end', () => { (0, log_1.logger)(safe_1.default.blue(`Gateway ${uuuu.uuid} on end()`)); socket.destroy(); }); socket.pipe(encrypt).pipe(_socket).pipe(httpBlock).pipe(decrypt).pipe(socket); }; return connect(); } } exports.default = gateWay;