@maiyunnet/kebab 2.0.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.
Files changed (114) hide show
  1. package/.VSCodeCounter/2025-02-14_14-46-44/details.md +82 -0
  2. package/.VSCodeCounter/2025-02-14_14-46-44/diff-details.md +15 -0
  3. package/.VSCodeCounter/2025-02-14_14-46-44/diff.csv +2 -0
  4. package/.VSCodeCounter/2025-02-14_14-46-44/diff.md +19 -0
  5. package/.VSCodeCounter/2025-02-14_14-46-44/diff.txt +22 -0
  6. package/.VSCodeCounter/2025-02-14_14-46-44/results.csv +69 -0
  7. package/.VSCodeCounter/2025-02-14_14-46-44/results.json +1 -0
  8. package/.VSCodeCounter/2025-02-14_14-46-44/results.md +48 -0
  9. package/.VSCodeCounter/2025-02-14_14-46-44/results.txt +118 -0
  10. package/.vscode/tasks.json +15 -0
  11. package/LICENSE +201 -0
  12. package/README.md +201 -0
  13. package/bin/kebab.js +2 -0
  14. package/eslint.config.js +22 -0
  15. package/index.js +19 -0
  16. package/index.ts +33 -0
  17. package/lib/buffer.js +108 -0
  18. package/lib/buffer.ts +152 -0
  19. package/lib/captcha/zcool-addict-italic.ttf +0 -0
  20. package/lib/captcha.js +71 -0
  21. package/lib/captcha.ts +63 -0
  22. package/lib/consistent.js +171 -0
  23. package/lib/consistent.ts +219 -0
  24. package/lib/core.js +663 -0
  25. package/lib/core.ts +880 -0
  26. package/lib/crypto.js +256 -0
  27. package/lib/crypto.ts +384 -0
  28. package/lib/db.js +521 -0
  29. package/lib/db.ts +719 -0
  30. package/lib/dns.js +321 -0
  31. package/lib/dns.ts +405 -0
  32. package/lib/fs.js +405 -0
  33. package/lib/fs.ts +527 -0
  34. package/lib/jwt.js +223 -0
  35. package/lib/jwt.ts +276 -0
  36. package/lib/kv.js +1004 -0
  37. package/lib/kv.ts +1489 -0
  38. package/lib/lan.js +99 -0
  39. package/lib/lan.ts +87 -0
  40. package/lib/net/cacert.pem +3480 -0
  41. package/lib/net/formdata.js +137 -0
  42. package/lib/net/formdata.ts +166 -0
  43. package/lib/net/request.js +102 -0
  44. package/lib/net/request.ts +150 -0
  45. package/lib/net/response.js +28 -0
  46. package/lib/net/response.ts +59 -0
  47. package/lib/net.js +462 -0
  48. package/lib/net.ts +662 -0
  49. package/lib/s3.js +180 -0
  50. package/lib/s3.ts +235 -0
  51. package/lib/scan.js +276 -0
  52. package/lib/scan.ts +364 -0
  53. package/lib/session.js +177 -0
  54. package/lib/session.ts +230 -0
  55. package/lib/sql.js +818 -0
  56. package/lib/sql.ts +1151 -0
  57. package/lib/ssh/sftp.js +373 -0
  58. package/lib/ssh/sftp.ts +508 -0
  59. package/lib/ssh/shell.js +109 -0
  60. package/lib/ssh/shell.ts +123 -0
  61. package/lib/ssh.js +171 -0
  62. package/lib/ssh.ts +191 -0
  63. package/lib/text/tld.json +1 -0
  64. package/lib/text.js +452 -0
  65. package/lib/text.ts +607 -0
  66. package/lib/time.js +216 -0
  67. package/lib/time.ts +254 -0
  68. package/lib/ws.js +373 -0
  69. package/lib/ws.ts +523 -0
  70. package/lib/zip.js +381 -0
  71. package/lib/zip.ts +447 -0
  72. package/lib/zlib.js +289 -0
  73. package/lib/zlib.ts +350 -0
  74. package/main.js +51 -0
  75. package/main.ts +27 -0
  76. package/package.json +37 -0
  77. package/sys/child.js +585 -0
  78. package/sys/child.ts +678 -0
  79. package/sys/cmd.js +226 -0
  80. package/sys/cmd.ts +225 -0
  81. package/sys/ctr.js +608 -0
  82. package/sys/ctr.ts +904 -0
  83. package/sys/master.js +314 -0
  84. package/sys/master.ts +355 -0
  85. package/sys/mod.js +1273 -0
  86. package/sys/mod.ts +1871 -0
  87. package/sys/route.js +922 -0
  88. package/sys/route.ts +1113 -0
  89. package/types/index.d.ts +283 -0
  90. package/www/example/ctr/main.js +42 -0
  91. package/www/example/ctr/main.ts +9 -0
  92. package/www/example/ctr/middle.js +57 -0
  93. package/www/example/ctr/middle.ts +26 -0
  94. package/www/example/ctr/test.js +2818 -0
  95. package/www/example/ctr/test.ts +3218 -0
  96. package/www/example/data/locale/en.test.json +8 -0
  97. package/www/example/data/locale/index.html +1 -0
  98. package/www/example/data/locale/ja.test.json +8 -0
  99. package/www/example/data/locale/sc.test.json +8 -0
  100. package/www/example/data/locale/tc.test.json +8 -0
  101. package/www/example/data/test.zip +0 -0
  102. package/www/example/kebab.json +24 -0
  103. package/www/example/mod/test.js +49 -0
  104. package/www/example/mod/test.ts +47 -0
  105. package/www/example/mod/testdata.js +11 -0
  106. package/www/example/mod/testdata.ts +30 -0
  107. package/www/example/route.json +6 -0
  108. package/www/example/view/test.ejs +11 -0
  109. package/www/example/ws/mproxy.js +49 -0
  110. package/www/example/ws/mproxy.ts +16 -0
  111. package/www/example/ws/rproxy.js +47 -0
  112. package/www/example/ws/rproxy.ts +14 -0
  113. package/www/example/ws/test.js +68 -0
  114. package/www/example/ws/test.ts +36 -0
package/package.json ADDED
@@ -0,0 +1,37 @@
1
+ {
2
+ "name": "@maiyunnet/kebab",
3
+ "version": "2.0.0",
4
+ "description": "Simple, easy-to-use, and fully-featured Node.js framework that is ready-to-use out of the box.",
5
+ "keywords": [
6
+ "kebab",
7
+ "node",
8
+ "framework"
9
+ ],
10
+ "main": "index.js",
11
+ "author": "hanguoshuai",
12
+ "license": "Apache-2.0",
13
+ "bin": {
14
+ "kebab": "./bin/kebab.js"
15
+ },
16
+ "dependencies": {
17
+ "@aws-sdk/client-s3": "^3.826.0",
18
+ "@aws-sdk/lib-storage": "^3.826.0",
19
+ "@litert/http-client": "^1.1.2",
20
+ "@litert/mime": "^0.1.3",
21
+ "@litert/redis": "^3.0.5",
22
+ "@litert/websocket": "^0.2.3",
23
+ "ejs": "^3.1.10",
24
+ "jszip": "^3.10.1",
25
+ "mysql2": "^3.14.1",
26
+ "ssh2": "^1.16.0",
27
+ "svg-captcha": "^1.4.0",
28
+ "ts-alias-loader": "^0.1.5"
29
+ },
30
+ "devDependencies": {
31
+ "@litert/eslint-plugin-rules": "^0.3.1",
32
+ "@types/ejs": "^3.1.5",
33
+ "@types/node": "^24.0.0",
34
+ "@types/ssh2": "^1.15.5",
35
+ "typescript": "^5.8.3"
36
+ }
37
+ }
package/sys/child.js ADDED
@@ -0,0 +1,585 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ const http2 = __importStar(require("http2"));
37
+ const tls = __importStar(require("tls"));
38
+ const http = __importStar(require("http"));
39
+ const crypto = __importStar(require("crypto"));
40
+ const fs = __importStar(require("~/lib/fs"));
41
+ const lCore = __importStar(require("~/lib/core"));
42
+ const lText = __importStar(require("~/lib/text"));
43
+ const sCtr = __importStar(require("~/sys/ctr"));
44
+ const kebab = __importStar(require("~/index"));
45
+ const sRoute = __importStar(require("~/sys/route"));
46
+ const hbTimer = setInterval(function () {
47
+ if (!process.connected || !process.send) {
48
+ return;
49
+ }
50
+ process.send({
51
+ action: 'hbtime',
52
+ pid: process.pid
53
+ });
54
+ }, 10_000);
55
+ const certList = [];
56
+ let certHostIndex = {};
57
+ let vhosts = [];
58
+ let httpServer;
59
+ let http2Server;
60
+ const linkCount = {};
61
+ async function run() {
62
+ await reload();
63
+ http2Server = http2.createSecureServer({
64
+ 'SNICallback': (servername, cb) => {
65
+ const i = certHostIndex[servername];
66
+ if (i !== undefined) {
67
+ cb(null, certList[i].sc);
68
+ return;
69
+ }
70
+ for (let i = 0; i < certList.length; ++i) {
71
+ if (!certList[i].cert.checkHost(servername)) {
72
+ continue;
73
+ }
74
+ cb(null, certList[i].sc);
75
+ certHostIndex[servername] = i;
76
+ return;
77
+ }
78
+ const err = new Error('CERT NOT FOUND');
79
+ cb(err);
80
+ },
81
+ 'ciphers': 'ECDHE-ECDSA-CHACHA20-POLY1305:ECDHE-RSA-CHACHA20-POLY1305:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA:ECDHE-RSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-RSA-AES256-SHA256:DHE-RSA-AES256-SHA:ECDHE-ECDSA-DES-CBC3-SHA:ECDHE-RSA-DES-CBC3-SHA:EDH-RSA-DES-CBC3-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:DES-CBC3-SHA:!DSS',
82
+ 'allowHTTP1': true
83
+ }, function (req, res) {
84
+ const host = (req.headers[':authority'] ?? req.headers['host'] ?? '');
85
+ if (!host) {
86
+ req.socket.destroy();
87
+ return;
88
+ }
89
+ const key = host + req.url;
90
+ (async function () {
91
+ if (!linkCount[key]) {
92
+ linkCount[key] = 0;
93
+ }
94
+ ++linkCount[key];
95
+ await requestHandler(req, res, true);
96
+ --linkCount[key];
97
+ if (!linkCount[key]) {
98
+ delete linkCount[key];
99
+ }
100
+ })().catch(async function (e) {
101
+ await lCore.log({
102
+ 'path': '',
103
+ 'urlFull': '',
104
+ 'hostname': '',
105
+ 'req': req,
106
+ 'get': {},
107
+ 'cookie': {},
108
+ 'headers': {}
109
+ }, '[child][http2][request]' + lText.stringifyJson(e.stack).slice(1, -1), '-error');
110
+ --linkCount[key];
111
+ if (!linkCount[key]) {
112
+ delete linkCount[key];
113
+ }
114
+ });
115
+ }).on('tlsClientError', (err, socket) => {
116
+ socket.destroy();
117
+ }).on('upgrade', function (req, socket) {
118
+ const host = (req.headers['host'] ?? '');
119
+ if (!host) {
120
+ req.socket.destroy();
121
+ return;
122
+ }
123
+ const key = host + (req.url ?? '');
124
+ (async function () {
125
+ if (!linkCount[key]) {
126
+ linkCount[key] = 0;
127
+ }
128
+ ++linkCount[key];
129
+ await upgradeHandler(req, socket, true);
130
+ --linkCount[key];
131
+ if (!linkCount[key]) {
132
+ delete linkCount[key];
133
+ }
134
+ })().catch(async function (e) {
135
+ await lCore.log({
136
+ 'path': '',
137
+ 'urlFull': '',
138
+ 'hostname': '',
139
+ 'req': req,
140
+ 'get': {},
141
+ 'cookie': {},
142
+ 'headers': {}
143
+ }, '[child][http2][upgrade]' + lText.stringifyJson(e.stack).slice(1, -1), '-error');
144
+ --linkCount[key];
145
+ if (!linkCount[key]) {
146
+ delete linkCount[key];
147
+ }
148
+ });
149
+ }).listen(lCore.globalConfig.httpsPort);
150
+ httpServer = http.createServer(function (req, res) {
151
+ const host = (req.headers['host'] ?? '');
152
+ if (!host) {
153
+ req.socket.destroy();
154
+ return;
155
+ }
156
+ const key = host + (req.url ?? '');
157
+ (async function () {
158
+ if (!linkCount[key]) {
159
+ linkCount[key] = 0;
160
+ }
161
+ ++linkCount[key];
162
+ await requestHandler(req, res, false);
163
+ --linkCount[key];
164
+ if (!linkCount[key]) {
165
+ delete linkCount[key];
166
+ }
167
+ })().catch(async function (e) {
168
+ await lCore.log({
169
+ 'path': '',
170
+ 'urlFull': '',
171
+ 'hostname': '',
172
+ 'req': req,
173
+ 'get': {},
174
+ 'cookie': {},
175
+ 'headers': {}
176
+ }, '[child][http][request]' + lText.stringifyJson(e.stack).slice(1, -1), '-error');
177
+ --linkCount[key];
178
+ if (!linkCount[key]) {
179
+ delete linkCount[key];
180
+ }
181
+ });
182
+ }).on('upgrade', function (req, socket) {
183
+ const host = (req.headers['host'] ?? '');
184
+ if (!host) {
185
+ req.socket.destroy();
186
+ return;
187
+ }
188
+ const key = host + (req.url ?? '');
189
+ (async function () {
190
+ if (!linkCount[key]) {
191
+ linkCount[key] = 0;
192
+ }
193
+ ++linkCount[key];
194
+ await upgradeHandler(req, socket, false);
195
+ --linkCount[key];
196
+ if (!linkCount[key]) {
197
+ delete linkCount[key];
198
+ }
199
+ })().catch(async function (e) {
200
+ await lCore.log({
201
+ 'path': '',
202
+ 'urlFull': '',
203
+ 'hostname': '',
204
+ 'req': req,
205
+ 'get': {},
206
+ 'cookie': {},
207
+ 'headers': {}
208
+ }, '[child][http][upgrade]' + lText.stringifyJson(e.stack).slice(1, -1), '-error');
209
+ --linkCount[key];
210
+ if (!linkCount[key]) {
211
+ delete linkCount[key];
212
+ }
213
+ });
214
+ }).listen(lCore.globalConfig.httpPort);
215
+ }
216
+ async function requestHandler(req, res, https) {
217
+ const timer = {
218
+ 'timer': {},
219
+ 'timeout': 30_000,
220
+ 'callback': () => {
221
+ if (!req.socket.writable) {
222
+ return;
223
+ }
224
+ if (res.headersSent) {
225
+ return;
226
+ }
227
+ res.setHeader('content-length', 37);
228
+ res.writeHead(504);
229
+ res.end('<h1>504 Gateway Timeout</h1><hr>Kebab');
230
+ }
231
+ };
232
+ timer.timer = setTimeout(timer.callback, timer.timeout);
233
+ res.setHeader('Server', 'Kebab/' + kebab.VER);
234
+ let host = req.headers[':authority'];
235
+ if (host === undefined || typeof host !== 'string') {
236
+ host = req.headers['host'];
237
+ if (host === undefined) {
238
+ req.socket.destroy();
239
+ return;
240
+ }
241
+ }
242
+ const uri = lText.parseUrl(`http${https ? 's' : ''}://${host}${req.url ?? ''}`);
243
+ const vhost = getVhostByHostname(uri.hostname ?? '');
244
+ if (!vhost) {
245
+ req.socket.destroy();
246
+ return;
247
+ }
248
+ const vhostRoot = vhost.root.replace(/\${example}/g, kebab.ROOT_PATH + 'www/example/');
249
+ let rootPath = lText.isRealPath(vhostRoot) ? vhostRoot : kebab.WWW_CWD + vhostRoot;
250
+ if (!rootPath.endsWith('/')) {
251
+ rootPath += '/';
252
+ }
253
+ let path = uri.pathname ?? '/';
254
+ if (path !== '/') {
255
+ path = lText.urlResolve('/', path);
256
+ }
257
+ const pathList = path.split('/');
258
+ let now = '';
259
+ for (let i = 0; i < pathList.length; ++i) {
260
+ const item = pathList[i];
261
+ if (item !== '') {
262
+ let stat = await fs.stats(rootPath + now + item);
263
+ if (!stat) {
264
+ res.setHeader('content-type', 'text/html; charset=utf-8');
265
+ res.setHeader('content-length', 22);
266
+ res.writeHead(404);
267
+ res.end('<h1>404 Not found</h1><hr>Kebab');
268
+ return;
269
+ }
270
+ if (stat.isDirectory()) {
271
+ now += item + '/';
272
+ stat = await fs.stats(rootPath + now + 'kebab.json');
273
+ if (stat) {
274
+ try {
275
+ if (await sRoute.run({
276
+ 'req': req,
277
+ 'res': res,
278
+ 'uri': uri,
279
+ 'rootPath': rootPath + now,
280
+ 'urlBase': '/' + now,
281
+ 'path': path.slice(('/' + pathList.slice(0, i).join('/')).length + 1),
282
+ 'timer': timer
283
+ })) {
284
+ return;
285
+ }
286
+ }
287
+ catch (e) {
288
+ await lCore.log({
289
+ 'path': path.slice(('/' + pathList.slice(0, i).join('/')).length + 1),
290
+ 'urlFull': (uri.protocol ?? '') + '//' + (uri.host ?? '') + '/' + now,
291
+ 'hostname': uri.hostname ?? '',
292
+ 'req': req,
293
+ 'get': uri.query ? lText.queryParse(uri.query) : {},
294
+ 'cookie': {},
295
+ 'headers': {}
296
+ }, '(E01)' + lText.stringifyJson(e.stack).slice(1, -1), '-error');
297
+ res.setHeader('content-type', 'text/html; charset=utf-8');
298
+ res.setHeader('content-length', 25);
299
+ res.writeHead(500);
300
+ res.end('<h1>500 Server Error</h1><hr>Kebab');
301
+ return;
302
+ }
303
+ }
304
+ }
305
+ else {
306
+ await fs.readToResponse(rootPath + now + item, req, res, stat);
307
+ return;
308
+ }
309
+ }
310
+ else {
311
+ if (i > 0) {
312
+ break;
313
+ }
314
+ const stat = await fs.stats(rootPath + now + 'kebab.json');
315
+ if (stat) {
316
+ try {
317
+ if (await sRoute.run({
318
+ 'req': req,
319
+ 'res': res,
320
+ 'uri': uri,
321
+ 'rootPath': rootPath + now,
322
+ 'urlBase': '/' + now,
323
+ 'path': path.slice(1),
324
+ 'timer': timer
325
+ })) {
326
+ return;
327
+ }
328
+ }
329
+ catch (e) {
330
+ await lCore.log({
331
+ 'path': path.slice(1),
332
+ 'urlFull': (uri.protocol ?? '') + '//' + (uri.host ?? '') + '/' + now,
333
+ 'hostname': uri.hostname ?? '',
334
+ 'req': req,
335
+ 'get': uri.query ? lText.queryParse(uri.query) : {},
336
+ 'cookie': {},
337
+ 'headers': {}
338
+ }, '(E02)' + lText.stringifyJson(e.stack).slice(1, -1), '-error');
339
+ res.setHeader('content-type', 'text/html; charset=utf-8');
340
+ res.setHeader('content-length', 25);
341
+ res.writeHead(500);
342
+ res.end('<h1>500 Server Error</h1><hr>Kebab');
343
+ return;
344
+ }
345
+ }
346
+ }
347
+ }
348
+ const indexFiles = ['index.html', 'index.htm'];
349
+ for (const indexFile of indexFiles) {
350
+ const stat = await fs.isFile(rootPath + now + indexFile);
351
+ if (stat) {
352
+ await fs.readToResponse(rootPath + now + indexFile, req, res, stat);
353
+ return;
354
+ }
355
+ }
356
+ res.setHeader('content-type', 'text/html; charset=utf-8');
357
+ res.setHeader('content-length', 22);
358
+ res.writeHead(403);
359
+ res.end('<h1>403 Forbidden</h1><hr>Kebab');
360
+ }
361
+ async function upgradeHandler(req, socket, https) {
362
+ socket.removeAllListeners('error');
363
+ const uri = lText.parseUrl(`ws${https ? 's' : ''}://${req.headers['host'] ?? ''}${req.url ?? ''}`);
364
+ const vhost = getVhostByHostname(uri.hostname ?? '');
365
+ if (!vhost) {
366
+ socket.destroy();
367
+ return;
368
+ }
369
+ const vhostRoot = vhost.root.replace(/\${example}/g, kebab.ROOT_PATH + 'www/example/');
370
+ let rootPath = lText.isRealPath(vhostRoot) ? vhostRoot : kebab.WWW_CWD + vhostRoot;
371
+ if (!rootPath.endsWith('/')) {
372
+ rootPath += '/';
373
+ }
374
+ let path = uri.pathname ?? '/';
375
+ if (path !== '/') {
376
+ path = lText.urlResolve('/', path);
377
+ }
378
+ const pathList = path.split('/');
379
+ let now = '';
380
+ for (let i = 0; i < pathList.length; ++i) {
381
+ const item = pathList[i];
382
+ if (item !== '') {
383
+ let stat = await fs.stats(rootPath + now + item);
384
+ if (!stat) {
385
+ socket.destroy();
386
+ return;
387
+ }
388
+ if (stat.isDirectory()) {
389
+ now += item + '/';
390
+ stat = await fs.stats(rootPath + now + 'kebab.json');
391
+ if (stat) {
392
+ if (await sRoute.run({
393
+ 'req': req,
394
+ 'socket': socket,
395
+ 'uri': uri,
396
+ 'rootPath': rootPath + now,
397
+ 'urlBase': '/' + now,
398
+ 'path': path.slice(('/' + pathList.slice(0, i).join('/')).length + 1)
399
+ })) {
400
+ return;
401
+ }
402
+ }
403
+ }
404
+ else {
405
+ socket.destroy();
406
+ return;
407
+ }
408
+ }
409
+ else {
410
+ if (i > 0) {
411
+ break;
412
+ }
413
+ const stat = await fs.stats(rootPath + now + 'kebab.json');
414
+ if (stat) {
415
+ if (await sRoute.run({
416
+ 'req': req,
417
+ 'socket': socket,
418
+ 'uri': uri,
419
+ 'rootPath': rootPath + now,
420
+ 'urlBase': '/' + now,
421
+ 'path': path.slice(1)
422
+ })) {
423
+ return;
424
+ }
425
+ }
426
+ }
427
+ }
428
+ socket.destroy();
429
+ }
430
+ async function reload() {
431
+ const configContent = await fs.getContent(kebab.CONF_CWD + 'config.json', 'utf8');
432
+ if (!configContent) {
433
+ throw `File '${kebab.CONF_CWD}config.json' not found.`;
434
+ }
435
+ const config = lText.parseJson(configContent);
436
+ for (const key in lCore.globalConfig) {
437
+ delete lCore.globalConfig[key];
438
+ }
439
+ for (const key in config) {
440
+ lCore.globalConfig[key] = config[key];
441
+ }
442
+ const files = await fs.readDir(kebab.VHOST_CWD);
443
+ vhosts = [];
444
+ for (const file of files) {
445
+ if (!file.name.endsWith('.json')) {
446
+ continue;
447
+ }
448
+ const fstr = await fs.getContent(kebab.VHOST_CWD + file.name, 'utf8');
449
+ if (!fstr) {
450
+ continue;
451
+ }
452
+ let list = lText.parseJson(fstr);
453
+ if (!Array.isArray(list)) {
454
+ list = [list];
455
+ }
456
+ for (const item of list) {
457
+ vhosts.push(item);
458
+ }
459
+ }
460
+ certList.length = 0;
461
+ try {
462
+ const certConfig = await fs.getContent(kebab.CONF_CWD + 'cert.json', 'utf8');
463
+ if (certConfig) {
464
+ const certs = lText.parseJson(certConfig);
465
+ for (const item of certs) {
466
+ const key = await fs.getContent(lText.isRealPath(item.key) ? item.key : kebab.CERT_CWD + item.key, 'utf8');
467
+ const cert = await fs.getContent(lText.isRealPath(item.cert) ? item.cert : kebab.CERT_CWD + item.cert, 'utf8');
468
+ if (!cert || !key) {
469
+ continue;
470
+ }
471
+ const certo = new crypto.X509Certificate(cert);
472
+ const sc = tls.createSecureContext({
473
+ 'key': key,
474
+ 'cert': cert
475
+ });
476
+ certList.push({
477
+ 'cert': certo,
478
+ 'sc': sc
479
+ });
480
+ }
481
+ }
482
+ }
483
+ catch {
484
+ }
485
+ certHostIndex = {};
486
+ sRoute.clearKebabConfigs();
487
+ sCtr.clearLocaleData();
488
+ }
489
+ process.on('message', function (msg) {
490
+ (async function () {
491
+ switch (msg.action) {
492
+ case 'reload': {
493
+ await reload();
494
+ console.log(`[child] Worker ${process.pid} reload execution succeeded.`);
495
+ break;
496
+ }
497
+ case 'stop': {
498
+ httpServer.close();
499
+ http2Server.close();
500
+ clearInterval(hbTimer);
501
+ let waiting = 0;
502
+ while (true) {
503
+ if (!Object.keys(linkCount).length) {
504
+ break;
505
+ }
506
+ const str = [];
507
+ for (const key in linkCount) {
508
+ str.push(key + ':' + linkCount[key].toString());
509
+ }
510
+ console.log(`[child] Worker ${process.pid} busy: ${str.join(',')}.`);
511
+ await lCore.log({
512
+ 'path': '',
513
+ 'urlFull': '',
514
+ 'hostname': '',
515
+ 'req': null,
516
+ 'get': {},
517
+ 'cookie': {},
518
+ 'headers': {}
519
+ }, `[child] Worker ${process.pid} busy: ${str.join(',')}.`, '-error');
520
+ await lCore.sleep(30_000);
521
+ waiting += 30_000;
522
+ if (waiting > 3600_000) {
523
+ break;
524
+ }
525
+ }
526
+ process.exit();
527
+ break;
528
+ }
529
+ case 'global': {
530
+ if (msg.data === undefined || msg.data === null) {
531
+ delete lCore.global[msg.key];
532
+ break;
533
+ }
534
+ if (msg.key === '__init__') {
535
+ for (const key in msg.data) {
536
+ lCore.global[key] = msg.data[key];
537
+ }
538
+ break;
539
+ }
540
+ lCore.global[msg.key] = msg.data;
541
+ break;
542
+ }
543
+ }
544
+ })().catch(async function (e) {
545
+ await lCore.log({
546
+ 'path': '',
547
+ 'urlFull': '',
548
+ 'hostname': '',
549
+ 'req': null,
550
+ 'get': {},
551
+ 'cookie': {},
552
+ 'headers': {}
553
+ }, '[child][process][message]' + lText.stringifyJson(e.stack).slice(1, -1), '-error');
554
+ });
555
+ });
556
+ function getVhostByHostname(hostname) {
557
+ let vGlobal, vSub;
558
+ for (const vhost of vhosts) {
559
+ for (let domain of vhost.domains) {
560
+ if (domain === '*') {
561
+ vGlobal = vhost;
562
+ }
563
+ else if (domain.includes('*')) {
564
+ domain = domain.replace(/\*/, '^.+?').replace(/\./, '\\.');
565
+ if (new RegExp(domain + '$').test(hostname)) {
566
+ vSub = vhost;
567
+ }
568
+ }
569
+ else if (domain === hostname) {
570
+ return vhost;
571
+ }
572
+ }
573
+ }
574
+ if (vSub) {
575
+ return vSub;
576
+ }
577
+ if (vGlobal) {
578
+ return vGlobal;
579
+ }
580
+ return null;
581
+ }
582
+ run().catch(function (e) {
583
+ console.log('[child] ------ [Process fatal Error] ------');
584
+ console.log(e);
585
+ });