@maiyunnet/kebab 3.2.14 → 3.2.16
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/fs.js +9 -10
- package/lib/net.js +2 -2
- package/package.json +6 -6
- package/sys/child.js +7 -7
- package/sys/mod.d.ts +7 -11
- package/sys/mod.js +5 -32
- package/sys/route.js +25 -24
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.16';
|
|
10
10
|
// --- 服务端用的路径 ---
|
|
11
11
|
const imu = decodeURIComponent(import.meta.url).replace('file://', '').replace(/^\/(\w:)/, '$1');
|
|
12
12
|
/** --- /xxx/xxx --- */
|
package/lib/fs.js
CHANGED
|
@@ -6,9 +6,9 @@
|
|
|
6
6
|
import * as fs from 'fs';
|
|
7
7
|
import * as http2 from 'http2';
|
|
8
8
|
import * as mime from '@litert/mime';
|
|
9
|
-
import * as
|
|
10
|
-
import * as
|
|
11
|
-
import * as
|
|
9
|
+
import * as lText from './text.js';
|
|
10
|
+
import * as lCore from './core.js';
|
|
11
|
+
import * as lZlib from './zlib.js';
|
|
12
12
|
/**
|
|
13
13
|
* --- 读取完整文件或一段 ---
|
|
14
14
|
* @param path 文件路径
|
|
@@ -124,7 +124,7 @@ export async function unlink(path) {
|
|
|
124
124
|
return true;
|
|
125
125
|
}
|
|
126
126
|
catch {
|
|
127
|
-
await
|
|
127
|
+
await lCore.sleep(250);
|
|
128
128
|
}
|
|
129
129
|
}
|
|
130
130
|
try {
|
|
@@ -326,7 +326,7 @@ export async function copyFolder(from, to, ignore = []) {
|
|
|
326
326
|
}
|
|
327
327
|
else if (item.isFile()) {
|
|
328
328
|
// --- 先判断本文件是否被排除 ---
|
|
329
|
-
if (ignore.length > 0 &&
|
|
329
|
+
if (ignore.length > 0 && lText.match(item.name, ignore)) {
|
|
330
330
|
continue;
|
|
331
331
|
}
|
|
332
332
|
if (!checkTo) {
|
|
@@ -424,11 +424,12 @@ export function createWriteStream(path, options) {
|
|
|
424
424
|
* @param stat 文件的 stat(如果有)
|
|
425
425
|
*/
|
|
426
426
|
export async function readToResponse(path, req, res, stat) {
|
|
427
|
+
res.statusCode = 200;
|
|
427
428
|
stat ??= await stats(path);
|
|
428
429
|
if (!stat) {
|
|
429
430
|
const content = '<h1>404 Not found</h1><hr>Kebab';
|
|
431
|
+
res.statusCode = 404;
|
|
430
432
|
res.setHeader('content-length', Buffer.byteLength(content));
|
|
431
|
-
res.writeHead(404);
|
|
432
433
|
res.end(content);
|
|
433
434
|
return;
|
|
434
435
|
}
|
|
@@ -446,7 +447,7 @@ export async function readToResponse(path, req, res, stat) {
|
|
|
446
447
|
const noneMatch = req.headers['if-none-match'];
|
|
447
448
|
const modifiedSince = req.headers['if-modified-since'];
|
|
448
449
|
if ((hash === noneMatch) && (lastModified === modifiedSince)) {
|
|
449
|
-
res.
|
|
450
|
+
res.statusCode = 304;
|
|
450
451
|
res.end();
|
|
451
452
|
return;
|
|
452
453
|
}
|
|
@@ -461,17 +462,15 @@ export async function readToResponse(path, req, res, stat) {
|
|
|
461
462
|
const encoding = req.headers['accept-encoding'] ?? '';
|
|
462
463
|
if (mimeData.compressible && (stat.size >= 1024)) {
|
|
463
464
|
// --- 压缩 ---
|
|
464
|
-
const compress = await
|
|
465
|
+
const compress = await lZlib.compress(encoding, await getContent(path));
|
|
465
466
|
if (compress) {
|
|
466
467
|
res.setHeader('content-encoding', compress.type);
|
|
467
468
|
res.setHeader('content-length', Buffer.byteLength(compress.buffer));
|
|
468
|
-
res.writeHead(200);
|
|
469
469
|
res.end(compress.buffer);
|
|
470
470
|
return;
|
|
471
471
|
}
|
|
472
472
|
}
|
|
473
473
|
// --- 不压缩 ---
|
|
474
474
|
res.setHeader('content-length', stat.size);
|
|
475
|
-
res.writeHead(200);
|
|
476
475
|
await pipe(path, res instanceof http2.Http2ServerResponse ? (res.stream ?? res) : res);
|
|
477
476
|
}
|
package/lib/net.js
CHANGED
|
@@ -525,7 +525,7 @@ export async function mproxy(ctr, auth, opt = {}) {
|
|
|
525
525
|
if (rres.headers) {
|
|
526
526
|
filterHeaders(rres.headers, res, opt.filter);
|
|
527
527
|
}
|
|
528
|
-
res.
|
|
528
|
+
res.statusCode = rres.headers?.['http-code'] ?? 200;
|
|
529
529
|
await new Promise((resolve) => {
|
|
530
530
|
stream.pipe(res).on('finish', () => {
|
|
531
531
|
resolve();
|
|
@@ -589,7 +589,7 @@ export async function rproxy(ctr, route, opt = {}) {
|
|
|
589
589
|
if (rres.headers) {
|
|
590
590
|
filterHeaders(rres.headers, res, opt.filter);
|
|
591
591
|
}
|
|
592
|
-
res.
|
|
592
|
+
res.statusCode = rres.headers?.['http-code'] ?? 200;
|
|
593
593
|
await new Promise((resolve) => {
|
|
594
594
|
stream.pipe(res).on('finish', () => {
|
|
595
595
|
resolve();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@maiyunnet/kebab",
|
|
3
|
-
"version": "3.2.
|
|
3
|
+
"version": "3.2.16",
|
|
4
4
|
"description": "Simple, easy-to-use, and fully-featured Node.js framework that is ready-to-use out of the box.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"keywords": [
|
|
@@ -19,24 +19,24 @@
|
|
|
19
19
|
"#kebab/*": "./*"
|
|
20
20
|
},
|
|
21
21
|
"dependencies": {
|
|
22
|
-
"@aws-sdk/client-s3": "^3.
|
|
23
|
-
"@aws-sdk/lib-storage": "^3.
|
|
22
|
+
"@aws-sdk/client-s3": "^3.913.0",
|
|
23
|
+
"@aws-sdk/lib-storage": "^3.913.0",
|
|
24
24
|
"@litert/http-client": "^1.1.2",
|
|
25
25
|
"@litert/mime": "^0.1.3",
|
|
26
26
|
"@litert/redis": "^3.0.5",
|
|
27
|
-
"@litert/websocket": "^0.2.
|
|
27
|
+
"@litert/websocket": "^0.2.7",
|
|
28
28
|
"@types/ssh2": "^1.15.5",
|
|
29
29
|
"ejs": "^3.1.10",
|
|
30
30
|
"jszip": "^3.10.1",
|
|
31
31
|
"mysql2": "^3.15.2",
|
|
32
32
|
"ssh2": "^1.17.0",
|
|
33
33
|
"svg-captcha": "^1.4.0",
|
|
34
|
-
"tencentcloud-sdk-nodejs": "^4.1.
|
|
34
|
+
"tencentcloud-sdk-nodejs": "^4.1.133"
|
|
35
35
|
},
|
|
36
36
|
"devDependencies": {
|
|
37
37
|
"@litert/eslint-plugin-rules": "^0.3.1",
|
|
38
38
|
"@types/ejs": "^3.1.5",
|
|
39
|
-
"@types/node": "^24.
|
|
39
|
+
"@types/node": "^24.9.1",
|
|
40
40
|
"tsc-alias": "^1.8.16",
|
|
41
41
|
"typescript": "^5.9.3"
|
|
42
42
|
}
|
package/sys/child.js
CHANGED
|
@@ -207,8 +207,8 @@ async function requestHandler(req, res, https) {
|
|
|
207
207
|
return;
|
|
208
208
|
}
|
|
209
209
|
const content = '<h1>504 Gateway Timeout</h1><hr>Kebab';
|
|
210
|
+
res.statusCode = 504;
|
|
210
211
|
res.setHeader('content-length', Buffer.byteLength(content));
|
|
211
|
-
res.writeHead(504);
|
|
212
212
|
res.end(content);
|
|
213
213
|
}
|
|
214
214
|
};
|
|
@@ -259,9 +259,9 @@ async function requestHandler(req, res, https) {
|
|
|
259
259
|
let stat = await lFs.stats(vhost.real + now + item);
|
|
260
260
|
if (!stat) {
|
|
261
261
|
const content = '<h1>404 Not found</h1><hr>Kebab';
|
|
262
|
+
res.statusCode = 404;
|
|
262
263
|
res.setHeader('content-type', 'text/html; charset=utf-8');
|
|
263
264
|
res.setHeader('content-length', Buffer.byteLength(content));
|
|
264
|
-
res.writeHead(404);
|
|
265
265
|
res.end(content);
|
|
266
266
|
return;
|
|
267
267
|
}
|
|
@@ -294,10 +294,10 @@ async function requestHandler(req, res, https) {
|
|
|
294
294
|
'cookie': {},
|
|
295
295
|
'headers': {}
|
|
296
296
|
}, '[CHILD][requestHandler][E0]' + lText.stringifyJson(e.stack).slice(1, -1), '-error');
|
|
297
|
-
const content = '<h1>500 Server Error</h1><hr>
|
|
297
|
+
const content = '<h1>500 Server Error</h1><hr>Kebab';
|
|
298
|
+
res.statusCode = 500;
|
|
298
299
|
res.setHeader('content-type', 'text/html; charset=utf-8');
|
|
299
300
|
res.setHeader('content-length', Buffer.byteLength(content));
|
|
300
|
-
res.writeHead(500);
|
|
301
301
|
res.end(content);
|
|
302
302
|
return;
|
|
303
303
|
}
|
|
@@ -333,10 +333,10 @@ async function requestHandler(req, res, https) {
|
|
|
333
333
|
}
|
|
334
334
|
catch (e) {
|
|
335
335
|
lCore.log({}, '[CHILD][requestHandler][E1]' + lText.stringifyJson(e.stack).slice(1, -1), '-error');
|
|
336
|
-
const content = '<h1>500 Server Error</h1><hr>
|
|
336
|
+
const content = '<h1>500 Server Error</h1><hr>Kebab';
|
|
337
|
+
res.statusCode = 500;
|
|
337
338
|
res.setHeader('content-type', 'text/html; charset=utf-8');
|
|
338
339
|
res.setHeader('content-length', Buffer.byteLength(content));
|
|
339
|
-
res.writeHead(500);
|
|
340
340
|
res.end(content);
|
|
341
341
|
return;
|
|
342
342
|
}
|
|
@@ -353,9 +353,9 @@ async function requestHandler(req, res, https) {
|
|
|
353
353
|
}
|
|
354
354
|
}
|
|
355
355
|
const content = '<h1>403 Forbidden</h1><hr>Kebab';
|
|
356
|
+
res.statusCode = 403;
|
|
356
357
|
res.setHeader('content-type', 'text/html; charset=utf-8');
|
|
357
358
|
res.setHeader('content-length', Buffer.byteLength(content));
|
|
358
|
-
res.writeHead(403);
|
|
359
359
|
res.end(content);
|
|
360
360
|
}
|
|
361
361
|
/**
|
package/sys/mod.d.ts
CHANGED
|
@@ -12,7 +12,7 @@ type TOnlyProperties<T> = {
|
|
|
12
12
|
[K in keyof T as T[K] extends (...args: any[]) => any ? never : K]: T[K];
|
|
13
13
|
};
|
|
14
14
|
/** --- 条数列表 --- */
|
|
15
|
-
declare class Rows<T extends Mod> implements
|
|
15
|
+
declare class Rows<T extends Mod> implements IRows<T> {
|
|
16
16
|
private readonly _items;
|
|
17
17
|
constructor(initialItems?: T[]);
|
|
18
18
|
/** --- 总行数 --- */
|
|
@@ -23,9 +23,10 @@ declare class Rows<T extends Mod> implements CRows<T> {
|
|
|
23
23
|
toArray(): Array<Record<string, any>>;
|
|
24
24
|
/** --- 根据规则筛掉项,predicate 返回 true 代表保留 --- */
|
|
25
25
|
filter(predicate: (value: T, index: number) => boolean): Rows<T>;
|
|
26
|
-
/** ---
|
|
26
|
+
/** --- 重塑对象内容为数组 --- */
|
|
27
27
|
map<TU>(allbackfn: (value: T, index: number) => TU): TU[];
|
|
28
|
-
|
|
28
|
+
/** --- for of --- */
|
|
29
|
+
[Symbol.iterator](): IterableIterator<T>;
|
|
29
30
|
}
|
|
30
31
|
/**
|
|
31
32
|
* --- 开启软更需要在表添加字段:ALTER TABLE `table_name` ADD `time_remove` bigint NOT NULL DEFAULT '0' AFTER `xxx`; ---
|
|
@@ -475,15 +476,10 @@ export default class Mod {
|
|
|
475
476
|
*/
|
|
476
477
|
protected _keyGenerator(): string;
|
|
477
478
|
}
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
/** --- 总行数 --- */
|
|
481
|
-
get length(): number;
|
|
482
|
-
/** --- 通过索引获取一个对象 --- */
|
|
479
|
+
export interface IRows<T> extends Iterable<T> {
|
|
480
|
+
readonly length: number;
|
|
483
481
|
item(index: number): T;
|
|
484
|
-
|
|
485
|
-
toArray(): Array<Record<string, kebab.DbValue>>;
|
|
486
|
-
[Symbol.iterator](): Iterator<T>;
|
|
482
|
+
toArray(): Array<Record<string, any>>;
|
|
487
483
|
}
|
|
488
484
|
export interface IModUnionItem {
|
|
489
485
|
'field': string;
|
package/sys/mod.js
CHANGED
|
@@ -11,7 +11,6 @@ import * as sCtr from '#kebab/sys/ctr.js';
|
|
|
11
11
|
/** --- 条数列表 --- */
|
|
12
12
|
class Rows {
|
|
13
13
|
constructor(initialItems = []) {
|
|
14
|
-
this._items = [];
|
|
15
14
|
this._items = initialItems;
|
|
16
15
|
}
|
|
17
16
|
/** --- 总行数 --- */
|
|
@@ -24,24 +23,13 @@ class Rows {
|
|
|
24
23
|
}
|
|
25
24
|
/** --- 转换为数组对象,获取的是新创建的数组 --- */
|
|
26
25
|
toArray() {
|
|
27
|
-
|
|
28
|
-
for (const item of this._items) {
|
|
29
|
-
arr.push(item.toArray());
|
|
30
|
-
}
|
|
31
|
-
return arr;
|
|
26
|
+
return this._items.map(i => i.toArray());
|
|
32
27
|
}
|
|
33
28
|
/** --- 根据规则筛掉项,predicate 返回 true 代表保留 --- */
|
|
34
29
|
filter(predicate) {
|
|
35
|
-
|
|
36
|
-
for (let i = 0; i < this._items.length; ++i) {
|
|
37
|
-
if (!predicate(this._items[i], i)) {
|
|
38
|
-
continue;
|
|
39
|
-
}
|
|
40
|
-
items.push(this._items[i]);
|
|
41
|
-
}
|
|
42
|
-
return new Rows(items);
|
|
30
|
+
return new Rows(this._items.filter(predicate));
|
|
43
31
|
}
|
|
44
|
-
/** ---
|
|
32
|
+
/** --- 重塑对象内容为数组 --- */
|
|
45
33
|
map(allbackfn) {
|
|
46
34
|
const items = [];
|
|
47
35
|
for (let i = 0; i < this._items.length; ++i) {
|
|
@@ -49,24 +37,9 @@ class Rows {
|
|
|
49
37
|
}
|
|
50
38
|
return items;
|
|
51
39
|
}
|
|
40
|
+
/** --- for of --- */
|
|
52
41
|
[Symbol.iterator]() {
|
|
53
|
-
|
|
54
|
-
return {
|
|
55
|
-
next: () => {
|
|
56
|
-
if (index < this._items.length) {
|
|
57
|
-
return {
|
|
58
|
-
value: this._items[++index],
|
|
59
|
-
done: false
|
|
60
|
-
};
|
|
61
|
-
}
|
|
62
|
-
else {
|
|
63
|
-
return {
|
|
64
|
-
value: undefined,
|
|
65
|
-
done: true
|
|
66
|
-
};
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
};
|
|
42
|
+
return this._items[Symbol.iterator]();
|
|
70
43
|
}
|
|
71
44
|
}
|
|
72
45
|
/**
|
package/sys/route.js
CHANGED
|
@@ -37,9 +37,9 @@ export async function run(data) {
|
|
|
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.statusCode = 500;
|
|
40
41
|
data.res.setHeader('content-type', 'text/html; charset=utf-8');
|
|
41
42
|
data.res.setHeader('content-length', Buffer.byteLength(content));
|
|
42
|
-
data.res.writeHead(500);
|
|
43
43
|
data.res.end(content);
|
|
44
44
|
}
|
|
45
45
|
else {
|
|
@@ -133,13 +133,13 @@ export async function run(data) {
|
|
|
133
133
|
/** --- 组合要跳转的路径 --- */
|
|
134
134
|
const apath = config.const.path + (config.const.qs ? '?' + config.const.qs : '');
|
|
135
135
|
if (config.lang.list.includes(lang)) {
|
|
136
|
+
data.res.statusCode = 302;
|
|
136
137
|
data.res.setHeader('location', config.const.urlBase + lang + '/' + apath);
|
|
137
|
-
data.res.writeHead(302);
|
|
138
138
|
data.res.end('');
|
|
139
139
|
return true;
|
|
140
140
|
}
|
|
141
|
+
data.res.statusCode = 302;
|
|
141
142
|
data.res.setHeader('location', config.const.urlBase + config.lang.list[0] + '/' + apath);
|
|
142
|
-
data.res.writeHead(302);
|
|
143
143
|
data.res.end('');
|
|
144
144
|
return true;
|
|
145
145
|
}
|
|
@@ -183,15 +183,15 @@ export async function run(data) {
|
|
|
183
183
|
if (pathLeft.startsWith('middle')) {
|
|
184
184
|
if (data.res) {
|
|
185
185
|
if (config.route['#404']) {
|
|
186
|
+
data.res.statusCode = 302;
|
|
186
187
|
data.res.setHeader('location', lText.urlResolve(config.const.urlBase, config.route['#404']));
|
|
187
|
-
data.res.writeHead(302);
|
|
188
188
|
data.res.end('');
|
|
189
189
|
return true;
|
|
190
190
|
}
|
|
191
191
|
const content = '[Error] Controller not found, path: ' + path + '.';
|
|
192
|
+
data.res.statusCode = 404;
|
|
192
193
|
data.res.setHeader('content-type', 'text/html; charset=utf-8');
|
|
193
194
|
data.res.setHeader('content-length', Buffer.byteLength(content));
|
|
194
|
-
data.res.writeHead(404);
|
|
195
195
|
data.res.end(content);
|
|
196
196
|
}
|
|
197
197
|
else {
|
|
@@ -413,9 +413,9 @@ export async function run(data) {
|
|
|
413
413
|
catch (e) {
|
|
414
414
|
lCore.log(middle, '(E03)' + lText.stringifyJson(e.stack).slice(1, -1), '-error');
|
|
415
415
|
const content = '<h1>500 Server Error</h1><hr>Kebab';
|
|
416
|
+
data.res.statusCode = 500;
|
|
416
417
|
data.res.setHeader('content-type', 'text/html; charset=utf-8');
|
|
417
418
|
data.res.setHeader('content-length', Buffer.byteLength(content));
|
|
418
|
-
data.res.writeHead(500);
|
|
419
419
|
data.res.end(content);
|
|
420
420
|
return true;
|
|
421
421
|
}
|
|
@@ -429,9 +429,9 @@ export async function run(data) {
|
|
|
429
429
|
catch (e) {
|
|
430
430
|
lCore.log(middle, '(E05)' + lText.stringifyJson(e.stack).slice(1, -1), '-error');
|
|
431
431
|
const content = '<h1>500 Server Error</h1><hr>Kebab';
|
|
432
|
+
data.res.statusCode = 500;
|
|
432
433
|
data.res.setHeader('content-type', 'text/html; charset=utf-8');
|
|
433
434
|
data.res.setHeader('content-length', Buffer.byteLength(content));
|
|
434
|
-
data.res.writeHead(500);
|
|
435
435
|
data.res.end(content);
|
|
436
436
|
return true;
|
|
437
437
|
}
|
|
@@ -443,15 +443,15 @@ export async function run(data) {
|
|
|
443
443
|
if (!await lFs.isFile(filePath)) {
|
|
444
444
|
// --- 指定的控制器不存在 ---
|
|
445
445
|
if (config.route['#404']) {
|
|
446
|
+
data.res.statusCode = 302;
|
|
446
447
|
data.res.setHeader('location', lText.urlResolve(config.const.urlBase, config.route['#404']));
|
|
447
|
-
data.res.writeHead(302);
|
|
448
448
|
data.res.end('');
|
|
449
449
|
return true;
|
|
450
450
|
}
|
|
451
451
|
const content = '[Error] Controller not found, path: ' + path + '.';
|
|
452
|
+
data.res.statusCode = 404;
|
|
452
453
|
data.res.setHeader('content-type', 'text/html; charset=utf-8');
|
|
453
454
|
data.res.setHeader('content-length', Buffer.byteLength(content));
|
|
454
|
-
data.res.writeHead(404);
|
|
455
455
|
data.res.end(content);
|
|
456
456
|
return true;
|
|
457
457
|
}
|
|
@@ -482,23 +482,24 @@ export async function run(data) {
|
|
|
482
482
|
lCore.log(cctr, '', '-visit');
|
|
483
483
|
// --- 强制 HTTPS ---
|
|
484
484
|
if (config.set.mustHttps && !config.const.https) {
|
|
485
|
+
data.res.statusCode = 302;
|
|
485
486
|
data.res.setHeader('location', data.req.url ?? '');
|
|
486
|
-
data.res.
|
|
487
|
+
data.res.end('');
|
|
487
488
|
return true;
|
|
488
489
|
}
|
|
489
490
|
// --- 检测 action 是否存在,以及排除内部方法 ---
|
|
490
491
|
if (pathRight.startsWith('_') || pathRight === 'onUpgrade' || pathRight === 'onLoad' || pathRight === 'onData' || pathRight === 'onDrain' || pathRight === 'onEnd' || pathRight === 'onClose' || pathRight === 'setPrototype' || pathRight === 'getPrototype' || pathRight === 'getAuthorization') {
|
|
491
492
|
// --- _ 开头的 action 是内部方法,不允许访问 ---
|
|
492
493
|
if (config.route['#404']) {
|
|
494
|
+
data.res.statusCode = 302;
|
|
493
495
|
data.res.setHeader('location', lText.urlResolve(config.const.urlBase, config.route['#404']));
|
|
494
|
-
data.res.writeHead(302);
|
|
495
496
|
data.res.end('');
|
|
496
497
|
return true;
|
|
497
498
|
}
|
|
498
499
|
const content = '[Error] Action not found, path: ' + path + '.';
|
|
500
|
+
data.res.statusCode = 404;
|
|
499
501
|
data.res.setHeader('content-type', 'text/html; charset=utf-8');
|
|
500
502
|
data.res.setHeader('content-length', Buffer.byteLength(content));
|
|
501
|
-
data.res.writeHead(404);
|
|
502
503
|
data.res.end(content);
|
|
503
504
|
return true;
|
|
504
505
|
}
|
|
@@ -507,15 +508,15 @@ export async function run(data) {
|
|
|
507
508
|
});
|
|
508
509
|
if (cctr[pathRight] === undefined) {
|
|
509
510
|
if (config.route['#404']) {
|
|
511
|
+
data.res.statusCode = 302;
|
|
510
512
|
data.res.setHeader('location', lText.urlResolve(config.const.urlBase, config.route['#404']));
|
|
511
|
-
data.res.writeHead(302);
|
|
512
513
|
data.res.end('');
|
|
513
514
|
return true;
|
|
514
515
|
}
|
|
515
516
|
const content = '[Error] Action not found, path: ' + path + '.';
|
|
517
|
+
data.res.statusCode = 404;
|
|
516
518
|
data.res.setHeader('content-type', 'text/html; charset=utf-8');
|
|
517
519
|
data.res.setHeader('content-length', Buffer.byteLength(content));
|
|
518
|
-
data.res.writeHead(404);
|
|
519
520
|
data.res.end(content);
|
|
520
521
|
return true;
|
|
521
522
|
}
|
|
@@ -540,9 +541,9 @@ export async function run(data) {
|
|
|
540
541
|
catch (e) {
|
|
541
542
|
lCore.log(cctr, '(E05)' + lText.stringifyJson(e.stack).slice(1, -1), '-error');
|
|
542
543
|
const content = '<h1>500 Server Error</h1><hr>Kebab';
|
|
544
|
+
data.res.statusCode = 500;
|
|
543
545
|
data.res.setHeader('content-type', 'text/html; charset=utf-8');
|
|
544
546
|
data.res.setHeader('content-length', Buffer.byteLength(content));
|
|
545
|
-
data.res.writeHead(500);
|
|
546
547
|
data.res.end(content);
|
|
547
548
|
await waitCtr(cctr);
|
|
548
549
|
return true;
|
|
@@ -555,9 +556,9 @@ export async function run(data) {
|
|
|
555
556
|
catch (e) {
|
|
556
557
|
lCore.log(cctr, '(E04)' + lText.stringifyJson(e.stack).slice(1, -1), '-error');
|
|
557
558
|
const content = '<h1>500 Server Error</h1><hr>Kebab';
|
|
559
|
+
data.res.statusCode = 500;
|
|
558
560
|
data.res.setHeader('content-type', 'text/html; charset=utf-8');
|
|
559
561
|
data.res.setHeader('content-length', Buffer.byteLength(content));
|
|
560
|
-
data.res.writeHead(500);
|
|
561
562
|
data.res.end(content);
|
|
562
563
|
await waitCtr(cctr);
|
|
563
564
|
return true;
|
|
@@ -579,7 +580,7 @@ export async function run(data) {
|
|
|
579
580
|
// --- 已经自行输出过 writeHead,可能自行处理了内容,如 pipe,则不再 writeHead ---
|
|
580
581
|
}
|
|
581
582
|
else {
|
|
582
|
-
data.res.
|
|
583
|
+
data.res.statusCode = data.res.getHeader('location') ? 302 : httpCode;
|
|
583
584
|
}
|
|
584
585
|
if (!data.res.writableEnded) {
|
|
585
586
|
// --- 如果当前还没结束,则强制关闭连接,一切 pipe 请自行在方法中 await,否则会被中断 ---
|
|
@@ -602,7 +603,7 @@ export async function run(data) {
|
|
|
602
603
|
data.res.setHeader('content-encoding', compress.type);
|
|
603
604
|
}
|
|
604
605
|
}
|
|
605
|
-
data.res.
|
|
606
|
+
data.res.statusCode = httpCode;
|
|
606
607
|
}
|
|
607
608
|
if (!data.res.writableEnded) {
|
|
608
609
|
if (compress) {
|
|
@@ -633,7 +634,7 @@ export async function run(data) {
|
|
|
633
634
|
if (compress) {
|
|
634
635
|
data.res.setHeader('content-encoding', compress.type);
|
|
635
636
|
}
|
|
636
|
-
data.res.
|
|
637
|
+
data.res.statusCode = httpCode;
|
|
637
638
|
}
|
|
638
639
|
if (!data.res.writableEnded) {
|
|
639
640
|
if (compress) {
|
|
@@ -651,7 +652,7 @@ export async function run(data) {
|
|
|
651
652
|
if (rtn.length === 0) {
|
|
652
653
|
// --- 异常 ---
|
|
653
654
|
if (!data.res.headersSent) {
|
|
654
|
-
data.res.
|
|
655
|
+
data.res.statusCode = 500;
|
|
655
656
|
}
|
|
656
657
|
if (!data.res.writableEnded) {
|
|
657
658
|
data.res.end('<h1>500 Internal server error</h1><hr>Kebab');
|
|
@@ -687,7 +688,7 @@ export async function run(data) {
|
|
|
687
688
|
data.res.setHeader('content-encoding', compress.type);
|
|
688
689
|
}
|
|
689
690
|
}
|
|
690
|
-
data.res.
|
|
691
|
+
data.res.statusCode = httpCode;
|
|
691
692
|
}
|
|
692
693
|
if (!data.res.writableEnded) {
|
|
693
694
|
if (compress) {
|
|
@@ -712,7 +713,7 @@ export async function run(data) {
|
|
|
712
713
|
if (compress) {
|
|
713
714
|
data.res.setHeader('content-encoding', compress.type);
|
|
714
715
|
}
|
|
715
|
-
data.res.
|
|
716
|
+
data.res.statusCode = httpCode;
|
|
716
717
|
}
|
|
717
718
|
if (!data.res.writableEnded) {
|
|
718
719
|
const passThrough = new stream.PassThrough();
|
|
@@ -741,7 +742,7 @@ export async function run(data) {
|
|
|
741
742
|
data.res.setHeader('content-encoding', compress.type);
|
|
742
743
|
}
|
|
743
744
|
}
|
|
744
|
-
data.res.
|
|
745
|
+
data.res.statusCode = httpCode;
|
|
745
746
|
}
|
|
746
747
|
if (!data.res.writableEnded) {
|
|
747
748
|
if (compress) {
|
|
@@ -758,7 +759,7 @@ export async function run(data) {
|
|
|
758
759
|
else {
|
|
759
760
|
// --- 异常 ---
|
|
760
761
|
if (!data.res.headersSent) {
|
|
761
|
-
data.res.
|
|
762
|
+
data.res.statusCode = 500;
|
|
762
763
|
}
|
|
763
764
|
if (!data.res.writableEnded) {
|
|
764
765
|
data.res.end('<h1>500 Internal server error</h1><hr>Kebab');
|