slower 1.1.23 → 1.1.26

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/lib/router.js CHANGED
@@ -1,7 +1,7 @@
1
1
  const http = require('http');
2
2
  const https = require('https');
3
3
  const fs = require('fs');
4
- const { clone, noop, slugify, isSparseEqual, last, renderDynamicHTML, setSocketLocals, setSocketSecurityHeaders, setResponseAssessors, isPromise } = require('./utils');
4
+ const { clone, noop, slugify, isSparseEqual, last, renderDynamicHTML, setSocketLocals, setSocketSecurityHeaders, setResponseAssessors, isPromise, UUID } = require('./utils');
5
5
  const mimetable = require('./mimetable.json');
6
6
 
7
7
  class Route {
@@ -36,6 +36,7 @@ class SlowerRouter {
36
36
  this.blockedMethodCallback = noop;
37
37
  this.tls = { use: false, key: null, cert: null };
38
38
  this.server = null;
39
+ this.connectionpool = {};
39
40
  }
40
41
 
41
42
  enableStrictHeaders () {
@@ -355,10 +356,9 @@ class SlowerRouter {
355
356
  * @category Router
356
357
  * @param {Number} port The port number the server will listen to.
357
358
  * @param {String} host The host's network interface address the server will listen into (use a falsy value or '0.0.0.0' for listening on all).
358
- * @param {Function} callback The function to execute after starting the server.
359
- * @returns {Object<http.Server>} The server instance
359
+ * @returns {Promise<http.Server>} The server instance
360
360
  */
361
- start = function (port = 8080, host = undefined, callback = () => {}) {
361
+ start = async function (port = 8080, host = undefined) {
362
362
  let routes = this.routes;
363
363
  let middle = this.middleware;
364
364
  let fallback = this.fallback;
@@ -372,6 +372,14 @@ class SlowerRouter {
372
372
  this.server = http.createServer({}, mainServerHandler);
373
373
  }
374
374
 
375
+ this.server.on('connection', (socket) => {
376
+ const id = UUID();
377
+ this.connectionpool[id] = socket;
378
+ socket.on('close', () => delete this.connectionpool[id]);
379
+ socket.on('error', () => delete this.connectionpool[id]);
380
+ socket.on('timeout', () => { this.connectionpool[id].destroy(); delete this.connectionpool[id]; });
381
+ });
382
+
375
383
  async function mainServerHandler (req, res) {
376
384
  try {
377
385
  // Sets local req.session object
@@ -421,12 +429,45 @@ class SlowerRouter {
421
429
  this.port = port;
422
430
  this.host = host;
423
431
  if (!host) host = undefined; // Turn falsy values into undefined, for default behaviour
424
- this.server.listen(port, host, callback);
425
- return this;
432
+ return new Promise((resolve, reject) => this.server.listen(port, host, () => resolve(this)));
426
433
  }
434
+
435
+ /**
436
+ *
437
+ * @param {Object} options
438
+ * @returns
439
+ * Options include:
440
+ * forceDisconnection: boolean (default: false) - If enabled, force sockets to disconnect after a 2 seconds timeout.
441
+ * instantClose: boolean (default: false) - Only relevant if 'forceDisconnection' is enabled. If enabled, force sockets to disconnect immediately.
442
+ * silent: boolean (default: true) - If set to false, show the disconnection status messages.
443
+ */
444
+ close = async function ({ forceDisconnection = false, instantClose = false, silent = true } = {forceDisconnection: false, instantClose: false, silent: true}) {
445
+ return new Promise (async (resolve, reject) => {
446
+ this.server.on('close', () => resolve());
447
+ this.server.on('error', (err) => reject(err));
448
+
449
+ // After this, no more sockets can connect, but the already connected ones, remain
450
+ this.server.close();
451
+ if (!silent) console.log('<> Shutting down server...');
427
452
 
428
- close = function (callback) {
429
- this.server.close(callback);
453
+ if (forceDisconnection) {
454
+ // wait 1 second before continuing
455
+ if (!instantClose) await new Promise ((resolve1, reject1) => setTimeout(resolve1, 1000));
456
+
457
+ // If there are sockets still connected (waiting for timeout),
458
+ // wait until all disconnected or force all to disconnect after 2 seconds
459
+ if (!silent) {
460
+ const activesockets = await new Promise((resolve2, reject2) => this.server.getConnections((err,count) => resolve2(count)));
461
+ console.log(`<> Awaiting disconnection of active sockets [${activesockets}]`);
462
+ }
463
+
464
+ // wait 1 second and destroy the ones still connected
465
+ if (!instantClose) await new Promise ((resolve1, reject1) => setTimeout(resolve1, 1000));
466
+ for (let sock in this.connectionpool) {
467
+ this.connectionpool[sock].destroy();
468
+ }
469
+ }
470
+ });
430
471
  }
431
472
  }
432
473
 
package/lib/utils.js CHANGED
@@ -167,4 +167,6 @@ const isPromise = obj => {
167
167
  typeof obj.then === 'function';
168
168
  }
169
169
 
170
- module.exports = { clone, noop, slugify, isSparseEqual, toBool, last, renderDynamicHTML, setSocketLocals, setSocketSecurityHeaders, setResponseAssessors, isPromise };
170
+ const UUID = () => '################################'.replace(new RegExp(`[#]`, 'gim'), () => Math.random().toString(16)[6]);
171
+
172
+ module.exports = { clone, noop, slugify, isSparseEqual, toBool, last, renderDynamicHTML, setSocketLocals, setSocketSecurityHeaders, setResponseAssessors, isPromise, UUID };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "slower",
3
- "version": "1.1.23",
3
+ "version": "1.1.26",
4
4
  "description": "A package for simple HTTP server routing.",
5
5
  "main": "index.js",
6
6
  "directories": {