@maiyunnet/kebab 3.2.15 → 3.2.17

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 CHANGED
@@ -5,7 +5,7 @@
5
5
  * --- 本文件用来定义每个目录实体地址的常量 ---
6
6
  */
7
7
  /** --- 当前系统版本号 --- */
8
- export declare const VER = "3.2.15";
8
+ export declare const VER = "3.2.17";
9
9
  /** --- 框架根目录,以 / 结尾 --- */
10
10
  export declare const ROOT_PATH: string;
11
11
  export declare const LIB_PATH: string;
package/index.js CHANGED
@@ -6,7 +6,7 @@
6
6
  * --- 本文件用来定义每个目录实体地址的常量 ---
7
7
  */
8
8
  /** --- 当前系统版本号 --- */
9
- export const VER = '3.2.15';
9
+ export const VER = '3.2.17';
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 text from './text.js';
10
- import * as core from './core.js';
11
- import * as zlib from './zlib.js';
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 core.sleep(250);
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 && text.match(item.name, ignore)) {
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.writeHead(304);
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 zlib.compress(encoding, await getContent(path));
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.writeHead(rres.headers?.['http-code'] ?? 200);
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.writeHead(rres.headers?.['http-code'] ?? 200);
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/lib/s3.d.ts CHANGED
@@ -60,7 +60,7 @@ export declare class S3 {
60
60
  * @param key 对象路径
61
61
  * @param bucket bucket 名
62
62
  */
63
- getObject(key: string, bucket?: string): Promise<any>;
63
+ getObject(key: string, bucket?: string): Promise<false | (stream.Readable & import("@smithy/types").SdkStreamMixin) | (Blob & import("@smithy/types").SdkStreamMixin) | (ReadableStream<any> & import("@smithy/types").SdkStreamMixin) | undefined>;
64
64
  /**
65
65
  * --- 删除对象 ---
66
66
  * @param key 对象路径
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@maiyunnet/kebab",
3
- "version": "3.2.15",
3
+ "version": "3.2.17",
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": [
@@ -24,7 +24,7 @@
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.6",
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",
package/sys/child.js CHANGED
@@ -89,7 +89,8 @@ async function run() {
89
89
  }, function (req, res) {
90
90
  const host = (req.headers[':authority'] ?? req.headers['host'] ?? '');
91
91
  if (!host) {
92
- req.socket.destroy();
92
+ res.statusCode = 403;
93
+ res.end();
93
94
  return;
94
95
  }
95
96
  const key = host + req.url;
@@ -115,7 +116,7 @@ async function run() {
115
116
  }).on('upgrade', function (req, socket) {
116
117
  const host = (req.headers['host'] ?? '');
117
118
  if (!host) {
118
- req.socket.destroy();
119
+ socket.destroy();
119
120
  return;
120
121
  }
121
122
  const key = host + (req.url ?? '');
@@ -140,7 +141,8 @@ async function run() {
140
141
  httpServer = http.createServer(function (req, res) {
141
142
  const host = (req.headers['host'] ?? '');
142
143
  if (!host) {
143
- req.socket.destroy();
144
+ res.statusCode = 403;
145
+ res.end();
144
146
  return;
145
147
  }
146
148
  const key = host + (req.url ?? '');
@@ -164,7 +166,7 @@ async function run() {
164
166
  }).on('upgrade', function (req, socket) {
165
167
  const host = (req.headers['host'] ?? '');
166
168
  if (!host) {
167
- req.socket.destroy();
169
+ socket.destroy();
168
170
  return;
169
171
  }
170
172
  const key = host + (req.url ?? '');
@@ -207,8 +209,8 @@ async function requestHandler(req, res, https) {
207
209
  return;
208
210
  }
209
211
  const content = '<h1>504 Gateway Timeout</h1><hr>Kebab';
212
+ res.statusCode = 504;
210
213
  res.setHeader('content-length', Buffer.byteLength(content));
211
- res.writeHead(504);
212
214
  res.end(content);
213
215
  }
214
216
  };
@@ -222,7 +224,7 @@ async function requestHandler(req, res, https) {
222
224
  if (host === undefined || typeof host !== 'string') {
223
225
  host = req.headers['host'];
224
226
  if (host === undefined) {
225
- req.socket.destroy();
227
+ res.end();
226
228
  return;
227
229
  }
228
230
  }
@@ -230,7 +232,8 @@ async function requestHandler(req, res, https) {
230
232
  /** --- 当前的 vhost 配置文件 --- */
231
233
  const vhost = await getVhostByHostname(uri.hostname ?? '');
232
234
  if (!vhost) {
233
- req.socket.destroy();
235
+ res.statusCode = 403;
236
+ res.end();
234
237
  return;
235
238
  /*
236
239
  const text = '<h1>Kebab: No permissions</h1>host: ' + (req.headers[':authority'] as string | undefined ?? req.headers['host'] ?? '') + '<br>url: ' + (lText.htmlescape(req.url ?? ''));
@@ -259,9 +262,9 @@ async function requestHandler(req, res, https) {
259
262
  let stat = await lFs.stats(vhost.real + now + item);
260
263
  if (!stat) {
261
264
  const content = '<h1>404 Not found</h1><hr>Kebab';
265
+ res.statusCode = 404;
262
266
  res.setHeader('content-type', 'text/html; charset=utf-8');
263
267
  res.setHeader('content-length', Buffer.byteLength(content));
264
- res.writeHead(404);
265
268
  res.end(content);
266
269
  return;
267
270
  }
@@ -295,9 +298,9 @@ async function requestHandler(req, res, https) {
295
298
  'headers': {}
296
299
  }, '[CHILD][requestHandler][E0]' + lText.stringifyJson(e.stack).slice(1, -1), '-error');
297
300
  const content = '<h1>500 Server Error</h1><hr>Kebab';
301
+ res.statusCode = 500;
298
302
  res.setHeader('content-type', 'text/html; charset=utf-8');
299
303
  res.setHeader('content-length', Buffer.byteLength(content));
300
- res.writeHead(500);
301
304
  res.end(content);
302
305
  return;
303
306
  }
@@ -334,9 +337,9 @@ async function requestHandler(req, res, https) {
334
337
  catch (e) {
335
338
  lCore.log({}, '[CHILD][requestHandler][E1]' + lText.stringifyJson(e.stack).slice(1, -1), '-error');
336
339
  const content = '<h1>500 Server Error</h1><hr>Kebab';
340
+ res.statusCode = 500;
337
341
  res.setHeader('content-type', 'text/html; charset=utf-8');
338
342
  res.setHeader('content-length', Buffer.byteLength(content));
339
- res.writeHead(500);
340
343
  res.end(content);
341
344
  return;
342
345
  }
@@ -353,9 +356,9 @@ async function requestHandler(req, res, https) {
353
356
  }
354
357
  }
355
358
  const content = '<h1>403 Forbidden</h1><hr>Kebab';
359
+ res.statusCode = 403;
356
360
  res.setHeader('content-type', 'text/html; charset=utf-8');
357
361
  res.setHeader('content-length', Buffer.byteLength(content));
358
- res.writeHead(403);
359
362
  res.end(content);
360
363
  }
361
364
  /**
package/sys/mod.d.ts CHANGED
@@ -23,8 +23,8 @@ declare class Rows<T extends Mod> implements IRows<T> {
23
23
  toArray(): Array<Record<string, any>>;
24
24
  /** --- 根据规则筛掉项,predicate 返回 true 代表保留 --- */
25
25
  filter(predicate: (value: T, index: number) => boolean): Rows<T>;
26
- /** --- 重塑对象内容 --- */
27
- map<TU extends Mod>(fn: (v: T, i: number) => TU): Rows<TU>;
26
+ /** --- 重塑对象内容为数组 --- */
27
+ map<TU>(allbackfn: (value: T, index: number) => TU): TU[];
28
28
  /** --- for of --- */
29
29
  [Symbol.iterator](): IterableIterator<T>;
30
30
  }
package/sys/mod.js CHANGED
@@ -29,9 +29,13 @@ class Rows {
29
29
  filter(predicate) {
30
30
  return new Rows(this._items.filter(predicate));
31
31
  }
32
- /** --- 重塑对象内容 --- */
33
- map(fn) {
34
- return new Rows(this._items.map(fn));
32
+ /** --- 重塑对象内容为数组 --- */
33
+ map(allbackfn) {
34
+ const items = [];
35
+ for (let i = 0; i < this._items.length; ++i) {
36
+ items.push(allbackfn(this._items[i], i));
37
+ }
38
+ return items;
35
39
  }
36
40
  /** --- for of --- */
37
41
  [Symbol.iterator]() {
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 {
@@ -218,7 +218,7 @@ export async function run(data) {
218
218
  headers['authorization'] ??= '';
219
219
  /** --- 开发者返回值 --- */
220
220
  let rtn;
221
- if (data.socket && data.req instanceof http.IncomingMessage) {
221
+ if (data.socket && (data.req instanceof http.IncomingMessage)) {
222
222
  // --- socket 模式 ---
223
223
  // --- 判断真实控制器文件是否存在 ---
224
224
  let filePath = config.const.wsPath + pathLeft + '.js';
@@ -245,7 +245,7 @@ export async function run(data) {
245
245
  }
246
246
  catch (e) {
247
247
  lCore.log(cctr, lText.stringifyJson(e.stack).slice(1, -1), '-error');
248
- data.socket.destroy();
248
+ data.socket?.destroy();
249
249
  return true;
250
250
  }
251
251
  cctr.setPrototype('_param', param);
@@ -259,7 +259,7 @@ export async function run(data) {
259
259
  }
260
260
  catch (e) {
261
261
  lCore.log(cctr, lText.stringifyJson(e.stack).slice(1, -1), '-error');
262
- data.socket.destroy();
262
+ data.socket?.destroy();
263
263
  return true;
264
264
  }
265
265
  if (rtn === undefined || rtn === true) {
@@ -268,7 +268,7 @@ export async function run(data) {
268
268
  }
269
269
  catch (e) {
270
270
  lCore.log(cctr, lText.stringifyJson(e.stack).slice(1, -1), '-error');
271
- data.socket.destroy();
271
+ data.socket?.destroy();
272
272
  return true;
273
273
  }
274
274
  if (rtn === undefined || rtn === true) {
@@ -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.writeHead(302);
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.writeHead(data.res.getHeader('location') ? 302 : httpCode);
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.writeHead(httpCode);
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.writeHead(httpCode);
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.writeHead(500);
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.writeHead(httpCode);
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.writeHead(httpCode);
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.writeHead(httpCode);
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.writeHead(500);
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');