Skip to content

Commit

Permalink
ports and addresses from command line arguments
Browse files Browse the repository at this point in the history
  • Loading branch information
Robin Gottfried committed Feb 18, 2020
1 parent 19b5091 commit c086871
Show file tree
Hide file tree
Showing 6 changed files with 52 additions and 22 deletions.
5 changes: 3 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,5 +5,6 @@ INSTALLATION
cd ws_rev_proxy
npm install
node run server &
node run client kpz-1 <forward-to-host> <forward-to-port> & # forward-to-* points to a server to forward http to
curl localhost:8080/api/kpz-1<path> # path is the path to get from <forward-to-host>
node run client <client-key> <server_host>:<server_port> <forward_to_base_uri> & # forward-to-* points to a server to forward http to
client_key=kpz-1
curl localhost:8080/api/$client_key # path is the path to get from <forward-to-host>
38 changes: 24 additions & 14 deletions client/index.js
Original file line number Diff line number Diff line change
@@ -1,28 +1,37 @@
'use strict';
//-- vim: ft=javascript tabstop=2 softtabstop=2 expandtab shiftwidth=2
const path = require('path');
const http = require('http');
const WebSocket = require('ws');
const ws_ = new WebSocket(`ws://localhost:8080/ws/pill/${process.argv[2]}`);
const WsJsonProtocol = require('../lib/ws-json');

const client_key = process.argv[2];
const server_host_port = process.argv[3];
const forward_base_uri = process.argv[4];

if (client_key === undefined) {
throw new Error("Missing client key.");
}

const ws_ = new WebSocket(`ws://${server_host_port}/ws/${client_key}`);
const ws = new WsJsonProtocol(ws_);
const forward_host = process.argv[3];
const forward_port = process.argv[4];

class RequestForwarder extends Object {
constructor(ws, host, port) {
constructor(ws, forward_base_uri) {
super();
if (!host || !port) throw new Error("Host and port are required arguments.");
this._forward_host = host;
this._forward_port = port;
if (!forward_base_uri) throw new Error("Missing the base uri to forward to.");
let parsed_uri = new URL(forward_base_uri);
if (parsed_uri.search) throw new Error("Search path is not implemented yet for forward base uri.");
if (!parsed_uri.protocol.match(/^https?:$/i)) throw new Error(`Only HTTP(s) protocol is implemented for forward base uri (got ${parsed_uri.protocol}).`);
this._forward_base_uri = parsed_uri;
this._ws = ws;
}

fire_request(message, ) {
const ireq = message.request;
let oreq_uri = new URL(this._forward_base_uri.toString()); // clone the original uri
oreq_uri.pathname = path.posix.join(oreq_uri.pathname, ireq.url);
const req_params = {
host: this._forward_host,
port: this._forward_port,
path: ireq.url,
method: ireq.method,
headers: ireq.headers,
}
Expand All @@ -37,7 +46,7 @@ class RequestForwarder extends Object {
})
}
}
const req = http.request(req_params, function handleResponse(res) {
const req = http.request(oreq_uri.toString(), req_params, function handleResponse(res) {
res.setEncoding('utf8');
sender('headers')({
statusCode: res.statusCode,
Expand All @@ -48,6 +57,7 @@ class RequestForwarder extends Object {
res.on('end', sender('end'));
});
req.on('error', sender('error'));
console.log(`C > ${oreq_uri.toString()}`);
if (ireq.body) {
console.log(`Sending body ${ireq.body}`);
req.write(ireq.body);
Expand All @@ -57,8 +67,8 @@ class RequestForwarder extends Object {
}

_send(data) {
console.log(`Sending ${message}`)
this._ws.send(message);
console.log(`Sending ${JSON.stringify(data)}`)
this._ws.send(data);
}

on_message(message) {
Expand All @@ -69,7 +79,7 @@ class RequestForwarder extends Object {


ws.on('open', function open() {
const request_forwarder = new RequestForwarder(ws, forward_host, forward_port);
const request_forwarder = new RequestForwarder(ws, forward_base_uri);
console.log("Client connection openned.");

ws.send({data:"Hallo."});
Expand Down
4 changes: 3 additions & 1 deletion lib/ws-json.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,12 +32,14 @@ class WsJsonProtocol extends Object {
on(eventName, callback) {
let decode_ = this._decode.bind(this);
let decoderCallback = function (message) {
console.log(`decoding message ${message}`);
let decodedMessage;
try {
let decodedMessage = decode_(message);
decodedMessage = decode_(message);
} catch(err) {
console.error(err);
}
console.log(`decoded message ${JSON.stringify(decodedMessage, undefined, 3)}`);
if (decodedMessage !== undefined) {
callback(decodedMessage);
}
Expand Down
1 change: 1 addition & 0 deletions server/api.js
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,7 @@ class Api extends Object {
request_data.body = req.body;
console.log(request_data.body);
request_data.url = resource_path;
console.log(`Sending to ${client_id} req_id: ${req_id} to ${websocket_client.id}`);
websocket_client.send(JSON.stringify({
channel: channel,
id: req_id,
Expand Down
3 changes: 2 additions & 1 deletion server/authenticator.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class KeyAuthenticator extends Object {

authenticate(request, callback) {
console.log(`Authenticating request ${request} on ${request.url}.`);
const match = /^\/ws\/pill\/(?<client_key>.*)$/.exec(request.url);
const match = /^\/ws\/(?<client_key>.*)$/.exec(request.url);
if (! match) return callback(new Error("Unknown url."));
if (this.allowed_keys.has(match.groups.client_key)) {
console.log(`Key ${match.groups.client_key} accepted`);
Expand All @@ -23,6 +23,7 @@ class KeyAuthenticator extends Object {

onConnected (ws, client) {
this._clients_by_id[client.key] = ws;
ws.id = client.key;
}

clientFromId (id) {
Expand Down
23 changes: 19 additions & 4 deletions server/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ const WebSocket = require('ws');
const Api = require('./api');
const KeyAuthenticator = require('./authenticator');
const authenticator = new KeyAuthenticator(['kpz-1', 'kpz-2', 'kpz-3']);
const server = http.createServer(
let server = http.createServer(
new Api(
'/api',
authenticator.clientFromId.bind(authenticator)
Expand All @@ -15,6 +15,9 @@ const server = http.createServer(
const wss = new WebSocket.Server({ noServer: true });


let server_port = process.argv[2];

if (! server_port) server_port=8000;
/*
* @authenticator ... function (request, callback) which calls callback(err, client).
* `err` is empty on success and client which should be an object with `key` property.
Expand Down Expand Up @@ -42,14 +45,26 @@ function createServer(authenticator) {

wss.handleUpgrade(request, socket, head, function done(ws) {
console.log("Emitting ws connection");
ws.send(JSON.stringify({"data": "ping"}));
authenticator.onConnected(ws, client);
ws.client = client;
ws.client_object = client;
wss.emit('connection', ws, request, client);
});
});
});
return server;
}

createServer(authenticator)
.listen(8080);
server = createServer(authenticator)
server.on("listening", function onListening() {
let addr = server.address();
console.log(`
Listening on ${addr.address}:${addr.port}.
To connect clients run:
node client <client-key> <server-host>:${addr.port} <uri-to-redirect-to>
`);

});
server.listen(server_port);

0 comments on commit c086871

Please sign in to comment.