@maiyunnet/kebab 3.2.8 → 3.2.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.
- package/index.d.ts +1 -1
- package/index.js +1 -1
- package/lib/db.js +2 -3
- package/lib/fs.js +3 -2
- package/lib/kv.js +1 -1
- package/lib/socket.js +5 -4
- package/package.json +1 -1
- package/sys/child.js +15 -10
- package/sys/ctr.d.ts +2 -2
- package/sys/ctr.js +4 -4
- package/sys/route.js +29 -23
- package/www/example/ctr/test.js +1 -1
package/index.d.ts
CHANGED
package/index.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* --- 本文件用来定义每个目录实体地址的常量 ---
|
|
7
7
|
*/
|
|
8
8
|
/** --- 当前系统版本号 --- */
|
|
9
|
-
export const VER = '3.2.
|
|
9
|
+
export const VER = '3.2.10';
|
|
10
10
|
// --- 服务端用的路径 ---
|
|
11
11
|
const imu = decodeURIComponent(import.meta.url).replace('file://', '').replace(/^\/(\w:)/, '$1');
|
|
12
12
|
/** --- /xxx/xxx --- */
|
package/lib/db.js
CHANGED
|
@@ -9,7 +9,6 @@ import * as mysql2 from 'mysql2/promise';
|
|
|
9
9
|
import * as lTime from '#kebab/lib/time.js';
|
|
10
10
|
import * as lSql from '#kebab/lib/sql.js';
|
|
11
11
|
import * as lCore from '#kebab/lib/core.js';
|
|
12
|
-
import * as lText from '#kebab/lib/text.js';
|
|
13
12
|
import * as sCtr from '#kebab/sys/ctr.js';
|
|
14
13
|
/** --- 连接列表池 --- */
|
|
15
14
|
const connections = [];
|
|
@@ -170,7 +169,7 @@ export class Pool {
|
|
|
170
169
|
link.on('error', function (err) {
|
|
171
170
|
c.setLost();
|
|
172
171
|
if (err.code !== 'PROTOCOL_CONNECTION_LOST') {
|
|
173
|
-
lCore.debug('[DB][_getConnection][error]', err);
|
|
172
|
+
lCore.debug('[DB][_getConnection][error]', err.message);
|
|
174
173
|
}
|
|
175
174
|
}).on('end', () => {
|
|
176
175
|
// lCore.debug('[DB][_getConnection] connection end.');
|
|
@@ -182,7 +181,7 @@ export class Pool {
|
|
|
182
181
|
connections.push(conn);
|
|
183
182
|
}
|
|
184
183
|
catch (e) {
|
|
185
|
-
const msg = '[DB][_getConnection] ' +
|
|
184
|
+
const msg = '[DB][_getConnection] ' + e.message;
|
|
186
185
|
lCore.debug(msg);
|
|
187
186
|
lCore.log({}, msg, '-error');
|
|
188
187
|
}
|
package/lib/fs.js
CHANGED
|
@@ -426,9 +426,10 @@ export function createWriteStream(path, options) {
|
|
|
426
426
|
export async function readToResponse(path, req, res, stat) {
|
|
427
427
|
stat ??= await stats(path);
|
|
428
428
|
if (!stat) {
|
|
429
|
-
|
|
429
|
+
const content = '<h1>404 Not found</h1><hr>Kebab';
|
|
430
|
+
res.setHeader('content-length', Buffer.byteLength(content));
|
|
430
431
|
res.writeHead(404);
|
|
431
|
-
res.end(
|
|
432
|
+
res.end(content);
|
|
432
433
|
return;
|
|
433
434
|
}
|
|
434
435
|
// --- 判断缓存以及 MIME 和编码 ---
|
package/lib/kv.js
CHANGED
|
@@ -618,7 +618,7 @@ export class Pool {
|
|
|
618
618
|
link.on('error', function (err) {
|
|
619
619
|
conn.setLost();
|
|
620
620
|
// console.log(`--- redis [${conn._etc.host}:${conn._etc.port}] error ---`);
|
|
621
|
-
lCore.debug('[KV][ERROR]', err);
|
|
621
|
+
lCore.debug('[KV][ERROR]', err.message);
|
|
622
622
|
}).on('end', () => {
|
|
623
623
|
conn.setLost();
|
|
624
624
|
}).on('close', () => {
|
package/lib/socket.js
CHANGED
|
@@ -4,6 +4,7 @@
|
|
|
4
4
|
* Last: 2025-9-25 16:49:48
|
|
5
5
|
*/
|
|
6
6
|
import net from 'net';
|
|
7
|
+
import * as lTime from '#kebab/lib/time.js';
|
|
7
8
|
import * as lWs from '#kebab/lib/ws.js';
|
|
8
9
|
import * as lCore from '#kebab/lib/core.js';
|
|
9
10
|
/**
|
|
@@ -17,7 +18,7 @@ export function rwebsocket(port, url, opt = {}) {
|
|
|
17
18
|
const server = net.createServer(socket => {
|
|
18
19
|
(async () => {
|
|
19
20
|
// --- 每次进一个新连接都反代到一个新 WebSocket ---
|
|
20
|
-
lCore.display('New client: ' + socket.remoteAddress + ':' + socket.remotePort);
|
|
21
|
+
lCore.display('[' + lTime.format(null, 'Y-m-d H:i:s') + '] New client: ' + socket.remoteAddress + ':' + socket.remotePort);
|
|
21
22
|
/** --- 远程端的双向 websocket --- */
|
|
22
23
|
const rws = await lWs.connect(url, opt);
|
|
23
24
|
if (!rws) {
|
|
@@ -52,13 +53,13 @@ export function rwebsocket(port, url, opt = {}) {
|
|
|
52
53
|
rws.writeBinary(data);
|
|
53
54
|
}).on('end', () => {
|
|
54
55
|
rws.end();
|
|
55
|
-
lCore.display('Client disconnected: ' + socket.remoteAddress + ':' + socket.remotePort);
|
|
56
|
+
lCore.display('[' + lTime.format(null, 'Y-m-d H:i:s') + '] Client disconnected: ' + socket.remoteAddress + ':' + socket.remotePort);
|
|
56
57
|
}).on('error', err => {
|
|
57
|
-
lCore.display('Client error: ' + socket.remoteAddress + ':' + socket.remotePort + ', ' + err.message);
|
|
58
|
+
lCore.display('[' + lTime.format(null, 'Y-m-d H:i:s') + '] Client error: ' + socket.remoteAddress + ':' + socket.remotePort + ', ' + err.message);
|
|
58
59
|
});
|
|
59
60
|
})().catch(() => { });
|
|
60
61
|
}).listen(port, () => {
|
|
61
|
-
lCore.display('Listening:' + port);
|
|
62
|
+
lCore.display('[' + lTime.format(null, 'Y-m-d H:i:s') + '] Listening: ' + port);
|
|
62
63
|
});
|
|
63
64
|
return server;
|
|
64
65
|
}
|
package/package.json
CHANGED
package/sys/child.js
CHANGED
|
@@ -206,9 +206,10 @@ async function requestHandler(req, res, https) {
|
|
|
206
206
|
// --- 已经开始输出的,需要用户自行处理 ---
|
|
207
207
|
return;
|
|
208
208
|
}
|
|
209
|
-
|
|
209
|
+
const content = '<h1>504 Gateway Timeout</h1><hr>Kebab';
|
|
210
|
+
res.setHeader('content-length', Buffer.byteLength(content));
|
|
210
211
|
res.writeHead(504);
|
|
211
|
-
res.end(
|
|
212
|
+
res.end(content);
|
|
212
213
|
}
|
|
213
214
|
};
|
|
214
215
|
timer.timer = setTimeout(timer.callback, timer.timeout);
|
|
@@ -257,10 +258,11 @@ async function requestHandler(req, res, https) {
|
|
|
257
258
|
/** --- 'abc' / 'def.json' --- */
|
|
258
259
|
let stat = await lFs.stats(vhost.real + now + item);
|
|
259
260
|
if (!stat) {
|
|
261
|
+
const content = '<h1>404 Not found</h1><hr>Kebab';
|
|
260
262
|
res.setHeader('content-type', 'text/html; charset=utf-8');
|
|
261
|
-
res.setHeader('content-length',
|
|
263
|
+
res.setHeader('content-length', Buffer.byteLength(content));
|
|
262
264
|
res.writeHead(404);
|
|
263
|
-
res.end(
|
|
265
|
+
res.end(content);
|
|
264
266
|
return;
|
|
265
267
|
}
|
|
266
268
|
if (stat.isDirectory()) {
|
|
@@ -292,10 +294,11 @@ async function requestHandler(req, res, https) {
|
|
|
292
294
|
'cookie': {},
|
|
293
295
|
'headers': {}
|
|
294
296
|
}, '[CHILD][requestHandler][E0]' + lText.stringifyJson(e.stack).slice(1, -1), '-error');
|
|
297
|
+
const content = '<h1>500 Server Error</h1><hr>Kebabb';
|
|
295
298
|
res.setHeader('content-type', 'text/html; charset=utf-8');
|
|
296
|
-
res.setHeader('content-length',
|
|
299
|
+
res.setHeader('content-length', Buffer.byteLength(content));
|
|
297
300
|
res.writeHead(500);
|
|
298
|
-
res.end(
|
|
301
|
+
res.end(content);
|
|
299
302
|
return;
|
|
300
303
|
}
|
|
301
304
|
}
|
|
@@ -330,10 +333,11 @@ async function requestHandler(req, res, https) {
|
|
|
330
333
|
}
|
|
331
334
|
catch (e) {
|
|
332
335
|
lCore.log({}, '[CHILD][requestHandler][E1]' + lText.stringifyJson(e.stack).slice(1, -1), '-error');
|
|
336
|
+
const content = '<h1>500 Server Error</h1><hr>Kebabb';
|
|
333
337
|
res.setHeader('content-type', 'text/html; charset=utf-8');
|
|
334
|
-
res.setHeader('content-length',
|
|
338
|
+
res.setHeader('content-length', Buffer.byteLength(content));
|
|
335
339
|
res.writeHead(500);
|
|
336
|
-
res.end(
|
|
340
|
+
res.end(content);
|
|
337
341
|
return;
|
|
338
342
|
}
|
|
339
343
|
}
|
|
@@ -348,10 +352,11 @@ async function requestHandler(req, res, https) {
|
|
|
348
352
|
return;
|
|
349
353
|
}
|
|
350
354
|
}
|
|
355
|
+
const content = '<h1>403 Forbidden</h1><hr>Kebab';
|
|
351
356
|
res.setHeader('content-type', 'text/html; charset=utf-8');
|
|
352
|
-
res.setHeader('content-length',
|
|
357
|
+
res.setHeader('content-length', Buffer.byteLength(content));
|
|
353
358
|
res.writeHead(403);
|
|
354
|
-
res.end(
|
|
359
|
+
res.end(content);
|
|
355
360
|
}
|
|
356
361
|
/**
|
|
357
362
|
* --- WebSocket 响应 handler ---
|
package/sys/ctr.d.ts
CHANGED
|
@@ -253,12 +253,12 @@ export declare class Ctr {
|
|
|
253
253
|
* --- 发送 socket ping ---
|
|
254
254
|
* @param data 要发送的信息
|
|
255
255
|
*/
|
|
256
|
-
protected _ping(): boolean;
|
|
256
|
+
protected _ping(data?: Buffer | string): boolean;
|
|
257
257
|
/**
|
|
258
258
|
* --- 发送 socket pong ---
|
|
259
259
|
* @param data 要发送的信息
|
|
260
260
|
*/
|
|
261
|
-
protected _pong(): boolean;
|
|
261
|
+
protected _pong(data?: Buffer | string): boolean;
|
|
262
262
|
/**
|
|
263
263
|
* --- 主动关闭当前 socket 连接 ---
|
|
264
264
|
*/
|
package/sys/ctr.js
CHANGED
|
@@ -725,15 +725,15 @@ export class Ctr {
|
|
|
725
725
|
* --- 发送 socket ping ---
|
|
726
726
|
* @param data 要发送的信息
|
|
727
727
|
*/
|
|
728
|
-
_ping() {
|
|
729
|
-
return this._socket.ping();
|
|
728
|
+
_ping(data) {
|
|
729
|
+
return this._socket.ping(data);
|
|
730
730
|
}
|
|
731
731
|
/**
|
|
732
732
|
* --- 发送 socket pong ---
|
|
733
733
|
* @param data 要发送的信息
|
|
734
734
|
*/
|
|
735
|
-
_pong() {
|
|
736
|
-
return this._socket.pong();
|
|
735
|
+
_pong(data) {
|
|
736
|
+
return this._socket.pong(data);
|
|
737
737
|
}
|
|
738
738
|
/**
|
|
739
739
|
* --- 主动关闭当前 socket 连接 ---
|
package/sys/route.js
CHANGED
|
@@ -36,9 +36,11 @@ export async function run(data) {
|
|
|
36
36
|
const configContent = await lFs.getContent(data.rootPath + 'kebab.json', 'utf8');
|
|
37
37
|
if (!configContent) {
|
|
38
38
|
if (data.res) {
|
|
39
|
-
|
|
39
|
+
const content = '<h1>500 File kebab.json can not be read</h1><hr>Kebab';
|
|
40
|
+
data.res.setHeader('content-type', 'text/html; charset=utf-8');
|
|
41
|
+
data.res.setHeader('content-length', Buffer.byteLength(content));
|
|
40
42
|
data.res.writeHead(500);
|
|
41
|
-
data.res.end(
|
|
43
|
+
data.res.end(content);
|
|
42
44
|
}
|
|
43
45
|
else {
|
|
44
46
|
data.socket?.destroy();
|
|
@@ -179,7 +181,6 @@ export async function run(data) {
|
|
|
179
181
|
}
|
|
180
182
|
// --- 若文件名为保留的 middle 将不允许进行 ---
|
|
181
183
|
if (pathLeft.startsWith('middle')) {
|
|
182
|
-
const text = '[Error] Controller not found, path: ' + path + '.';
|
|
183
184
|
if (data.res) {
|
|
184
185
|
if (config.route['#404']) {
|
|
185
186
|
data.res.setHeader('location', lText.urlResolve(config.const.urlBase, config.route['#404']));
|
|
@@ -187,10 +188,11 @@ export async function run(data) {
|
|
|
187
188
|
data.res.end('');
|
|
188
189
|
return true;
|
|
189
190
|
}
|
|
191
|
+
const content = '[Error] Controller not found, path: ' + path + '.';
|
|
190
192
|
data.res.setHeader('content-type', 'text/html; charset=utf-8');
|
|
191
|
-
data.res.setHeader('content-length', Buffer.byteLength(
|
|
193
|
+
data.res.setHeader('content-length', Buffer.byteLength(content));
|
|
192
194
|
data.res.writeHead(404);
|
|
193
|
-
data.res.end(
|
|
195
|
+
data.res.end(content);
|
|
194
196
|
}
|
|
195
197
|
else {
|
|
196
198
|
data.socket?.destroy();
|
|
@@ -235,7 +237,7 @@ export async function run(data) {
|
|
|
235
237
|
// --- 先处理 web socket 的情况 ---
|
|
236
238
|
let wsSocket;
|
|
237
239
|
try {
|
|
238
|
-
const options =
|
|
240
|
+
const options = cctr.onUpgrade();
|
|
239
241
|
// --- 默认无消息发送 3 分钟 ---
|
|
240
242
|
options.timeout ??= 60_000 * 3;
|
|
241
243
|
wsSocket = lWs.createServer(data.req, data.socket, options);
|
|
@@ -410,10 +412,11 @@ export async function run(data) {
|
|
|
410
412
|
}
|
|
411
413
|
catch (e) {
|
|
412
414
|
lCore.log(middle, '(E03)' + lText.stringifyJson(e.stack).slice(1, -1), '-error');
|
|
415
|
+
const content = '<h1>500 Server Error</h1><hr>Kebab';
|
|
413
416
|
data.res.setHeader('content-type', 'text/html; charset=utf-8');
|
|
414
|
-
data.res.setHeader('content-length',
|
|
417
|
+
data.res.setHeader('content-length', Buffer.byteLength(content));
|
|
415
418
|
data.res.writeHead(500);
|
|
416
|
-
data.res.end(
|
|
419
|
+
data.res.end(content);
|
|
417
420
|
return true;
|
|
418
421
|
}
|
|
419
422
|
let cacheTTL = middle.getPrototype('_cacheTTL');
|
|
@@ -425,10 +428,11 @@ export async function run(data) {
|
|
|
425
428
|
}
|
|
426
429
|
catch (e) {
|
|
427
430
|
lCore.log(middle, '(E05)' + lText.stringifyJson(e.stack).slice(1, -1), '-error');
|
|
431
|
+
const content = '<h1>500 Server Error</h1><hr>Kebab';
|
|
428
432
|
data.res.setHeader('content-type', 'text/html; charset=utf-8');
|
|
429
|
-
data.res.setHeader('content-length',
|
|
433
|
+
data.res.setHeader('content-length', Buffer.byteLength(content));
|
|
430
434
|
data.res.writeHead(500);
|
|
431
|
-
data.res.end(
|
|
435
|
+
data.res.end(content);
|
|
432
436
|
return true;
|
|
433
437
|
}
|
|
434
438
|
cacheTTL = middle.getPrototype('_cacheTTL');
|
|
@@ -438,17 +442,17 @@ export async function run(data) {
|
|
|
438
442
|
const filePath = config.const.ctrPath + pathLeft + '.js';
|
|
439
443
|
if (!await lFs.isFile(filePath)) {
|
|
440
444
|
// --- 指定的控制器不存在 ---
|
|
441
|
-
const text = '[Error] Controller not found, path: ' + path + '.';
|
|
442
445
|
if (config.route['#404']) {
|
|
443
446
|
data.res.setHeader('location', lText.urlResolve(config.const.urlBase, config.route['#404']));
|
|
444
447
|
data.res.writeHead(302);
|
|
445
448
|
data.res.end('');
|
|
446
449
|
return true;
|
|
447
450
|
}
|
|
451
|
+
const content = '[Error] Controller not found, path: ' + path + '.';
|
|
448
452
|
data.res.setHeader('content-type', 'text/html; charset=utf-8');
|
|
449
|
-
data.res.setHeader('content-length', Buffer.byteLength(
|
|
453
|
+
data.res.setHeader('content-length', Buffer.byteLength(content));
|
|
450
454
|
data.res.writeHead(404);
|
|
451
|
-
data.res.end(
|
|
455
|
+
data.res.end(content);
|
|
452
456
|
return true;
|
|
453
457
|
}
|
|
454
458
|
// --- 加载控制器文件 ---
|
|
@@ -491,11 +495,11 @@ export async function run(data) {
|
|
|
491
495
|
data.res.end('');
|
|
492
496
|
return true;
|
|
493
497
|
}
|
|
494
|
-
const
|
|
498
|
+
const content = '[Error] Action not found, path: ' + path + '.';
|
|
495
499
|
data.res.setHeader('content-type', 'text/html; charset=utf-8');
|
|
496
|
-
data.res.setHeader('content-length', Buffer.byteLength(
|
|
500
|
+
data.res.setHeader('content-length', Buffer.byteLength(content));
|
|
497
501
|
data.res.writeHead(404);
|
|
498
|
-
data.res.end(
|
|
502
|
+
data.res.end(content);
|
|
499
503
|
return true;
|
|
500
504
|
}
|
|
501
505
|
pathRight = pathRight.replace(/-([a-zA-Z0-9])/g, function (t, t1) {
|
|
@@ -508,11 +512,11 @@ export async function run(data) {
|
|
|
508
512
|
data.res.end('');
|
|
509
513
|
return true;
|
|
510
514
|
}
|
|
511
|
-
const
|
|
515
|
+
const content = '[Error] Action not found, path: ' + path + '.';
|
|
512
516
|
data.res.setHeader('content-type', 'text/html; charset=utf-8');
|
|
513
|
-
data.res.setHeader('content-length', Buffer.byteLength(
|
|
517
|
+
data.res.setHeader('content-length', Buffer.byteLength(content));
|
|
514
518
|
data.res.writeHead(404);
|
|
515
|
-
data.res.end(
|
|
519
|
+
data.res.end(content);
|
|
516
520
|
return true;
|
|
517
521
|
}
|
|
518
522
|
// --- 执行 onLoad 方法 ---
|
|
@@ -535,10 +539,11 @@ export async function run(data) {
|
|
|
535
539
|
}
|
|
536
540
|
catch (e) {
|
|
537
541
|
lCore.log(cctr, '(E05)' + lText.stringifyJson(e.stack).slice(1, -1), '-error');
|
|
542
|
+
const content = '<h1>500 Server Error</h1><hr>Kebab';
|
|
538
543
|
data.res.setHeader('content-type', 'text/html; charset=utf-8');
|
|
539
|
-
data.res.setHeader('content-length',
|
|
544
|
+
data.res.setHeader('content-length', Buffer.byteLength(content));
|
|
540
545
|
data.res.writeHead(500);
|
|
541
|
-
data.res.end(
|
|
546
|
+
data.res.end(content);
|
|
542
547
|
await waitCtr(cctr);
|
|
543
548
|
return true;
|
|
544
549
|
}
|
|
@@ -549,10 +554,11 @@ export async function run(data) {
|
|
|
549
554
|
}
|
|
550
555
|
catch (e) {
|
|
551
556
|
lCore.log(cctr, '(E04)' + lText.stringifyJson(e.stack).slice(1, -1), '-error');
|
|
557
|
+
const content = '<h1>500 Server Error</h1><hr>Kebab';
|
|
552
558
|
data.res.setHeader('content-type', 'text/html; charset=utf-8');
|
|
553
|
-
data.res.setHeader('content-length',
|
|
559
|
+
data.res.setHeader('content-length', Buffer.byteLength(content));
|
|
554
560
|
data.res.writeHead(500);
|
|
555
|
-
data.res.end(
|
|
561
|
+
data.res.end(content);
|
|
556
562
|
await waitCtr(cctr);
|
|
557
563
|
return true;
|
|
558
564
|
}
|
package/www/example/ctr/test.js
CHANGED
|
@@ -31,7 +31,7 @@ export default class extends sCtr.Ctr {
|
|
|
31
31
|
}
|
|
32
32
|
onLoad() {
|
|
33
33
|
if (this._config.const.hostname !== '127.0.0.1' && this._config.const.hostname !== '172.17.0.1' &&
|
|
34
|
-
this._config.const.hostname !== 'localhost' && this._config.const.hostname
|
|
34
|
+
this._config.const.hostname !== 'localhost' && !this._config.const.hostname.endsWith('.local.brc-app.com') &&
|
|
35
35
|
!this._config.const.hostname.startsWith('192.168.')) {
|
|
36
36
|
return [0, 'Please use 127.0.0.1 or local to access the file (' + this._config.const.host + ').'];
|
|
37
37
|
}
|