cloudcms-server 3.3.1-beta.9 → 4.0.0-beta.10

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.
Files changed (119) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +1 -1
  3. package/broadcast/broadcast.js +6 -3
  4. package/broadcast/providers/redis.js +24 -49
  5. package/clients/nrp.js +117 -0
  6. package/clients/redis.js +64 -0
  7. package/cloudcms-server.iml +1 -0
  8. package/d1/index.js +629 -0
  9. package/d1/index.js.works +203 -0
  10. package/d1/package.json +86 -0
  11. package/d1/package.json.works +14 -0
  12. package/duster/helpers/sample/nyt.js +2 -1
  13. package/framework/controllers.js +4 -4
  14. package/index.js +21 -14
  15. package/insight/insight.js +1 -1
  16. package/launchpad/index.js +203 -11
  17. package/launchpad/launchers/cluster.js +103 -110
  18. package/launchpad/launchers/redis.js +70 -0
  19. package/launchpad/launchers/single.js +36 -22
  20. package/locks/locks.js +63 -9
  21. package/locks/providers/cluster.js +3 -1
  22. package/locks/providers/memory.js +10 -7
  23. package/locks/providers/redis.js +62 -82
  24. package/middleware/admin/admin.js +3 -3
  25. package/middleware/authentication/adapters/session.js +11 -8
  26. package/middleware/authentication/authentication.js +28 -16
  27. package/middleware/authentication/authenticators/default.js +5 -2
  28. package/middleware/authentication/authenticators/session.js +5 -2
  29. package/middleware/authentication/providers/saml.js +2 -2
  30. package/middleware/authorization/authorization.js +11 -8
  31. package/middleware/awareness/awareness.js +63 -38
  32. package/middleware/awareness/plugins/api_event.js +105 -0
  33. package/middleware/awareness/plugins/editorial.js +8 -7
  34. package/middleware/awareness/plugins/resources.js +13 -5
  35. package/middleware/awareness/providers/abstract-async.js +107 -84
  36. package/middleware/awareness/providers/abstract.js +1 -1
  37. package/middleware/awareness/providers/memory.js +0 -14
  38. package/middleware/awareness/providers/redis.js +186 -279
  39. package/middleware/cache/cache.js +4 -2
  40. package/middleware/cache/providers/redis.js +127 -89
  41. package/middleware/cache/providers/shared-memory.js +3 -3
  42. package/middleware/cloudcms/cloudcms.js +22 -16
  43. package/middleware/driver-config/driver-config.js +0 -6
  44. package/middleware/form/form.js +3 -3
  45. package/middleware/modules/modules.js +17 -8
  46. package/middleware/perf/perf.js +3 -2
  47. package/middleware/proxy/proxy.js +8 -21
  48. package/middleware/stores/store.js +0 -1
  49. package/middleware/stores/stores.js +4 -4
  50. package/middleware/virtual-config/virtual-config.js +11 -11
  51. package/middleware/virtual-files/virtual-files.js +0 -3
  52. package/middleware/wcm/wcm.js +4 -4
  53. package/middleware/welcome/welcome.js +0 -3
  54. package/notifications/notifications.js +74 -12
  55. package/notifications/providers/kafka.js +182 -0
  56. package/notifications/providers/stomp.js +4 -0
  57. package/package.json +33 -30
  58. package/server/index.js +508 -416
  59. package/server/standalone.js +9 -0
  60. package/temp/clusterlock/index.js +3 -3
  61. package/temp/clusterlock/package.json +1 -1
  62. package/temp/passport-saml/LICENSE +23 -0
  63. package/temp/passport-saml/README.md +406 -0
  64. package/temp/passport-saml/lib/node-saml/algorithms.d.ts +5 -0
  65. package/temp/passport-saml/lib/node-saml/algorithms.js +41 -0
  66. package/temp/passport-saml/lib/node-saml/algorithms.js.map +1 -0
  67. package/temp/passport-saml/lib/node-saml/index.d.ts +3 -0
  68. package/temp/passport-saml/lib/node-saml/index.js +6 -0
  69. package/temp/passport-saml/lib/node-saml/index.js.map +1 -0
  70. package/temp/passport-saml/lib/node-saml/inmemory-cache-provider.d.ts +45 -0
  71. package/temp/passport-saml/lib/node-saml/inmemory-cache-provider.js +86 -0
  72. package/temp/passport-saml/lib/node-saml/inmemory-cache-provider.js.map +1 -0
  73. package/temp/passport-saml/lib/node-saml/saml-post-signing.d.ts +3 -0
  74. package/temp/passport-saml/lib/node-saml/saml-post-signing.js +15 -0
  75. package/temp/passport-saml/lib/node-saml/saml-post-signing.js.map +1 -0
  76. package/temp/passport-saml/lib/node-saml/saml.d.ts +77 -0
  77. package/temp/passport-saml/lib/node-saml/saml.js +1170 -0
  78. package/temp/passport-saml/lib/node-saml/saml.js.map +1 -0
  79. package/temp/passport-saml/lib/node-saml/types.d.ts +95 -0
  80. package/temp/passport-saml/lib/node-saml/types.js +8 -0
  81. package/temp/passport-saml/lib/node-saml/types.js.map +1 -0
  82. package/temp/passport-saml/lib/node-saml/utility.d.ts +3 -0
  83. package/temp/passport-saml/lib/node-saml/utility.js +19 -0
  84. package/temp/passport-saml/lib/node-saml/utility.js.map +1 -0
  85. package/temp/passport-saml/lib/node-saml/xml.d.ts +21 -0
  86. package/temp/passport-saml/lib/node-saml/xml.js +140 -0
  87. package/temp/passport-saml/lib/node-saml/xml.js.map +1 -0
  88. package/temp/passport-saml/lib/passport-saml/index.d.ts +6 -0
  89. package/temp/passport-saml/lib/passport-saml/index.js +11 -0
  90. package/temp/passport-saml/lib/passport-saml/index.js.map +1 -0
  91. package/temp/passport-saml/lib/passport-saml/multiSamlStrategy.d.ts +13 -0
  92. package/temp/passport-saml/lib/passport-saml/multiSamlStrategy.js +63 -0
  93. package/temp/passport-saml/lib/passport-saml/multiSamlStrategy.js.map +1 -0
  94. package/temp/passport-saml/lib/passport-saml/strategy.d.ts +20 -0
  95. package/temp/passport-saml/lib/passport-saml/strategy.js +167 -0
  96. package/temp/passport-saml/lib/passport-saml/strategy.js.map +1 -0
  97. package/temp/passport-saml/lib/passport-saml/types.d.ts +51 -0
  98. package/temp/passport-saml/lib/passport-saml/types.js +11 -0
  99. package/temp/passport-saml/lib/passport-saml/types.js.map +1 -0
  100. package/temp/passport-saml/package.json +96 -0
  101. package/util/auth.js +16 -10
  102. package/util/cloudcms.js +108 -120
  103. package/util/proxy-factory.js +103 -237
  104. package/util/redis.js +113 -0
  105. package/util/renditions.js +12 -6
  106. package/util/request.js +12 -6
  107. package/util/util.js +16 -2
  108. package/.last_command +0 -7
  109. package/launchpad/launchers/sticky-cluster.js +0 -43
  110. package/temp/memored/.jshintrc +0 -4
  111. package/temp/memored/README.md +0 -240
  112. package/temp/memored/demo/demo1.js +0 -37
  113. package/temp/memored/demo/demo2.js +0 -32
  114. package/temp/memored/gulpfile.js +0 -8
  115. package/temp/memored/index.js +0 -343
  116. package/temp/memored/package.json +0 -54
  117. package/temp/memored/spec/memored.spec.js +0 -265
  118. package/web/cms/ice.js +0 -109
  119. package/web/cms/preview.js +0 -106
package/server/index.js CHANGED
@@ -16,19 +16,20 @@ var session = require('express-session');
16
16
  var cookieParser = require('cookie-parser');
17
17
  var flash = require("connect-flash");
18
18
 
19
+ //const redis = require('redis');
20
+ const connectRedis = require('connect-redis');
21
+
19
22
  // we don't bind a single passport - instead, we get the constructor here by hand
20
23
  var Passport = require("passport").Passport;
21
24
 
22
25
  var util = require("../util/util");
26
+ var redisHelper = require("../util/redis");
23
27
 
24
28
  var launchPad = require("../launchpad/index");
25
29
  var cluster = require("cluster");
26
30
 
27
31
  var requestParam = require("request-param")();
28
32
 
29
- var app = express();
30
- app.disable('x-powered-by');
31
-
32
33
  // cloudcms app server support
33
34
  var main = require("../index");
34
35
 
@@ -37,17 +38,31 @@ var duster = require("../duster/index");
37
38
 
38
39
  var coreHelpers = require("../duster/helpers/core/index");
39
40
 
40
- var toobusy = require("toobusy-js");
41
- toobusy.maxLag(500); // 500 ms lag in event queue, quite high but usable for now
42
- toobusy.interval(250);
41
+ var helmet = require("helmet");
43
42
 
44
43
  var responseTime = require("response-time");
45
44
 
45
+ // safely checks for the existence of a path
46
+ var safeExists = function(_path)
47
+ {
48
+ var exists = false;
49
+ try
50
+ {
51
+ exists = fs.existsSync(_path);
52
+ }
53
+ catch (e)
54
+ {
55
+ // swallow
56
+ }
57
+
58
+ return exists;
59
+ }
60
+
46
61
  var requestCounter = 0;
47
62
 
48
63
  // holds configuration settings
49
64
  var SETTINGS = {
50
- "setup": "single", // single, cluster, sticky-cluster
65
+ "setup": "single", // single, cluster, redis
51
66
  "name": "Cloud CMS Application Server",
52
67
  "socketFunctions": [],
53
68
  "routeFunctions": [],
@@ -128,7 +143,7 @@ var SETTINGS = {
128
143
  "web": "app",
129
144
  "content": "hosts_fs",
130
145
  "templates": "app",
131
- "themes": "app",
146
+ "themes": "hosts_fs",
132
147
  "modules": "hosts_fs"
133
148
  },
134
149
  "net-development": {
@@ -154,8 +169,8 @@ var SETTINGS = {
154
169
  "config": "hosts_s3",
155
170
  "web": "hosts_s3",
156
171
  "content": "hosts_s3",
157
- "templates": "hosts_s3",
158
- "themes": "hosts_s3"
172
+ "themes": "hosts_s3",
173
+ "templates": "hosts_s3"
159
174
  },
160
175
  "net-development-s3fs": {
161
176
  "root": "hosts_s3fs",
@@ -299,9 +314,7 @@ var SETTINGS = {
299
314
  //"reapInterval": -1
300
315
  },
301
316
  "awareness": {
302
- "enabled": false,
303
- "type": "memory",
304
- "config": {}
317
+ "enabled": false
305
318
  },
306
319
  "graphql": {
307
320
  "enabled": true,
@@ -311,17 +324,67 @@ var SETTINGS = {
311
324
  }
312
325
  };
313
326
 
327
+ // always push core tag helpers to the front
328
+ SETTINGS.dustFunctions.unshift(coreHelpers);
329
+
330
+ // if SETTINGS.errorFunctions is empty, plug in a default error handler
331
+ if (SETTINGS.errorFunctions.length === 0)
332
+ {
333
+ SETTINGS.errorFunctions.push(main.defaultErrorHandler);
334
+ }
335
+ else
336
+ {
337
+ // otherwise, if they plugged in a custom error handler, make sure we at least have a console logger ahead of it
338
+ // so that things are sure to get logged out to console
339
+ SETTINGS.errorFunctions.unshift(main.consoleErrorLogger);
340
+ }
341
+
342
+ // insert an error handler to handle refresh token failures
343
+ SETTINGS.errorFunctions.unshift(main.refreshTokenErrorHandler);
344
+
345
+ // CLOUDCMS_HOSTS_PATH environment variable
346
+ // assume /hosts with optional fallback to /System/Volumes/Data/hosts for MacOS support
347
+ if (!process.env.CLOUDCMS_HOSTS_PATH)
348
+ {
349
+ process.env.CLOUDCMS_HOSTS_PATH = "/hosts";
350
+
351
+ if (!safeExists(process.env.CLOUDCMS_HOSTS_PATH))
352
+ {
353
+ if (safeExists("/System/Volumes/Data/hosts"))
354
+ {
355
+ process.env.CLOUDCMS_HOSTS_PATH = "/System/Volumes/Data/hosts";
356
+ }
357
+ else
358
+ {
359
+ const homedir = require('os').homedir();
360
+
361
+ if (safeExists(homedir + "/hosts"))
362
+ {
363
+ process.env.CLOUDCMS_HOSTS_PATH = homedir + "/hosts";
364
+ }
365
+ }
366
+ }
367
+ }
368
+
369
+
370
+
371
+
372
+
373
+
374
+
375
+
376
+
377
+
378
+
379
+
380
+
381
+
382
+
383
+
384
+
314
385
  // runs on 2999 by default
315
386
  process.env.PORT = process.env.PORT || 2999;
316
387
 
317
- // allows for specification of alternative transports
318
- SETTINGS.socketTransports = [
319
- 'websocket',
320
- 'xhr-polling',
321
- 'jsonp-polling',
322
- 'polling'
323
- ];
324
-
325
388
  var exports = module.exports;
326
389
 
327
390
  /**
@@ -484,7 +547,6 @@ var runFunctions = function (functions, args, callback) {
484
547
  * @param callback optional callback function
485
548
  */
486
549
  exports.start = function(overrides, callback) {
487
-
488
550
  setTimeout(function() {
489
551
  _start(overrides, function(err) {
490
552
  if (callback) {
@@ -505,62 +567,19 @@ var _start = function(overrides, callback) {
505
567
  callback = function() {};
506
568
  }
507
569
 
508
- // always push core tag helpers to the front
509
- SETTINGS.dustFunctions.unshift(coreHelpers);
510
-
511
- // if SETTINGS.errorFunctions is empty, plug in a default error handler
512
- if (SETTINGS.errorFunctions.length === 0)
513
- {
514
- SETTINGS.errorFunctions.push(main.defaultErrorHandler);
515
- }
516
- else
517
- {
518
- // otherwise, if they plugged in a custom error handler, make sure we at least have a console logger ahead of it
519
- // so that things are sure to get logged out to console
520
- SETTINGS.errorFunctions.unshift(main.consoleErrorLogger);
521
- }
522
-
523
- // insert an error handler to handle refresh token failures
524
- SETTINGS.errorFunctions.unshift(main.refreshTokenErrorHandler);
525
-
526
570
  // create our master config
527
571
  var config = clone(SETTINGS);
528
572
  if (overrides) {
529
573
  util.merge(overrides, config);
530
574
  }
531
-
532
- // assume for launchpad
533
- if (!config.setup) {
534
- config.setup = "single";
535
- }
536
-
537
- launchPad({
538
- "setup": config.setup,
539
- "factory": function(done) {
540
- startSlave(config, function(app, server) {
541
- done(server);
542
- });
543
- },
544
- "report": function() {
545
- runFunctions(config.reportFunctions, [], function(err) {
546
- // todo
547
- });
548
- },
549
- "complete": function() {
550
- callback();
551
- }
552
- });
553
- };
554
-
555
- var startSlave = function(config, afterStartFn)
556
- {
575
+
557
576
  // set up modes
558
577
  process.env.CLOUDCMS_APPSERVER_MODE = "development";
559
-
560
- if (process.env.NODE_ENV == "production") {
578
+
579
+ if (process.env.NODE_ENV === "production") {
561
580
  process.env.CLOUDCMS_APPSERVER_MODE = "production";
562
581
  }
563
-
582
+
564
583
  /*
565
584
  // set up domain hosting
566
585
  // if not otherwise specified, we assume hosting at *.cloudcms.net
@@ -571,10 +590,10 @@ var startSlave = function(config, afterStartFn)
571
590
  }
572
591
  }
573
592
  */
574
-
593
+
575
594
  // store config on process instance
576
595
  process.configuration = config;
577
-
596
+
578
597
  // some config overrides can come in through process.configuration
579
598
  if (process.configuration) {
580
599
  if (process.configuration.virtualHost && process.configuration.virtualHost.domain) {
@@ -588,111 +607,185 @@ var startSlave = function(config, afterStartFn)
588
607
  if (process.env.CLOUDCMS_VIRTUAL_HOST_DOMAIN) {
589
608
  process.env.CLOUDCMS_VIRTUAL_HOST_DOMAIN = process.env.CLOUDCMS_VIRTUAL_HOST_DOMAIN.toLowerCase();
590
609
  }
591
-
610
+
592
611
  if (!process.env.CLOUDCMS_STANDALONE_HOST) {
593
612
  process.env.CLOUDCMS_STANDALONE_HOST = "local";
594
613
  }
595
-
596
- // session store
597
- var initializedSession = null;
598
- if (process.configuration.session)
599
- {
600
- if (process.configuration.session.enabled)
601
- {
602
- var sessionSecret = process.configuration.session.secret;
603
- if (!sessionSecret) {
604
- sessionSecret = "secret";
605
- }
606
-
607
- var sessionConfig = {
608
- secret: sessionSecret,
609
- resave: false,
610
- saveUninitialized: false
611
- };
612
-
613
- if (process.configuration.session.type === "file")
614
- {
615
- var options = {};
616
- if (process.configuration.session.ttl)
617
- {
618
- options.ttl = process.configuration.session.ttl;
619
- }
620
- if (process.configuration.session.reapInterval)
621
- {
622
- options.reapInterval = process.configuration.session.reapInterval;
623
- }
624
- // session file store
625
- var SessionFileStore = require('session-file-store')(session);
626
- sessionConfig.store = new SessionFileStore(options);
627
- }
628
- else if (process.configuration.session.type === "memory" || !process.configuration.session.type)
629
- {
630
- var options = {};
631
- options.checkPeriod = 86400000; // prune expired entries every 24h
632
-
633
- // session memory store
634
- var MemoryStore = require('memorystore')(session);
635
- sessionConfig.store = new MemoryStore(options);
614
+
615
+
616
+ // auto-configuration for HTTPS
617
+ if (!process.configuration.https) {
618
+ process.configuration.https = {};
619
+ }
620
+ if (process.env.CLOUDCMS_HTTPS) {
621
+ process.configuration.https = JSON.parse(process.env.CLOUDCMS_HTTPS);
622
+ }
623
+ if (process.env.CLOUDCMS_HTTPS_KEY_FILEPATH) {
624
+ process.configuration.https.key = fs.readFileSync(process.env.CLOUDCMS_HTTPS_KEY_FILEPATH);
625
+ }
626
+ if (process.env.CLOUDCMS_HTTPS_CERT_FILEPATH) {
627
+ process.configuration.https.cert = fs.readFileSync(process.env.CLOUDCMS_HTTPS_CERT_FILEPATH);
628
+ }
629
+ if (process.env.CLOUDCMS_HTTPS_PFX_FILEPATH) {
630
+ process.configuration.https.pfx = fs.readFileSync(process.env.CLOUDCMS_HTTPS_PFX_FILEPATH);
631
+ }
632
+ if (process.env.CLOUDCMS_HTTPS_PASSPHRASE) {
633
+ process.configuration.https.passphrase = process.env.CLOUDCMS_HTTPS_PASSPHRASE;
634
+ }
635
+ if (process.env.CLOUDCMS_HTTPS_REQUEST_CERT === "true") {
636
+ process.configuration.https.requestCert = true;
637
+ }
638
+ if (process.env.CLOUDCMS_HTTPS_CA_FILEPATH) {
639
+ process.configuration.https.ca = [ fs.readFileSync(process.env.CLOUDCMS_HTTPS_CA_FILEPATH) ];
640
+ }
641
+
642
+ // if https config is empty, remove it
643
+ if (Object.keys(process.configuration.https).length === 0) {
644
+ delete process.configuration.https;
645
+ }
646
+
647
+
648
+ // auto configuration of session store
649
+ if (!process.configuration.session) {
650
+ process.configuration.session = {};
651
+ }
652
+ // auto-configuration for redis?
653
+ if (process.env.CLOUDCMS_REDIS_URL || (process.env.CLOUDCMS_REDIS_ENDPOINT && process.env.CLOUDCMS_REDIS_PORT)) {
654
+ process.env.CLOUDCMS_SESSION_TYPE = "redis";
655
+ }
656
+
657
+ if (process.env.CLOUDCMS_SESSION_TYPE) {
658
+ process.configuration.session.enabled = true;
659
+ process.configuration.session.type = process.env.CLOUDCMS_SESSION_TYPE;
660
+ }
661
+ if (process.env.CLOUDCMS_SESSION_SECRET) {
662
+ process.configuration.session.secret = process.env.CLOUDCMS_SESSION_SECRET;
663
+ }
664
+
665
+
666
+ // determine the max files
667
+ util.maxFiles(function(err, maxFiles) {
668
+ process.env.CLOUDCMS_MAX_FILES = maxFiles;
669
+
670
+ // assume for launchpad
671
+ if (!config.setup) {
672
+ config.setup = "single";
673
+ }
674
+
675
+ launchPad(config.setup, config, {
676
+ "createHttpServer": function(app, done) {
677
+ createHttpServer(app, function(err, httpServer) {
678
+ done(err, httpServer);
679
+ });
680
+ },
681
+ "startServer": function(config, done) {
682
+ startServer(config, function(err, app, httpServer, httpServerPort) {
683
+ done(err, app, httpServer, httpServerPort);
684
+ });
685
+ },
686
+ "configureServer": function(config, app, httpServer, done) {
687
+ configureServer(config, app, httpServer, function(err) {
688
+ done(err);
689
+ });
690
+ },
691
+ "report": function(config) {
692
+ runFunctions(config.reportFunctions, [], function(err) {
693
+ // todo
694
+ });
695
+ },
696
+ "complete": function(config, err) {
697
+ callback(err);
636
698
  }
699
+ });
700
+ });
701
+ };
637
702
 
638
- initializedSession = session(sessionConfig);
639
- }
703
+ var initSession = function(initDone)
704
+ {
705
+ if (!process.configuration.session) {
706
+ return initDone();
640
707
  }
641
-
642
- // safely checks for the existence of a path
643
- var safeExists = function(_path)
708
+ if (!process.configuration.session.enabled) {
709
+ return initDone();
710
+ }
711
+
712
+ var sessionSecret = process.configuration.session.secret;
713
+ if (!sessionSecret) {
714
+ sessionSecret = "secret";
715
+ }
716
+
717
+ var sessionConfig = {
718
+ secret: sessionSecret,
719
+ resave: false,
720
+ saveUninitialized: false
721
+ };
722
+
723
+ if (process.configuration.session.type) {
724
+ process.configuration.session.type = process.configuration.session.type.toLowerCase();
725
+ }
726
+
727
+ if (process.configuration.session.type === "file")
644
728
  {
645
- var exists = false;
646
- try
729
+ var options = {};
730
+ if (process.configuration.session.ttl)
647
731
  {
648
- exists = fs.existsSync(_path);
732
+ options.ttl = process.configuration.session.ttl;
649
733
  }
650
- catch (e)
734
+ if (process.configuration.session.reapInterval)
651
735
  {
652
- // swallow
736
+ options.reapInterval = process.configuration.session.reapInterval;
653
737
  }
654
-
655
- return exists;
738
+ // session file store
739
+ var SessionFileStore = require('session-file-store')(session);
740
+ sessionConfig.store = new SessionFileStore(options);
741
+ return initDone(null, session(sessionConfig));
656
742
  }
657
-
658
- // CLOUDCMS_HOSTS_PATH environment variable
659
- // assume /hosts with optional fallback to /System/Volumes/Data/hosts for MacOS support
660
- if (!process.env.CLOUDCMS_HOSTS_PATH)
743
+ else if (process.configuration.session.type === "redis")
661
744
  {
662
- process.env.CLOUDCMS_HOSTS_PATH = "/hosts";
663
-
664
- if (!safeExists(process.env.CLOUDCMS_HOSTS_PATH))
665
- {
666
- if (safeExists("/System/Volumes/Data/hosts"))
667
- {
668
- process.env.CLOUDCMS_HOSTS_PATH = "/System/Volumes/Data/hosts";
669
- }
670
- else
671
- {
672
- const homedir = require('os').homedir();
673
-
674
- if (safeExists(homedir + "/hosts"))
675
- {
676
- process.env.CLOUDCMS_HOSTS_PATH = homedir + "/hosts";
677
- }
678
- }
679
- }
745
+ var IORedis = require("ioredis");
746
+ var redisOptions = redisHelper.redisOptions();
747
+ var redisClient = new IORedis(redisOptions.url);
748
+
749
+ var RedisStore = connectRedis(session);
750
+ sessionConfig.store = new RedisStore({ client: redisClient });
751
+ initDone(null, session(sessionConfig));
680
752
  }
753
+ else if (process.configuration.session.type === "memory" || !process.configuration.session.type)
754
+ {
755
+ var options = {};
756
+ options.checkPeriod = 86400000; // prune expired entries every 24h
757
+
758
+ // session memory store
759
+ var MemoryStore = require('memorystore')(session);
760
+ sessionConfig.store = new MemoryStore(options);
761
+ return initDone(null, session(sessionConfig));
762
+ }
763
+ };
681
764
 
682
- // global temp directory
683
- util.createTempDirectory(function(err, tempDirectory) {
684
- process.env.CLOUDCMS_TEMPDIR_PATH = tempDirectory;
685
-
686
- // determine the max files
687
- util.maxFiles(function(err, maxFiles) {
688
-
689
- process.env.CLOUDCMS_MAX_FILES = maxFiles;
765
+ var startServer = function(config, startServerFinishedFn)
766
+ {
767
+ var app = express();
768
+ app.disable('x-powered-by');
769
+
770
+ initSession(function(err, initializedSession) {
690
771
 
772
+ if (err) {
773
+ throw err;
774
+ }
775
+
776
+ // global temp directory
777
+ util.createTempDirectory(function(err, tempDirectory) {
778
+ process.env.CLOUDCMS_TEMPDIR_PATH = tempDirectory;
779
+
691
780
  // global service starts
692
781
  main.init(app, function (err) {
693
-
782
+
783
+ if (err) {
784
+ return startServerFinishedFn(err);
785
+ }
786
+
694
787
  app.enable('strict routing');
695
-
788
+
696
789
  ////////////////////////////////////////////////////////////////////////////
697
790
  //
698
791
  // BASE CONFIGURATION
@@ -701,15 +794,15 @@ var startSlave = function(config, afterStartFn)
701
794
  // Runs on port 3000 by default
702
795
  //
703
796
  ////////////////////////////////////////////////////////////////////////////
704
-
797
+
705
798
  // all environments
706
799
  app.set('port', process.env.PORT);
707
800
  app.set('views', process.env.CLOUDCMS_APPSERVER_BASE_PATH + "/views");
708
-
801
+
709
802
  if (config.viewEngine === "dust")
710
803
  {
711
804
  var cons = require('consolidate');
712
-
805
+
713
806
  app.set('view engine', 'html');
714
807
  app.set('view engine', 'dust');
715
808
  app.engine('html', cons.dust);
@@ -718,13 +811,13 @@ var startSlave = function(config, afterStartFn)
718
811
  else if (config.viewEngine === "handlebars" || config.viewEngine === "hbs")
719
812
  {
720
813
  var hbs = require('hbs');
721
-
814
+
722
815
  app.set('view engine', 'html');
723
816
  app.set('view engine', 'hbs');
724
817
  app.engine('html', hbs.__express);
725
818
  app.engine('hbs', hbs.__express);
726
819
  }
727
-
820
+
728
821
  ////////////////////////////////////////////////////////////////////////////
729
822
  //
730
823
  // VIRTUAL SUPPORT
@@ -733,26 +826,26 @@ var startSlave = function(config, afterStartFn)
733
826
  // ahead of anything else running.
734
827
  //
735
828
  ////////////////////////////////////////////////////////////////////////////
736
-
829
+
737
830
  // custom morgan logger
738
831
  morgan(function (tokens, req, res) {
739
-
832
+
740
833
  var status = res.statusCode;
741
834
  var len = parseInt(res.getHeader('Content-Length'), 10);
742
835
  var host = req.domainHost;
743
836
  if (req.virtualHost) {
744
837
  host = req.virtualHost;
745
838
  }
746
-
839
+
747
840
  len = isNaN(len) ? '0b' : len = bytes(len);
748
-
841
+
749
842
  var d = new Date();
750
843
  var dateString = d.toDateString();
751
844
  var timeString = d.toTimeString();
752
-
845
+
753
846
  // gray color
754
847
  var grayColor = "\x1b[90m";
755
-
848
+
756
849
  // status color
757
850
  var color = 32;
758
851
  if (status >= 500) {
@@ -765,17 +858,17 @@ var startSlave = function(config, afterStartFn)
765
858
  color = 36;
766
859
  }
767
860
  var statusColor = "\x1b[" + color + "m";
768
-
861
+
769
862
  // final color
770
863
  var finalColor = "\x1b[0m";
771
-
772
- if (process.env.CLOUDCMS_APPSERVER_MODE == "production")
864
+
865
+ if (process.env.CLOUDCMS_APPSERVER_MODE === "production")
773
866
  {
774
867
  grayColor = "";
775
868
  statusColor = "";
776
869
  finalColor = "";
777
870
  }
778
-
871
+
779
872
  var message = '';
780
873
  message += grayColor + '<' + req.id + '> ';
781
874
  message += grayColor + '[' + dateString + ' ' + timeString + '] ';
@@ -787,10 +880,10 @@ var startSlave = function(config, afterStartFn)
787
880
  message += grayColor + req.originalUrl + '" ';
788
881
  message += grayColor + len + ' ';
789
882
  message += finalColor;
790
-
883
+
791
884
  return message;
792
885
  });
793
-
886
+
794
887
  /*
795
888
  // debug headers being set
796
889
  app.use(function(req, res, next) {
@@ -802,58 +895,49 @@ var startSlave = function(config, afterStartFn)
802
895
  next();
803
896
  });
804
897
  */
805
-
806
- // middleware which blocks requests when we're too busy
807
- app.use(function(req, res, next) {
808
- if (toobusy()) {
809
- res.status(503).send("The web application is too busy to serve this request. Please try again.");
810
- } else {
811
- next();
812
- }
813
- });
814
-
815
- // add req.id re
898
+
899
+ // increment and assign request id
816
900
  app.use(function (req, res, next) {
817
901
  requestCounter++;
818
902
  req.id = requestCounter;
819
903
  next();
820
904
  });
821
-
905
+
822
906
  // APPLY CUSTOM INIT FUNCTIONS
823
907
  runFunctions(config.initFunctions, [app], function (err) {
824
-
908
+
825
909
  // retain originalUrl and originalPath since these can get modified along the way
826
910
  app.use(function (req, res, next) {
827
911
  req.originalUrl = req.url;
828
912
  req.originalPath = req.path;
829
913
  next();
830
914
  });
831
-
915
+
832
916
  // req.param method
833
917
  app.use(requestParam);
834
-
918
+
835
919
  // add req.log function
836
920
  app.use(function (req, res, next) {
837
-
921
+
838
922
  req._log = req.log = function (text/*, warn*/) {
839
-
923
+
840
924
  var host = req.domainHost;
841
925
  if (req.virtualHost)
842
926
  {
843
927
  host = req.virtualHost;
844
928
  }
845
-
929
+
846
930
  var timestamp = moment(new Date()).format("MM/DD/YYYY HH:mm:ss Z");
847
931
  var grayColor = "\x1b[90m";
848
932
  var finalColor = "\x1b[0m";
849
-
933
+
850
934
  // in production, don't use colors
851
935
  if (process.env.CLOUDCMS_APPSERVER_MODE === "production")
852
936
  {
853
937
  grayColor = "";
854
938
  finalColor = "";
855
939
  }
856
-
940
+
857
941
  var message = '';
858
942
  message += grayColor + '<' + req.id + '> ';
859
943
  if (cluster.worker && cluster.worker.id)
@@ -864,33 +948,33 @@ var startSlave = function(config, afterStartFn)
864
948
  message += grayColor + host + ' ';
865
949
  message += grayColor + text + '';
866
950
  message += finalColor;
867
-
951
+
868
952
  /*
869
953
  if (warn)
870
954
  {
871
955
  message = "\r\n**** SLOW RESPONSE ****\r\n" + message + "\r\n";
872
956
  }
873
957
  */
874
-
958
+
875
959
  console.log(message);
876
960
  };
877
-
961
+
878
962
  next();
879
963
  });
880
-
964
+
881
965
  // common interceptors and config
882
966
  main.common1(app);
883
-
967
+
884
968
  // general logging of requests
885
969
  // gather statistics on response time
886
970
  app.use(responseTime(function (req, res, time) {
887
-
971
+
888
972
  var warn = false;
889
973
  if (time > 1000)
890
974
  {
891
975
  warn = true;
892
976
  }
893
-
977
+
894
978
  var requestPath = req.originalPath;
895
979
  if (requestPath)
896
980
  {
@@ -908,51 +992,51 @@ var startSlave = function(config, afterStartFn)
908
992
  requestPath = util.stripQueryStringFromUrl(requestPath);
909
993
  }
910
994
  }
911
-
995
+
912
996
  req.log(req.method + " " + requestPath + " [" + res.statusCode + "] (" + time.toFixed(2) + " ms)", warn);
913
997
  }));
914
-
998
+
915
999
  // set up CORS allowances
916
1000
  // this lets CORS requests float through the proxy
917
1001
  app.use(main.ensureCORS());
918
-
1002
+
919
1003
  // set up default security headers
920
1004
  app.use(main.ensureHeaders());
921
-
1005
+
922
1006
  // common interceptors and config
923
1007
  main.common2(app);
924
-
1008
+
925
1009
  // APPLY CUSTOM DRIVER FUNCTIONS
926
1010
  runFunctions(config.driverFunctions, [app], function(err) {
927
-
1011
+
928
1012
  // binds gitana driver into place
929
1013
  main.common3(app);
930
-
1014
+
931
1015
  // parse cookies
932
1016
  app.use(cookieParser());
933
-
1017
+
934
1018
  // cloudcms things need to run here
935
1019
  main.common4(app, true);
936
-
1020
+
937
1021
  // APPLY CUSTOM FILTER FUNCTIONS
938
1022
  runFunctions(config.filterFunctions, [app], function (err) {
939
-
1023
+
940
1024
  // PATH BASED PERFORMANCE CACHING
941
1025
  main.perf1(app);
942
-
1026
+
943
1027
  // proxy - anything that goes to /proxy is handled here early and nothing processes afterwards
944
1028
  main.proxy(app);
945
-
1029
+
946
1030
  // MIMETYPE BASED PERFORMANCE CACHING
947
1031
  main.perf2(app);
948
-
1032
+
949
1033
  // DEVELOPMENT BASED PERFORMANCE CACHING
950
1034
  main.perf3(app);
951
-
1035
+
952
1036
  // standard body parsing + a special cloud cms body parser that makes a last ditch effort for anything
953
1037
  // that might be JSON (regardless of content type)
954
1038
  app.use(function (req, res, next) {
955
-
1039
+
956
1040
  multipart(process.configuration.bodyParsers.multipart || {})(req, res, function (err) {
957
1041
  bodyParser.json(process.configuration.bodyParsers.json || {})(req, res, function (err) {
958
1042
  bodyParser.urlencoded(process.configuration.bodyParsers.urlencoded || {})(req, res, function (err) {
@@ -962,35 +1046,35 @@ var startSlave = function(config, afterStartFn)
962
1046
  });
963
1047
  });
964
1048
  });
965
-
1049
+
966
1050
  });
967
-
1051
+
968
1052
  if (initializedSession)
969
1053
  {
970
1054
  app.use(initializedSession);
971
1055
  app.use(flash());
972
1056
  }
973
-
1057
+
974
1058
  // this is the same as calling
975
1059
  // app.use(passport.initialize());
976
1060
  // except we create a new passport each time and store on request to support multitenancy
977
1061
  app.use(function(req, res, next) {
978
-
1062
+
979
1063
  var passport = new Passport();
980
1064
  passport._key = "passport-" + req.virtualHost;
981
-
1065
+
982
1066
  req._passport = {};
983
1067
  req._passport.instance = passport;
984
-
1068
+
985
1069
  if (req.session && req.session[passport._key])
986
1070
  {
987
1071
  // load data from existing session
988
1072
  req._passport.session = req.session[passport._key];
989
1073
  }
990
-
1074
+
991
1075
  // add this in
992
1076
  req.passport = req._passport.instance;
993
-
1077
+
994
1078
  // passport - serialize and deserialize
995
1079
  req.passport.serializeUser(function(user, done) {
996
1080
  done(null, user);
@@ -998,10 +1082,10 @@ var startSlave = function(config, afterStartFn)
998
1082
  req.passport.deserializeUser(function(user, done) {
999
1083
  done(null, user);
1000
1084
  });
1001
-
1085
+
1002
1086
  next();
1003
1087
  });
1004
-
1088
+
1005
1089
  // passport session
1006
1090
  if (initializedSession)
1007
1091
  {
@@ -1009,27 +1093,27 @@ var startSlave = function(config, afterStartFn)
1009
1093
  req.passport.session()(req, res, next);
1010
1094
  });
1011
1095
  }
1012
-
1096
+
1013
1097
  // welcome files
1014
1098
  main.welcome(app);
1015
-
1099
+
1016
1100
  // configure cloudcms app server command handing
1017
1101
  main.interceptors(app, true);
1018
-
1102
+
1019
1103
  //app.use(app.router);
1020
-
1104
+
1021
1105
  // healthcheck middleware
1022
1106
  main.healthcheck(app);
1023
-
1107
+
1024
1108
  // APPLY CUSTOM ROUTES
1025
1109
  runFunctions(config.routeFunctions, [app], function (err) {
1026
-
1110
+
1027
1111
  // configure cloudcms app server handlers
1028
1112
  main.handlers(app, true);
1029
-
1113
+
1030
1114
  // register error functions
1031
1115
  runFunctions(config.errorFunctions, [app], function (err) {
1032
-
1116
+
1033
1117
  // APPLY CUSTOM CONFIGURE FUNCTIONS
1034
1118
  var allConfigureFunctions = [];
1035
1119
  for (var env in config.configureFunctions)
@@ -1044,188 +1128,15 @@ var startSlave = function(config, afterStartFn)
1044
1128
  }
1045
1129
  }
1046
1130
  runFunctions(allConfigureFunctions, [app], function (err) {
1047
-
1048
- ////////////////////////////////////////////////////////////////////////////
1049
- //
1050
- // INITIALIZE THE SERVER
1051
- //
1052
- ////////////////////////////////////////////////////////////////////////////
1053
-
1054
-
1055
- // CORE OBJECTS
1056
- var server = http.Server(app);
1057
-
1058
- // request timeout
1059
- var requestTimeout = 30000; // 30 seconds
1060
- if (process.configuration && process.configuration.timeout)
1061
- {
1062
- requestTimeout = process.configuration.timeout;
1063
- }
1064
- server.setTimeout(requestTimeout);
1065
-
1066
- // socket
1067
- server.on("connection", function (socket) {
1068
- socket.setNoDelay(true);
1069
- });
1070
- var io = process.IO = require("socket.io")(server, {
1071
- "transports": config.socketTransports
1072
- });
1073
- io.use(function (socket, next) {
1074
-
1075
- // console.log("New socket being initialized");
1076
-
1077
- // attach _log function
1078
- socket._log = function (text) {
1079
-
1080
- var host = socket.handshake.headers.host;
1081
- if (socket.handshake.headers["x-forwarded-host"])
1082
- {
1083
- host = socket.handshake.headers["x-forwarded-host"];
1084
- }
1085
-
1086
- var d = new Date();
1087
- var dateString = d.toDateString();
1088
- var timeString = d.toTimeString();
1089
-
1090
- // gray color
1091
- var grayColor = "\x1b[90m";
1092
-
1093
- // final color
1094
- var finalColor = "\x1b[0m";
1095
-
1096
- if (process.env.CLOUDCMS_APPSERVER_MODE === "production")
1097
- {
1098
- grayColor = "";
1099
- finalColor = "";
1100
- }
1101
-
1102
- var message = '';
1103
- message += grayColor + '<socket> ';
1104
- message += grayColor + '[' + dateString + ' ' + timeString + '] ';
1105
- message += grayColor + host + ' ';
1106
- message += grayColor + text + '';
1107
- message += finalColor;
1108
-
1109
- console.log(message);
1110
- };
1111
- /*
1112
- socket.on("connect", function () {
1113
- console.log("Socket connect()");
1114
- });
1115
- */
1116
- /*
1117
- socket.on("disconnect", function () {
1118
- var message = "Socket disconnected";
1119
- if (socket && socket.host)
1120
- {
1121
- message += ", host=" + socket.host;
1122
- }
1123
- if (socket && socket.gitana && socket.gitana.application && socket.gitana.application())
1124
- {
1125
- message += ", application=" + socket.gitana.application().title;
1126
- }
1127
- console.log(message);
1128
- });
1129
- */
1130
-
1131
- // APPLY CUSTOM SOCKET.IO CONFIG
1132
- runFunctions(config.socketFunctions, [socket], function (err) {
1133
-
1134
- require("../middleware/awareness/awareness").initSocketIO(function() {
1135
- next();
1136
- });
1137
-
1138
- // INSIGHT SERVER
1139
- // if (config.insight && config.insight.enabled)
1140
- // {
1141
- // console.log("Init Insight to Socket");
1142
-
1143
- // require("../insight/insight").init(socket, function () {
1144
- // next();
1145
- // });
1146
- // }
1147
- // else
1148
- // {
1149
- // next();
1150
- // }
1151
- });
1152
-
1153
- });
1154
-
1155
- // SET INITIAL VALUE FOR SERVER TIMESTAMP
1156
- process.env.CLOUDCMS_APPSERVER_TIMESTAMP = new Date().getTime();
1157
-
1158
- // DUST
1159
- runFunctions(config.dustFunctions, [app, duster.getDust()], function (err) {
1160
-
1161
- // APPLY SERVER BEFORE START FUNCTIONS
1162
- runFunctions(config.beforeFunctions, [app], function (err) {
1163
-
1164
- server._listenPort = app.get("port");
1165
-
1166
- // AFTER SERVER START
1167
- runFunctions(config.afterFunctions, [app], function (err) {
1168
-
1169
- function cleanup() {
1170
-
1171
- if (cluster.isMaster)
1172
- {
1173
- console.log("");
1174
- console.log("");
1175
-
1176
- console.log("Cloud CMS Module shutting down");
1177
-
1178
- // close server connections as cleanly as we can
1179
- console.log(" -> Closing server connections");
1180
- }
1181
-
1182
- try
1183
- {
1184
- server.close();
1185
- }
1186
- catch (e)
1187
- {
1188
- console.log("Server.close produced error: " + JSON.stringify(e));
1189
- }
1190
-
1191
- // ask toobusy to shut down as cleanly as we can
1192
- if (cluster.isMaster)
1193
- {
1194
- console.log(" -> Closing toobusy monitor");
1195
- }
1196
-
1197
- try
1198
- {
1199
- toobusy.shutdown();
1200
- }
1201
- catch (e)
1202
- {
1203
- console.log("toobusy.shutdown produced error: " + JSON.stringify(e));
1204
- }
1205
-
1206
- if (cluster.isMaster)
1207
- {
1208
- console.log("");
1209
- }
1210
-
1211
- // tell the process to exit
1212
- process.exit();
1213
- }
1214
-
1215
- // listen for kill or interrupt so that we can shut down cleanly
1216
- process.on('SIGINT', cleanup);
1217
- process.on('SIGTERM', cleanup);
1218
-
1219
- // if we are on a worker process, then inform the master that we completed
1220
- if (process.send)
1221
- {
1222
- process.send("server-startup");
1223
- }
1224
-
1225
- afterStartFn(app, server);
1226
-
1227
- });
1228
- });
1131
+
1132
+ // create the server (either HTTP or HTTPS)
1133
+ createHttpServer(app, function(err, httpServer) {
1134
+
1135
+ if (err) {
1136
+ return startServerFinishedFn(err);
1137
+ }
1138
+
1139
+ startServerFinishedFn(null, app, httpServer);
1229
1140
  });
1230
1141
  });
1231
1142
  });
@@ -1238,6 +1149,187 @@ var startSlave = function(config, afterStartFn)
1238
1149
  });
1239
1150
  };
1240
1151
 
1152
+ var createHttpServer = function(app, done)
1153
+ {
1154
+ // create the server (either HTTP or HTTPS)
1155
+ var httpServer = null;
1156
+
1157
+ if (process.configuration.https)
1158
+ {
1159
+ if (app)
1160
+ {
1161
+ // configure helmet to support auto-upgrade of http->https
1162
+ app.use(helmet());
1163
+ }
1164
+
1165
+ // create https server
1166
+ httpServer = https.createServer(process.configuration.https, app);
1167
+ }
1168
+ else
1169
+ {
1170
+ // legacy
1171
+ httpServer = http.Server(app);
1172
+ }
1173
+
1174
+ // request timeout
1175
+ var requestTimeout = 30000; // 30 seconds
1176
+ if (process.configuration && process.configuration.timeout)
1177
+ {
1178
+ requestTimeout = process.configuration.timeout;
1179
+ }
1180
+ httpServer.setTimeout(requestTimeout);
1181
+
1182
+ // socket
1183
+ httpServer.on("connection", function (socket) {
1184
+ socket.setNoDelay(true);
1185
+ });
1186
+
1187
+ done(null, httpServer);
1188
+ }
1189
+
1190
+ var configureServer = function(config, app, httpServer, configureServerFinishedFn)
1191
+ {
1192
+ var io = httpServer.io;
1193
+ if (io)
1194
+ {
1195
+ //io.set('transports', config.socketTransports);
1196
+ io.use(function (socket, next) {
1197
+
1198
+ // console.log("New socket being initialized");
1199
+
1200
+ // attach _log function
1201
+ socket._log = function (text) {
1202
+
1203
+ var host = socket.handshake.headers.host;
1204
+ if (socket.handshake.headers["x-forwarded-host"])
1205
+ {
1206
+ host = socket.handshake.headers["x-forwarded-host"];
1207
+ }
1208
+
1209
+ var d = new Date();
1210
+ var dateString = d.toDateString();
1211
+ var timeString = d.toTimeString();
1212
+
1213
+ // gray color
1214
+ var grayColor = "\x1b[90m";
1215
+
1216
+ // final color
1217
+ var finalColor = "\x1b[0m";
1218
+
1219
+ if (process.env.CLOUDCMS_APPSERVER_MODE === "production")
1220
+ {
1221
+ grayColor = "";
1222
+ finalColor = "";
1223
+ }
1224
+
1225
+ var message = '';
1226
+ message += grayColor + '<socket> ';
1227
+ message += grayColor + '[' + dateString + ' ' + timeString + '] ';
1228
+ message += grayColor + host + ' ';
1229
+ message += grayColor + text + '';
1230
+ message += finalColor;
1231
+
1232
+ console.log(message);
1233
+ };
1234
+ /*
1235
+ socket.on("connect", function () {
1236
+ console.log("Socket connect()");
1237
+ });
1238
+ */
1239
+ /*
1240
+ socket.on("disconnect", function () {
1241
+ var message = "Socket disconnected";
1242
+ if (socket && socket.host)
1243
+ {
1244
+ message += ", host=" + socket.host;
1245
+ }
1246
+ if (socket && socket.gitana && socket.gitana.application && socket.gitana.application())
1247
+ {
1248
+ message += ", application=" + socket.gitana.application().title;
1249
+ }
1250
+ console.log(message);
1251
+ });
1252
+ */
1253
+
1254
+ // APPLY CUSTOM SOCKET.IO CONFIG
1255
+ runFunctions(config.socketFunctions, [socket], function (err) {
1256
+
1257
+ require("../middleware/awareness/awareness").initSocketIO(io, function() {
1258
+ next();
1259
+ });
1260
+
1261
+ // INSIGHT SERVER
1262
+ // if (config.insight && config.insight.enabled)
1263
+ // {
1264
+ // console.log("Init Insight to Socket");
1265
+
1266
+ // require("../insight/insight").init(socket, function () {
1267
+ // next();
1268
+ // });
1269
+ // }
1270
+ // else
1271
+ // {
1272
+ // next();
1273
+ // }
1274
+ });
1275
+
1276
+ });
1277
+ }
1278
+
1279
+ // SET INITIAL VALUE FOR SERVER TIMESTAMP
1280
+ process.env.CLOUDCMS_APPSERVER_TIMESTAMP = new Date().getTime();
1281
+
1282
+ // DUST
1283
+ runFunctions(config.dustFunctions, [app, duster.getDust()], function (err) {
1284
+
1285
+ // APPLY SERVER BEFORE START FUNCTIONS
1286
+ runFunctions(config.beforeFunctions, [app], function (err) {
1287
+
1288
+ // AFTER SERVER START
1289
+ runFunctions(config.afterFunctions, [app], function (err) {
1290
+
1291
+ function cleanup() {
1292
+
1293
+ if (cluster.isMaster)
1294
+ {
1295
+ console.log("");
1296
+ console.log("");
1297
+
1298
+ console.log("Cloud CMS Module shutting down");
1299
+
1300
+ // close server connections as cleanly as we can
1301
+ console.log(" -> Closing server connections");
1302
+ }
1303
+
1304
+ try
1305
+ {
1306
+ httpServer.close();
1307
+ }
1308
+ catch (e)
1309
+ {
1310
+ console.log("Server.close produced error: " + JSON.stringify(e));
1311
+ }
1312
+
1313
+ if (cluster.isMaster)
1314
+ {
1315
+ console.log("");
1316
+ }
1317
+
1318
+ // tell the process to exit
1319
+ process.exit();
1320
+ }
1321
+
1322
+ // listen for kill or interrupt so that we can shut down cleanly
1323
+ process.on('SIGINT', cleanup);
1324
+ process.on('SIGTERM', cleanup);
1325
+
1326
+ configureServerFinishedFn();
1327
+ });
1328
+ });
1329
+ });
1330
+ };
1331
+
1332
+
1241
1333
 
1242
1334
  ////////////////////////////////////////////////////////////////////////////
1243
1335
  //