block-proxy 0.1.9 → 0.1.10

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/config.json CHANGED
@@ -147,4 +147,4 @@
147
147
  "mac": "FA:27:3C:E5:31:5F"
148
148
  }
149
149
  ]
150
- }
150
+ }
package/example/rule.js CHANGED
@@ -37,3 +37,4 @@ module.exports = {
37
37
  }
38
38
  ]
39
39
  };
40
+
@@ -46,6 +46,28 @@ function normalizeSocketKey(ip, port) {
46
46
  return ip + ":" + port
47
47
  }
48
48
 
49
+ // 判断是否命中 responseRules
50
+ function matchResponseRule(responseRules, userConfig) {
51
+ try {
52
+ var hostname = userConfig.requestOptions.hostname.split(":")[0].toLowerCase();
53
+ var pathname = userConfig.requestOptions.path; // 带query
54
+ var url = `${userConfig.protocol}://${hostname}${pathname}`
55
+ var matched = false;
56
+ for (const item of responseRules) {
57
+ if (hostname.endsWith(item["host"]) && new RegExp(item['regexp']).test(url)) {
58
+ matched = true;
59
+ break;
60
+ } else {
61
+ continue;
62
+ }
63
+ }
64
+ return matched;
65
+ } catch (e) {
66
+ console.log(e);
67
+ return false;
68
+ }
69
+ }
70
+
49
71
  class CommonReadableStream extends Readable {
50
72
  constructor(config) {
51
73
  super({
@@ -467,6 +489,15 @@ function getUserReqHandler(userRule, recorder) {
467
489
 
468
490
  // route user config
469
491
  .then(co.wrap(function *(userConfig) {
492
+ // Modified 2026-1-15
493
+ // 增加了对 responseRules 的判断,如果需要对 BeforeResponse 进行拦截
494
+ // 则让 chunkSizeThreshold 为很大的值(默认20M),以便让 response 一次性返回,方便BeforeResponse处理
495
+ // 否则以 512k 为上线,只要返回的数据达到阈值,就直接返回给调用端,以提高性能
496
+ if (userRule.responseRules && matchResponseRule(userRule.responseRules, userConfig)) {
497
+ var _chunkSizeThreshold = chunkSizeThreshold;
498
+ } else {
499
+ var _chunkSizeThreshold = 0.5 * 1024 * 1024; // 512K
500
+ }
470
501
  if (userConfig.response) {
471
502
  // user-assigned local response
472
503
  userConfig._directlyPassToRespond = true;
@@ -474,7 +505,7 @@ function getUserReqHandler(userRule, recorder) {
474
505
  } else if (userConfig.requestOptions) {
475
506
  const remoteResponse = yield fetchRemoteResponse(userConfig.protocol, userConfig.requestOptions, userConfig.requestData, {
476
507
  dangerouslyIgnoreUnauthorized: reqHandlerCtx.dangerouslyIgnoreUnauthorized,
477
- chunkSizeThreshold,
508
+ chunkSizeThreshold: _chunkSizeThreshold,
478
509
  });
479
510
  return {
480
511
  response: {
@@ -1026,3 +1057,4 @@ class RequestHandler {
1026
1057
  }
1027
1058
 
1028
1059
  module.exports = RequestHandler;
1060
+
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "block-proxy",
3
- "version": "0.1.9",
3
+ "version": "0.1.10",
4
4
  "description": "Small-scale network mitm proxy filter",
5
5
  "bin": {
6
6
  "block-proxy": "bin/start.js"
@@ -16,7 +16,7 @@
16
16
  "url": "git+https://github.com/jayli/block-proxy.git"
17
17
  },
18
18
  "scripts": {
19
- "cp": "echo '---- program start ----'",
19
+ "cp": "echo '----- program start -----'",
20
20
  "craco": "craco start",
21
21
  "dev": "BLOCK_PROXY_DEV=1 npm run express",
22
22
  "start": "npm run express",
package/proxy/proxy.js CHANGED
@@ -29,11 +29,12 @@ var Rule = require("./mitm/rule.js");
29
29
  // 启用全局 keep-alive,使 AnyProxy 内部转发也复用连接
30
30
  http.globalAgent.keepAlive = true;
31
31
  https.globalAgent.keepAlive = true;
32
- http.globalAgent.maxSockets = 50;
33
- https.globalAgent.maxSockets = 50;
32
+ // 连接上限 50 应该足够了,设置 100 留足 buffer
33
+ http.globalAgent.maxSockets = 100;
34
+ https.globalAgent.maxSockets = 100;
34
35
 
35
- const httpAgent = new http.Agent({ keepAlive: true, maxSockets: 50 });
36
- const httpsAgent = new https.Agent({ keepAlive: true, maxSockets: 50 });
36
+ const httpAgent = new http.Agent({ keepAlive: true, maxSockets: 100 });
37
+ const httpsAgent = new https.Agent({ keepAlive: true, maxSockets: 100 });
37
38
 
38
39
  // 全局参数
39
40
  const configPath = path.join(__dirname, '../config.json');
@@ -90,6 +91,8 @@ function authPass(protocol, host, url) {
90
91
  "weixin.qq.com",
91
92
  // xiaohongshu.com:443,小红书App和知乎 App 里发起带端口的请求,收到 407 后第二次
92
93
  "xiaohongshu.com:443",
94
+ "xiaohongshu.com",
95
+ "xhscdn.com",
93
96
  "zhihu.com:443",
94
97
  ...filtered_mitm_domains
95
98
  ];
package/proxy/scan.js CHANGED
@@ -78,6 +78,46 @@ async function getScanStatus() {
78
78
  return loadedConfig.network_scanning_status;
79
79
  }
80
80
 
81
+ // 并发控制器,限制同时进行的 ping 数量
82
+ class ConcurrentPingController {
83
+ constructor(maxConcurrent = 32, batchDelay = 50) {
84
+ this.maxConcurrent = maxConcurrent;
85
+ this.batchDelay = batchDelay; // 批次之间的延迟(毫秒)
86
+ }
87
+
88
+ // 批量执行 ping,控制并发数(真正的批次并发)
89
+ async batchPing(ips, timeout = 1) {
90
+ const results = [];
91
+
92
+ // 将IP列表分成多个批次
93
+ for (let i = 0; i < ips.length; i += this.maxConcurrent) {
94
+ const batch = ips.slice(i, i + this.maxConcurrent);
95
+
96
+ // 并发执行当前批次的所有ping
97
+ const batchPromises = batch.map(ip =>
98
+ ping.promise.probe(ip, { timeout })
99
+ );
100
+
101
+ const batchResults = await Promise.allSettled(batchPromises);
102
+
103
+ // 将批次结果添加到总结果中
104
+ batch.forEach((ip, index) => {
105
+ results.push({
106
+ ip,
107
+ result: batchResults[index]
108
+ });
109
+ });
110
+
111
+ // 如果不是最后一个批次,则添加延迟
112
+ if (i + this.maxConcurrent < ips.length) {
113
+ await new Promise(resolve => setTimeout(resolve, this.batchDelay));
114
+ }
115
+ }
116
+
117
+ return results;
118
+ }
119
+ }
120
+
81
121
  async function doScan() {
82
122
  const subnet = getLocalSubnet();
83
123
  // 如果是 30 网段,直接返回空
@@ -86,11 +126,17 @@ async function doScan() {
86
126
  }
87
127
  console.log(`正在扫描网段: ${subnet}.0/24`);
88
128
 
89
- // Ping all IPs to populate ARP cache
129
+ // 创建并发控制器,限制同时进行32个ping,批次间延迟50ms
130
+ const controller = new ConcurrentPingController(32, 50);
131
+
132
+ // 生成所有IP地址
90
133
  const ips = Array.from({ length: 254 }, (_, i) => `${subnet}.${i + 1}`);
91
- await Promise.allSettled(ips.map(ip => ping.promise.probe(ip, { timeout: 1 })));
92
134
 
93
- // Read ARP table via system command
135
+ // 使用并发控制器分批ping所有IP
136
+ console.log(`开始并发ping扫描,最大并发数: 32,批次延迟: 50ms`);
137
+ await controller.batchPing(ips, 1); // 使用1秒超时,ping结果仅用于填充ARP缓存
138
+
139
+ // 读取ARP表以获取MAC地址
94
140
  const cmd = process.platform === 'win32' ? 'arp -a' : 'arp -a';
95
141
  const arpOutput = await new Promise((resolve, reject) => {
96
142
  exec(cmd, async (error, stdout) => {
package/server/express.js CHANGED
@@ -232,3 +232,4 @@ module.exports = {
232
232
  });
233
233
  }
234
234
  };
235
+
@@ -38,3 +38,4 @@ sock1.on('secureConnect', () => {
38
38
  };
39
39
  setTimeout(trySecond, 5);
40
40
  });
41
+
package/src/setupTests.js CHANGED
@@ -3,3 +3,4 @@
3
3
  // expect(element).toHaveTextContent(/react/i)
4
4
  // learn more: https://github.com/testing-library/jest-dom
5
5
  import '@testing-library/jest-dom';
6
+
@@ -119,3 +119,4 @@ if [ -n "$real_time" ]; then
119
119
  else
120
120
  echo "⚠️ 无法获取耗时(shell 不支持 time 内置命令的格式)"
121
121
  fi
122
+
Binary file