UNPKG

@soubhikchatterjee/tunnel-agent

Version:
132 lines (120 loc) 3.98 kB
"use strict"; const { io } = require("socket.io-client"); const HttpsProxyAgent = require("https-proxy-agent"); const { TunnelRequest, TunnelResponse } = require("./stream.helper"); const http = require("http"); const { version } = require("../package.json"); let socket = null; function keepAlive() { setTimeout(() => { if (socket && socket.connected) { socket.send("ping"); } keepAlive(); }, 5000); } function initClient(options) { const initParams = { path: "/$web_tunnel", transports: ["websocket"], auth: { token: options.jwtToken, }, extraHeaders: {}, }; if (options.path) { initParams.extraHeaders["path-prefix"] = options.path; } const http_proxy = process.env.https_proxy || process.env.http_proxy; if (http_proxy) { initParams.agent = new HttpsProxyAgent(http_proxy); } socket = io(options.server, initParams); socket.on("connect", () => { if (socket.connected) { console.log(` ▀▀█▀▀ █░░█ █▀▀▄ █▀▀▄ █▀▀ █░░   ░█▀▀█ █▀▀▀ █▀▀ █▀▀▄ ▀▀█▀▀ ░▒█░░ █░░█ █░░█ █░░█ █▀▀ █░░   ▒█▄▄█ █░▀█ █▀▀ █░░█ ░░█░░ ░▒█░░ ░▀▀▀ ▀░░▀ ▀░░▀ ▀▀▀ ▀▀▀   ▒█░▒█ ▀▀▀▀ ▀▀▀ ▀░░▀ ░░▀░░ `); console.log(`Version ${version}`); console.log("\n\n"); console.log("You url is ready at:"); console.log(options.server); console.log("\n"); } }); socket.on("connect_error", (e) => { console.log("Error: ", e && e.message); }); socket.on("disconnect", () => { console.log("client disconnected"); }); socket.on("request", (requestId, request) => { const isWebSocket = request.headers.upgrade === "websocket"; console.log(`${isWebSocket ? "WS" : request.method}: `, request.path); request.port = options.port; request.hostname = options.host; if (options.origin) { request.headers.host = options.origin; } const tunnelRequest = new TunnelRequest({ requestId, socket: socket, }); const localReq = http.request(request); tunnelRequest.pipe(localReq); const onTunnelRequestError = (e) => { tunnelRequest.off("end", onTunnelRequestEnd); localReq.destroy(e); }; const onTunnelRequestEnd = () => { tunnelRequest.off("error", onTunnelRequestError); }; tunnelRequest.once("error", onTunnelRequestError); tunnelRequest.once("end", onTunnelRequestEnd); const onLocalResponse = (localRes) => { localReq.off("error", onLocalError); if (isWebSocket && localRes.upgrade) { return; } const tunnelResponse = new TunnelResponse({ responseId: requestId, socket: socket, }); tunnelResponse.writeHead( localRes.statusCode, localRes.statusMessage, localRes.headers, localRes.httpVersion ); localRes.pipe(tunnelResponse); }; const onLocalError = (error) => { console.log(error); localReq.off("response", onLocalResponse); socket.emit("request-error", requestId, error && error.message); tunnelRequest.destroy(error); }; const onUpgrade = (localRes, localSocket, localHead) => { if (localHead && localHead.length) localSocket.unshift(localHead); const tunnelResponse = new TunnelResponse({ responseId: requestId, socket: socket, duplex: true, }); tunnelResponse.writeHead(null, null, localRes.headers); localSocket.pipe(tunnelResponse).pipe(localSocket); }; localReq.once("error", onLocalError); localReq.once("response", onLocalResponse); if (isWebSocket) { localReq.on("upgrade", onUpgrade); } }); keepAlive(); } module.exports = { keepAlive, initClient, };