mm_os 3.2.9 → 3.3.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.
Files changed (38) hide show
  1. package/README.md +47 -1
  2. package/core/base/mqtt/index.js +10 -10
  3. package/core/base/web/index.js +98 -11
  4. package/core/com/middleware/com.js +152 -152
  5. package/core/com/socket/config.tpl.json +2 -2
  6. package/core/com/socket/drive.js +2 -2
  7. package/core/com/socket/index.js +1 -1
  8. package/core/com/sql/drive.js +7 -7
  9. package/index.js +40 -30
  10. package/middleware/performance/index.js +150 -142
  11. package/middleware/security_audit/index.js +549 -0
  12. package/middleware/security_audit/middleware.json +48 -0
  13. package/middleware/security_headers/index.js +487 -0
  14. package/middleware/security_headers/middleware.json +45 -0
  15. package/middleware/waf/index.js +277 -6
  16. package/middleware/waf/middleware.json +2 -1
  17. package/middleware/waf_ddos/index.js +520 -0
  18. package/middleware/waf_ddos/middleware.json +38 -0
  19. package/middleware/waf_ip/index.js +231 -20
  20. package/middleware/waf_ip/middleware.json +43 -4
  21. package/middleware/waf_xss/index.js +269 -0
  22. package/middleware/waf_xss/middleware.json +18 -0
  23. package/middleware/web_before/middleware.json +1 -1
  24. package/middleware/web_socket/middleware.json +2 -2
  25. package/package.json +18 -7
  26. package/middleware/cors/index.js +0 -103
  27. package/middleware/cors/middleware.json +0 -9
  28. package/middleware/log/index.js +0 -32
  29. package/middleware/log/middleware.json +0 -9
  30. package/middleware/rate_limit/index.js +0 -112
  31. package/middleware/rate_limit/middleware.json +0 -10
  32. package/nodemon.json +0 -31
  33. package/package.txt +0 -1
  34. package/rps.bat +0 -3
  35. package/test.js +0 -10
  36. package/tps.bat +0 -3
  37. package/update.bat +0 -1
  38. package//347/263/273/347/273/237/346/236/266/346/236/204/350/257/204/344/274/260/344/270/216/344/274/230/345/214/226/345/273/272/350/256/256.md +0 -599
package/index.js CHANGED
@@ -1,3 +1,10 @@
1
+ // 增强版补丁:彻底解决util._extend API弃用警告
2
+ const util = require('util');
3
+ // 完全替换util._extend为Object.assign的包装函数,确保行为一致
4
+ util._extend = function(target, source) {
5
+ return Object.assign({}, target, source);
6
+ };
7
+
1
8
  require('mm_logs');
2
9
  require('mm_ret');
3
10
  $.Tpl = require('mm_tpl');
@@ -73,6 +80,11 @@ class OS {
73
80
  "database": "mm",
74
81
  "user": "admin",
75
82
  "password": "asd123"
83
+ },
84
+ "modules": {
85
+ "hotReload": true,
86
+ "watchInterval": 5000,
87
+ "autoLoad": true
76
88
  }
77
89
  };
78
90
  this.init(config);
@@ -204,34 +216,34 @@ OS.prototype.init = function(config) {
204
216
  this.initErrorHandler();
205
217
  }
206
218
 
207
- /**
208
- * 运行基础数据
209
- * @param {Object} cg - 配置对象
210
- */
211
- OS.prototype.initBase = function(cg) {
212
- var middleware = $.middleware;
213
- middleware.update();
214
- var mqtt, web;
215
- if (cg.web && cg.web.state) {
216
- web = new WEB(cg.web);
217
- web.list = middleware.list.filter((o) => {
218
- return !o.mode || o.mode == "web"
219
- });
220
- web.init();
221
- this.web = web;
222
- }
223
-
224
- if (cg.mqtt && cg.mqtt.state) {
225
- mqtt = new MQTT(Object.assign(cg.mqtt, {
226
- redis: cg.redis,
227
- mongodb: cg.mongodb
228
- }));
229
- mqtt.list = middleware.list.filter((o) => {
230
- return o.mode == "mqtt"
231
- });
232
- mqtt.init();
233
- this.mqtt = mqtt;
234
- }
219
+ /**
220
+ * 运行基础数据
221
+ * @param {Object} cg - 配置对象
222
+ */
223
+ OS.prototype.initBase = function(cg) {
224
+ var middleware = $.middleware;
225
+ middleware.update();
226
+ var mqtt, web;
227
+ if (cg.web && cg.web.state) {
228
+ web = new WEB(cg.web);
229
+ web.list = middleware.list.filter((o) => {
230
+ return !o.mode || o.mode == "web"
231
+ });
232
+ web.init();
233
+ this.web = web;
234
+ }
235
+
236
+ if (cg.mqtt && cg.mqtt.state) {
237
+ mqtt = new MQTT(Object.assign(cg.mqtt, {
238
+ redis: cg.redis,
239
+ mongodb: cg.mongodb
240
+ }));
241
+ mqtt.list = middleware.list.filter((o) => {
242
+ return o.mode == "mqtt"
243
+ });
244
+ mqtt.init();
245
+ this.mqtt = mqtt;
246
+ }
235
247
  }
236
248
 
237
249
  /**
@@ -243,8 +255,6 @@ OS.prototype.main = async function(state) {
243
255
  $.timer.run();
244
256
 
245
257
  var cg = this.config;
246
- var web_server = this.web_server;
247
- var mqtt_server = this.mqtt_server;
248
258
  var tip = "启动";
249
259
  if (cg.web && cg.web.state) {
250
260
  tip += " web";
@@ -1,143 +1,151 @@
1
- /**
2
- * 请求性能监控中间件
3
- * 记录请求响应时间,监控慢请求,提供性能数据收集
4
- */
5
- module.exports = function(server, config) {
6
- if(config.web && !config.web.performance) {
7
- return server;
8
- }
9
-
10
- // 默认配置
11
- const cg = Object.assign({
12
- slowThreshold: 1000, // 慢请求阈值,单位毫秒
13
- enableMetrics: true, // 是否启用性能指标收集
14
- ignorePaths: [] // 忽略监控的路径
15
- }, config);
16
-
17
- // 性能监控数据收集器
18
- const performanceData = {
19
- counters: new Map(), // 请求计数器
20
- responseTimes: new Map(), // 响应时间数据
21
- slowRequests: [] // 慢请求记录
22
- };
23
-
24
- // 全局性能监控对象
25
- $.performanceMonitor = {
26
- record: function(path, responseTime) {
27
- if (!cg.enableMetrics) return;
28
-
29
- // 更新请求计数
30
- if (!performanceData.counters.has(path)) {
31
- performanceData.counters.set(path, 1);
32
- performanceData.responseTimes.set(path, { sum: responseTime, count: 1, min: responseTime, max: responseTime });
33
- } else {
34
- performanceData.counters.set(path, performanceData.counters.get(path) + 1);
35
- const stats = performanceData.responseTimes.get(path);
36
- stats.sum += responseTime;
37
- stats.count += 1;
38
- stats.min = Math.min(stats.min, responseTime);
39
- stats.max = Math.max(stats.max, responseTime);
40
- }
41
-
42
- // 记录慢请求
43
- if (responseTime > cg.slowThreshold) {
44
- performanceData.slowRequests.push({
45
- path: path,
46
- time: new Date(),
47
- responseTime: responseTime
48
- });
49
- // 限制慢请求记录数量
50
- if (performanceData.slowRequests.length > 1000) {
51
- performanceData.slowRequests.shift();
52
- }
53
- }
54
- },
55
-
56
- getStats: function() {
57
- const result = {};
58
- performanceData.counters.forEach((count, path) => {
59
- const times = performanceData.responseTimes.get(path);
60
- result[path] = {
61
- count: count,
62
- avg: times.sum / times.count,
63
- min: times.min,
64
- max: times.max
65
- };
66
- });
67
- return result;
68
- },
69
-
70
- getSlowRequests: function(limit = 100) {
71
- return performanceData.slowRequests.slice(-limit);
72
- },
73
-
74
- reset: function() {
75
- performanceData.counters.clear();
76
- performanceData.responseTimes.clear();
77
- performanceData.slowRequests = [];
78
- }
79
- };
80
-
81
- // 性能监控中间件
82
- server.use(async (ctx, next) => {
83
- // 检查是否需要忽略此路径
84
- const shouldIgnore = cg.ignorePaths.some(pattern => {
85
- if (typeof pattern === 'string') {
86
- return ctx.path === pattern;
87
- } else if (pattern instanceof RegExp) {
88
- return pattern.test(ctx.path);
89
- }
90
- return false;
91
- });
92
-
93
- if (shouldIgnore) {
94
- await next();
95
- return;
96
- }
97
-
98
- const start = Date.now();
99
- const startTime = process.hrtime();
100
-
101
- try {
102
- await next();
103
- } finally {
104
- const ms = Date.now() - start;
105
- const [seconds, nanoseconds] = process.hrtime(startTime);
106
- const executionTime = seconds * 1000 + nanoseconds / 1000000;
107
-
108
- // 设置响应时间头
109
- ctx.set('X-Response-Time', `${ms}ms`);
110
-
111
- // 记录性能数据
112
- $.performanceMonitor.record(ctx.path, ms);
113
-
114
- // 慢请求报警
115
- if (ms > cg.slowThreshold) {
116
- const clientIP = ctx.headers['x-forwarded-for'] || ctx.ip;
117
- $.log.warn(`【慢请求】 ${ctx.method} ${ctx.path} - ${ms}ms - ${clientIP}`);
118
-
119
- // 如果是非常慢的请求(超过阈值的2倍),记录更多信息
120
- if (ms > cg.slowThreshold * 2) {
121
- const userAgent = ctx.headers['user-agent'] || 'unknown';
122
- let requestData = '';
123
- try {
124
- if (ctx.method !== 'GET' && ctx.request.body) {
125
- const bodyStr = JSON.stringify(ctx.request.body);
126
- // 限制记录的请求体大小
127
- requestData = bodyStr.length > 1024 ? bodyStr.substring(0, 1024) + '...' : bodyStr;
128
- }
129
- } catch (e) {
130
- requestData = '[无法序列化请求体]';
131
- }
132
-
133
- $.log.warn(`【慢请求详情】路径: ${ctx.path}, 方法: ${ctx.method}, 耗时: ${ms}ms, IP: ${clientIP}, UA: ${userAgent.substring(0, 200)}`);
134
- if (requestData) {
135
- $.log.warn(`【慢请求数据】${requestData}`);
136
- }
137
- }
138
- }
139
- }
140
- });
141
-
142
- return server;
1
+ /**
2
+ * 请求性能监控中间件
3
+ * 记录请求响应时间,监控慢请求,提供性能数据收集
4
+ */
5
+ module.exports = function(server, config) {
6
+ if (config.web && !config.web.performance) {
7
+ return server;
8
+ }
9
+
10
+ // 默认配置
11
+ const cg = Object.assign({
12
+ slowThreshold: 1000, // 慢请求阈值,单位毫秒
13
+ enableMetrics: true, // 是否启用性能指标收集
14
+ ignorePaths: [] // 忽略监控的路径
15
+ }, config);
16
+
17
+ // 性能监控数据收集器
18
+ const performanceData = {
19
+ counters: new Map(), // 请求计数器
20
+ responseTimes: new Map(), // 响应时间数据
21
+ slowRequests: [] // 慢请求记录
22
+ };
23
+
24
+ // 全局性能监控对象
25
+ $.performanceMonitor = {
26
+ record: function(path, responseTime) {
27
+ if (!cg.enableMetrics) return;
28
+
29
+ // 更新请求计数
30
+ if (!performanceData.counters.has(path)) {
31
+ performanceData.counters.set(path, 1);
32
+ performanceData.responseTimes.set(path, {
33
+ sum: responseTime,
34
+ count: 1,
35
+ min: responseTime,
36
+ max: responseTime
37
+ });
38
+ } else {
39
+ performanceData.counters.set(path, performanceData.counters.get(path) + 1);
40
+ const stats = performanceData.responseTimes.get(path);
41
+ stats.sum += responseTime;
42
+ stats.count += 1;
43
+ stats.min = Math.min(stats.min, responseTime);
44
+ stats.max = Math.max(stats.max, responseTime);
45
+ }
46
+
47
+ // 记录慢请求
48
+ if (responseTime > cg.slowThreshold) {
49
+ performanceData.slowRequests.push({
50
+ path: path,
51
+ time: new Date(),
52
+ responseTime: responseTime
53
+ });
54
+ // 限制慢请求记录数量
55
+ if (performanceData.slowRequests.length > 1000) {
56
+ performanceData.slowRequests.shift();
57
+ }
58
+ }
59
+ },
60
+
61
+ getStats: function() {
62
+ const result = {};
63
+ performanceData.counters.forEach((count, path) => {
64
+ const times = performanceData.responseTimes.get(path);
65
+ result[path] = {
66
+ count: count,
67
+ avg: times.sum / times.count,
68
+ min: times.min,
69
+ max: times.max
70
+ };
71
+ });
72
+ return result;
73
+ },
74
+
75
+ getSlowRequests: function(limit = 100) {
76
+ return performanceData.slowRequests.slice(-limit);
77
+ },
78
+
79
+ reset: function() {
80
+ performanceData.counters.clear();
81
+ performanceData.responseTimes.clear();
82
+ performanceData.slowRequests = [];
83
+ }
84
+ };
85
+
86
+ // 性能监控中间件
87
+ server.use(async (ctx, next) => {
88
+ // 检查是否需要忽略此路径
89
+ const shouldIgnore = cg.ignorePaths.some(pattern => {
90
+ if (typeof pattern === 'string') {
91
+ return ctx.path === pattern;
92
+ } else if (pattern instanceof RegExp) {
93
+ return pattern.test(ctx.path);
94
+ }
95
+ return false;
96
+ });
97
+
98
+ if (shouldIgnore) {
99
+ await next();
100
+ return;
101
+ }
102
+
103
+ const start = Date.now();
104
+ const startTime = process.hrtime();
105
+
106
+ try {
107
+ await next();
108
+ } finally {
109
+ const ms = Date.now() - start;
110
+ const [seconds, nanoseconds] = process.hrtime(startTime);
111
+ const executionTime = seconds * 1000 + nanoseconds / 1000000;
112
+
113
+ // 设置响应时间头
114
+ ctx.set('X-Response-Time', `${ms}ms`);
115
+
116
+ // 记录性能数据
117
+ $.performanceMonitor.record(ctx.path, ms);
118
+
119
+ // 慢请求报警
120
+ if (ms > cg.slowThreshold) {
121
+ const clientIP = ctx.headers['x-forwarded-for'] || ctx.ip;
122
+ $.log.warn(`【慢请求】 ${ctx.method} ${ctx.path} - ${ms}ms - ${clientIP}`);
123
+
124
+ // 如果是非常慢的请求(超过阈值的2倍),记录更多信息
125
+ if (ms > cg.slowThreshold * 2) {
126
+ const userAgent = ctx.headers['user-agent'] || 'unknown';
127
+ let requestData = '';
128
+ try {
129
+ if (ctx.method !== 'GET' && ctx.request.body) {
130
+ const bodyStr = JSON.stringify(ctx.request.body);
131
+ // 限制记录的请求体大小
132
+ requestData = bodyStr.length > 1024 ? bodyStr.substring(0, 1024) + '...' :
133
+ bodyStr;
134
+ }
135
+ } catch (e) {
136
+ requestData = '[无法序列化请求体]';
137
+ }
138
+
139
+ $.log.warn(
140
+ `【慢请求详情】路径: ${ctx.path}, 方法: ${ctx.method}, 耗时: ${ms}ms, IP: ${clientIP}, UA: ${userAgent.substring(0, 200)}`
141
+ );
142
+ if (requestData) {
143
+ $.log.warn(`【慢请求数据】${requestData}`);
144
+ }
145
+ }
146
+ }
147
+ }
148
+ });
149
+
150
+ return server;
143
151
  };