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/d1/index.js ADDED
@@ -0,0 +1,629 @@
1
+ delete process.env.NODE_DEBUG;
2
+
3
+ var moment = require("moment");
4
+ var cluster = require("cluster");
5
+ var http = require("http");
6
+ var os = require("os");
7
+ var numCPUs = os.cpus().length;
8
+
9
+ // default agents
10
+ process.defaultHttpTimeoutMs = 60000;
11
+ var HttpKeepAliveAgent = require('agentkeepalive');
12
+ http.globalAgent = new HttpKeepAliveAgent({
13
+ keepAlive: true,
14
+ keepAliveMsecs: 5000,
15
+ maxSockets: 16000,
16
+ maxFreeSockets: 256,
17
+ timeout: process.defaultHttpTimeoutMs,
18
+ freeSocketTimeout: 4000
19
+ });
20
+
21
+ require("ssl-root-cas").inject();
22
+
23
+ var REDIS_URL = "redis://redis.default.svc.cluster.local:6379";
24
+
25
+ // track temporary files
26
+ var temp = require('temp');
27
+ const https = require("https");
28
+ const {setupMaster} = require("@socket.io/sticky");
29
+ temp.track();
30
+
31
+ var initWorker = function(allDone)
32
+ {
33
+ var initSession = function (initDone) {
34
+ var sessionSecret = "secret";
35
+ var sessionConfig = {
36
+ secret: sessionSecret,
37
+ resave: false,
38
+ saveUninitialized: false
39
+ };
40
+
41
+ const connectRedis = require('connect-redis');
42
+ var session = require('express-session');
43
+ var RedisStore = connectRedis(session);
44
+ var IORedis = require("ioredis");
45
+ var redisClient = new IORedis(REDIS_URL);
46
+ sessionConfig.store = new RedisStore({client: redisClient});
47
+ initDone(null, session(sessionConfig));
48
+ //
49
+ // var options = {};
50
+ // options.checkPeriod = 86400000; // prune expired entries every 24h
51
+ //
52
+ // // session memory store
53
+ // var MemoryStore = require('memorystore')(session);
54
+ // sessionConfig.store = new MemoryStore(options);
55
+ // initDone(null, session(sessionConfig));
56
+ };
57
+
58
+ var setHeaderOnce = exports.setHeaderOnce = function (response, name, value) {
59
+ var existing = response.getHeader(name);
60
+ if (typeof (existing) === "undefined") {
61
+ setHeader(response, name, value);
62
+ }
63
+ };
64
+
65
+ var setHeader = exports.setHeader = function (response, name, value) {
66
+ try {
67
+ response.setHeader(name, value);
68
+ } catch (e) {
69
+ }
70
+ };
71
+
72
+ var createProxyHandler = function (protocol, hostname, port, pathPrefix) {
73
+ const proxy = require("http2-proxy");
74
+ const finalhandler = require('finalhandler')
75
+
76
+ const defaultWebHandler = function (err, req, res) {
77
+ if (err) {
78
+ console.log("A web proxy error was caught, path: " + req.path + ", err: ", err);
79
+ try {
80
+ res.status(500);
81
+ } catch (e) {
82
+ }
83
+ try {
84
+ res.end('Something went wrong while proxying the request.');
85
+ } catch (e) {
86
+ }
87
+ }
88
+
89
+ finalhandler(req, res)(err);
90
+ };
91
+
92
+ // web
93
+ var webConfig = {};
94
+ webConfig.hostname = hostname;
95
+ webConfig.port = port;
96
+ webConfig.protocol = protocol;
97
+ //webConfig.path = null;
98
+ webConfig.timeout = 120000;
99
+ webConfig.proxyTimeout = 120000;
100
+ webConfig.proxyName = "Cloud CMS UI Proxy";
101
+ webConfig.onReq = function (req, options) {
102
+
103
+ if (!options.headers) {
104
+ options.headers = {};
105
+ }
106
+ var headers = options.headers;
107
+
108
+ console.log("path: " + options.path);
109
+
110
+ if (options.path && options.path.startsWith("/proxy")) {
111
+ options.path = options.path.substring(6);
112
+ }
113
+
114
+ if (pathPrefix) {
115
+ options.path = path.join(pathPrefix, options.path);
116
+ }
117
+
118
+ // used to auto-assign the client header for /oauth/token requests
119
+ //oauth2.autoProxy(req);
120
+
121
+ // copy domain host into "x-cloudcms-domainhost"
122
+ if (req.domainHost) {
123
+ headers["x-cloudcms-domainhost"] = req.domainHost; // this could be "localhost"
124
+ }
125
+
126
+ // copy virtual host into "x-cloudcms-virtualhost"
127
+ if (req.virtualHost) {
128
+ headers["x-cloudcms-virtualhost"] = req.virtualHost; // this could be "root.cloudcms.net" or "abc.cloudcms.net"
129
+ }
130
+
131
+ // copy deployment descriptor info
132
+ if (req.descriptor) {
133
+ if (req.descriptor.tenant) {
134
+ if (req.descriptor.tenant.id) {
135
+ headers["x-cloudcms-tenant-id"] = req.descriptor.tenant.id;
136
+ }
137
+
138
+ if (req.descriptor.tenant.title) {
139
+ headers["x-cloudcms-tenant-title"] = req.descriptor.tenant.title;
140
+ }
141
+ }
142
+
143
+ if (req.descriptor.application) {
144
+ if (req.descriptor.application.id) {
145
+ headers["x-cloudcms-application-id"] = req.descriptor.application.id;
146
+ }
147
+
148
+ if (req.descriptor.application.title) {
149
+ headers["x-cloudcms-application-title"] = req.descriptor.application.title;
150
+ }
151
+ }
152
+ }
153
+
154
+ // set optional "x-cloudcms-origin" header
155
+ var cloudcmsOrigin = null;
156
+ if (req.virtualHost) {
157
+ cloudcmsOrigin = req.virtualHost;
158
+ }
159
+ if (cloudcmsOrigin) {
160
+ headers["x-cloudcms-origin"] = cloudcmsOrigin;
161
+ }
162
+
163
+ // set x-cloudcms-server-version header
164
+ //headers["x-cloudcms-server-version"] = process.env.CLOUDCMS_APPSERVER_PACKAGE_VERSION;
165
+
166
+ // keep alive
167
+ //req.headers["connection"] = "keep-alive";
168
+
169
+ // if the incoming request didn't have an "Authorization" header
170
+ // and we have a logged in Gitana User via Auth, then set authorization header to Bearer Access Token
171
+ if (!req.headers["authorization"]) {
172
+ if (req.gitana_user) {
173
+ headers["authorization"] = "Bearer " + req.gitana_user.getDriver().http.accessToken();
174
+ } else if (req.gitana_proxy_access_token) {
175
+ headers["authorization"] = "Bearer " + req.gitana_proxy_access_token;
176
+ }
177
+ }
178
+ };
179
+ webConfig.onRes = function (req, res, proxyRes) {
180
+
181
+ var chunks = [];
182
+
183
+ // triggers on data receive
184
+ proxyRes.on('data', function (chunk) {
185
+ // add received chunk to chunks array
186
+ chunks.push(chunk);
187
+ });
188
+
189
+ proxyRes.on("end", function () {
190
+
191
+ if (proxyRes.statusCode === 401) {
192
+ var text = "" + Buffer.concat(chunks);
193
+ if (text && (text.indexOf("invalid_token") > -1) || (text.indexOf("invalid_grant") > -1)) {
194
+ console.log("ah1");
195
+ }
196
+ }
197
+ });
198
+
199
+ //res.setHeader('x-powered-by', 'cloudcms');
200
+ res.writeHead(proxyRes.statusCode, proxyRes.headers)
201
+ proxyRes.pipe(res)
202
+ };
203
+
204
+ var proxyRequestHandler = function (req, res) {
205
+ proxy.web(req, res, webConfig, function (err, req, res) {
206
+ defaultWebHandler(err, req, res);
207
+ });
208
+ };
209
+
210
+ return proxyRequestHandler;
211
+ };
212
+
213
+ var express = require('express');
214
+
215
+ var app = express();
216
+ app.disable('x-powered-by');
217
+
218
+ var bodyParser = require("body-parser");
219
+ var multipart = require("connect-multiparty");
220
+ var flash = require("connect-flash");
221
+
222
+ var bodyParserFn = function () {
223
+ return function (req, res, next) {
224
+ if (req._body) {
225
+ return next();
226
+ }
227
+
228
+ var contentType = req.get("Content-Type");
229
+ //if (contentType == "application/json" && req.method.toLowerCase() == "post") {
230
+ if (req.method.toLowerCase() == "post") {
231
+
232
+ req._body = true;
233
+
234
+ var responseString = "";
235
+
236
+ req.on('data', function (data) {
237
+ responseString += data;
238
+ });
239
+
240
+ req.on('end', function () {
241
+
242
+ if (responseString.length > 0) {
243
+
244
+ try {
245
+ var b = JSON.parse(responseString);
246
+ if (b) {
247
+ req.body = b;
248
+ }
249
+ } catch (e) {
250
+ }
251
+ }
252
+
253
+ next();
254
+ });
255
+ } else {
256
+ next();
257
+ }
258
+ };
259
+ };
260
+
261
+ initSession(function () {
262
+
263
+ // middleware
264
+ app.enable('strict routing');
265
+ app.set('port', 3000);
266
+ // custom morgan logger
267
+ var morgan = require("morgan");
268
+ morgan(function (tokens, req, res) {
269
+
270
+ var status = res.statusCode;
271
+ var len = parseInt(res.getHeader('Content-Length'), 10);
272
+ var host = req.domainHost;
273
+ if (req.virtualHost) {
274
+ host = req.virtualHost;
275
+ }
276
+
277
+ len = isNaN(len) ? '0b' : len = bytes(len);
278
+
279
+ var d = new Date();
280
+ var dateString = d.toDateString();
281
+ var timeString = d.toTimeString();
282
+
283
+ // gray color
284
+ var grayColor = "\x1b[90m";
285
+
286
+ // status color
287
+ var color = 32;
288
+ if (status >= 500) {
289
+ color = 31;
290
+ } else if (status >= 400) {
291
+ color = 33;
292
+ } else if (status >= 300) {
293
+ color = 36;
294
+ }
295
+ var statusColor = "\x1b[" + color + "m";
296
+
297
+ // final color
298
+ var finalColor = "\x1b[0m";
299
+
300
+ if (process.env.CLOUDCMS_APPSERVER_MODE === "production") {
301
+ grayColor = "";
302
+ statusColor = "";
303
+ finalColor = "";
304
+ }
305
+
306
+ var message = '';
307
+ message += grayColor + '<' + req.id + '> ';
308
+ message += grayColor + '[' + dateString + ' ' + timeString + '] ';
309
+ message += grayColor + host + ' ';
310
+ //message += grayColor + '(' + req.ip + ') ';
311
+ message += statusColor + res.statusCode + ' ';
312
+ message += statusColor + (new Date - req._startTime) + ' ms ';
313
+ message += grayColor + '"' + req.method + ' ';
314
+ message += grayColor + req.originalUrl + '" ';
315
+ message += grayColor + len + ' ';
316
+ message += finalColor;
317
+
318
+ return message;
319
+ });
320
+ // add req.id
321
+ var requestCounter = 0;
322
+ app.use(function (req, res, next) {
323
+ requestCounter++;
324
+ req.id = requestCounter;
325
+ next();
326
+ });
327
+ // retain originalUrl and originalPath since these can get modified along the way
328
+ app.use(function (req, res, next) {
329
+ req.originalUrl = req.url;
330
+ req.originalPath = req.path;
331
+ next();
332
+ });
333
+ // req.param method
334
+ var requestParam = require("request-param")();
335
+ app.use(requestParam);
336
+ // add req.log function
337
+ app.use(function (req, res, next) {
338
+
339
+ req._log = req.log = function (text/*, warn*/) {
340
+
341
+ var host = req.domainHost;
342
+ if (req.virtualHost) {
343
+ host = req.virtualHost;
344
+ }
345
+
346
+ var timestamp = moment(new Date()).format("MM/DD/YYYY HH:mm:ss Z");
347
+ var grayColor = "\x1b[90m";
348
+ var finalColor = "\x1b[0m";
349
+
350
+ // in production, don't use colors
351
+ if (process.env.CLOUDCMS_APPSERVER_MODE === "production") {
352
+ grayColor = "";
353
+ finalColor = "";
354
+ }
355
+
356
+ var message = '';
357
+ message += grayColor + '<' + req.id + '> ';
358
+ if (cluster.worker && cluster.worker.id) {
359
+ message += grayColor + '(' + cluster.worker.id + ') ';
360
+ }
361
+ message += grayColor + '[' + timestamp + '] ';
362
+ message += grayColor + host + ' ';
363
+ message += grayColor + text + '';
364
+ message += finalColor;
365
+
366
+ /*
367
+ if (warn)
368
+ {
369
+ message = "\r\n**** SLOW RESPONSE ****\r\n" + message + "\r\n";
370
+ }
371
+ */
372
+
373
+ console.log(message);
374
+ };
375
+
376
+ next();
377
+ });
378
+
379
+ // TODO: SKIP THIS FOR NOW
380
+ // common interceptors and config
381
+ //main.common1(app);
382
+
383
+ // general logging of requests
384
+ // gather statistics on response time
385
+ var responseTime = require("response-time");
386
+ app.use(responseTime(function (req, res, time) {
387
+
388
+ var warn = false;
389
+ if (time > 1000) {
390
+ warn = true;
391
+ }
392
+
393
+ var requestPath = req.originalPath;
394
+ if (requestPath) {
395
+ var filter = false;
396
+ if (requestPath.indexOf("/login") > -1) {
397
+ filter = true;
398
+ }
399
+ if (requestPath.indexOf("/token") > -1) {
400
+ filter = true;
401
+ }
402
+ // if (filter)
403
+ // {
404
+ // requestPath = util.stripQueryStringFromUrl(requestPath);
405
+ // }
406
+ }
407
+
408
+ req.log(req.method + " " + requestPath + " [" + res.statusCode + "] (" + time.toFixed(2) + " ms)", warn);
409
+ }));
410
+
411
+ // TODO
412
+ // // set up CORS allowances
413
+ // // this lets CORS requests float through the proxy
414
+ app.use(function (req, res, next) {
415
+
416
+ var origin = null;
417
+ if (!origin) {
418
+ origin = req.headers["origin"];
419
+ }
420
+ if (!origin) {
421
+ origin = req.headers["x-cloudcms-origin"];
422
+ }
423
+ if (!origin) {
424
+ origin = "*";
425
+ }
426
+
427
+ // var methods = null
428
+ // var headers = null;
429
+ // var credentials = null;
430
+
431
+ setHeaderOnce(res, "Access-Control-Allow-Origin", origin);
432
+
433
+ // if (methods)
434
+ // {
435
+ // setHeaderOnce(res, "Access-Control-Allow-Methods", methods);
436
+ // }
437
+ //
438
+ // if (headers)
439
+ // {
440
+ // setHeaderOnce(res, "Access-Control-Allow-Headers", headers);
441
+ // }
442
+ //
443
+ // if (credentials)
444
+ // {
445
+ // setHeaderOnce(res, "Access-Control-Allow-Credentials", "" + credentials);
446
+ // }
447
+
448
+ // res.set('Access-Control-Allow-Max-Age', 3600);
449
+
450
+ if ('OPTIONS' === req.method) {
451
+ return res.sendStatus(200);
452
+ }
453
+
454
+ next();
455
+ });
456
+
457
+ //
458
+ // set up default security headers
459
+ app.use(function (req, res, next) {
460
+
461
+ // defaults
462
+ var xFrameOptions = "SAMEORIGIN";
463
+ var xXssProtection = "1; mode=block";
464
+
465
+ // TODO: allow overrides here?
466
+
467
+ if (xFrameOptions) {
468
+ setHeaderOnce(res, "X-Frame-Options", xFrameOptions);
469
+ }
470
+
471
+ if (xXssProtection) {
472
+ setHeaderOnce(res, "X-XSS-Protection", xXssProtection)
473
+ }
474
+
475
+ setHeaderOnce(res, "X-Powered-By", "Cloud CMS");
476
+
477
+ next();
478
+ });
479
+
480
+ // TODO: SKIP THIS FOR NOW
481
+ // // common interceptors and config
482
+ // main.common2(app);
483
+
484
+ // TODO: SKIP THIS FOR NOW
485
+ // binds gitana driver into place
486
+ // main.common3(app);
487
+
488
+ // parse cookies
489
+ var cookieParser = require('cookie-parser');
490
+ app.use(cookieParser());
491
+
492
+ // TODO: SKIP THIS FOR NOW
493
+ // // cloudcms things need to run here
494
+ // main.common4(app, true);
495
+
496
+ // TODO
497
+ // PATH BASED PERFORMANCE CACHING
498
+ //main.perf1(app);
499
+
500
+ var proxyRequestHandler = createProxyHandler("http", "api.default.svc.cluster.local", 80);
501
+ app.use(function (req, res) {
502
+ req.virtualHost = "mt85.us1.cloudcms.net";
503
+ proxyRequestHandler(req, res);
504
+ });
505
+
506
+ // standard body parsing + a special cloud cms body parser that makes a last ditch effort for anything
507
+ // that might be JSON (regardless of content type)
508
+ app.use(function (req, res, next) {
509
+
510
+ multipart({})(req, res, function (err) {
511
+ bodyParser.json({})(req, res, function (err) {
512
+ bodyParser.urlencoded({})(req, res, function (err) {
513
+ bodyParserFn()(req, res, function (err) {
514
+ next(err);
515
+ });
516
+ });
517
+ });
518
+ });
519
+
520
+ });
521
+
522
+ app.use(flash());
523
+
524
+ // var server = app.listen(3000, function() {
525
+ // console.log('Process ' + process.pid + ' is listening to all incoming requests');
526
+ // });
527
+ //const server = http.createServer()
528
+ var server = http.Server(app);
529
+
530
+ // request timeout
531
+ var requestTimeout = 30000; // 30 seconds
532
+ server.setTimeout(requestTimeout);
533
+
534
+ // socket
535
+ server.on("connection", function (socket) {
536
+ console.log("server connection");
537
+ socket.setNoDelay(true);
538
+ });
539
+
540
+ // configure socket IO
541
+ const { setupWorker } = require("@socket.io/sticky");
542
+ const { Server } = require("socket.io");
543
+ const { createAdapter } = require("@socket.io/redis-adapter");
544
+ const IORedis = require("ioredis");
545
+
546
+ var pubClient = new IORedis(REDIS_URL);
547
+ var subClient = pubClient.duplicate();
548
+
549
+ const io = new Server(server);
550
+ server.io = io;
551
+
552
+ io.engine.on("connection_error", function(err) {
553
+ // console.log("CONNECTION ERROR");
554
+ // console.log("REQUEST: ", err.req); // the request object
555
+ // console.log("CODE: " + err.code); // the error code, for example 1
556
+ // console.log("MESSAGE: ", err.message); // the error message, for example "Session ID unknown"
557
+ // console.log("CONTEXT: ", err.context); // some additional error context
558
+ });
559
+
560
+ // use the redis adapter
561
+ io.adapter(createAdapter(pubClient, subClient, {
562
+ //publishOnSpecificResponseChannel: true
563
+ }));
564
+
565
+ // setup connection with the primary process
566
+ setupWorker(io);
567
+
568
+ // on connect
569
+ io.on("connection", (socket) => {
570
+ //console.log("Redis Launcher on('connection') - socket id:" + socket.id);
571
+ socket.on('message', function(m) {
572
+ console.log("Socket Connection message: " + m);
573
+ });
574
+
575
+ // always catch err
576
+ socket.on("error", function(err) {
577
+ console.log("Caught socket error");
578
+ console.log(err.stack);
579
+ });
580
+
581
+ // TODO
582
+ });
583
+
584
+ allDone(null, server);
585
+ });
586
+ }
587
+
588
+ if (cluster.isMaster)
589
+ {
590
+ console.log(`Primary ${process.pid} is starting`);
591
+
592
+ var server = http.createServer();
593
+ //server.listen(3000);
594
+
595
+ const { setupMaster } = require("@socket.io/sticky");
596
+ const { setupPrimary } = require("@socket.io/cluster-adapter");
597
+
598
+ // setup connections between the workers
599
+ setupPrimary();
600
+
601
+ // needed for packets containing buffers
602
+ cluster.setupMaster({
603
+ serialization: "advanced"
604
+ });
605
+
606
+ // setup sticky sessions
607
+ setupMaster(server, {
608
+ //loadBalancingMethod: "least-connection"
609
+ loadBalancingMethod: "round-robin"
610
+ });
611
+
612
+ // Fork workers.
613
+ for (let i = 0; i < numCPUs; i++) {
614
+ cluster.fork();
615
+ }
616
+
617
+ cluster.on('exit', (worker, code, signal) => {
618
+ console.log(`Worker ${worker.process.pid} died`);
619
+ });
620
+
621
+ console.log(`Primary ${process.pid} is running`);
622
+ }
623
+ else
624
+ {
625
+ initWorker(function(err, server) {
626
+ server.listen(3000);
627
+ console.log(`Worker ${process.pid} started`);
628
+ });
629
+ }