Merge pull request #1 from CUBETIQ/ts
Reflecting from JavaScript to TypeScript
This commit is contained in:
commit
4fbcf1f82c
1
.gitignore
vendored
1
.gitignore
vendored
@ -1,2 +1,3 @@
|
|||||||
node_modules/
|
node_modules/
|
||||||
npm-debug.log
|
npm-debug.log
|
||||||
|
dist/
|
2
.npmignore
Normal file
2
.npmignore
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
src/
|
||||||
|
.github/
|
2
bin/hlt
2
bin/hlt
@ -1,3 +1,3 @@
|
|||||||
#!/usr/bin/env node
|
#!/usr/bin/env node
|
||||||
|
|
||||||
require('../client');
|
require('../dist/client');
|
156
lib.js
156
lib.js
@ -1,156 +0,0 @@
|
|||||||
const stream = require("stream");
|
|
||||||
|
|
||||||
class TunnelRequest extends stream.Readable {
|
|
||||||
constructor({ socket, requestId }) {
|
|
||||||
super();
|
|
||||||
this._socket = socket;
|
|
||||||
this._requestId = requestId;
|
|
||||||
|
|
||||||
const onRequestPipe = (requestId, data) => {
|
|
||||||
if (this._requestId === requestId) {
|
|
||||||
this.push(data);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const onRequestPipes = (requestId, data) => {
|
|
||||||
if (this._requestId === requestId) {
|
|
||||||
data.forEach((chunk) => {
|
|
||||||
this.push(chunk);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const onRequestPipeError = (requestId, error) => {
|
|
||||||
if (this._requestId === requestId) {
|
|
||||||
this._socket.off("request-pipe", onRequestPipe);
|
|
||||||
this._socket.off("request-pipes", onRequestPipes);
|
|
||||||
this._socket.off("request-pipe-error", onRequestPipeError);
|
|
||||||
this._socket.off("request-pipe-end", onRequestPipeEnd);
|
|
||||||
this.destroy(new Error(error));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const onRequestPipeEnd = (requestId, data) => {
|
|
||||||
if (this._requestId === requestId) {
|
|
||||||
this._socket.off("request-pipe", onRequestPipe);
|
|
||||||
this._socket.off("request-pipes", onRequestPipes);
|
|
||||||
this._socket.off("request-pipe-error", onRequestPipeError);
|
|
||||||
this._socket.off("request-pipe-end", onRequestPipeEnd);
|
|
||||||
if (data) {
|
|
||||||
this.push(data);
|
|
||||||
}
|
|
||||||
this.push(null);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
this._socket.on("request-pipe", onRequestPipe);
|
|
||||||
this._socket.on("request-pipes", onRequestPipes);
|
|
||||||
this._socket.on("request-pipe-error", onRequestPipeError);
|
|
||||||
this._socket.on("request-pipe-end", onRequestPipeEnd);
|
|
||||||
}
|
|
||||||
|
|
||||||
_read() { }
|
|
||||||
}
|
|
||||||
|
|
||||||
class TunnelResponse extends stream.Duplex {
|
|
||||||
constructor({ socket, responseId, duplex }) {
|
|
||||||
super();
|
|
||||||
this._socket = socket;
|
|
||||||
this._responseId = responseId;
|
|
||||||
|
|
||||||
if (duplex) {
|
|
||||||
// for websocket request: bidirection
|
|
||||||
const onResponsePipe = (responseId, data) => {
|
|
||||||
if (this._responseId === responseId) {
|
|
||||||
this.push(data);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const onResponsePipes = (responseId, data) => {
|
|
||||||
if (this._responseId === responseId) {
|
|
||||||
data.forEach((chunk) => {
|
|
||||||
this.push(chunk);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const onResponsePipeError = (responseId, error) => {
|
|
||||||
if (this._responseId === responseId) {
|
|
||||||
this._socket.off("response-pipe", onResponsePipe);
|
|
||||||
this._socket.off("response-pipes", onResponsePipes);
|
|
||||||
this._socket.off("response-pipe-error", onResponsePipeError);
|
|
||||||
this._socket.off("response-pipe-end", onResponsePipeEnd);
|
|
||||||
this.destroy(new Error(error));
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
const onResponsePipeEnd = (responseId, data) => {
|
|
||||||
if (this._responseId === responseId) {
|
|
||||||
this._socket.off("response-pipe", onResponsePipe);
|
|
||||||
this._socket.off("response-pipes", onResponsePipes);
|
|
||||||
this._socket.off("response-pipe-error", onResponsePipeError);
|
|
||||||
this._socket.off("response-pipe-end", onResponsePipeEnd);
|
|
||||||
if (data) {
|
|
||||||
this.push(data);
|
|
||||||
}
|
|
||||||
this.push(null);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
this._socket.on("response-pipe", onResponsePipe);
|
|
||||||
this._socket.on("response-pipes", onResponsePipes);
|
|
||||||
this._socket.on("response-pipe-error", onResponsePipeError);
|
|
||||||
this._socket.on("response-pipe-end", onResponsePipeEnd);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
_write(chunk, encoding, callback) {
|
|
||||||
this._socket.emit("response-pipe", this._responseId, chunk);
|
|
||||||
this._socket.io.engine.once("drain", () => {
|
|
||||||
callback();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
_writev(chunks, callback) {
|
|
||||||
this._socket.emit("response-pipes", this._responseId, chunks);
|
|
||||||
this._socket.io.engine.once("drain", () => {
|
|
||||||
callback();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
_final(callback) {
|
|
||||||
this._socket.emit("response-pipe-end", this._responseId);
|
|
||||||
this._socket.io.engine.once("drain", () => {
|
|
||||||
callback();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
_destroy(e, callback) {
|
|
||||||
if (e) {
|
|
||||||
this._socket.emit(
|
|
||||||
"response-pipe-error",
|
|
||||||
this._responseId,
|
|
||||||
e && e.message
|
|
||||||
);
|
|
||||||
this._socket.io.engine.once("drain", () => {
|
|
||||||
callback();
|
|
||||||
});
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
callback();
|
|
||||||
}
|
|
||||||
|
|
||||||
writeHead(statusCode, statusMessage, headers, httpVersion) {
|
|
||||||
this._socket.emit("response", this._responseId, {
|
|
||||||
statusCode,
|
|
||||||
statusMessage,
|
|
||||||
headers,
|
|
||||||
httpVersion,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
_read(size) { }
|
|
||||||
}
|
|
||||||
|
|
||||||
exports.TunnelRequest = TunnelRequest;
|
|
||||||
exports.TunnelResponse = TunnelResponse;
|
|
1219
package-lock.json
generated
1219
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
12
package.json
12
package.json
@ -1,13 +1,14 @@
|
|||||||
{
|
{
|
||||||
"name": "@cubetiq/hlt",
|
"name": "@cubetiq/hlt",
|
||||||
"version": "0.0.9",
|
"version": "0.1.0",
|
||||||
"description": "A lightweight http tunnel client using nodejs and socket.io client",
|
"description": "A lightweight http tunnel client using nodejs and socket.io client",
|
||||||
"main": "client.js",
|
"main": "dist/client.js",
|
||||||
"bin": {
|
"bin": {
|
||||||
"hlt": "bin/hlt"
|
"hlt": "bin/hlt"
|
||||||
},
|
},
|
||||||
"scripts": {
|
"scripts": {
|
||||||
"start": "node client.js"
|
"start": "ts-node-dev --respawn --transpile-only src/client.ts",
|
||||||
|
"build": "tsc"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
@ -27,5 +28,10 @@
|
|||||||
},
|
},
|
||||||
"publishConfig": {
|
"publishConfig": {
|
||||||
"access": "public"
|
"access": "public"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/node": "^18.0.3",
|
||||||
|
"ts-node-dev": "^2.0.0",
|
||||||
|
"typescript": "^4.7.4"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,16 +1,17 @@
|
|||||||
const os = require("os");
|
import * as os from "os";
|
||||||
const fs = require("fs");
|
import * as fs from "fs";
|
||||||
const path = require("path");
|
import * as path from "path";
|
||||||
const http = require("http");
|
import * as http from "http";
|
||||||
const { io } = require("socket.io-client");
|
import { io } from "socket.io-client";
|
||||||
const HttpsProxyAgent = require("https-proxy-agent");
|
import { HttpsProxyAgent } from "https-proxy-agent";
|
||||||
const { program, InvalidArgumentError, Argument } = require("commander");
|
import { program, InvalidArgumentError, Argument } from "commander";
|
||||||
const { TunnelRequest, TunnelResponse } = require("./lib");
|
import { TunnelRequest, TunnelResponse } from "./lib";
|
||||||
const { generateUUID, addPrefixOnHttpSchema } = require("./util");
|
import { generateUUID, addPrefixOnHttpSchema } from "./util";
|
||||||
|
import { Socket } from 'socket.io-client';
|
||||||
|
|
||||||
const sdk = require("./sdk");
|
import { getTokenFree } from './sdk'
|
||||||
|
|
||||||
const packageInfo = require("./package.json");
|
const packageInfo = require("../package.json");
|
||||||
|
|
||||||
// constants
|
// constants
|
||||||
const PROFILE_DEFAULT = "default";
|
const PROFILE_DEFAULT = "default";
|
||||||
@ -19,7 +20,7 @@ const SERVER_DEFAULT_URL = "https://lt.ctdn.net";
|
|||||||
const TOKEN_FREE = "FREE";
|
const TOKEN_FREE = "FREE";
|
||||||
|
|
||||||
// create socket instance
|
// create socket instance
|
||||||
let socket = null;
|
let socket: Socket | null = null;
|
||||||
|
|
||||||
function keepAlive() {
|
function keepAlive() {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
@ -30,7 +31,7 @@ function keepAlive() {
|
|||||||
}, 5000);
|
}, 5000);
|
||||||
}
|
}
|
||||||
|
|
||||||
function initClient(options) {
|
function initClient(options: any) {
|
||||||
// Please change this if your domain goes wrong here
|
// Please change this if your domain goes wrong here
|
||||||
// Current style using sub-domain: https://{{clientId}}-tunnel.myhostingdomain.com
|
// Current style using sub-domain: https://{{clientId}}-tunnel.myhostingdomain.com
|
||||||
// (Original server: https://tunnel.myhostingdomain.com)
|
// (Original server: https://tunnel.myhostingdomain.com)
|
||||||
@ -66,7 +67,7 @@ function initClient(options) {
|
|||||||
release: os.release(),
|
release: os.release(),
|
||||||
};
|
};
|
||||||
|
|
||||||
const initParams = {
|
const initParams: any = {
|
||||||
path: "/$cubetiq_http_tunnel",
|
path: "/$cubetiq_http_tunnel",
|
||||||
transports: ["websocket"],
|
transports: ["websocket"],
|
||||||
auth: {
|
auth: {
|
||||||
@ -91,7 +92,7 @@ function initClient(options) {
|
|||||||
|
|
||||||
const clientLogPrefix = `client: ${clientId} on profile: ${profile}`;
|
const clientLogPrefix = `client: ${clientId} on profile: ${profile}`;
|
||||||
socket.on("connect", () => {
|
socket.on("connect", () => {
|
||||||
if (socket.connected) {
|
if (socket!.connected) {
|
||||||
console.log(`${clientLogPrefix} is connected to server successfully!`);
|
console.log(`${clientLogPrefix} is connected to server successfully!`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -112,7 +113,7 @@ function initClient(options) {
|
|||||||
|
|
||||||
socket.on("disconnect_exit", (reason) => {
|
socket.on("disconnect_exit", (reason) => {
|
||||||
console.log(`${clientLogPrefix} disconnected and exited ${reason}!`);
|
console.log(`${clientLogPrefix} disconnected and exited ${reason}!`);
|
||||||
socket.disconnect();
|
socket?.disconnect();
|
||||||
process.exit(1);
|
process.exit(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -126,15 +127,12 @@ function initClient(options) {
|
|||||||
request.headers.host = options.origin;
|
request.headers.host = options.origin;
|
||||||
}
|
}
|
||||||
|
|
||||||
const tunnelRequest = new TunnelRequest({
|
const tunnelRequest = new TunnelRequest(socket!, requestId);
|
||||||
requestId,
|
|
||||||
socket: socket,
|
|
||||||
});
|
|
||||||
|
|
||||||
const localReq = http.request(request);
|
const localReq = http.request(request);
|
||||||
tunnelRequest.pipe(localReq);
|
tunnelRequest.pipe(localReq);
|
||||||
|
|
||||||
const onTunnelRequestError = (e) => {
|
const onTunnelRequestError = (e: any) => {
|
||||||
tunnelRequest.off("end", onTunnelRequestEnd);
|
tunnelRequest.off("end", onTunnelRequestEnd);
|
||||||
localReq.destroy(e);
|
localReq.destroy(e);
|
||||||
};
|
};
|
||||||
@ -146,17 +144,14 @@ function initClient(options) {
|
|||||||
tunnelRequest.once("error", onTunnelRequestError);
|
tunnelRequest.once("error", onTunnelRequestError);
|
||||||
tunnelRequest.once("end", onTunnelRequestEnd);
|
tunnelRequest.once("end", onTunnelRequestEnd);
|
||||||
|
|
||||||
const onLocalResponse = (localRes) => {
|
const onLocalResponse = (localRes: any) => {
|
||||||
localReq.off("error", onLocalError);
|
localReq.off("error", onLocalError);
|
||||||
|
|
||||||
if (isWebSocket && localRes.upgrade) {
|
if (isWebSocket && localRes.upgrade) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
const tunnelResponse = new TunnelResponse({
|
const tunnelResponse = new TunnelResponse(socket!, requestId);
|
||||||
responseId: requestId,
|
|
||||||
socket: socket,
|
|
||||||
});
|
|
||||||
|
|
||||||
tunnelResponse.writeHead(
|
tunnelResponse.writeHead(
|
||||||
localRes.statusCode,
|
localRes.statusCode,
|
||||||
@ -168,23 +163,18 @@ function initClient(options) {
|
|||||||
localRes.pipe(tunnelResponse);
|
localRes.pipe(tunnelResponse);
|
||||||
};
|
};
|
||||||
|
|
||||||
const onLocalError = (error) => {
|
const onLocalError = (error: any) => {
|
||||||
console.log(error);
|
console.log(error);
|
||||||
localReq.off("response", onLocalResponse);
|
localReq.off("response", onLocalResponse);
|
||||||
socket.emit("request-error", requestId, error && error.message);
|
socket?.emit("request-error", requestId, error && error.message);
|
||||||
tunnelRequest.destroy(error);
|
tunnelRequest.destroy(error);
|
||||||
};
|
};
|
||||||
|
|
||||||
const onUpgrade = (localRes, localSocket, localHead) => {
|
const onUpgrade = (localRes: any, localSocket: any, localHead: any) => {
|
||||||
// localSocket.once('error', onTunnelRequestError);
|
// localSocket.once('error', onTunnelRequestError);
|
||||||
if (localHead && localHead.length) localSocket.unshift(localHead);
|
if (localHead && localHead.length) localSocket.unshift(localHead);
|
||||||
|
|
||||||
const tunnelResponse = new TunnelResponse({
|
const tunnelResponse = new TunnelResponse(socket!, requestId, true);
|
||||||
responseId: requestId,
|
|
||||||
socket: socket,
|
|
||||||
duplex: true,
|
|
||||||
});
|
|
||||||
|
|
||||||
tunnelResponse.writeHead(null, null, localRes.headers);
|
tunnelResponse.writeHead(null, null, localRes.headers);
|
||||||
localSocket.pipe(tunnelResponse).pipe(localSocket);
|
localSocket.pipe(tunnelResponse).pipe(localSocket);
|
||||||
};
|
};
|
||||||
@ -200,7 +190,7 @@ function initClient(options) {
|
|||||||
// reconnect manually
|
// reconnect manually
|
||||||
const tryReconnect = () => {
|
const tryReconnect = () => {
|
||||||
setTimeout(() => {
|
setTimeout(() => {
|
||||||
socket.io.open((err) => {
|
socket!.io.open((err) => {
|
||||||
if (err) {
|
if (err) {
|
||||||
tryReconnect();
|
tryReconnect();
|
||||||
}
|
}
|
||||||
@ -245,7 +235,7 @@ program
|
|||||||
console.log(`config file ${configDir} was created`);
|
console.log(`config file ${configDir} was created`);
|
||||||
}
|
}
|
||||||
|
|
||||||
let config = {};
|
let config: any = {};
|
||||||
const configFilename = `${options.profile}.json`;
|
const configFilename = `${options.profile}.json`;
|
||||||
const configFilePath = path.resolve(configDir, configFilename);
|
const configFilePath = path.resolve(configDir, configFilename);
|
||||||
|
|
||||||
@ -275,9 +265,8 @@ program
|
|||||||
|
|
||||||
if (!config.token) {
|
if (!config.token) {
|
||||||
console.log("Generating token...");
|
console.log("Generating token...");
|
||||||
await sdk
|
await getTokenFree(config.server)
|
||||||
.getTokenFree(config.server)
|
.then((resp: any) => {
|
||||||
.then((resp) => {
|
|
||||||
if (resp.data?.token) {
|
if (resp.data?.token) {
|
||||||
config.token = resp.data?.token;
|
config.token = resp.data?.token;
|
||||||
} else {
|
} else {
|
||||||
@ -285,7 +274,7 @@ program
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err: any) => {
|
||||||
console.error("cannot get free token from server", err);
|
console.error("cannot get free token from server", err);
|
||||||
return;
|
return;
|
||||||
});
|
});
|
||||||
@ -327,7 +316,7 @@ program
|
|||||||
fs.mkdirSync(configDir);
|
fs.mkdirSync(configDir);
|
||||||
}
|
}
|
||||||
|
|
||||||
let config = {};
|
let config: any = {};
|
||||||
const configFilename = `${options.profile}.json`;
|
const configFilename = `${options.profile}.json`;
|
||||||
const configFilePath = path.resolve(configDir, configFilename);
|
const configFilePath = path.resolve(configDir, configFilename);
|
||||||
|
|
||||||
@ -399,7 +388,7 @@ program
|
|||||||
console.log(`config file ${configDir} was created`);
|
console.log(`config file ${configDir} was created`);
|
||||||
}
|
}
|
||||||
|
|
||||||
let config = {};
|
let config: any = {};
|
||||||
const configFilename = `${options.profile}.json`;
|
const configFilename = `${options.profile}.json`;
|
||||||
const configFilePath = path.resolve(configDir, configFilename);
|
const configFilePath = path.resolve(configDir, configFilename);
|
||||||
|
|
||||||
@ -429,9 +418,8 @@ program
|
|||||||
|
|
||||||
// FREE
|
// FREE
|
||||||
if (config.access === TOKEN_FREE) {
|
if (config.access === TOKEN_FREE) {
|
||||||
await sdk
|
await getTokenFree(config.server)
|
||||||
.getTokenFree(config.server)
|
.then((resp: any) => {
|
||||||
.then((resp) => {
|
|
||||||
if (resp.data?.token) {
|
if (resp.data?.token) {
|
||||||
config.token = resp.data?.token;
|
config.token = resp.data?.token;
|
||||||
} else {
|
} else {
|
||||||
@ -439,7 +427,7 @@ program
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch((err) => {
|
.catch((err: any) => {
|
||||||
console.error("cannot get free token from server", err);
|
console.error("cannot get free token from server", err);
|
||||||
return;
|
return;
|
||||||
});
|
});
|
||||||
@ -480,7 +468,7 @@ program
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
let config = {};
|
let config: any = {};
|
||||||
const configFilename = `${options.profile}.json`;
|
const configFilename = `${options.profile}.json`;
|
||||||
const configFilePath = path.resolve(configDir, configFilename);
|
const configFilePath = path.resolve(configDir, configFilename);
|
||||||
|
|
165
src/lib.ts
Normal file
165
src/lib.ts
Normal file
@ -0,0 +1,165 @@
|
|||||||
|
import * as stream from "stream";
|
||||||
|
import { Socket } from 'socket.io-client';
|
||||||
|
|
||||||
|
class TunnelRequest extends stream.Readable {
|
||||||
|
constructor(private socket: Socket, private requestId: string) {
|
||||||
|
super();
|
||||||
|
|
||||||
|
const onRequestPipe = (requestId: string, data: any) => {
|
||||||
|
if (this.requestId === requestId) {
|
||||||
|
this.push(data);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const onRequestPipes = (requestId: string, data: any) => {
|
||||||
|
if (!data) return;
|
||||||
|
if (this.requestId === requestId) {
|
||||||
|
data.forEach((chunk: any) => {
|
||||||
|
this.push(chunk);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const onRequestPipeError = (requestId: string, error?: any) => {
|
||||||
|
if (this.requestId === requestId) {
|
||||||
|
this.socket.off("request-pipe", onRequestPipe);
|
||||||
|
this.socket.off("request-pipes", onRequestPipes);
|
||||||
|
this.socket.off("request-pipe-error", onRequestPipeError);
|
||||||
|
this.socket.off("request-pipe-end", onRequestPipeEnd);
|
||||||
|
this.destroy(new Error(error));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const onRequestPipeEnd = (requestId: string, data: any) => {
|
||||||
|
if (this.requestId === requestId) {
|
||||||
|
this.socket.off("request-pipe", onRequestPipe);
|
||||||
|
this.socket.off("request-pipes", onRequestPipes);
|
||||||
|
this.socket.off("request-pipe-error", onRequestPipeError);
|
||||||
|
this.socket.off("request-pipe-end", onRequestPipeEnd);
|
||||||
|
if (data) {
|
||||||
|
this.push(data);
|
||||||
|
}
|
||||||
|
this.push(null);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
this.socket.on("request-pipe", onRequestPipe);
|
||||||
|
this.socket.on("request-pipes", onRequestPipes);
|
||||||
|
this.socket.on("request-pipe-error", onRequestPipeError);
|
||||||
|
this.socket.on("request-pipe-end", onRequestPipeEnd);
|
||||||
|
}
|
||||||
|
|
||||||
|
_read() { }
|
||||||
|
}
|
||||||
|
|
||||||
|
class TunnelResponse extends stream.Duplex {
|
||||||
|
constructor(private socket: Socket, private responseId: string, duplex?: boolean) {
|
||||||
|
super();
|
||||||
|
|
||||||
|
if (duplex) {
|
||||||
|
// for websocket request: bidirection
|
||||||
|
const onResponsePipe = (responseId: string, data: any) => {
|
||||||
|
if (this.responseId === responseId) {
|
||||||
|
this.push(data);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const onResponsePipes = (responseId: string, data: any) => {
|
||||||
|
if (this.responseId === responseId) {
|
||||||
|
data.forEach((chunk: any) => {
|
||||||
|
this.push(chunk);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const onResponsePipeError = (responseId: string, error?: any) => {
|
||||||
|
if (this.responseId === responseId) {
|
||||||
|
this.socket.off("response-pipe", onResponsePipe);
|
||||||
|
this.socket.off("response-pipes", onResponsePipes);
|
||||||
|
this.socket.off("response-pipe-error", onResponsePipeError);
|
||||||
|
this.socket.off("response-pipe-end", onResponsePipeEnd);
|
||||||
|
this.destroy(new Error(error));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
const onResponsePipeEnd = (responseId: string, data: any) => {
|
||||||
|
if (this.responseId === responseId) {
|
||||||
|
this.socket.off("response-pipe", onResponsePipe);
|
||||||
|
this.socket.off("response-pipes", onResponsePipes);
|
||||||
|
this.socket.off("response-pipe-error", onResponsePipeError);
|
||||||
|
this.socket.off("response-pipe-end", onResponsePipeEnd);
|
||||||
|
if (data) {
|
||||||
|
this.push(data);
|
||||||
|
}
|
||||||
|
this.push(null);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
this.socket.on("response-pipe", onResponsePipe);
|
||||||
|
this.socket.on("response-pipes", onResponsePipes);
|
||||||
|
this.socket.on("response-pipe-error", onResponsePipeError);
|
||||||
|
this.socket.on("response-pipe-end", onResponsePipeEnd);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
_write(chunk: any, encoding: BufferEncoding, callback: (error?: Error | null) => void) {
|
||||||
|
this.socket.emit("response-pipe", this.responseId, chunk);
|
||||||
|
this.socket.io.engine.once("drain", () => {
|
||||||
|
callback && callback();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
_writev(
|
||||||
|
chunks: Array<{
|
||||||
|
chunk: any;
|
||||||
|
encoding: BufferEncoding;
|
||||||
|
}>,
|
||||||
|
callback: (error?: Error | null) => void) {
|
||||||
|
this.socket.emit("response-pipes", this.responseId, chunks);
|
||||||
|
this.socket.io.engine.once("drain", () => {
|
||||||
|
callback();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
_final(callback: (error?: Error | null) => void) {
|
||||||
|
this.socket.emit("response-pipe-end", this.responseId);
|
||||||
|
this.socket.io.engine.once("drain", () => {
|
||||||
|
callback();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
_destroy(error: Error | null, callback: (error: Error | null) => void) {
|
||||||
|
if (error) {
|
||||||
|
this.socket.emit(
|
||||||
|
"response-pipe-error",
|
||||||
|
this.responseId,
|
||||||
|
error && error.message
|
||||||
|
);
|
||||||
|
|
||||||
|
this.socket.io.engine.once("drain", () => {
|
||||||
|
callback(error);
|
||||||
|
});
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
callback(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
writeHead(statusCode: any, statusMessage?: any, headers?: any, httpVersion?: any) {
|
||||||
|
this.socket.emit("response", this.responseId, {
|
||||||
|
statusCode,
|
||||||
|
statusMessage,
|
||||||
|
headers,
|
||||||
|
httpVersion,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
_read(size: number) { }
|
||||||
|
}
|
||||||
|
|
||||||
|
export {
|
||||||
|
TunnelRequest,
|
||||||
|
TunnelResponse
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
const axios = require("axios").default;
|
const axios = require("axios").default;
|
||||||
|
|
||||||
const getTokenFree = async (baseUrl, data = {}) => {
|
const getTokenFree = async (baseUrl: string, data: any = {}) => {
|
||||||
const url = `${baseUrl}/__free__/api/get_token`;
|
const url = `${baseUrl}/__free__/api/get_token`;
|
||||||
return axios({
|
return axios({
|
||||||
method: "POST",
|
method: "POST",
|
||||||
@ -14,6 +14,6 @@ const getTokenFree = async (baseUrl, data = {}) => {
|
|||||||
});
|
});
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = {
|
export {
|
||||||
getTokenFree,
|
getTokenFree,
|
||||||
};
|
};
|
@ -1,6 +1,6 @@
|
|||||||
const crypto = require("crypto");
|
import * as crypto from "crypto";
|
||||||
|
|
||||||
const addPrefixOnHttpSchema = (url, prefixDomain) => {
|
const addPrefixOnHttpSchema = (url: string, prefixDomain: string) => {
|
||||||
let prefixSubDomain = prefixDomain;
|
let prefixSubDomain = prefixDomain;
|
||||||
const prefixSchema = url.substring(0, url.indexOf("://") + 3);
|
const prefixSchema = url.substring(0, url.indexOf("://") + 3);
|
||||||
const splitDomain = url.substring(url.indexOf("://") + 3);
|
const splitDomain = url.substring(url.indexOf("://") + 3);
|
||||||
@ -16,4 +16,4 @@ const generateUUID = () => {
|
|||||||
return crypto.randomUUID();
|
return crypto.randomUUID();
|
||||||
};
|
};
|
||||||
|
|
||||||
module.exports = { addPrefixOnHttpSchema, generateUUID };
|
export { addPrefixOnHttpSchema, generateUUID };
|
14
tsconfig.json
Normal file
14
tsconfig.json
Normal file
@ -0,0 +1,14 @@
|
|||||||
|
{
|
||||||
|
"compilerOptions": {
|
||||||
|
"lib": ["ES2015"],
|
||||||
|
"target": "es5",
|
||||||
|
|
||||||
|
"module": "commonjs",
|
||||||
|
"moduleResolution": "node",
|
||||||
|
"sourceMap": false,
|
||||||
|
"outDir": "dist",
|
||||||
|
"forceConsistentCasingInFileNames": true,
|
||||||
|
"strict": true,
|
||||||
|
"skipLibCheck": true
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user