142 lines
5.5 KiB
JavaScript
142 lines
5.5 KiB
JavaScript
|
const fs = require('fs');
|
||
|
const http = require('http');
|
||
|
const httpProxy = require('http-proxy');
|
||
|
const HyperDHTServer = require('hyperdht');
|
||
|
const libNet = require('hyper-cmd-lib-net');
|
||
|
const goodbye = require('graceful-goodbye');
|
||
|
const libKeys = require('hyper-cmd-lib-keys');
|
||
|
const b32 = require("hi-base32");
|
||
|
const net = require("net");
|
||
|
const pump = require("pump");
|
||
|
let invalid = false;
|
||
|
|
||
|
let mod = 0;
|
||
|
const tunnels = {};
|
||
|
const agent = new http.Agent({ maxSockets: Number.MAX_VALUE });
|
||
|
const content = fs.readFileSync('404.txt', 'utf8');
|
||
|
const DEBUG = 0; // Set DEBUG to 1 to enable debug mode
|
||
|
// Enabling DEBUG mode will slow down the code, please only enable this if you need
|
||
|
// Information about connections coming in because you need to validate connection hashes.
|
||
|
|
||
|
const startServer = async () => {
|
||
|
console.log("Creating HyperDHT server...");
|
||
|
const dhtServer = new HyperDHTServer();
|
||
|
await dhtServer.ready();
|
||
|
console.log("HyperDHT server created and ready.");
|
||
|
|
||
|
const proxy = httpProxy.createProxyServer({
|
||
|
ws: true,
|
||
|
agent: agent,
|
||
|
timeout: 360000
|
||
|
});
|
||
|
|
||
|
const server = http.createServer(async function (req, res) {
|
||
|
try {
|
||
|
console.log("Incoming HTTP request...");
|
||
|
const split = req.headers.host.split('.');
|
||
|
if (DEBUG === 1) console.log("Request Headers Host Split: ", split);
|
||
|
const publicKey = Buffer.from(b32.decode.asBytes(split[0].toUpperCase()));
|
||
|
if (DEBUG === 1) {
|
||
|
console.log("Public Key Buffer: ", publicKey);
|
||
|
console.log("Length: " + publicKey.length);
|
||
|
}
|
||
|
if (!(publicKey.length >= 32)) {
|
||
|
console.log("Invalid Connection!")
|
||
|
res.writeHead(404, { 'Content-Type': 'text/html' });
|
||
|
res.end(content);
|
||
|
invalid = true
|
||
|
} else {
|
||
|
invalid = false
|
||
|
}
|
||
|
if (invalid == true) return
|
||
|
if (!tunnels[publicKey]) {
|
||
|
console.log("No tunnel found for public key, creating new tunnel...");
|
||
|
const port = 1337 + ((mod++) % 1000);
|
||
|
const server = net.createServer(function (servsock) {
|
||
|
console.log('Incoming Connection, Connecting to:', publicKey.toString('hex'));
|
||
|
if (DEBUG === 1) console.log("Public Key Length: ", publicKey.toString('hex').length);
|
||
|
const socket = dhtServer.connect(publicKey);
|
||
|
|
||
|
const local = servsock;
|
||
|
let open = { local: true, remote: true };
|
||
|
local.on('data', (d) => {
|
||
|
if (DEBUG === 1) console.log("Local Data: ", d);
|
||
|
socket.write(d);
|
||
|
});
|
||
|
socket.on('data', (d) => {
|
||
|
if (DEBUG === 1) console.log("Socket Data: ", d);
|
||
|
local.write(d);
|
||
|
});
|
||
|
|
||
|
const remoteend = (type) => {
|
||
|
if (DEBUG === 1) console.log('Local Connection Ended, Ending Remote Connection');
|
||
|
if (open.remote) socket.end();
|
||
|
open.remote = false;
|
||
|
};
|
||
|
|
||
|
const localend = (type) => {
|
||
|
if (DEBUG === 1) console.log('Remote Connection Ended, Ending Local Connection');
|
||
|
if (open.local) local.end();
|
||
|
open.local = false;
|
||
|
};
|
||
|
|
||
|
local.on('error', remoteend);
|
||
|
local.on('finish', remoteend);
|
||
|
local.on('end', remoteend);
|
||
|
socket.on('finish', localend);
|
||
|
socket.on('error', localend);
|
||
|
socket.on('end', localend);
|
||
|
});
|
||
|
|
||
|
server.listen(port, "127.0.0.1");
|
||
|
tunnels[publicKey] = port;
|
||
|
console.log("New tunnel created. Public Key:", publicKey, "Port:", port);
|
||
|
proxy.web(req, res, {
|
||
|
target: 'http://127.0.0.1:' + port
|
||
|
}, function (e) {
|
||
|
console.log("Proxy Web Error: ", e);
|
||
|
res.writeHead(404, { 'Content-Type': 'text/html' });
|
||
|
res.end(content);
|
||
|
});
|
||
|
return;
|
||
|
} else {
|
||
|
console.log('Tunnel exists for public key:', publicKey);
|
||
|
proxy.web(req, res, {
|
||
|
target: 'http://127.0.0.1:' + tunnels[publicKey]
|
||
|
}, function (e) {
|
||
|
console.log("Proxy Web Error: ", e);
|
||
|
res.writeHead(404, { 'Content-Type': 'text/html' });
|
||
|
res.end(content);
|
||
|
});
|
||
|
}
|
||
|
} catch (e) {
|
||
|
console.error("Error Occurred: ", e);
|
||
|
}
|
||
|
});
|
||
|
|
||
|
server.on('upgrade', function (req, socket, head) {
|
||
|
console.log('Upgrade Request');
|
||
|
const split = req.headers.host.split('.');
|
||
|
const publicKey = Buffer.from(b32.decode.asBytes(split[0].toUpperCase()));
|
||
|
proxy.ws(req, socket, {
|
||
|
target: 'http://127.0.0.1:' + tunnels[publicKey]
|
||
|
}, function (e) {
|
||
|
console.error("Proxy WS Error: ", e);
|
||
|
socket.end();
|
||
|
});
|
||
|
});
|
||
|
|
||
|
server.listen(8081);
|
||
|
console.log("HTTP server listening on port 8081");
|
||
|
|
||
|
process.on('SIGINT', function () {
|
||
|
console.log("Shutting down...");
|
||
|
server.close();
|
||
|
dhtServer.destroy();
|
||
|
console.log("Shutdown complete.");
|
||
|
process.exit();
|
||
|
});
|
||
|
};
|
||
|
|
||
|
startServer().catch(console.error);
|