hsync 0.16.1 → 0.18.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/Readme.md +27 -13
- package/cli.js +4 -3
- package/connection.js +44 -66
- package/dist/hsync.js +529 -27
- package/dist/hsync.min.js +1 -1
- package/dist/hsync.min.js.LICENSE.txt +2 -0
- package/hsync-web.js +4 -0
- package/hsync.js +3 -0
- package/lib/peers.js +237 -0
- package/lib/rtc-node.js +168 -0
- package/lib/rtc-web.js +172 -0
- package/lib/socket-listen-handler.js +28 -39
- package/lib/socket-map.js +19 -0
- package/lib/socket-relay-handler.js +12 -10
- package/package.json +9 -5
- package/tn.js +34 -0
- package/lib/rpc.js +0 -95
- package/lib/web-net.js +0 -67
package/Readme.md
CHANGED
|
@@ -2,27 +2,41 @@
|
|
|
2
2
|
|
|
3
3
|
[](https://nodei.co/npm/hsync/)
|
|
4
4
|
|
|
5
|
-
|
|
6
|
-
|
|
5
|
+
hsync is a [reverse-proxy](https://en.wikipedia.org/wiki/Reverse_proxy) client for node.js and browsers that connects to an [hsync-server](https://github.com/monteslu/hsync-server).
|
|
6
|
+
|
|
7
|
+
You can share your local webserver as a secure public URL, as well as tunnel whatever tcp/ip traffic you'd like between two hsync clients.
|
|
8
|
+
|
|
7
9
|
|
|
8
10
|
## basic usage
|
|
9
11
|
|
|
10
|
-
|
|
11
|
-
`npm i`
|
|
12
|
+
## install globally
|
|
13
|
+
`npm i -g hsync`
|
|
14
|
+
|
|
15
|
+
### run
|
|
16
|
+
`hsync`
|
|
12
17
|
|
|
13
|
-
|
|
18
|
+
## run with npx
|
|
14
19
|
|
|
20
|
+
`npx hsync`
|
|
15
21
|
|
|
16
|
-
|
|
17
|
-
`export HSYNC_SERVER="wss://myhost.myserver.com"`
|
|
22
|
+
## configuration
|
|
18
23
|
|
|
24
|
+
by default hsync will connect to the default hsync.tech server and allow a connection for up to 4 hours.
|
|
19
25
|
|
|
20
|
-
|
|
21
|
-
|
|
26
|
+
However you can pass flags to the command line or configure env variables:
|
|
27
|
+
|
|
28
|
+
| flag | long flag | type | env variable | description |
|
|
29
|
+
| ---- | --------------------- | ------- | ------------------ | ---------------------------------------------------------- |
|
|
30
|
+
| -p | -port | number | PORT | port for local webserver |
|
|
31
|
+
| -d | --dynamic-host | url | HSYNC_DYNAMIC_HOST | host to get a dynamic connection from |
|
|
32
|
+
| -s | --hsync-server | url | HSYNC_SERVER | hsync-server location ex: wss://sub.mydomain.com |
|
|
33
|
+
| -hs | --hsync-secret | string | HSYNC_SECRET | password to connect to hsync-server |
|
|
34
|
+
| -llp | --listener-local-port | number | HSYNC_LLP | local port to open for listener |
|
|
35
|
+
| -lth | --listener-target-host | url | HSYNC_LTH | target host for listener |
|
|
36
|
+
| -ltp | --listener-target-port | number | HSYNC_LTP | target port for listener |
|
|
37
|
+
| -rip | --relay-inbound-port | number | HSYNC_RIP | inbound port for remote relay requests |
|
|
38
|
+
| -rth | --relay-target-host | url | HSYNC_RTH | target host for relay to open tcp connection on |
|
|
39
|
+
| -rtp | --relay-target-port | number | HSYNC_RTP | target port for relay to open tcp connection on |
|
|
22
40
|
|
|
23
|
-
### local webserver port
|
|
24
|
-
`export PORT="8080"`
|
|
25
41
|
|
|
26
|
-
### run
|
|
27
|
-
`node index`
|
|
28
42
|
|
package/cli.js
CHANGED
|
@@ -16,9 +16,9 @@ program
|
|
|
16
16
|
.addOption(new Option('-llp, --listener-local-port <number>', 'local port to open for listener').env('HSYNC_LLP'))
|
|
17
17
|
.addOption(new Option('-lth, --listener-target-host <url>', 'target host for listener').env('HSYNC_LTH'))
|
|
18
18
|
.addOption(new Option('-ltp, --listener-target-port <number>', 'target port for listener').env('HSYNC_LTP'))
|
|
19
|
-
.addOption(new Option('-rip, --relay-inbound-port <number>', 'inbound port
|
|
20
|
-
.addOption(new Option('-rth, --relay-target-host <
|
|
21
|
-
.addOption(new Option('-rtp, --relay-target-port <number>', 'target port for relay').env('HSYNC_RTP'));
|
|
19
|
+
.addOption(new Option('-rip, --relay-inbound-port <number>', 'inbound port for remote relay requests').env('HSYNC_RIP'))
|
|
20
|
+
.addOption(new Option('-rth, --relay-target-host <url>', 'target host for relay to open tcp connection on').env('HSYNC_RTH'))
|
|
21
|
+
.addOption(new Option('-rtp, --relay-target-port <number>', 'target port for relay to open tcp connection on').env('HSYNC_RTP'));
|
|
22
22
|
|
|
23
23
|
program.parse();
|
|
24
24
|
|
|
@@ -70,4 +70,5 @@ config.connections.forEach(async (conConfig) => {
|
|
|
70
70
|
console.log();
|
|
71
71
|
console.log('Admin ui at: ', con.webAdmin);
|
|
72
72
|
console.log('Secret: ', con.hsyncSecret);
|
|
73
|
+
console.log();
|
|
73
74
|
});
|
package/connection.js
CHANGED
|
@@ -3,7 +3,7 @@ const b64id = require('b64id');
|
|
|
3
3
|
const debug = require('debug')('hsync:info');
|
|
4
4
|
const debugVerbose = require('debug')('hsync:verbose');
|
|
5
5
|
const debugError = require('debug')('hsync:error');
|
|
6
|
-
const { getRPCPeer, createServerPeer } = require('./lib/
|
|
6
|
+
const { getRPCPeer, createServerPeer } = require('./lib/peers');
|
|
7
7
|
const { createWebHandler, setNet: webSetNet } = require('./lib/web-handler');
|
|
8
8
|
const { createSocketListenHandler, setNet: listenSetNet, receiveRelayData } = require('./lib/socket-listen-handler');
|
|
9
9
|
const { createSocketRelayHandler, setNet: relaySetNet, receiveListenerData, connectSocket } = require('./lib/socket-relay-handler');
|
|
@@ -15,6 +15,8 @@ debugError.color = 1;
|
|
|
15
15
|
|
|
16
16
|
let mqtt;
|
|
17
17
|
|
|
18
|
+
console.log('connection from hsync');
|
|
19
|
+
|
|
18
20
|
function setNet(netImpl) {
|
|
19
21
|
webSetNet(netImpl);
|
|
20
22
|
listenSetNet(netImpl);
|
|
@@ -116,65 +118,14 @@ async function createHsync(config) {
|
|
|
116
118
|
} catch (e) {
|
|
117
119
|
debugError('error parsing json message');
|
|
118
120
|
}
|
|
119
|
-
} else if (action === 'rpc') {
|
|
120
|
-
const peer = getRPCPeer({hostName: from, temporary: true, hsyncClient});
|
|
121
|
-
// const peer = getPeer({hostName: from, temporary: true});
|
|
122
|
-
peer.transport.receiveData(message.toString());
|
|
123
121
|
}
|
|
124
122
|
else if (!action && (segment3 === 'srpc')) {
|
|
125
123
|
hsyncClient.serverPeer.transport.receiveData(message.toString());
|
|
126
124
|
}
|
|
127
|
-
else if (action === 'socketData') {
|
|
128
|
-
// events.emit('socketData', from, segment5, message);
|
|
129
|
-
receiveSocketData(segment5, message);
|
|
130
|
-
}
|
|
131
|
-
else if (action === 'relayData') {
|
|
132
|
-
// events.emit('socketData', from, segment5, message);
|
|
133
|
-
receiveRelayData(segment5, message);
|
|
134
|
-
}
|
|
135
|
-
else if (action === 'socketClose') {
|
|
136
|
-
events.emit('socketClose', from, segment5);
|
|
137
|
-
}
|
|
138
125
|
}
|
|
139
126
|
|
|
140
127
|
});
|
|
141
128
|
|
|
142
|
-
// function getPeer({hostName, temporary, timeout = 10000}) {
|
|
143
|
-
// let peer = peers[hostName];
|
|
144
|
-
// if (!peer) {
|
|
145
|
-
// peer = createRPCPeer({hostName, hsyncClient, timeout, methods: peerMethods});
|
|
146
|
-
// if (temporary) {
|
|
147
|
-
// peer.rpcTemporary = true;
|
|
148
|
-
// }
|
|
149
|
-
// peers[host] = peer;
|
|
150
|
-
// }
|
|
151
|
-
// return peer;
|
|
152
|
-
// }
|
|
153
|
-
|
|
154
|
-
function sendJson(host, json) {
|
|
155
|
-
if (!host || !json) {
|
|
156
|
-
return;
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
if (host === myHostName) {
|
|
160
|
-
debugError('cannot send message to self', host);
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
if (typeof json === 'object') {
|
|
164
|
-
json = JSON.stringify(json);
|
|
165
|
-
} else if (typeof json === 'string') {
|
|
166
|
-
try {
|
|
167
|
-
json = JSON.stringify(JSON.parse(json));
|
|
168
|
-
} catch(e) {
|
|
169
|
-
debugError('not well formed json or object', e);
|
|
170
|
-
return;
|
|
171
|
-
}
|
|
172
|
-
} else {
|
|
173
|
-
return;
|
|
174
|
-
}
|
|
175
|
-
mqConn.publish(`msg/${host}/${myHostName}/json`, json);
|
|
176
|
-
}
|
|
177
|
-
|
|
178
129
|
function endClient(force, callback) {
|
|
179
130
|
if (force) {
|
|
180
131
|
mqConn.end(force);
|
|
@@ -232,32 +183,41 @@ async function createHsync(config) {
|
|
|
232
183
|
peerRpc: async (requestInfo) => {
|
|
233
184
|
requestInfo.hsyncClient = hsyncClient;
|
|
234
185
|
const { msg } = requestInfo;
|
|
235
|
-
debug('peerRpc handler', requestInfo.fromHost, msg);
|
|
236
|
-
const
|
|
186
|
+
debug('peerRpc handler', requestInfo.fromHost, msg.method);
|
|
187
|
+
const peer = getRPCPeer({hostName: requestInfo.fromHost, hsyncClient});
|
|
188
|
+
if (!msg.id) {
|
|
189
|
+
// notification
|
|
190
|
+
if (Array.isArray(msg.params)) {
|
|
191
|
+
msg.params.unshift(peer);
|
|
192
|
+
}
|
|
193
|
+
peer.transport.emit('rpc', msg);
|
|
194
|
+
return { result: {}, id: msg.id};
|
|
195
|
+
}
|
|
196
|
+
const reply = {id: msg.id, jsonrpc:'2.0'};
|
|
237
197
|
try {
|
|
238
|
-
if (!
|
|
198
|
+
if (!peer.localMethods[msg.method]) {
|
|
239
199
|
const notFoundError = new Error('method not found');
|
|
240
200
|
notFoundError.code = -32601;
|
|
241
201
|
throw notFoundError;
|
|
242
202
|
}
|
|
243
|
-
const result = await
|
|
203
|
+
const result = await peer.localMethods[msg.method](requestInfo, ...msg.params);
|
|
244
204
|
reply.result = result;
|
|
245
205
|
return result;
|
|
246
206
|
} catch (e) {
|
|
247
207
|
debug('peer rpc error', e, msg);
|
|
248
|
-
|
|
208
|
+
reply.error = {
|
|
249
209
|
code: e.code || 500,
|
|
250
210
|
message: e.toString(),
|
|
251
211
|
};
|
|
252
|
-
return
|
|
212
|
+
return reply;
|
|
253
213
|
}
|
|
254
214
|
}
|
|
255
215
|
};
|
|
256
216
|
|
|
257
217
|
const peerMethods = {
|
|
258
|
-
ping: (
|
|
259
|
-
debug('ping called',
|
|
260
|
-
return `${greeting} back atcha, ${
|
|
218
|
+
ping: (remotePeer, greeting) => {
|
|
219
|
+
debug('ping called', remotePeer.hostName, greeting);
|
|
220
|
+
return `${greeting} back atcha, ${remotePeer.hostName}.`;
|
|
261
221
|
},
|
|
262
222
|
connectSocket,
|
|
263
223
|
receiveListenerData,
|
|
@@ -265,9 +225,10 @@ async function createHsync(config) {
|
|
|
265
225
|
};
|
|
266
226
|
|
|
267
227
|
hsyncClient.serverPeer = createServerPeer(hsyncClient, serverReplyMethods);
|
|
268
|
-
|
|
228
|
+
hsyncClient.getPeer = (hostName) => {
|
|
229
|
+
return getRPCPeer({hostName, hsyncClient});
|
|
230
|
+
};
|
|
269
231
|
hsyncClient.hsyncBase = hsyncBase;
|
|
270
|
-
hsyncClient.sendJson = sendJson;
|
|
271
232
|
hsyncClient.endClient = endClient;
|
|
272
233
|
hsyncClient.serverReplyMethods = serverReplyMethods;
|
|
273
234
|
hsyncClient.getRPCPeer = getRPCPeer;
|
|
@@ -276,23 +237,40 @@ async function createHsync(config) {
|
|
|
276
237
|
hsyncClient.hsyncServer = hsyncServer;
|
|
277
238
|
hsyncClient.dynamicTimeout = dynamicTimeout;
|
|
278
239
|
const { host, protocol } = new URL(hsyncServer);
|
|
279
|
-
debug('url', host, protocol);
|
|
280
240
|
if (protocol === 'wss:') {
|
|
281
241
|
hsyncClient.webUrl = `https://${host}`;
|
|
282
242
|
} else {
|
|
283
243
|
hsyncClient.webUrl = `http://${host}`;
|
|
284
244
|
}
|
|
245
|
+
debug('url', host, protocol, hsyncClient.webUrl);
|
|
285
246
|
hsyncClient.webAdmin = `${hsyncClient.webUrl}/${hsyncBase}/admin`;
|
|
286
247
|
hsyncClient.webBase = `${hsyncClient.webUrl}/${hsyncBase}`;
|
|
287
248
|
hsyncClient.port = port;
|
|
288
249
|
|
|
289
250
|
if (listenerLocalPort) {
|
|
290
251
|
listenerLocalPort.forEach((llp, i) => {
|
|
291
|
-
|
|
252
|
+
let lth = listenerTargetHost ? listenerTargetHost[i] || listenerTargetHost[0] : null;
|
|
292
253
|
if (lth) {
|
|
254
|
+
if (lth.endsWith('/')) {
|
|
255
|
+
lth = lth.substring(0, lth.length - 1);
|
|
256
|
+
}
|
|
293
257
|
const ltp = listenerTargetPort ? listenerTargetPort[i] : llp;
|
|
294
258
|
addSocketListener(llp, myHostName, ltp, lth);
|
|
295
|
-
|
|
259
|
+
debug('relaying local', llp, 'to', lth, ltp);
|
|
260
|
+
}
|
|
261
|
+
});
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
if (relayInboundPort) {
|
|
265
|
+
relayInboundPort.forEach((rip, i) => {
|
|
266
|
+
const rth = relayTargetHost ? relayTargetHost[i] : relayTargetHost[0] || 'localhost';
|
|
267
|
+
if (rth) {
|
|
268
|
+
if (rth.endsWith('/')) {
|
|
269
|
+
rth = rth.substring(0, rth.length - 1);
|
|
270
|
+
}
|
|
271
|
+
const rtp = relayTargetPort ? relayTargetPort[i] : rip;
|
|
272
|
+
addSocketRelay(rip, myHostName, rtp, rth);
|
|
273
|
+
debug('relaying inbound', rip, 'to', rth, rtp);
|
|
296
274
|
}
|
|
297
275
|
});
|
|
298
276
|
}
|