95 lines
3.0 KiB
JavaScript
95 lines
3.0 KiB
JavaScript
const net = require("net");
|
|
const ws = require("ws");
|
|
const tls = require("tls");
|
|
|
|
const PORT = 8081;
|
|
const wss = new ws.WebSocketServer({ port: PORT });
|
|
|
|
const host = process.argv[2] || process.env['HOST'];
|
|
const port = process.argv[3] || process.env['PORT'];
|
|
if (!host || !port) {
|
|
console.error("Please specify host and port");
|
|
process.exit(1);
|
|
}
|
|
|
|
const log = process.env['NODE_ENV'] === 'development' ? console.log : () => {};
|
|
|
|
async function handleClient(ws) {
|
|
let serverSocket;
|
|
const upgradedStatus = { tls: false, secureSocket: null };
|
|
try {
|
|
serverSocket = net.connect({ host, port });
|
|
} catch (e) {
|
|
console.error(`Connect to remote failed: ${e}`);
|
|
ws.send(`Connect to remote failed: ${e}`);
|
|
ws.close();
|
|
return;
|
|
}
|
|
try {
|
|
serverSocket.on('error', (err) => {
|
|
console.error(`Connect to remote failed: ${err}`);
|
|
ws.send(`Connect to remote failed: ${err}`);
|
|
ws.close();
|
|
});
|
|
|
|
serverSocket.on('data', (data) => {
|
|
log("Plain. recv socket:", data);
|
|
if (!upgradedStatus.tls)
|
|
ws.send(data, { binary: true });
|
|
});
|
|
|
|
ws.on('message', (msg, isBinary) => {
|
|
log("Plain. recv ws:", msg);
|
|
if (!isBinary && msg == 'SSL') {
|
|
log("Upgrade to SSL");
|
|
// Upgrade to SSL/TLS
|
|
upgradedStatus.secureSocket = tls.connect({
|
|
socket: serverSocket,
|
|
rejectUnauthorized: false
|
|
});
|
|
|
|
upgradedStatus.secureSocket.on('secureConnect', () => {
|
|
const certificate = upgradedStatus.secureSocket.getPeerCertificate(true);
|
|
ws.send(certificate.raw, { binary: true });
|
|
upgradedStatus.tls = true;
|
|
});
|
|
|
|
upgradedStatus.secureSocket.on('data', (data) => {
|
|
log("Upgraded to SSL. Send ws:", data);
|
|
if (upgradedStatus.tls)
|
|
ws.send(data, { binary: true });
|
|
});
|
|
|
|
upgradedStatus.secureSocket.on('error', (error) => {
|
|
log("Upgraded to SSL. error:", error);
|
|
ws.close();
|
|
});
|
|
|
|
ws.on('message', (msg) => {
|
|
log("Upgraded to SSL. Send socket:", msg);
|
|
upgradedStatus.secureSocket.write(msg);
|
|
});
|
|
|
|
} else {
|
|
if (!upgradedStatus.tls)
|
|
serverSocket.write(msg);
|
|
}
|
|
});
|
|
|
|
ws.on('close', () => {
|
|
console.info('Client close');
|
|
serverSocket.end();
|
|
});
|
|
|
|
serverSocket.on('end', () => {
|
|
console.info('Server close');
|
|
ws.close();
|
|
});
|
|
} catch (error) {
|
|
console.error('An error occurred:', error);
|
|
ws.close();
|
|
}
|
|
}
|
|
|
|
wss.on('connection', handleClient);
|
|
console.log("Server is running on port " + PORT) |