@maiyunnet/kebab 3.1.18 → 3.1.20
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/net.d.ts +13 -5
- package/lib/net.js +22 -10
- package/lib/ws.d.ts +10 -3
- package/lib/ws.js +13 -7
- package/package.json +1 -1
- package/www/example/ctr/test.d.ts +1 -0
- package/www/example/ctr/test.js +35 -0
package/index.d.ts
CHANGED
package/index.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* --- 本文件用来定义每个目录实体地址的常量 ---
|
|
7
7
|
*/
|
|
8
8
|
/** --- 当前系统版本号 --- */
|
|
9
|
-
export const VER = '3.1.
|
|
9
|
+
export const VER = '3.1.20';
|
|
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
|
|
82
|
+
export declare function filterHeaders(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 ---
|
|
@@ -106,7 +107,8 @@ export interface IRequestOptions {
|
|
|
106
107
|
/** --- 秒数 --- */
|
|
107
108
|
'timeout'?: number;
|
|
108
109
|
'follow'?: number;
|
|
109
|
-
'
|
|
110
|
+
/** --- 自定义 host 映射,如 {'www.maiyun.net': '127.0.0.1'},或全部映射到一个 host --- */
|
|
111
|
+
'hosts'?: Record<string, string> | string;
|
|
110
112
|
'save'?: string;
|
|
111
113
|
'local'?: string;
|
|
112
114
|
'headers'?: THttpHeaders;
|
|
@@ -126,9 +128,12 @@ export interface IMproxyOptions {
|
|
|
126
128
|
/** --- 秒数 --- */
|
|
127
129
|
'timeout'?: number;
|
|
128
130
|
'follow'?: number;
|
|
129
|
-
'
|
|
131
|
+
/** --- 自定义 host 映射,如 {'www.maiyun.net': '127.0.0.1'},或全部映射到一个 host --- */
|
|
132
|
+
'hosts'?: Record<string, string> | string;
|
|
130
133
|
'local'?: string;
|
|
131
134
|
'headers'?: THttpHeaders;
|
|
135
|
+
/** --- 过滤 header,返回 true 则留下 --- */
|
|
136
|
+
filter?: (h: string) => boolean;
|
|
132
137
|
/** --- 默认为 default --- */
|
|
133
138
|
'reuse'?: string;
|
|
134
139
|
}
|
|
@@ -137,9 +142,12 @@ export interface IRproxyOptions {
|
|
|
137
142
|
/** --- 秒数 --- */
|
|
138
143
|
'timeout'?: number;
|
|
139
144
|
'follow'?: number;
|
|
140
|
-
'
|
|
145
|
+
/** --- 自定义 host 映射,如 {'www.maiyun.net': '127.0.0.1'},或全部映射到一个 host --- */
|
|
146
|
+
'hosts'?: Record<string, string> | string;
|
|
141
147
|
'local'?: string;
|
|
142
148
|
'headers'?: THttpHeaders;
|
|
149
|
+
/** --- 过滤 header,返回 true 则留下 --- */
|
|
150
|
+
filter?: (h: string) => boolean;
|
|
143
151
|
/** --- 正向 mproxy 代理,url 如 https://xxx/abc --- */
|
|
144
152
|
'mproxy'?: {
|
|
145
153
|
'url': string;
|
package/lib/net.js
CHANGED
|
@@ -136,7 +136,9 @@ export async function request(u, data, opt = {}) {
|
|
|
136
136
|
};
|
|
137
137
|
return res;
|
|
138
138
|
}
|
|
139
|
-
if (hosts
|
|
139
|
+
if (typeof hosts === 'string' ?
|
|
140
|
+
!hosts :
|
|
141
|
+
(hosts[host] !== undefined && !hosts[host])) {
|
|
140
142
|
const res = new lResponse.Response(null);
|
|
141
143
|
res.error = {
|
|
142
144
|
'name': 'hosts error',
|
|
@@ -160,7 +162,7 @@ export async function request(u, data, opt = {}) {
|
|
|
160
162
|
'localAddress': local,
|
|
161
163
|
'ca': ca,
|
|
162
164
|
'connectionOptions': {
|
|
163
|
-
'remoteHost': hosts[host],
|
|
165
|
+
'remoteHost': typeof hosts === 'string' ? hosts : hosts[host],
|
|
164
166
|
},
|
|
165
167
|
});
|
|
166
168
|
}
|
|
@@ -434,11 +436,12 @@ const proxyContinueHeaders = [
|
|
|
434
436
|
'transfer-encoding'
|
|
435
437
|
];
|
|
436
438
|
/**
|
|
437
|
-
* --- 剔除不代理的 header ---
|
|
439
|
+
* --- 剔除不代理的 header,返回新的 header ---
|
|
438
440
|
* @param headers 剔除前的 header
|
|
439
441
|
* @param res 直接设置头部而不返回,可置空
|
|
442
|
+
* @param filter 返回 true 则留下
|
|
440
443
|
*/
|
|
441
|
-
export function
|
|
444
|
+
export function filterHeaders(headers, res, filter) {
|
|
442
445
|
const heads = {};
|
|
443
446
|
for (const h in headers) {
|
|
444
447
|
if (proxyContinueHeaders.includes(h)) {
|
|
@@ -451,6 +454,9 @@ export function filterProxyHeaders(headers, res) {
|
|
|
451
454
|
if (v === undefined) {
|
|
452
455
|
continue;
|
|
453
456
|
}
|
|
457
|
+
if (filter && !filter(h)) {
|
|
458
|
+
continue;
|
|
459
|
+
}
|
|
454
460
|
if (res) {
|
|
455
461
|
res.setHeader(h, v);
|
|
456
462
|
continue;
|
|
@@ -482,14 +488,17 @@ export async function mproxy(ctr, auth, opt = {}) {
|
|
|
482
488
|
}
|
|
483
489
|
opt.method = req.method ?? 'GET';
|
|
484
490
|
opt.headers ??= {};
|
|
485
|
-
Object.assign(
|
|
491
|
+
const headers = Object.assign(filterHeaders(req.headers, undefined, opt.filter), opt.headers);
|
|
486
492
|
// --- 发起请求 ---
|
|
487
|
-
const rres = await request(get['url'], req,
|
|
493
|
+
const rres = await request(get['url'], req, {
|
|
494
|
+
...opt,
|
|
495
|
+
headers
|
|
496
|
+
});
|
|
488
497
|
if (rres.error) {
|
|
489
498
|
return -2;
|
|
490
499
|
}
|
|
491
500
|
if (rres.headers) {
|
|
492
|
-
|
|
501
|
+
filterHeaders(rres.headers, res, opt.filter);
|
|
493
502
|
}
|
|
494
503
|
res.writeHead(rres.headers?.['http-code'] ?? 200);
|
|
495
504
|
await new Promise((resolve) => {
|
|
@@ -539,14 +548,17 @@ export async function rproxy(ctr, route, opt = {}) {
|
|
|
539
548
|
const lpath = path.slice(key.length);
|
|
540
549
|
opt.method = req.method ?? 'GET';
|
|
541
550
|
opt.headers ??= {};
|
|
542
|
-
Object.assign(
|
|
551
|
+
const headers = Object.assign(filterHeaders(req.headers, undefined, opt.filter), opt.headers);
|
|
543
552
|
// --- 发起请求 ---
|
|
544
|
-
const rres = await request(route[key] + lpath, req,
|
|
553
|
+
const rres = await request(route[key] + lpath, req, {
|
|
554
|
+
...opt,
|
|
555
|
+
headers
|
|
556
|
+
});
|
|
545
557
|
if (rres.error) {
|
|
546
558
|
return false;
|
|
547
559
|
}
|
|
548
560
|
if (rres.headers) {
|
|
549
|
-
|
|
561
|
+
filterHeaders(rres.headers, res, opt.filter);
|
|
550
562
|
}
|
|
551
563
|
res.writeHead(rres.headers?.['http-code'] ?? 200);
|
|
552
564
|
await new Promise((resolve) => {
|
package/lib/ws.d.ts
CHANGED
|
@@ -27,7 +27,8 @@ export declare enum EOpcode {
|
|
|
27
27
|
export interface IConnectOptions {
|
|
28
28
|
/** --- 秒数 --- */
|
|
29
29
|
'timeout'?: number;
|
|
30
|
-
'
|
|
30
|
+
/** --- 自定义 host 映射,如 {'www.maiyun.net': '127.0.0.1'},或全部映射到一个 host --- */
|
|
31
|
+
'hosts'?: Record<string, string> | string;
|
|
31
32
|
'local'?: string;
|
|
32
33
|
'headers'?: lNet.THttpHeaders;
|
|
33
34
|
/** --- cookie 托管对象 --- */
|
|
@@ -46,9 +47,12 @@ export interface IConnectOptions {
|
|
|
46
47
|
export interface IMproxyOptions {
|
|
47
48
|
/** --- 秒数 --- */
|
|
48
49
|
'timeout'?: number;
|
|
49
|
-
'
|
|
50
|
+
/** --- 自定义 host 映射,如 {'www.maiyun.net': '127.0.0.1'},或全部映射到一个 host --- */
|
|
51
|
+
'hosts'?: Record<string, string> | string;
|
|
50
52
|
'local'?: string;
|
|
51
53
|
'headers'?: lNet.THttpHeaders;
|
|
54
|
+
/** --- 过滤 header,返回 true 则留下 --- */
|
|
55
|
+
filter?: (h: string) => boolean;
|
|
52
56
|
/** --- 小帧模式,默认 false --- */
|
|
53
57
|
'mode'?: EFrameReceiveMode;
|
|
54
58
|
/** --- 加密模式,默认 true --- */
|
|
@@ -58,9 +62,12 @@ export interface IMproxyOptions {
|
|
|
58
62
|
export interface IRproxyOptions {
|
|
59
63
|
/** --- 秒数 --- */
|
|
60
64
|
'timeout'?: number;
|
|
61
|
-
'
|
|
65
|
+
/** --- 自定义 host 映射,如 {'www.maiyun.net': '127.0.0.1'},或全部映射到一个 host --- */
|
|
66
|
+
'hosts'?: Record<string, string> | string;
|
|
62
67
|
'local'?: string;
|
|
63
68
|
'headers'?: lNet.THttpHeaders;
|
|
69
|
+
/** --- 过滤 header,返回 true 则留下 --- */
|
|
70
|
+
filter?: (h: string) => boolean;
|
|
64
71
|
/** --- 小帧模式,默认 false --- */
|
|
65
72
|
'mode'?: EFrameReceiveMode;
|
|
66
73
|
/** --- 加密模式,默认 true --- */
|
package/lib/ws.js
CHANGED
|
@@ -92,7 +92,7 @@ export class Socket {
|
|
|
92
92
|
const ca = puri ?
|
|
93
93
|
puri.protocol === 'wss:' ? await lNet.getCa() : null :
|
|
94
94
|
uri.protocol === 'wss:' ? await lNet.getCa() : null;
|
|
95
|
-
if (!ca && hosts[uri.hostname]) {
|
|
95
|
+
if (!ca && (typeof hosts === 'string' ? hosts : hosts[uri.hostname])) {
|
|
96
96
|
// --- 没有 ca,但是要设置 额外的 host ---
|
|
97
97
|
headers['host'] = uri.hostname + (uri.port ? ':' + uri.port : '');
|
|
98
98
|
}
|
|
@@ -106,7 +106,7 @@ export class Socket {
|
|
|
106
106
|
}) : uri.path;
|
|
107
107
|
const cli = ca ?
|
|
108
108
|
await liws.wssConnect({
|
|
109
|
-
'hostname': hosts[host]
|
|
109
|
+
'hostname': (typeof hosts === 'string' ? hosts : hosts[host]) || host,
|
|
110
110
|
'port': port,
|
|
111
111
|
'path': path,
|
|
112
112
|
'servername': host,
|
|
@@ -117,7 +117,7 @@ export class Socket {
|
|
|
117
117
|
'ca': ca
|
|
118
118
|
}) :
|
|
119
119
|
await liws.wsConnect({
|
|
120
|
-
'hostname': hosts[host]
|
|
120
|
+
'hostname': (typeof hosts === 'string' ? hosts : hosts[host]) || host,
|
|
121
121
|
'port': port,
|
|
122
122
|
'path': path,
|
|
123
123
|
'headers': headers,
|
|
@@ -366,10 +366,13 @@ export async function mproxy(ctr, auth, opt = {}) {
|
|
|
366
366
|
return -1;
|
|
367
367
|
}
|
|
368
368
|
opt.headers ??= {};
|
|
369
|
-
Object.assign(
|
|
369
|
+
const headers = Object.assign(lNet.filterHeaders(req.headers, undefined, opt.filter), opt.headers);
|
|
370
370
|
// --- 发起请求 ---
|
|
371
371
|
/** --- 远程端的双向 socket --- */
|
|
372
|
-
const rsocket = await connect(get['url'],
|
|
372
|
+
const rsocket = await connect(get['url'], {
|
|
373
|
+
...opt,
|
|
374
|
+
headers
|
|
375
|
+
});
|
|
373
376
|
if (!rsocket) {
|
|
374
377
|
return -2;
|
|
375
378
|
}
|
|
@@ -387,10 +390,13 @@ export async function rproxy(ctr, url, opt = {}) {
|
|
|
387
390
|
/** --- 请求端产生的双向 socket --- */
|
|
388
391
|
const socket = ctr.getPrototype('_socket');
|
|
389
392
|
opt.headers ??= {};
|
|
390
|
-
Object.assign(
|
|
393
|
+
const headers = Object.assign(lNet.filterHeaders(req.headers, undefined, opt.filter), opt.headers);
|
|
391
394
|
// --- 发起请求 ---
|
|
392
395
|
/** --- 远程端的双向 socket --- */
|
|
393
|
-
const rsocket = await connect(url,
|
|
396
|
+
const rsocket = await connect(url, {
|
|
397
|
+
...opt,
|
|
398
|
+
headers
|
|
399
|
+
});
|
|
394
400
|
if (!rsocket) {
|
|
395
401
|
return false;
|
|
396
402
|
}
|
package/package.json
CHANGED
|
@@ -71,6 +71,7 @@ export default class extends sCtr.Ctr {
|
|
|
71
71
|
netRproxy(): Promise<string | boolean>;
|
|
72
72
|
netMproxy(): Promise<string | boolean>;
|
|
73
73
|
netMproxy1(): Promise<string | boolean>;
|
|
74
|
+
netFilterheaders(): string;
|
|
74
75
|
scan(): Promise<kebab.Json>;
|
|
75
76
|
scan1(): Promise<kebab.Json>;
|
|
76
77
|
scan2(): Promise<kebab.Json>;
|
package/www/example/ctr/test.js
CHANGED
|
@@ -160,6 +160,7 @@ export default class extends sCtr.Ctr {
|
|
|
160
160
|
`<br><a href="${this._config.const.urlBase}test/net-hosts">View "test/net-hosts"</a>`,
|
|
161
161
|
`<br><a href="${this._config.const.urlBase}test/net-rproxy/dist/core.js">View "test/net-rproxy/dist/core.js"</a> <a href="${this._config.const.urlBase}test/net-rproxy/package.json">View "package.json"</a>`,
|
|
162
162
|
`<br><a href="${this._config.const.urlBase}test/net-mproxy">View "test/net-mproxy"</a>`,
|
|
163
|
+
`<br><a href="${this._config.const.urlBase}test/net-filterheaders">View "test/net-filterheaders"</a>`,
|
|
163
164
|
'<br><br><b>Scan:</b>',
|
|
164
165
|
`<br><br><a href="${this._config.const.urlBase}test/scan?s=db">View "test/scan?s=db"</a>`,
|
|
165
166
|
`<br><a href="${this._config.const.urlBase}test/scan?s=kv">View "test/scan?s=kv"</a>`,
|
|
@@ -1813,6 +1814,40 @@ error: <pre>${JSON.stringify(res.error, null, 4)}</pre>`);
|
|
|
1813
1814
|
}
|
|
1814
1815
|
return 'Nothing(' + rtn + ')';
|
|
1815
1816
|
}
|
|
1817
|
+
netFilterheaders() {
|
|
1818
|
+
const echo = [];
|
|
1819
|
+
const headers = {
|
|
1820
|
+
'host': 'www.maiyun.net',
|
|
1821
|
+
'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/180.0.0.0 Safari/537.36',
|
|
1822
|
+
'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7',
|
|
1823
|
+
'accept-encoding': 'gzip, deflate',
|
|
1824
|
+
'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8',
|
|
1825
|
+
'cache-control': 'no-cache',
|
|
1826
|
+
'cdn-loop': 'TencentEdgeOne; loops=2',
|
|
1827
|
+
'eo-connecting-ip': 'xx:xx:xx:xx:xx',
|
|
1828
|
+
'eo-log-uuid': '102780998859203995',
|
|
1829
|
+
'pragma': 'no-cache',
|
|
1830
|
+
'priority': 'u=0, i',
|
|
1831
|
+
'sec-ch-ua': '"Chromium";v="140", "Not=A?Brand";v="24", "Google Chrome";v="180"',
|
|
1832
|
+
'sec-ch-ua-mobile': '?0',
|
|
1833
|
+
'sec-ch-ua-platform': '"Windows"',
|
|
1834
|
+
'sec-fetch-dest': 'document',
|
|
1835
|
+
'sec-fetch-mode': 'navigate',
|
|
1836
|
+
'sec-fetch-site': 'none',
|
|
1837
|
+
'sec-fetch-user': '?1',
|
|
1838
|
+
'upgrade-insecure-requests': '1',
|
|
1839
|
+
'x-forwarded-for': '127.1.2.3',
|
|
1840
|
+
'x-forwarded-host': 'www.maiyun.net',
|
|
1841
|
+
'x-forwarded-proto': 'http',
|
|
1842
|
+
'authorization': ''
|
|
1843
|
+
};
|
|
1844
|
+
echo.push(`origin:<pre>${JSON.stringify(headers, null, 4)}</pre>`);
|
|
1845
|
+
const filtered = lNet.filterHeaders(headers, undefined, h => {
|
|
1846
|
+
return !['x-', 'eo-'].some(i => h.startsWith(i));
|
|
1847
|
+
});
|
|
1848
|
+
echo.push(`const filtered = lNet.filterHeaders(headers);<pre>${JSON.stringify(filtered, null, 4)}</pre>`);
|
|
1849
|
+
return echo.join('') + this._getEnd();
|
|
1850
|
+
}
|
|
1816
1851
|
async scan() {
|
|
1817
1852
|
const link = await this._scanLink();
|
|
1818
1853
|
if (!link) {
|