@maiyunnet/kebab 3.1.19 → 3.2.0
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 +7 -4
- package/lib/net.js +17 -9
- package/lib/ws.d.ts +6 -3
- package/lib/ws.js +13 -7
- package/package.json +1 -1
- package/sys/child.js +2 -0
- package/sys/ctr.d.ts +2 -2
- package/sys/ctr.js +2 -2
- package/sys/route.js +16 -12
- package/www/example/ctr/middle.d.ts +1 -1
- package/www/example/ctr/middle.js +9 -6
- package/www/example/ctr/test.d.ts +1 -1
- package/www/example/ctr/test.js +35 -9
package/index.d.ts
CHANGED
package/index.js
CHANGED
|
@@ -6,7 +6,7 @@
|
|
|
6
6
|
* --- 本文件用来定义每个目录实体地址的常量 ---
|
|
7
7
|
*/
|
|
8
8
|
/** --- 当前系统版本号 --- */
|
|
9
|
-
export const VER = '3.
|
|
9
|
+
export const VER = '3.2.0';
|
|
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
|
@@ -79,7 +79,7 @@ export declare function getFormData(): fd.FormData;
|
|
|
79
79
|
* @param res 直接设置头部而不返回,可置空
|
|
80
80
|
* @param filter 返回 true 则留下
|
|
81
81
|
*/
|
|
82
|
-
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[]>;
|
|
83
83
|
/**
|
|
84
84
|
* --- 正向 mproxy 代理,注意提前处理不要自动处理 post 数据,读取 get 的 url 为实际请求地址 ---
|
|
85
85
|
* --- get: url, auth ---
|
|
@@ -107,7 +107,8 @@ export interface IRequestOptions {
|
|
|
107
107
|
/** --- 秒数 --- */
|
|
108
108
|
'timeout'?: number;
|
|
109
109
|
'follow'?: number;
|
|
110
|
-
'
|
|
110
|
+
/** --- 自定义 host 映射,如 {'www.maiyun.net': '127.0.0.1'},或全部映射到一个 host --- */
|
|
111
|
+
'hosts'?: Record<string, string> | string;
|
|
111
112
|
'save'?: string;
|
|
112
113
|
'local'?: string;
|
|
113
114
|
'headers'?: THttpHeaders;
|
|
@@ -127,7 +128,8 @@ export interface IMproxyOptions {
|
|
|
127
128
|
/** --- 秒数 --- */
|
|
128
129
|
'timeout'?: number;
|
|
129
130
|
'follow'?: number;
|
|
130
|
-
'
|
|
131
|
+
/** --- 自定义 host 映射,如 {'www.maiyun.net': '127.0.0.1'},或全部映射到一个 host --- */
|
|
132
|
+
'hosts'?: Record<string, string> | string;
|
|
131
133
|
'local'?: string;
|
|
132
134
|
'headers'?: THttpHeaders;
|
|
133
135
|
/** --- 过滤 header,返回 true 则留下 --- */
|
|
@@ -140,7 +142,8 @@ export interface IRproxyOptions {
|
|
|
140
142
|
/** --- 秒数 --- */
|
|
141
143
|
'timeout'?: number;
|
|
142
144
|
'follow'?: number;
|
|
143
|
-
'
|
|
145
|
+
/** --- 自定义 host 映射,如 {'www.maiyun.net': '127.0.0.1'},或全部映射到一个 host --- */
|
|
146
|
+
'hosts'?: Record<string, string> | string;
|
|
144
147
|
'local'?: string;
|
|
145
148
|
'headers'?: THttpHeaders;
|
|
146
149
|
/** --- 过滤 header,返回 true 则留下 --- */
|
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
|
}
|
|
@@ -439,7 +441,7 @@ const proxyContinueHeaders = [
|
|
|
439
441
|
* @param res 直接设置头部而不返回,可置空
|
|
440
442
|
* @param filter 返回 true 则留下
|
|
441
443
|
*/
|
|
442
|
-
export function
|
|
444
|
+
export function filterHeaders(headers, res, filter) {
|
|
443
445
|
const heads = {};
|
|
444
446
|
for (const h in headers) {
|
|
445
447
|
if (proxyContinueHeaders.includes(h)) {
|
|
@@ -486,14 +488,17 @@ export async function mproxy(ctr, auth, opt = {}) {
|
|
|
486
488
|
}
|
|
487
489
|
opt.method = req.method ?? 'GET';
|
|
488
490
|
opt.headers ??= {};
|
|
489
|
-
Object.assign(
|
|
491
|
+
const headers = Object.assign(filterHeaders(req.headers, undefined, opt.filter), opt.headers);
|
|
490
492
|
// --- 发起请求 ---
|
|
491
|
-
const rres = await request(get['url'], req,
|
|
493
|
+
const rres = await request(get['url'], req, {
|
|
494
|
+
...opt,
|
|
495
|
+
headers
|
|
496
|
+
});
|
|
492
497
|
if (rres.error) {
|
|
493
498
|
return -2;
|
|
494
499
|
}
|
|
495
500
|
if (rres.headers) {
|
|
496
|
-
|
|
501
|
+
filterHeaders(rres.headers, res, opt.filter);
|
|
497
502
|
}
|
|
498
503
|
res.writeHead(rres.headers?.['http-code'] ?? 200);
|
|
499
504
|
await new Promise((resolve) => {
|
|
@@ -543,14 +548,17 @@ export async function rproxy(ctr, route, opt = {}) {
|
|
|
543
548
|
const lpath = path.slice(key.length);
|
|
544
549
|
opt.method = req.method ?? 'GET';
|
|
545
550
|
opt.headers ??= {};
|
|
546
|
-
Object.assign(
|
|
551
|
+
const headers = Object.assign(filterHeaders(req.headers, undefined, opt.filter), opt.headers);
|
|
547
552
|
// --- 发起请求 ---
|
|
548
|
-
const rres = await request(route[key] + lpath, req,
|
|
553
|
+
const rres = await request(route[key] + lpath, req, {
|
|
554
|
+
...opt,
|
|
555
|
+
headers
|
|
556
|
+
});
|
|
549
557
|
if (rres.error) {
|
|
550
558
|
return false;
|
|
551
559
|
}
|
|
552
560
|
if (rres.headers) {
|
|
553
|
-
|
|
561
|
+
filterHeaders(rres.headers, res, opt.filter);
|
|
554
562
|
}
|
|
555
563
|
res.writeHead(rres.headers?.['http-code'] ?? 200);
|
|
556
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,7 +47,8 @@ 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;
|
|
52
54
|
/** --- 过滤 header,返回 true 则留下 --- */
|
|
@@ -60,7 +62,8 @@ export interface IMproxyOptions {
|
|
|
60
62
|
export interface IRproxyOptions {
|
|
61
63
|
/** --- 秒数 --- */
|
|
62
64
|
'timeout'?: number;
|
|
63
|
-
'
|
|
65
|
+
/** --- 自定义 host 映射,如 {'www.maiyun.net': '127.0.0.1'},或全部映射到一个 host --- */
|
|
66
|
+
'hosts'?: Record<string, string> | string;
|
|
64
67
|
'local'?: string;
|
|
65
68
|
'headers'?: lNet.THttpHeaders;
|
|
66
69
|
/** --- 过滤 header,返回 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(lNet.
|
|
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(lNet.
|
|
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
package/sys/child.js
CHANGED
|
@@ -203,6 +203,8 @@ async function requestHandler(req, res, https) {
|
|
|
203
203
|
timer.timer = setTimeout(timer.callback, timer.timeout);
|
|
204
204
|
// --- 设置服务器名版本 ---
|
|
205
205
|
res.setHeader('Server', 'Kebab/' + kebab.VER);
|
|
206
|
+
res.setHeader('expires', 'Mon, 26 Jul 1994 05:00:00 GMT');
|
|
207
|
+
res.setHeader('cache-control', 'no-store');
|
|
206
208
|
// --- 当前 uri ---
|
|
207
209
|
let host = req.headers[':authority'];
|
|
208
210
|
if (host === undefined || typeof host !== 'string') {
|
package/sys/ctr.d.ts
CHANGED
|
@@ -128,8 +128,8 @@ export declare class Ctr {
|
|
|
128
128
|
* --- WebSocket 下连接被终止后会自动被调用的事件,可重写此方法 ---
|
|
129
129
|
*/
|
|
130
130
|
onClose(): void | Promise<void>;
|
|
131
|
-
/** --- 请求发送开始时调用,返回
|
|
132
|
-
onReqStart():
|
|
131
|
+
/** --- 请求发送开始时调用,返回 -1-流程中断,一般用于代理/反代,0-框架不会自动处理 post,1-自动处理(默认)(仅会在 middle 内触发) --- */
|
|
132
|
+
onReqStart(): number | Promise<number>;
|
|
133
133
|
/**
|
|
134
134
|
* --- 获取截止当前时间的总运行时间 ---
|
|
135
135
|
* @param ms 为 true 为毫秒,否则为秒
|
package/sys/ctr.js
CHANGED
|
@@ -169,9 +169,9 @@ export class Ctr {
|
|
|
169
169
|
onClose() {
|
|
170
170
|
return;
|
|
171
171
|
}
|
|
172
|
-
/** --- 请求发送开始时调用,返回
|
|
172
|
+
/** --- 请求发送开始时调用,返回 -1-流程中断,一般用于代理/反代,0-框架不会自动处理 post,1-自动处理(默认)(仅会在 middle 内触发) --- */
|
|
173
173
|
onReqStart() {
|
|
174
|
-
return
|
|
174
|
+
return 1;
|
|
175
175
|
}
|
|
176
176
|
/**
|
|
177
177
|
* --- 获取截止当前时间的总运行时间 ---
|
package/sys/route.js
CHANGED
|
@@ -31,15 +31,6 @@ export function clearKebabConfigs() {
|
|
|
31
31
|
* @param data 传导的数据
|
|
32
32
|
*/
|
|
33
33
|
export async function run(data) {
|
|
34
|
-
// --- 检测 path 是否是静态文件 ---
|
|
35
|
-
if (/^(stc\/.*|favicon.\w+?\??.*|apple[\w-]+?\.png\??.*|[\w-]+?\.txt\??.*|[\w-]+?\.html\??.*)/.test(data.path)) {
|
|
36
|
-
return false;
|
|
37
|
-
}
|
|
38
|
-
// --- 根据 res 还是 socket 进行初始化设置 ---
|
|
39
|
-
if (data.res) {
|
|
40
|
-
data.res.setHeader('expires', 'Mon, 26 Jul 1994 05:00:00 GMT');
|
|
41
|
-
data.res.setHeader('cache-control', 'no-store');
|
|
42
|
-
}
|
|
43
34
|
// --- 判断 kebab config 是否已经读取过 ---
|
|
44
35
|
if (!kebabConfigs[data.rootPath + 'kebab.json']) {
|
|
45
36
|
const configContent = await lFs.getContent(data.rootPath + 'kebab.json', 'utf8');
|
|
@@ -80,6 +71,7 @@ export async function run(data) {
|
|
|
80
71
|
// --- 加载 kebab config ---
|
|
81
72
|
const config = {};
|
|
82
73
|
const configData = kebabConfigs[data.rootPath + 'kebab.json'];
|
|
74
|
+
// --- 合并 configData 到 config ---
|
|
83
75
|
for (const name in configData) {
|
|
84
76
|
config[name] = configData[name];
|
|
85
77
|
}
|
|
@@ -123,9 +115,11 @@ export async function run(data) {
|
|
|
123
115
|
if (path === '') {
|
|
124
116
|
path = '@';
|
|
125
117
|
}
|
|
118
|
+
/** --- 不做语言跳转、不进入动态处理流程的路径 --- */
|
|
119
|
+
const stcPaths = /^(stc\/.*|favicon.\w+?\??.*|apple[\w-]+?\.png\??.*|[\w-]+?\.txt\??.*|[\w-]+?\.html\??.*)/;
|
|
126
120
|
// --- 检测是否托管语言页面 ---
|
|
127
121
|
const param = [];
|
|
128
|
-
if (config.lang && data.res) {
|
|
122
|
+
if (config.lang && data.res && !stcPaths.test(path)) {
|
|
129
123
|
// --- 仅仅 res 模式支持 config.lang ---
|
|
130
124
|
if (path[2] !== '/') {
|
|
131
125
|
// --- 不管是首页还是 @ 页,都会到此处(已经有语言目录不会到这里) ---
|
|
@@ -375,9 +369,19 @@ export async function run(data) {
|
|
|
375
369
|
middle.setPrototype('_action', pathRight);
|
|
376
370
|
middle.setPrototype('_headers', headers);
|
|
377
371
|
middle.setPrototype('_get', get);
|
|
378
|
-
/** --- 是否让框架自动获取 post,
|
|
372
|
+
/** --- 是否让框架自动获取 post,1 为自动(默认) --- */
|
|
379
373
|
const reqStartRtn = await middle.onReqStart();
|
|
380
|
-
if (reqStartRtn) {
|
|
374
|
+
if (reqStartRtn === -1) {
|
|
375
|
+
// --- 代理/反代了,什么也不管 ---
|
|
376
|
+
return true;
|
|
377
|
+
}
|
|
378
|
+
// --- 检测 path 是否是静态文件 ---
|
|
379
|
+
// --- 只能在这里做,因为 onReqStart 里面可能有反代,反代不能让 stc 等路径直连 ---
|
|
380
|
+
// --- 也得同时给反代走,所以 onReqStart 之后才能走到这一步判断 ---
|
|
381
|
+
if (stcPaths.test(data.path)) {
|
|
382
|
+
return false;
|
|
383
|
+
}
|
|
384
|
+
if (reqStartRtn === 1) {
|
|
381
385
|
const rawPost = await getPost(data.req);
|
|
382
386
|
// --- 原始 POST ---
|
|
383
387
|
middle.setPrototype('_rawPost', rawPost.raw);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as kebab from '#kebab/index.js';
|
|
2
2
|
import * as sCtr from '#kebab/sys/ctr.js';
|
|
3
3
|
export default class extends sCtr.Ctr {
|
|
4
|
-
onReqStart():
|
|
4
|
+
onReqStart(): Promise<number>;
|
|
5
5
|
onLoad(): string | boolean;
|
|
6
6
|
onUnload(rtn: string | boolean | kebab.DbValue[]): string | boolean | kebab.DbValue[];
|
|
7
7
|
}
|
|
@@ -1,13 +1,16 @@
|
|
|
1
|
+
import * as lNet from '#kebab/lib/net.js';
|
|
1
2
|
import * as sCtr from '#kebab/sys/ctr.js';
|
|
2
3
|
export default class extends sCtr.Ctr {
|
|
3
|
-
onReqStart() {
|
|
4
|
-
if (this
|
|
5
|
-
|
|
4
|
+
async onReqStart() {
|
|
5
|
+
if (await lNet.rproxy(this, {
|
|
6
|
+
'test/net-rproxy/': 'https://cdn.jsdelivr.net/npm/deskrt@2.0.10/'
|
|
7
|
+
})) {
|
|
8
|
+
return -1;
|
|
6
9
|
}
|
|
7
|
-
if (this._config.const.path
|
|
8
|
-
return
|
|
10
|
+
if (this._config.const.path === 'test/net-mproxy1') {
|
|
11
|
+
return 0;
|
|
9
12
|
}
|
|
10
|
-
return
|
|
13
|
+
return 1;
|
|
11
14
|
}
|
|
12
15
|
onLoad() {
|
|
13
16
|
if (this._config.const.path !== 'test/middle') {
|
|
@@ -68,9 +68,9 @@ export default class extends sCtr.Ctr {
|
|
|
68
68
|
netReuse(): Promise<string>;
|
|
69
69
|
netError(): Promise<string>;
|
|
70
70
|
netHosts(): Promise<string>;
|
|
71
|
-
netRproxy(): Promise<string | boolean>;
|
|
72
71
|
netMproxy(): Promise<string | boolean>;
|
|
73
72
|
netMproxy1(): Promise<string | boolean>;
|
|
73
|
+
netFilterheaders(): string;
|
|
74
74
|
scan(): Promise<kebab.Json>;
|
|
75
75
|
scan1(): Promise<kebab.Json>;
|
|
76
76
|
scan2(): Promise<kebab.Json>;
|
package/www/example/ctr/test.js
CHANGED
|
@@ -46,7 +46,6 @@ export default class extends sCtr.Ctr {
|
|
|
46
46
|
return true;
|
|
47
47
|
}
|
|
48
48
|
onReady() {
|
|
49
|
-
lCore.display('onReady');
|
|
50
49
|
return true;
|
|
51
50
|
}
|
|
52
51
|
onUnload(rtn) {
|
|
@@ -160,6 +159,7 @@ export default class extends sCtr.Ctr {
|
|
|
160
159
|
`<br><a href="${this._config.const.urlBase}test/net-hosts">View "test/net-hosts"</a>`,
|
|
161
160
|
`<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
161
|
`<br><a href="${this._config.const.urlBase}test/net-mproxy">View "test/net-mproxy"</a>`,
|
|
162
|
+
`<br><a href="${this._config.const.urlBase}test/net-filterheaders">View "test/net-filterheaders"</a>`,
|
|
163
163
|
'<br><br><b>Scan:</b>',
|
|
164
164
|
`<br><br><a href="${this._config.const.urlBase}test/scan?s=db">View "test/scan?s=db"</a>`,
|
|
165
165
|
`<br><a href="${this._config.const.urlBase}test/scan?s=kv">View "test/scan?s=kv"</a>`,
|
|
@@ -1775,14 +1775,6 @@ content: <pre>${lText.htmlescape((await res.getContent())?.toString() ?? '')}</p
|
|
|
1775
1775
|
error: <pre>${JSON.stringify(res.error, null, 4)}</pre>`);
|
|
1776
1776
|
return echo.join('') + this._getEnd();
|
|
1777
1777
|
}
|
|
1778
|
-
async netRproxy() {
|
|
1779
|
-
if (await lNet.rproxy(this, {
|
|
1780
|
-
'test/net-rproxy/': 'https://cdn.jsdelivr.net/npm/deskrt@2.0.10/'
|
|
1781
|
-
})) {
|
|
1782
|
-
return false;
|
|
1783
|
-
}
|
|
1784
|
-
return 'Nothing';
|
|
1785
|
-
}
|
|
1786
1778
|
async netMproxy() {
|
|
1787
1779
|
const echo = [];
|
|
1788
1780
|
const res = await lNet.get('https://cdn.jsdelivr.net/npm/deskrt@2.0.10/package.json', {
|
|
@@ -1813,6 +1805,40 @@ error: <pre>${JSON.stringify(res.error, null, 4)}</pre>`);
|
|
|
1813
1805
|
}
|
|
1814
1806
|
return 'Nothing(' + rtn + ')';
|
|
1815
1807
|
}
|
|
1808
|
+
netFilterheaders() {
|
|
1809
|
+
const echo = [];
|
|
1810
|
+
const headers = {
|
|
1811
|
+
'host': 'www.maiyun.net',
|
|
1812
|
+
'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',
|
|
1813
|
+
'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',
|
|
1814
|
+
'accept-encoding': 'gzip, deflate',
|
|
1815
|
+
'accept-language': 'zh-CN,zh;q=0.9,en;q=0.8',
|
|
1816
|
+
'cache-control': 'no-cache',
|
|
1817
|
+
'cdn-loop': 'TencentEdgeOne; loops=2',
|
|
1818
|
+
'eo-connecting-ip': 'xx:xx:xx:xx:xx',
|
|
1819
|
+
'eo-log-uuid': '102780998859203995',
|
|
1820
|
+
'pragma': 'no-cache',
|
|
1821
|
+
'priority': 'u=0, i',
|
|
1822
|
+
'sec-ch-ua': '"Chromium";v="140", "Not=A?Brand";v="24", "Google Chrome";v="180"',
|
|
1823
|
+
'sec-ch-ua-mobile': '?0',
|
|
1824
|
+
'sec-ch-ua-platform': '"Windows"',
|
|
1825
|
+
'sec-fetch-dest': 'document',
|
|
1826
|
+
'sec-fetch-mode': 'navigate',
|
|
1827
|
+
'sec-fetch-site': 'none',
|
|
1828
|
+
'sec-fetch-user': '?1',
|
|
1829
|
+
'upgrade-insecure-requests': '1',
|
|
1830
|
+
'x-forwarded-for': '127.1.2.3',
|
|
1831
|
+
'x-forwarded-host': 'www.maiyun.net',
|
|
1832
|
+
'x-forwarded-proto': 'http',
|
|
1833
|
+
'authorization': ''
|
|
1834
|
+
};
|
|
1835
|
+
echo.push(`origin:<pre>${JSON.stringify(headers, null, 4)}</pre>`);
|
|
1836
|
+
const filtered = lNet.filterHeaders(headers, undefined, h => {
|
|
1837
|
+
return !['x-', 'eo-'].some(i => h.startsWith(i));
|
|
1838
|
+
});
|
|
1839
|
+
echo.push(`const filtered = lNet.filterHeaders(headers);<pre>${JSON.stringify(filtered, null, 4)}</pre>`);
|
|
1840
|
+
return echo.join('') + this._getEnd();
|
|
1841
|
+
}
|
|
1816
1842
|
async scan() {
|
|
1817
1843
|
const link = await this._scanLink();
|
|
1818
1844
|
if (!link) {
|