@maiyunnet/kebab 3.1.17 → 3.1.19

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.1.17";
8
+ export declare const VER = "3.1.19";
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.1.17';
9
+ export const VER = '3.1.19';
10
10
  // --- 服务端用的路径 ---
11
11
  const imu = decodeURIComponent(import.meta.url).replace('file://', '').replace(/^\/(\w:)/, '$1');
12
12
  /** --- /xxx/xxx --- */
package/lib/net.d.ts CHANGED
@@ -74,11 +74,12 @@ export declare function resetCookieSession(cookie: Record<string, ICookie>): voi
74
74
  */
75
75
  export declare function getFormData(): fd.FormData;
76
76
  /**
77
- * --- 剔除不代理的 header ---
77
+ * --- 剔除不代理的 header,返回新的 header ---
78
78
  * @param headers 剔除前的 header
79
79
  * @param res 直接设置头部而不返回,可置空
80
+ * @param filter 返回 true 则留下
80
81
  */
81
- export declare function filterProxyHeaders(headers: http.IncomingHttpHeaders | http2.IncomingHttpHeaders | THttpHeaders, res?: http2.Http2ServerResponse | http.ServerResponse): Record<string, string | string[]>;
82
+ export declare function filterProxyHeaders(headers: http.IncomingHttpHeaders | http2.IncomingHttpHeaders | THttpHeaders, res?: http2.Http2ServerResponse | http.ServerResponse, filter?: (h: string) => boolean): Record<string, string | string[]>;
82
83
  /**
83
84
  * --- 正向 mproxy 代理,注意提前处理不要自动处理 post 数据,读取 get 的 url 为实际请求地址 ---
84
85
  * --- get: url, auth ---
@@ -129,6 +130,8 @@ export interface IMproxyOptions {
129
130
  'hosts'?: Record<string, string>;
130
131
  'local'?: string;
131
132
  'headers'?: THttpHeaders;
133
+ /** --- 过滤 header,返回 true 则留下 --- */
134
+ filter?: (h: string) => boolean;
132
135
  /** --- 默认为 default --- */
133
136
  'reuse'?: string;
134
137
  }
@@ -140,6 +143,8 @@ export interface IRproxyOptions {
140
143
  'hosts'?: Record<string, string>;
141
144
  'local'?: string;
142
145
  'headers'?: THttpHeaders;
146
+ /** --- 过滤 header,返回 true 则留下 --- */
147
+ filter?: (h: string) => boolean;
143
148
  /** --- 正向 mproxy 代理,url 如 https://xxx/abc --- */
144
149
  'mproxy'?: {
145
150
  'url': string;
package/lib/net.js CHANGED
@@ -434,11 +434,12 @@ const proxyContinueHeaders = [
434
434
  'transfer-encoding'
435
435
  ];
436
436
  /**
437
- * --- 剔除不代理的 header ---
437
+ * --- 剔除不代理的 header,返回新的 header ---
438
438
  * @param headers 剔除前的 header
439
439
  * @param res 直接设置头部而不返回,可置空
440
+ * @param filter 返回 true 则留下
440
441
  */
441
- export function filterProxyHeaders(headers, res) {
442
+ export function filterProxyHeaders(headers, res, filter) {
442
443
  const heads = {};
443
444
  for (const h in headers) {
444
445
  if (proxyContinueHeaders.includes(h)) {
@@ -451,6 +452,9 @@ export function filterProxyHeaders(headers, res) {
451
452
  if (v === undefined) {
452
453
  continue;
453
454
  }
455
+ if (filter && !filter(h)) {
456
+ continue;
457
+ }
454
458
  if (res) {
455
459
  res.setHeader(h, v);
456
460
  continue;
@@ -482,14 +486,14 @@ export async function mproxy(ctr, auth, opt = {}) {
482
486
  }
483
487
  opt.method = req.method ?? 'GET';
484
488
  opt.headers ??= {};
485
- Object.assign(opt.headers, filterProxyHeaders(req.headers));
489
+ Object.assign(filterProxyHeaders(req.headers, undefined, opt.filter), opt.headers);
486
490
  // --- 发起请求 ---
487
491
  const rres = await request(get['url'], req, opt);
488
492
  if (rres.error) {
489
493
  return -2;
490
494
  }
491
495
  if (rres.headers) {
492
- filterProxyHeaders(rres.headers, res);
496
+ filterProxyHeaders(rres.headers, res, opt.filter);
493
497
  }
494
498
  res.writeHead(rres.headers?.['http-code'] ?? 200);
495
499
  await new Promise((resolve) => {
@@ -539,14 +543,14 @@ export async function rproxy(ctr, route, opt = {}) {
539
543
  const lpath = path.slice(key.length);
540
544
  opt.method = req.method ?? 'GET';
541
545
  opt.headers ??= {};
542
- Object.assign(opt.headers, filterProxyHeaders(req.headers));
546
+ Object.assign(filterProxyHeaders(req.headers, undefined, opt.filter), opt.headers);
543
547
  // --- 发起请求 ---
544
548
  const rres = await request(route[key] + lpath, req, opt);
545
549
  if (rres.error) {
546
550
  return false;
547
551
  }
548
552
  if (rres.headers) {
549
- filterProxyHeaders(rres.headers, res);
553
+ filterProxyHeaders(rres.headers, res, opt.filter);
550
554
  }
551
555
  res.writeHead(rres.headers?.['http-code'] ?? 200);
552
556
  await new Promise((resolve) => {
package/lib/ws.d.ts CHANGED
@@ -49,6 +49,8 @@ export interface IMproxyOptions {
49
49
  'hosts'?: Record<string, string>;
50
50
  'local'?: string;
51
51
  'headers'?: lNet.THttpHeaders;
52
+ /** --- 过滤 header,返回 true 则留下 --- */
53
+ filter?: (h: string) => boolean;
52
54
  /** --- 小帧模式,默认 false --- */
53
55
  'mode'?: EFrameReceiveMode;
54
56
  /** --- 加密模式,默认 true --- */
@@ -61,6 +63,8 @@ export interface IRproxyOptions {
61
63
  'hosts'?: Record<string, string>;
62
64
  'local'?: string;
63
65
  'headers'?: lNet.THttpHeaders;
66
+ /** --- 过滤 header,返回 true 则留下 --- */
67
+ filter?: (h: string) => boolean;
64
68
  /** --- 小帧模式,默认 false --- */
65
69
  'mode'?: EFrameReceiveMode;
66
70
  /** --- 加密模式,默认 true --- */
package/lib/ws.js CHANGED
@@ -283,6 +283,10 @@ function bindPipe(s1, s2) {
283
283
  switch (msg.opcode) {
284
284
  case EOpcode.TEXT:
285
285
  case EOpcode.BINARY: {
286
+ if (typeof msg.data === 'string') {
287
+ s2.writeText(msg.data);
288
+ break;
289
+ }
286
290
  s2.writeBinary(msg.buffer);
287
291
  break;
288
292
  }
@@ -312,6 +316,10 @@ function bindPipe(s1, s2) {
312
316
  switch (msg.opcode) {
313
317
  case EOpcode.TEXT:
314
318
  case EOpcode.BINARY: {
319
+ if (typeof msg.data === 'string') {
320
+ s1.writeText(msg.data);
321
+ break;
322
+ }
315
323
  s1.writeBinary(msg.buffer);
316
324
  break;
317
325
  }
@@ -358,7 +366,7 @@ export async function mproxy(ctr, auth, opt = {}) {
358
366
  return -1;
359
367
  }
360
368
  opt.headers ??= {};
361
- Object.assign(opt.headers, lNet.filterProxyHeaders(req.headers));
369
+ Object.assign(lNet.filterProxyHeaders(req.headers, undefined, opt.filter), opt.headers);
362
370
  // --- 发起请求 ---
363
371
  /** --- 远程端的双向 socket --- */
364
372
  const rsocket = await connect(get['url'], opt);
@@ -379,7 +387,7 @@ export async function rproxy(ctr, url, opt = {}) {
379
387
  /** --- 请求端产生的双向 socket --- */
380
388
  const socket = ctr.getPrototype('_socket');
381
389
  opt.headers ??= {};
382
- Object.assign(opt.headers, lNet.filterProxyHeaders(req.headers));
390
+ Object.assign(lNet.filterProxyHeaders(req.headers, undefined, opt.filter), opt.headers);
383
391
  // --- 发起请求 ---
384
392
  /** --- 远程端的双向 socket --- */
385
393
  const rsocket = await connect(url, opt);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@maiyunnet/kebab",
3
- "version": "3.1.17",
3
+ "version": "3.1.19",
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": [
package/sys/child.js CHANGED
@@ -8,7 +8,7 @@ import * as tls from 'tls';
8
8
  import * as http from 'http';
9
9
  import * as crypto from 'crypto';
10
10
  // --- 库 ---
11
- import * as fs from '#kebab/lib/fs.js';
11
+ import * as lFs from '#kebab/lib/fs.js';
12
12
  import * as lCore from '#kebab/lib/core.js';
13
13
  import * as lText from '#kebab/lib/text.js';
14
14
  import * as sCtr from '#kebab/sys/ctr.js';
@@ -214,7 +214,7 @@ async function requestHandler(req, res, https) {
214
214
  }
215
215
  const uri = lText.parseUrl(`http${https ? 's' : ''}://${host}${req.url ?? ''}`);
216
216
  /** --- 当前的 vhost 配置文件 --- */
217
- const vhost = getVhostByHostname(uri.hostname ?? '');
217
+ const vhost = await getVhostByHostname(uri.hostname ?? '');
218
218
  if (!vhost) {
219
219
  req.socket.destroy();
220
220
  return;
@@ -227,12 +227,6 @@ async function requestHandler(req, res, https) {
227
227
  return;
228
228
  */
229
229
  }
230
- const vhostRoot = vhost.root.replace(/\${example}/g, kebab.ROOT_PATH + 'www/example/');
231
- /** --- 网站绝对根目录,末尾带 / --- */
232
- let rootPath = lText.isRealPath(vhostRoot) ? vhostRoot : kebab.WWW_CWD + vhostRoot;
233
- if (!rootPath.endsWith('/')) {
234
- rootPath += '/';
235
- }
236
230
  /** --- 请求的路径部分,前导带 / 末尾不一定,用户怎么请求就是什么 --- */
237
231
  let path = uri.pathname ?? '/';
238
232
  if (path !== '/') {
@@ -248,7 +242,7 @@ async function requestHandler(req, res, https) {
248
242
  if (item !== '') {
249
243
  // --- 判断 item 是文件还是文件夹 ---
250
244
  /** --- 'abc' / 'def.json' --- */
251
- let stat = await fs.stats(rootPath + now + item);
245
+ let stat = await lFs.stats(vhost.real + now + item);
252
246
  if (!stat) {
253
247
  res.setHeader('content-type', 'text/html; charset=utf-8');
254
248
  res.setHeader('content-length', 22);
@@ -259,7 +253,7 @@ async function requestHandler(req, res, https) {
259
253
  if (stat.isDirectory()) {
260
254
  now += item + '/';
261
255
  // --- 判断是不是动态层 ---
262
- stat = await fs.stats(rootPath + now + 'kebab.json');
256
+ stat = await lFs.stats(vhost.real + now + 'kebab.json');
263
257
  if (stat) {
264
258
  // --- 动态层,交给 Route 处理器 ---
265
259
  try {
@@ -267,7 +261,7 @@ async function requestHandler(req, res, https) {
267
261
  'req': req,
268
262
  'res': res,
269
263
  'uri': uri,
270
- 'rootPath': rootPath + now,
264
+ 'rootPath': vhost.real + now,
271
265
  'urlBase': '/' + now,
272
266
  'path': path.slice(('/' + pathList.slice(0, i).join('/')).length + 1),
273
267
  'timer': timer
@@ -295,7 +289,7 @@ async function requestHandler(req, res, https) {
295
289
  }
296
290
  else {
297
291
  // --- 文件,直接输出并结束 ---
298
- await fs.readToResponse(rootPath + now + item, req, res, stat);
292
+ await lFs.readToResponse(vhost.real + now + item, req, res, stat);
299
293
  return;
300
294
  }
301
295
  }
@@ -305,7 +299,7 @@ async function requestHandler(req, res, https) {
305
299
  break;
306
300
  }
307
301
  // --- 本层是根,判断根是不是动态层 ---
308
- const stat = await fs.stats(rootPath + now + 'kebab.json');
302
+ const stat = await lFs.stats(vhost.real + now + 'kebab.json');
309
303
  if (stat) {
310
304
  // --- 动态层,交给 Route 处理器 ---
311
305
  try {
@@ -313,7 +307,7 @@ async function requestHandler(req, res, https) {
313
307
  'req': req,
314
308
  'res': res,
315
309
  'uri': uri,
316
- 'rootPath': rootPath + now,
310
+ 'rootPath': vhost.real + now,
317
311
  'urlBase': '/' + now,
318
312
  'path': path.slice(1),
319
313
  'timer': timer
@@ -335,9 +329,9 @@ async function requestHandler(req, res, https) {
335
329
  // --- 最后一层是目录,且不是动态层,判断有没有主页,有则输出,没有则 403 出错 ---
336
330
  const indexFiles = ['index.html', 'index.htm'];
337
331
  for (const indexFile of indexFiles) {
338
- const stat = await fs.isFile(rootPath + now + indexFile);
332
+ const stat = await lFs.isFile(vhost.real + now + indexFile);
339
333
  if (stat) {
340
- await fs.readToResponse(rootPath + now + indexFile, req, res, stat);
334
+ await lFs.readToResponse(vhost.real + now + indexFile, req, res, stat);
341
335
  return;
342
336
  }
343
337
  }
@@ -357,17 +351,11 @@ async function upgradeHandler(req, socket, https) {
357
351
  // --- 当前 uri ---
358
352
  const uri = lText.parseUrl(`ws${https ? 's' : ''}://${req.headers['host'] ?? ''}${req.url ?? ''}`);
359
353
  /** --- 当前的 vhost 配置文件 --- */
360
- const vhost = getVhostByHostname(uri.hostname ?? '');
354
+ const vhost = await getVhostByHostname(uri.hostname ?? '');
361
355
  if (!vhost) {
362
356
  socket.destroy();
363
357
  return;
364
358
  }
365
- const vhostRoot = vhost.root.replace(/\${example}/g, kebab.ROOT_PATH + 'www/example/');
366
- /** --- 网站绝对根目录,末尾带 / --- */
367
- let rootPath = lText.isRealPath(vhostRoot) ? vhostRoot : kebab.WWW_CWD + vhostRoot;
368
- if (!rootPath.endsWith('/')) {
369
- rootPath += '/';
370
- }
371
359
  /** --- 请求的路径部分,前导带 / 末尾不一定,用户怎么请求就是什么 --- */
372
360
  let path = uri.pathname ?? '/';
373
361
  if (path !== '/') {
@@ -383,7 +371,7 @@ async function upgradeHandler(req, socket, https) {
383
371
  if (item !== '') {
384
372
  // --- 判断 item 是文件还是文件夹 ---
385
373
  /** --- 'abc' / 'def.json' --- */
386
- let stat = await fs.stats(rootPath + now + item);
374
+ let stat = await lFs.stats(vhost.real + now + item);
387
375
  if (!stat) {
388
376
  socket.destroy();
389
377
  return;
@@ -391,14 +379,14 @@ async function upgradeHandler(req, socket, https) {
391
379
  if (stat.isDirectory()) {
392
380
  now += item + '/';
393
381
  // --- 判断是不是动态层 ---
394
- stat = await fs.stats(rootPath + now + 'kebab.json');
382
+ stat = await lFs.stats(vhost.real + now + 'kebab.json');
395
383
  if (stat) {
396
384
  // --- 动态层,交给 Route 处理器 ---
397
385
  if (await sRoute.run({
398
386
  'req': req,
399
387
  'socket': socket,
400
388
  'uri': uri,
401
- 'rootPath': rootPath + now,
389
+ 'rootPath': vhost.real + now,
402
390
  'urlBase': '/' + now,
403
391
  'path': path.slice(('/' + pathList.slice(0, i).join('/')).length + 1)
404
392
  })) {
@@ -418,14 +406,14 @@ async function upgradeHandler(req, socket, https) {
418
406
  break;
419
407
  }
420
408
  // --- 判断根是不是动态层 ---
421
- const stat = await fs.stats(rootPath + now + 'kebab.json');
409
+ const stat = await lFs.stats(vhost.real + now + 'kebab.json');
422
410
  if (stat) {
423
411
  // --- 动态层,交给 Route 处理器 ---
424
412
  if (await sRoute.run({
425
413
  'req': req,
426
414
  'socket': socket,
427
415
  'uri': uri,
428
- 'rootPath': rootPath + now,
416
+ 'rootPath': vhost.real + now,
429
417
  'urlBase': '/' + now,
430
418
  'path': path.slice(1)
431
419
  })) {
@@ -442,7 +430,7 @@ async function upgradeHandler(req, socket, https) {
442
430
  */
443
431
  async function reload() {
444
432
  // --- 清除全局 config,并重新加载全局信息 ---
445
- const configContent = await fs.getContent(kebab.CONF_CWD + 'config.json', 'utf8');
433
+ const configContent = await lFs.getContent(kebab.CONF_CWD + 'config.json', 'utf8');
446
434
  if (!configContent) {
447
435
  throw `File '${kebab.CONF_CWD}config.json' not found.`;
448
436
  }
@@ -454,13 +442,13 @@ async function reload() {
454
442
  lCore.globalConfig[key] = config[key];
455
443
  }
456
444
  // --- 重新加载 VHOST 信息(/conf/vhost/) ---
457
- const files = await fs.readDir(kebab.VHOST_CWD);
445
+ const files = await lFs.readDir(kebab.VHOST_CWD);
458
446
  vhosts = [];
459
447
  for (const file of files) {
460
448
  if (!file.name.endsWith('.json')) {
461
449
  continue;
462
450
  }
463
- const fstr = await fs.getContent(kebab.VHOST_CWD + file.name, 'utf8');
451
+ const fstr = await lFs.getContent(kebab.VHOST_CWD + file.name, 'utf8');
464
452
  if (!fstr) {
465
453
  continue;
466
454
  }
@@ -485,12 +473,12 @@ async function reloadCert() {
485
473
  certLastLoad = Date.now();
486
474
  const cl = [];
487
475
  try {
488
- const certConfig = await fs.getContent(kebab.CONF_CWD + 'cert.json', 'utf8');
476
+ const certConfig = await lFs.getContent(kebab.CONF_CWD + 'cert.json', 'utf8');
489
477
  if (certConfig) {
490
478
  const certs = lText.parseJson(certConfig);
491
479
  for (const item of certs) {
492
- const key = await fs.getContent(lText.isRealPath(item.key) ? item.key : kebab.CERT_CWD + item.key, 'utf8');
493
- const cert = await fs.getContent(lText.isRealPath(item.cert) ? item.cert : kebab.CERT_CWD + item.cert, 'utf8');
480
+ const key = await lFs.getContent(lText.isRealPath(item.key) ? item.key : kebab.CERT_CWD + item.key, 'utf8');
481
+ const cert = await lFs.getContent(lText.isRealPath(item.cert) ? item.cert : kebab.CERT_CWD + item.cert, 'utf8');
494
482
  if (!cert || !key) {
495
483
  continue;
496
484
  }
@@ -571,37 +559,62 @@ process.on('message', function (msg) {
571
559
  lCore.log({}, '[CHILD][process][message] ' + lText.stringifyJson(e.stack).slice(1, -1), '-error');
572
560
  });
573
561
  });
562
+ /**
563
+ * --- 获取 vhost 的真实路径 ---
564
+ * --- 替换 ${example} 为实际路径 ---
565
+ * --- 如果不是真实路径,添加 WWW_CWD 前缀 ---
566
+ * --- 确保路径以 / 结尾 ---
567
+ */
568
+ function getVhostReal(root) {
569
+ let real = root.replace(/\${example}/g, kebab.ROOT_PATH + 'www/example/');
570
+ real = lText.isRealPath(real) ? real : kebab.WWW_CWD + real;
571
+ return real.endsWith('/') ? real : real + '/';
572
+ }
574
573
  /**
575
574
  * --- 获取匹配的 vhost 对象 ---
576
575
  * --- 如果有精准匹配,以精准匹配为准,否则为通配符匹配(vSub),最后全局泛匹配(vGlobal) ---
577
576
  * @param hostname 当前的 hostname,不带端口
578
577
  */
579
- function getVhostByHostname(hostname) {
580
- let vGlobal, vSub;
578
+ async function getVhostByHostname(hostname) {
579
+ let vGlobal;
580
+ let vGlobalReal = '';
581
+ let vSub;
582
+ let vSubReal = '';
581
583
  for (const vhost of vhosts) {
582
584
  for (let domain of vhost.domains) {
583
585
  if (domain === '*') {
584
586
  // --- 全局泛匹配 ---
585
- vGlobal = vhost;
587
+ const real = getVhostReal(vhost.root);
588
+ if (await lFs.isDir(real)) {
589
+ vGlobal = vhost;
590
+ vGlobalReal = real;
591
+ }
586
592
  }
587
593
  else if (domain.includes('*')) {
588
594
  // --- 通配符匹配 ---
589
595
  domain = domain.replace(/\./g, '\\.').replace(/\*/g, '[\\w-]+?');
590
596
  if (new RegExp(`^${domain}$`).test(hostname)) {
591
- vSub = vhost;
597
+ const real = getVhostReal(vhost.root);
598
+ if (await lFs.isDir(real)) {
599
+ vSub = vhost;
600
+ vSubReal = real;
601
+ }
592
602
  }
593
603
  }
594
604
  else if (domain === hostname) {
595
605
  // --- 完全匹配 ---
596
- return vhost;
606
+ const real = getVhostReal(vhost.root);
607
+ if (await lFs.isDir(real)) {
608
+ return { ...vhost, real };
609
+ }
597
610
  }
598
611
  }
599
612
  }
600
613
  if (vSub) {
601
- return vSub;
614
+ return { ...vSub, 'real': vSubReal };
602
615
  }
603
616
  if (vGlobal) {
604
- return vGlobal;
617
+ return { ...vGlobal, 'real': vGlobalReal };
605
618
  }
606
619
  return null;
607
620
  }
package/sys/ctr.d.ts CHANGED
@@ -115,11 +115,11 @@ export declare class Ctr {
115
115
  */
116
116
  onData(data: Buffer | string, opcode: lWs.EOpcode): kebab.Json;
117
117
  /**
118
- * --- 包含所有 opcode 的消息,若要发送数据需自行调用 write 方法,返回 false 则不会执行默认方法 ---
118
+ * --- 包含所有 opcode 的消息,若要发送数据需自行调用 write 方法,data 恒定为原始 buffer,返回 false 则不会执行默认方法 ---
119
119
  * @param data 数据
120
120
  * @param opcode opcode
121
121
  */
122
- onMessage(data: Buffer | string, opcode: lWs.EOpcode): undefined | boolean | Promise<undefined | boolean>;
122
+ onMessage(data: Buffer, opcode: lWs.EOpcode): undefined | boolean | Promise<undefined | boolean>;
123
123
  /**
124
124
  * --- WebSocket 下连接恢复可写入状态后会调用此事件,可重写此方法 ---
125
125
  */
package/sys/route.js CHANGED
@@ -274,7 +274,7 @@ export async function run(data) {
274
274
  wsSocket.on('message', async function (msg) {
275
275
  switch (msg.opcode) {
276
276
  case ws.EOpcode.CLOSE: {
277
- const r = await cctr['onMessage'](msg.data, msg.opcode);
277
+ const r = await cctr['onMessage'](msg.buffer, msg.opcode);
278
278
  if (r === false) {
279
279
  break;
280
280
  }
@@ -282,7 +282,7 @@ export async function run(data) {
282
282
  break;
283
283
  }
284
284
  case ws.EOpcode.PING: {
285
- const r = await cctr['onMessage'](msg.data, msg.opcode);
285
+ const r = await cctr['onMessage'](msg.buffer, msg.opcode);
286
286
  if (r === false) {
287
287
  break;
288
288
  }
@@ -292,7 +292,7 @@ export async function run(data) {
292
292
  case ws.EOpcode.BINARY:
293
293
  case ws.EOpcode.TEXT: {
294
294
  try {
295
- const r = await cctr['onMessage'](msg.data, msg.opcode);
295
+ const r = await cctr['onMessage'](msg.buffer, msg.opcode);
296
296
  if (r === false) {
297
297
  break;
298
298
  }