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 CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "tlsd",
3
- "version": "2.12.2",
3
+ "version": "2.15.0",
4
4
  "description": "A server for web app prototyping with HTTPS and Websockets",
5
5
  "main": "tlsd.js",
6
6
  "bin": {
@@ -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 2024 Sleepless Software Inc.
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" ).globalize();
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 = error => {
75
- D( "<<<*********** "+transport.type+" ERROR "+o2j( error, null, 2 ) );
76
- _fail( error );
77
- };
78
-
79
- const ouch = audit_error => {
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
- V( "path=" + path );
70
+ //D( "path=" + path );
88
71
  const mod = require( path );
89
72
  try {
90
- mod( msg, okay, ouch, transport );
73
+ mod( msg, okay, fail, transport );
91
74
  } catch( err ) {
92
- E( (err instanceof Error ) ? err.stack : err );
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
- V( "path=" + path );
83
+ //D( "path=" + path );
102
84
  const mod = require( path );
103
85
  try {
104
- mod( msg, okay, ouch, transport );
86
+ mod( msg, okay, fail, transport );
105
87
  } catch( err ) {
106
- E( (err instanceof Error ) ? err.stack : err );
107
- ouch( "RPC handler exception" );
88
+ fail( err );
108
89
  }
109
90
 
110
91
  } catch( err ) {
111
- E( (err instanceof Error ) ? err.stack : err );
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
- }, error => {
125
- msg.error( { 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
- // Set up callbacks
175
- const done = ( error, data ) => {
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
- res.write( o2j( data ) );
160
+ D( method + " <------< " + o2j( output, null, 2 ) );
161
+ res.write( o2j( output ) );
181
162
  res.end();
182
- };
183
- const okay = ( data ) => { done( null, data ); };
184
- // XXX wrong
185
- const fail = ( error, body ) => { done( error, body ); };
186
-
187
- // Summon the rpc handler for the domain root.
188
- rpc_handler( root, input, { type: method, connection: { req, res, } } , okay, fail );
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 domain = wsreq.httpRequest.headers[ "host" ];
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+" <=== WS ===<< "+o2j( msg ) );
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( name+" >>--- WS ---> "+x.utf8Data );
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, domain );
312
+ msg_handler( msg_in, conn, host );
336
313
  return;
337
314
  }
338
315
 
339
- E( "WS: invalid message" );
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
- const { DOMAINS_ROOT, MAINTAINER_EMAIL, VERBOSITY, } = process.env;
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, domain ) => {
382
- const root = path.resolve( DOMAINS_ROOT + "/" + domain );
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, domain ) => {
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