tlsd 2.12.1 → 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.1",
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,73 +50,70 @@ 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
- const mod = require( root + "/rpc/index.cjs" );
68
+ // try loading explicit common js module
69
+ const path = root + "/rpc/index.cjs";
70
+ //D( "path=" + path );
71
+ const mod = require( path );
86
72
  try {
87
- mod( msg, okay, ouch, transport );
73
+ mod( msg, okay, fail, transport );
88
74
  } catch( err ) {
89
- E( (err instanceof Error ) ? err.stack : err );
90
- ouch( "RPC handler exception" );
75
+ fail( err );
91
76
  }
77
+
92
78
  } catch( err ) {
93
- E( (err instanceof Error ) ? err.stack : err );
94
- ouch( "Error loading RPC handler" );
79
+
80
+ // try loading it the old way using the dir
81
+ try {
82
+ const path = root + "/rpc";
83
+ //D( "path=" + path );
84
+ const mod = require( path );
85
+ try {
86
+ mod( msg, okay, fail, transport );
87
+ } catch( err ) {
88
+ fail( err );
89
+ }
90
+
91
+ } catch( err ) {
92
+ fail( err );
93
+ }
94
+
95
95
  }
96
96
  };
97
97
 
98
98
 
99
99
  // Glue function to call rpc handler module and then return response
100
100
  // via the websockets msg object
101
- function ws_msg_handler( root, msg, connection ) {
102
- 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 => {
103
103
  msg.reply( data );
104
- }, error => {
105
- msg.error( { error } );
106
- E( "Should this happen? "+o2j(error,null,2) );
104
+ }, err => {
105
+ msg.error( err || "Unspecified Error" );
107
106
  } );
108
107
  };
109
108
 
110
109
 
111
- // -----------------------
112
-
113
-
114
110
  // Handler that populates the req.query var with what's in query args
115
111
  function populate_query( req, res, next ) {
116
112
  req.query = queryString.parse( req._parsedUrl.query );
117
113
  next();
118
114
  }
119
115
 
116
+
120
117
  // Simple logging handler
121
118
  function logger( req, res, next ) {
122
119
  const host = req.headers[ "host" ];
@@ -126,6 +123,7 @@ function logger( req, res, next ) {
126
123
  next();
127
124
  }
128
125
 
126
+
129
127
  // Creates and returns a handler function that intercepts and services
130
128
  // POST requests to "/rpc" endpoint.
131
129
  function rpc_post( root ) {
@@ -151,24 +149,28 @@ function rpc_post( root ) {
151
149
  input = query;
152
150
  }
153
151
 
154
- // Set up callbacks
155
- 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 => {
156
156
  res.writeHead( 200, {
157
157
  "Content-Type": "application/json",
158
158
  "Cache-Control": "no-store",
159
159
  });
160
- res.write( o2j( data ) );
160
+ D( method + " <------< " + o2j( output, null, 2 ) );
161
+ res.write( o2j( output ) );
161
162
  res.end();
162
- };
163
- const okay = ( data ) => { done( null, data ); };
164
- // XXX wrong
165
- const fail = ( error, body ) => { done( error, body ); };
166
-
167
- // Summon the rpc handler for the domain root.
168
- 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
+ } );
169
170
  };
170
171
  }
171
172
 
173
+
172
174
  // Handler for tlsd's own static files.
173
175
  // This is so that "GET /rpc/rpc.js" can return the client-side code for
174
176
  // sending WS RPC messages (similar to how socket.io works).
@@ -194,6 +196,7 @@ function not_found( root ) {
194
196
  }
195
197
  }
196
198
 
199
+
197
200
  // Create and return a connect app/function that implements
198
201
  // default (basic) functionality.
199
202
  function basic_handler( root ) {
@@ -213,6 +216,7 @@ function basic_handler( root ) {
213
216
 
214
217
  const cached_basic_handlers = {};
215
218
 
219
+
216
220
  // Handle REST calls (as opposed to websocket messages)
217
221
  function rest_handler( root, req, rsp ) {
218
222
 
@@ -252,33 +256,27 @@ function rest_handler( root, req, rsp ) {
252
256
  };
253
257
 
254
258
 
255
- // -----------------------
256
-
257
-
258
- // tracked websocket connections
259
- //const ws_connections = {};
260
-
261
-
262
259
  // Associate a websocket message handler (msg_handler) to a webserver instance (server)
263
260
  function ws_attach( server, msg_handler ) {
264
261
 
265
262
  const wsd = new websocket.server( { httpServer: server, autoAcceptConnections: false, } );
266
263
 
267
264
  wsd.on( "request", function( wsreq ) {
265
+
268
266
  V( "WS: connection request from "+wsreq.remoteAddress+" "+wsreq.resource )
269
267
 
270
- const domain = wsreq.httpRequest.headers[ "host" ];
268
+ const host = wsreq.httpRequest.headers[ "host" ];
271
269
 
272
270
  const socket = wsreq.accept( null, wsreq.origin );
273
271
 
274
- 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
275
273
 
276
274
  // send msg to connected client
277
275
  const send = function( msg, cb ) {
278
276
  if( msg.msg_id === undefined ) {
279
277
  msg.msg_id = "msg-id-" + next_seq(); // every message must have an id
280
278
  }
281
- D( name+" <=== WS ===<< "+o2j( msg ) );
279
+ D( name+"WS <------< "+o2j( msg ) );
282
280
  socket.send( o2j( msg ) );
283
281
  };
284
282
 
@@ -290,12 +288,11 @@ function ws_attach( server, msg_handler ) {
290
288
 
291
289
  socket.on("close", function() {
292
290
  D( "WS: disconnect" );
293
- //delete ws_connections[ name ]; // remove from tracked connections
294
291
  });
295
292
 
296
293
  // incoming msgs from client come through here
297
294
  socket.on( "message", function( x ) {
298
- D( name+" >>--- WS ---> "+x.utf8Data );
295
+ D( "WS >------> "+x.utf8Data );
299
296
 
300
297
  const json = x.utf8Data; // raw message is a utf8 string
301
298
  const msg_in = j2o( json );
@@ -305,25 +302,23 @@ function ws_attach( server, msg_handler ) {
305
302
  }
306
303
 
307
304
  if( msg_in.msg ) {
308
- // message initiated by client
305
+ // this is a message initiated by the client
309
306
  msg_in.reply = function( response ) {
310
307
  send( { msg_id: msg_in.msg_id, response, } );
311
308
  }
312
309
  msg_in.error = function( error ) {
313
310
  send( { msg_id: msg_in.msg_id, error, } );
314
311
  }
315
- msg_handler( msg_in, conn, domain );
312
+ msg_handler( msg_in, conn, host );
316
313
  return;
317
314
  }
318
315
 
319
- E( "WS: invalid message" );
316
+ I( "WS: invalid message dropped" );
320
317
 
321
318
  } );
322
319
 
323
320
  D( "WS: connected: "+name );
324
321
 
325
- //ws_connections[ name ] = conn; // add to tracked connections
326
-
327
322
  } );
328
323
 
329
324
  D( "WS: initialized" );
@@ -333,15 +328,16 @@ function ws_attach( server, msg_handler ) {
333
328
  };
334
329
 
335
330
 
336
- // -----------------------
337
-
338
331
  const argv = process.argv;
339
332
 
340
333
  if( argv.length == 2 ) {
341
334
 
342
- const { DOMAINS_ROOT, MAINTAINER_EMAIL, VERBOSITY, } = process.env;
335
+ let { DOMAINS_ROOT, MAINTAINER_EMAIL, VERBOSITY, } = process.env;
336
+
337
+ VERBOSITY = toInt( VERBOSITY );
343
338
 
344
339
  if( DOMAINS_ROOT && MAINTAINER_EMAIL && VERBOSITY ) {
340
+
345
341
  L( toInt( VERBOSITY ) );
346
342
 
347
343
  I( "=== TLS MODE ===" );
@@ -358,12 +354,12 @@ if( argv.length == 2 ) {
358
354
 
359
355
  var server = glx.httpsServer();
360
356
 
361
- ws_attach( server, ( msg, connection, domain ) => {
362
- const root = path.resolve( DOMAINS_ROOT + "/" + domain );
363
- 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 );
364
360
  } );
365
361
 
366
- glx.serveApp( ( req, res ) => {
362
+ glx.serveApp( function( req, res ) {
367
363
  const root = path.resolve( DOMAINS_ROOT + "/" + req.headers[ "host" ] );
368
364
  rest_handler( root, req, res );
369
365
  } );
@@ -380,9 +376,13 @@ if( argv.length == 5 ) {
380
376
 
381
377
  let [ exe, script, SITE_ROOT, PORT, VERBOSITY, ] = argv;
382
378
 
379
+ VERBOSITY = toInt( VERBOSITY );
380
+ PORT = toInt( PORT );
381
+
383
382
  dev_mode = true;
384
383
 
385
384
  if( SITE_ROOT && PORT && VERBOSITY ) {
385
+
386
386
  L( toInt( VERBOSITY ) );
387
387
 
388
388
  SITE_ROOT = path.resolve( SITE_ROOT );
@@ -396,8 +396,8 @@ if( argv.length == 5 ) {
396
396
  rest_handler( SITE_ROOT, req, res );
397
397
  } );
398
398
 
399
- ws_attach( server, ( msg, connection, domain ) => {
400
- ws_msg_handler( SITE_ROOT, msg, connection );
399
+ ws_attach( server, ( msg, connection, host ) => {
400
+ ws_msg_handler( SITE_ROOT, msg, host, connection );
401
401
  } );
402
402
 
403
403
  server.listen( toInt( PORT ), () => {
@@ -414,7 +414,6 @@ else
414
414
  if( argv.length == 3 && argv[ 2 ] == "-v" ) {
415
415
 
416
416
  // pull package version from package.json and print it
417
-
418
417
  const p = require( __dirname + "/package.json" );
419
418
  log( p.version );
420
419