tlsd 2.12.2 → 2.15.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/package.json +1 -1
- package/rpc_static/rpc/rpc.js +2 -6
- package/tlsd.js +61 -82
package/package.json
CHANGED
package/rpc_static/rpc/rpc.js
CHANGED
|
@@ -48,11 +48,9 @@
|
|
|
48
48
|
delete wraps[id]
|
|
49
49
|
num -= 1
|
|
50
50
|
if(num == 0) {
|
|
51
|
-
//DBG( "clearInterval", timer );
|
|
52
51
|
clearInterval(timer)
|
|
53
52
|
timer = null
|
|
54
53
|
}
|
|
55
|
-
//DBG("forgetting", id, p );
|
|
56
54
|
}
|
|
57
55
|
return p
|
|
58
56
|
}
|
|
@@ -61,7 +59,6 @@
|
|
|
61
59
|
// Put a msg into the list
|
|
62
60
|
// ttl is in secs and should not be less than 10 (default is 60 if not provided)
|
|
63
61
|
const ins = self.ins = function(p, id, ttl) {
|
|
64
|
-
//DBG( "remembering", id, p );
|
|
65
62
|
const w = {
|
|
66
63
|
expire: time() + (ttl || 60),
|
|
67
64
|
payload: p,
|
|
@@ -78,7 +75,6 @@
|
|
|
78
75
|
}
|
|
79
76
|
}
|
|
80
77
|
}, 10 * 1000);
|
|
81
|
-
//DBG( "setInterval", timer );
|
|
82
78
|
}
|
|
83
79
|
}
|
|
84
80
|
|
|
@@ -177,7 +173,7 @@
|
|
|
177
173
|
var m = x.msg
|
|
178
174
|
var fail = x.fail;
|
|
179
175
|
if( fail ) {
|
|
180
|
-
fail(msg_in.error);
|
|
176
|
+
fail( msg_in.error );
|
|
181
177
|
}
|
|
182
178
|
|
|
183
179
|
return
|
|
@@ -201,7 +197,7 @@
|
|
|
201
197
|
|
|
202
198
|
return
|
|
203
199
|
}
|
|
204
|
-
|
|
200
|
+
|
|
205
201
|
cb_ctrl( "error", "invalid message", msg_in );
|
|
206
202
|
}
|
|
207
203
|
|
package/tlsd.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
|
|
2
|
-
//Copyright
|
|
3
|
-
//All Rights Reserved
|
|
2
|
+
// Copyright 2025 Sleepless Software Inc.
|
|
3
|
+
// All Rights Reserved
|
|
4
4
|
|
|
5
5
|
const { path, http, https, fs, crypto, tls, } = require( "allcore" );
|
|
6
6
|
|
|
@@ -13,8 +13,7 @@ const compression = require( "compression" )();
|
|
|
13
13
|
const cors = require( "cors" )();
|
|
14
14
|
const queryString = require( "querystring" );
|
|
15
15
|
|
|
16
|
-
require( "sleepless" )
|
|
17
|
-
|
|
16
|
+
const { log5, o2j, j2o, toInt, is_dir } = require( "sleepless" );
|
|
18
17
|
const L = log5.mkLog( "TLSD: " );
|
|
19
18
|
const { D, V, I, W, E } = L;
|
|
20
19
|
|
|
@@ -35,6 +34,7 @@ function usage() {
|
|
|
35
34
|
process.exit( 1 );
|
|
36
35
|
}
|
|
37
36
|
|
|
37
|
+
|
|
38
38
|
let seq = 0;
|
|
39
39
|
function next_seq() {
|
|
40
40
|
seq += 1;
|
|
@@ -50,47 +50,29 @@ function next_seq() {
|
|
|
50
50
|
// { type: "POST", connection: { req, res } }
|
|
51
51
|
function rpc_handler( root, msg, transport, _okay, _fail ) {
|
|
52
52
|
|
|
53
|
-
let ll = toInt( msg.log_level );
|
|
54
|
-
if( ll > 0 ) {
|
|
55
|
-
D( "Setting log level to "+ll );
|
|
56
|
-
log_level = ll;
|
|
57
|
-
L( log_level );
|
|
58
|
-
if( ! dev_mode ) {
|
|
59
|
-
setTimeout( () => {
|
|
60
|
-
ll = process.env.VERBOSITY;
|
|
61
|
-
D( "Reverting log level to "+ll );
|
|
62
|
-
}, 15 * 1000 );
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
|
|
66
53
|
V( "RPC " + o2j( msg ).abbr( 70 ) );
|
|
67
|
-
D( "----------->>> "+transport.type+" "+o2j( msg, null, 2 ) );
|
|
68
54
|
|
|
69
55
|
const okay = data => {
|
|
70
|
-
D( "<<<=========== "+transport.type+" OKAY "+o2j( data, null, 2 ) );
|
|
71
56
|
_okay( data );
|
|
72
57
|
};
|
|
73
58
|
|
|
74
|
-
const fail =
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
E( root + ": " + o2j(audit_error) );
|
|
81
|
-
fail( "RPC error" ); // this is returned to browser
|
|
59
|
+
const fail = ( why ) => {
|
|
60
|
+
if( ! ( why instanceof Error ) ) {
|
|
61
|
+
why = new Error( why );
|
|
62
|
+
}
|
|
63
|
+
E( root + ": " + why.stack );
|
|
64
|
+
_fail();
|
|
82
65
|
};
|
|
83
66
|
|
|
84
67
|
try {
|
|
85
68
|
// try loading explicit common js module
|
|
86
69
|
const path = root + "/rpc/index.cjs";
|
|
87
|
-
|
|
70
|
+
//D( "path=" + path );
|
|
88
71
|
const mod = require( path );
|
|
89
72
|
try {
|
|
90
|
-
mod( msg, okay,
|
|
73
|
+
mod( msg, okay, fail, transport );
|
|
91
74
|
} catch( err ) {
|
|
92
|
-
|
|
93
|
-
ouch( "RPC handler exception" );
|
|
75
|
+
fail( err );
|
|
94
76
|
}
|
|
95
77
|
|
|
96
78
|
} catch( err ) {
|
|
@@ -98,18 +80,16 @@ function rpc_handler( root, msg, transport, _okay, _fail ) {
|
|
|
98
80
|
// try loading it the old way using the dir
|
|
99
81
|
try {
|
|
100
82
|
const path = root + "/rpc";
|
|
101
|
-
|
|
83
|
+
//D( "path=" + path );
|
|
102
84
|
const mod = require( path );
|
|
103
85
|
try {
|
|
104
|
-
mod( msg, okay,
|
|
86
|
+
mod( msg, okay, fail, transport );
|
|
105
87
|
} catch( err ) {
|
|
106
|
-
|
|
107
|
-
ouch( "RPC handler exception" );
|
|
88
|
+
fail( err );
|
|
108
89
|
}
|
|
109
90
|
|
|
110
91
|
} catch( err ) {
|
|
111
|
-
|
|
112
|
-
ouch( "Error loading RPC handler" );
|
|
92
|
+
fail( err );
|
|
113
93
|
}
|
|
114
94
|
|
|
115
95
|
}
|
|
@@ -118,25 +98,22 @@ function rpc_handler( root, msg, transport, _okay, _fail ) {
|
|
|
118
98
|
|
|
119
99
|
// Glue function to call rpc handler module and then return response
|
|
120
100
|
// via the websockets msg object
|
|
121
|
-
function ws_msg_handler( root, msg, connection ) {
|
|
122
|
-
rpc_handler( root, msg.msg, { type: "WS", connection }, data => {
|
|
101
|
+
function ws_msg_handler( root, msg, host, connection ) {
|
|
102
|
+
rpc_handler( root, msg.msg, { type: "WS", host, connection }, data => {
|
|
123
103
|
msg.reply( data );
|
|
124
|
-
},
|
|
125
|
-
msg.error(
|
|
126
|
-
E( "Should this happen? "+o2j(error,null,2) );
|
|
104
|
+
}, err => {
|
|
105
|
+
msg.error( err || "Unspecified Error" );
|
|
127
106
|
} );
|
|
128
107
|
};
|
|
129
108
|
|
|
130
109
|
|
|
131
|
-
// -----------------------
|
|
132
|
-
|
|
133
|
-
|
|
134
110
|
// Handler that populates the req.query var with what's in query args
|
|
135
111
|
function populate_query( req, res, next ) {
|
|
136
112
|
req.query = queryString.parse( req._parsedUrl.query );
|
|
137
113
|
next();
|
|
138
114
|
}
|
|
139
115
|
|
|
116
|
+
|
|
140
117
|
// Simple logging handler
|
|
141
118
|
function logger( req, res, next ) {
|
|
142
119
|
const host = req.headers[ "host" ];
|
|
@@ -146,6 +123,7 @@ function logger( req, res, next ) {
|
|
|
146
123
|
next();
|
|
147
124
|
}
|
|
148
125
|
|
|
126
|
+
|
|
149
127
|
// Creates and returns a handler function that intercepts and services
|
|
150
128
|
// POST requests to "/rpc" endpoint.
|
|
151
129
|
function rpc_post( root ) {
|
|
@@ -171,24 +149,28 @@ function rpc_post( root ) {
|
|
|
171
149
|
input = query;
|
|
172
150
|
}
|
|
173
151
|
|
|
174
|
-
|
|
175
|
-
|
|
152
|
+
D( method + " >------> " + o2j( input, null, 2 ) );
|
|
153
|
+
|
|
154
|
+
// Summon the rpc handler for the domain root.
|
|
155
|
+
rpc_handler( root, input, { type: method, connection: { host: req.headers[ "host" ], req, res, } } , output => {
|
|
176
156
|
res.writeHead( 200, {
|
|
177
157
|
"Content-Type": "application/json",
|
|
178
158
|
"Cache-Control": "no-store",
|
|
179
159
|
});
|
|
180
|
-
|
|
160
|
+
D( method + " <------< " + o2j( output, null, 2 ) );
|
|
161
|
+
res.write( o2j( output ) );
|
|
181
162
|
res.end();
|
|
182
|
-
}
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
163
|
+
}, () => {
|
|
164
|
+
res.writeHead( 500, {
|
|
165
|
+
"Content-Type": "application/json",
|
|
166
|
+
"Cache-Control": "no-store",
|
|
167
|
+
} );
|
|
168
|
+
res.end();
|
|
169
|
+
} );
|
|
189
170
|
};
|
|
190
171
|
}
|
|
191
172
|
|
|
173
|
+
|
|
192
174
|
// Handler for tlsd's own static files.
|
|
193
175
|
// This is so that "GET /rpc/rpc.js" can return the client-side code for
|
|
194
176
|
// sending WS RPC messages (similar to how socket.io works).
|
|
@@ -214,6 +196,7 @@ function not_found( root ) {
|
|
|
214
196
|
}
|
|
215
197
|
}
|
|
216
198
|
|
|
199
|
+
|
|
217
200
|
// Create and return a connect app/function that implements
|
|
218
201
|
// default (basic) functionality.
|
|
219
202
|
function basic_handler( root ) {
|
|
@@ -233,6 +216,7 @@ function basic_handler( root ) {
|
|
|
233
216
|
|
|
234
217
|
const cached_basic_handlers = {};
|
|
235
218
|
|
|
219
|
+
|
|
236
220
|
// Handle REST calls (as opposed to websocket messages)
|
|
237
221
|
function rest_handler( root, req, rsp ) {
|
|
238
222
|
|
|
@@ -272,33 +256,27 @@ function rest_handler( root, req, rsp ) {
|
|
|
272
256
|
};
|
|
273
257
|
|
|
274
258
|
|
|
275
|
-
// -----------------------
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
// tracked websocket connections
|
|
279
|
-
//const ws_connections = {};
|
|
280
|
-
|
|
281
|
-
|
|
282
259
|
// Associate a websocket message handler (msg_handler) to a webserver instance (server)
|
|
283
260
|
function ws_attach( server, msg_handler ) {
|
|
284
261
|
|
|
285
262
|
const wsd = new websocket.server( { httpServer: server, autoAcceptConnections: false, } );
|
|
286
263
|
|
|
287
264
|
wsd.on( "request", function( wsreq ) {
|
|
265
|
+
|
|
288
266
|
V( "WS: connection request from "+wsreq.remoteAddress+" "+wsreq.resource )
|
|
289
267
|
|
|
290
|
-
const
|
|
268
|
+
const host = wsreq.httpRequest.headers[ "host" ];
|
|
291
269
|
|
|
292
270
|
const socket = wsreq.accept( null, wsreq.origin );
|
|
293
271
|
|
|
294
|
-
const name = "ws-conn-"+next_seq(); // XXX just use the websocket id
|
|
272
|
+
const name = "ws-conn-" + next_seq(); // XXX just use the websocket id
|
|
295
273
|
|
|
296
274
|
// send msg to connected client
|
|
297
275
|
const send = function( msg, cb ) {
|
|
298
276
|
if( msg.msg_id === undefined ) {
|
|
299
277
|
msg.msg_id = "msg-id-" + next_seq(); // every message must have an id
|
|
300
278
|
}
|
|
301
|
-
D( name+"
|
|
279
|
+
D( name+"WS <------< "+o2j( msg ) );
|
|
302
280
|
socket.send( o2j( msg ) );
|
|
303
281
|
};
|
|
304
282
|
|
|
@@ -310,12 +288,11 @@ function ws_attach( server, msg_handler ) {
|
|
|
310
288
|
|
|
311
289
|
socket.on("close", function() {
|
|
312
290
|
D( "WS: disconnect" );
|
|
313
|
-
//delete ws_connections[ name ]; // remove from tracked connections
|
|
314
291
|
});
|
|
315
292
|
|
|
316
293
|
// incoming msgs from client come through here
|
|
317
294
|
socket.on( "message", function( x ) {
|
|
318
|
-
D(
|
|
295
|
+
D( "WS >------> "+x.utf8Data );
|
|
319
296
|
|
|
320
297
|
const json = x.utf8Data; // raw message is a utf8 string
|
|
321
298
|
const msg_in = j2o( json );
|
|
@@ -325,25 +302,23 @@ function ws_attach( server, msg_handler ) {
|
|
|
325
302
|
}
|
|
326
303
|
|
|
327
304
|
if( msg_in.msg ) {
|
|
328
|
-
// message initiated by client
|
|
305
|
+
// this is a message initiated by the client
|
|
329
306
|
msg_in.reply = function( response ) {
|
|
330
307
|
send( { msg_id: msg_in.msg_id, response, } );
|
|
331
308
|
}
|
|
332
309
|
msg_in.error = function( error ) {
|
|
333
310
|
send( { msg_id: msg_in.msg_id, error, } );
|
|
334
311
|
}
|
|
335
|
-
msg_handler( msg_in, conn,
|
|
312
|
+
msg_handler( msg_in, conn, host );
|
|
336
313
|
return;
|
|
337
314
|
}
|
|
338
315
|
|
|
339
|
-
|
|
316
|
+
I( "WS: invalid message dropped" );
|
|
340
317
|
|
|
341
318
|
} );
|
|
342
319
|
|
|
343
320
|
D( "WS: connected: "+name );
|
|
344
321
|
|
|
345
|
-
//ws_connections[ name ] = conn; // add to tracked connections
|
|
346
|
-
|
|
347
322
|
} );
|
|
348
323
|
|
|
349
324
|
D( "WS: initialized" );
|
|
@@ -353,15 +328,16 @@ function ws_attach( server, msg_handler ) {
|
|
|
353
328
|
};
|
|
354
329
|
|
|
355
330
|
|
|
356
|
-
// -----------------------
|
|
357
|
-
|
|
358
331
|
const argv = process.argv;
|
|
359
332
|
|
|
360
333
|
if( argv.length == 2 ) {
|
|
361
334
|
|
|
362
|
-
|
|
335
|
+
let { DOMAINS_ROOT, MAINTAINER_EMAIL, VERBOSITY, } = process.env;
|
|
336
|
+
|
|
337
|
+
VERBOSITY = toInt( VERBOSITY );
|
|
363
338
|
|
|
364
339
|
if( DOMAINS_ROOT && MAINTAINER_EMAIL && VERBOSITY ) {
|
|
340
|
+
|
|
365
341
|
L( toInt( VERBOSITY ) );
|
|
366
342
|
|
|
367
343
|
I( "=== TLS MODE ===" );
|
|
@@ -378,12 +354,12 @@ if( argv.length == 2 ) {
|
|
|
378
354
|
|
|
379
355
|
var server = glx.httpsServer();
|
|
380
356
|
|
|
381
|
-
ws_attach( server, ( msg, connection,
|
|
382
|
-
const root = path.resolve( DOMAINS_ROOT + "/" +
|
|
383
|
-
ws_msg_handler( root, msg, connection );
|
|
357
|
+
ws_attach( server, function( msg, connection, host ) {
|
|
358
|
+
const root = path.resolve( DOMAINS_ROOT + "/" + host );
|
|
359
|
+
ws_msg_handler( root, msg, host, connection );
|
|
384
360
|
} );
|
|
385
361
|
|
|
386
|
-
glx.serveApp( ( req, res )
|
|
362
|
+
glx.serveApp( function( req, res ) {
|
|
387
363
|
const root = path.resolve( DOMAINS_ROOT + "/" + req.headers[ "host" ] );
|
|
388
364
|
rest_handler( root, req, res );
|
|
389
365
|
} );
|
|
@@ -400,9 +376,13 @@ if( argv.length == 5 ) {
|
|
|
400
376
|
|
|
401
377
|
let [ exe, script, SITE_ROOT, PORT, VERBOSITY, ] = argv;
|
|
402
378
|
|
|
379
|
+
VERBOSITY = toInt( VERBOSITY );
|
|
380
|
+
PORT = toInt( PORT );
|
|
381
|
+
|
|
403
382
|
dev_mode = true;
|
|
404
383
|
|
|
405
384
|
if( SITE_ROOT && PORT && VERBOSITY ) {
|
|
385
|
+
|
|
406
386
|
L( toInt( VERBOSITY ) );
|
|
407
387
|
|
|
408
388
|
SITE_ROOT = path.resolve( SITE_ROOT );
|
|
@@ -416,8 +396,8 @@ if( argv.length == 5 ) {
|
|
|
416
396
|
rest_handler( SITE_ROOT, req, res );
|
|
417
397
|
} );
|
|
418
398
|
|
|
419
|
-
ws_attach( server, ( msg, connection,
|
|
420
|
-
ws_msg_handler( SITE_ROOT, msg, connection );
|
|
399
|
+
ws_attach( server, ( msg, connection, host ) => {
|
|
400
|
+
ws_msg_handler( SITE_ROOT, msg, host, connection );
|
|
421
401
|
} );
|
|
422
402
|
|
|
423
403
|
server.listen( toInt( PORT ), () => {
|
|
@@ -434,7 +414,6 @@ else
|
|
|
434
414
|
if( argv.length == 3 && argv[ 2 ] == "-v" ) {
|
|
435
415
|
|
|
436
416
|
// pull package version from package.json and print it
|
|
437
|
-
|
|
438
417
|
const p = require( __dirname + "/package.json" );
|
|
439
418
|
log( p.version );
|
|
440
419
|
|