Compare commits

...

1 Commits
master ... h

Author SHA1 Message Date
Lamp 409ab09790 rewrite attempt 12/13/21(?) not work 2022-01-17 17:43:38 -08:00
4 changed files with 109 additions and 63 deletions

View File

@ -1,54 +1,44 @@
var WebSocket = require('ws');
var {parse:parseQueryString} = require('query-string');
var wss = new WebSocket.Server({
port: process.env.OPENSHIFT_NODEJS_PORT || process.env.PORT || 8080
var http = require("http");
var https = require("https");
var server = http.createServer();
server.listen(process.env.OPENSHIFT_NODEJS_PORT || process.env.PORT || 8080);
server.on("request", function (req, res) {
res.writeHead(400);
res.end("Websockets only!");
});
var conncount = 0;
wss.on('connection', function (cws, req){
var number = conncount++;
console.log(`New connection #${number} from ${req.connection.remoteAddress} with ${req.url}`);
cws.on('close', function(){
console.log(`Closing connection #${number} from ${req.connection.remoteAddress}`);
server.on("upgrade", function (req, socket) {
if (req.headers["upgrade"] != "websocket") return socket.end("HTTP/1.1 400 Websocket upgrade only");
var xof = req.url.indexOf('?');
if (xof < 0) return socket.end("HTTP/1.1 400 Missing querystring");
var params = new URLSearchParams(req.url.substring(xof));
var targetURL = decodeURIComponent(params.get("target"));
if (!targetURL) return socket.end("HTTP/1.1 400 Target parameter is required");
targetURL = new URL(targetURL);
if (["https:","wss:"].includes(targetURL.protocol))
var secure = true;
else if (!["http:","ws:"].includes(targetURL.protocol))
return socket.end("HTTP/1.1 400 Unsupported target protocol");
targetURL.protocol = targetURL.protocol.replace("ws", "http");
var targetReq = (secure ? https : http).get(targetURL, {
headers: {
"Connection": "Upgrade",
"Upgrade": "websocket",
"Sec-WebSocket-Version": 13,
"Sec-WebSocket-Key": require('crypto').randomBytes(16).toString('base64')
}
});
var querystring = req.url.substr(1);
if (!querystring) return cws.close();
var params = parseQueryString(querystring);
var target = params.target;
if (!target) return cws.close();
var headers = {};
for (let key in params) if (key != "target") headers[key] = params[key];
try {
var tws = new WebSocket(target, {headers});
} catch(e) {
console.error(e);
cws.close();
return;
}
// client to target
var messageBuffer = [];
tws.on('open', function(){
for (let message of messageBuffer) tws.send(message);
messageBuffer = undefined;
console.debug("sdfsdfjig");
targetReq.on("response", function(targetRes) {
console.log(req.socket.remoteAddress, targetURL.href, targetRes.statusCode);
if (targetRes.statusCode == 101) {
targetRes.pipe(socket);
socket.pipe(targetRes);
} else {
socket.end(`HTTP/1.1 502 Unexpected status code from target server: ${targetRes.statusCode}`);
}
});
cws.on('message', function(message){
if (tws.readyState == WebSocket.OPEN) tws.send(message);
else if (messageBuffer) messageBuffer.push(message);
targetReq.on("error", function(error) {
console.log(req.socket.remoteAddress, targetURL.href, error.message);
socket.end();
});
cws.on('close', function(){
tws.close();
messageBuffer = undefined;
});
cws.on('error', console.error);
// target to client
tws.on('message', function(message){
if (cws.readyState == WebSocket.OPEN) cws.send(message);
});
tws.on('close', function(){
cws.close();
});
tws.on('error', console.error);
});
});

74
package-lock.json generated
View File

@ -1,12 +1,64 @@
{
"name": "websocket-proxy",
"lockfileVersion": 2,
"requires": true,
"lockfileVersion": 1,
"dependencies": {
"async-limiter": {
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/async-limiter/-/async-limiter-1.0.0.tgz",
"integrity": "sha512-jp/uFnooOiO+L211eZOoSyzpOITMXx1rBITauYykG3BRYPu8h0UcxsPNB04RR5vo4Tyz3+ay17tR6JVf9qzYWg=="
"packages": {
"": {
"dependencies": {
"query-string": "^6.2.0",
"ws": "^8.3.0"
}
},
"node_modules/decode-uri-component": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz",
"integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=",
"engines": {
"node": ">=0.10"
}
},
"node_modules/query-string": {
"version": "6.2.0",
"resolved": "https://registry.npmjs.org/query-string/-/query-string-6.2.0.tgz",
"integrity": "sha512-5wupExkIt8RYL4h/FE+WTg3JHk62e6fFPWtAZA9J5IWK1PfTfKkMS93HBUHcFpeYi9KsY5pFbh+ldvEyaz5MyA==",
"dependencies": {
"decode-uri-component": "^0.2.0",
"strict-uri-encode": "^2.0.0"
},
"engines": {
"node": ">=6"
}
},
"node_modules/strict-uri-encode": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/strict-uri-encode/-/strict-uri-encode-2.0.0.tgz",
"integrity": "sha1-ucczDHBChi9rFC3CdLvMWGbONUY=",
"engines": {
"node": ">=4"
}
},
"node_modules/ws": {
"version": "8.3.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.3.0.tgz",
"integrity": "sha512-Gs5EZtpqZzLvmIM59w4igITU57lrtYVFneaa434VROv4thzJyV6UjIL3D42lslWlI+D4KzLYnxSwtfuiO79sNw==",
"engines": {
"node": ">=10.0.0"
},
"peerDependencies": {
"bufferutil": "^4.0.1",
"utf-8-validate": "^5.0.2"
},
"peerDependenciesMeta": {
"bufferutil": {
"optional": true
},
"utf-8-validate": {
"optional": true
}
}
}
},
"dependencies": {
"decode-uri-component": {
"version": "0.2.0",
"resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz",
@ -27,12 +79,10 @@
"integrity": "sha1-ucczDHBChi9rFC3CdLvMWGbONUY="
},
"ws": {
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-6.0.0.tgz",
"integrity": "sha512-c2UlYcAZp1VS8AORtpq6y4RJIkJ9dQz18W32SpR/qXGfLDZ2jU4y4wKvvZwqbi7U6gxFQTeE+urMbXU/tsDy4w==",
"requires": {
"async-limiter": "~1.0.0"
}
"version": "8.3.0",
"resolved": "https://registry.npmjs.org/ws/-/ws-8.3.0.tgz",
"integrity": "sha512-Gs5EZtpqZzLvmIM59w4igITU57lrtYVFneaa434VROv4thzJyV6UjIL3D42lslWlI+D4KzLYnxSwtfuiO79sNw==",
"requires": {}
}
}
}

View File

@ -4,6 +4,6 @@
},
"dependencies": {
"query-string": "^6.2.0",
"ws": "^6.0.0"
"ws": "^8.3.0"
}
}

6
test.js Normal file
View File

@ -0,0 +1,6 @@
var {WebSocketServer} = require("ws");
var wss = new WebSocketServer({port:4444});
wss.on("connection", ws => {
ws.send("ohayo");
ws.on("message", console.log);
});