@maiyunnet/kebab 9.14.0 → 9.14.2
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/doc/kebab-rag.md +428 -232
- package/index.d.ts +1 -1
- package/index.js +1 -1
- package/lib/core.d.ts +17 -0
- package/lib/core.js +163 -7
- package/lib/db/pool.js +3 -2
- package/lib/sql.d.ts +26 -0
- package/lib/sql.js +34 -1
- package/lib/text.d.ts +2 -9
- package/lib/text.js +5 -6
- package/package.json +1 -1
- package/sys/ctr.d.ts +4 -0
- package/sys/mod.d.ts +32 -0
- package/sys/mod.js +37 -1
- package/sys/route.d.ts +4 -0
- package/sys/route.js +63 -0
- package/www/example/ctr/test.d.ts +2 -0
- package/www/example/ctr/test.js +36 -0
- package/www/example/stc/chunk-FG5CKGYR.js +81 -0
- package/www/example/stc/view/hello.page.bundle.js +1 -1
- package/www/example/stc/view/hello.page.css +2 -2
- package/www/example/stc/view/react-router.page.bundle.js +1 -1
- package/www/example/stc/view/react-router.page.css +2 -2
- package/www/example/stc/view/react-router.page.js +1 -1
- package/www/example/stc/view/react-router.page.tsx +1 -1
- package/www/example/stc/view/react.page.bundle.js +3 -3
- package/www/example/stc/view/react.page.css +2 -2
- package/www/example/stc/chunk-YJ3GYATF.js +0 -81
package/sys/route.js
CHANGED
|
@@ -935,6 +935,18 @@ export function getFormData(req, events = {}, limits = {}) {
|
|
|
935
935
|
};
|
|
936
936
|
/** --- 获取的 boundary 文本 --- */
|
|
937
937
|
const boundary = ct.slice(clio + 9);
|
|
938
|
+
// --- 超时护盾:防止网络静默断开时 Promise 永不 resolve ---
|
|
939
|
+
/** --- 超时定时器 --- */
|
|
940
|
+
let timer;
|
|
941
|
+
/** --- 是否已经结束(防止重复 resolve) --- */
|
|
942
|
+
let finished = false;
|
|
943
|
+
/** --- 清理定时器 --- */
|
|
944
|
+
function clearTimer() {
|
|
945
|
+
if (timer) {
|
|
946
|
+
clearTimeout(timer);
|
|
947
|
+
timer = undefined;
|
|
948
|
+
}
|
|
949
|
+
}
|
|
938
950
|
// 一下变量是相对于 data 事件的全局变量 ---
|
|
939
951
|
/** --- 当前临时读入的还未处理的 buffer --- */
|
|
940
952
|
let buffer = Buffer.from('');
|
|
@@ -978,6 +990,23 @@ export function getFormData(req, events = {}, limits = {}) {
|
|
|
978
990
|
}
|
|
979
991
|
}
|
|
980
992
|
}
|
|
993
|
+
// --- 启动超时定时器(在所有变量声明之后,确保回调闭包可引用) ---
|
|
994
|
+
const timeoutMs = limits.timeout ?? 300_000;
|
|
995
|
+
if (timeoutMs > 0) {
|
|
996
|
+
timer = setTimeout(() => {
|
|
997
|
+
if (finished) {
|
|
998
|
+
return;
|
|
999
|
+
}
|
|
1000
|
+
finished = true;
|
|
1001
|
+
if ((state === EState.FILE) && ftmpName && ftmpStream) {
|
|
1002
|
+
ftmpStream.destroy();
|
|
1003
|
+
}
|
|
1004
|
+
lCore.debug('[ROUTE][GETFORMDATA] formdata request timeout');
|
|
1005
|
+
lCore.log({}, '[ROUTE][GETFORMDATA] formdata request timeout after ' + timeoutMs + 'ms', '-error');
|
|
1006
|
+
cleanupFiles();
|
|
1007
|
+
resolve(false);
|
|
1008
|
+
}, timeoutMs);
|
|
1009
|
+
}
|
|
981
1010
|
/** --- 拒绝当前文件:销毁流、删临时文件、标记 rejected --- */
|
|
982
1011
|
function rejectFile() {
|
|
983
1012
|
rejected = true;
|
|
@@ -988,6 +1017,11 @@ export function getFormData(req, events = {}, limits = {}) {
|
|
|
988
1017
|
}
|
|
989
1018
|
/** --- 最终输出 --- */
|
|
990
1019
|
function finalize() {
|
|
1020
|
+
if (finished) {
|
|
1021
|
+
return;
|
|
1022
|
+
}
|
|
1023
|
+
finished = true;
|
|
1024
|
+
clearTimer();
|
|
991
1025
|
if (rejected) {
|
|
992
1026
|
cleanupFiles();
|
|
993
1027
|
resolve(false);
|
|
@@ -1064,6 +1098,12 @@ export function getFormData(req, events = {}, limits = {}) {
|
|
|
1064
1098
|
// --- POST 模式 ---
|
|
1065
1099
|
const io = buffer.indexOf('\r\n--' + boundary);
|
|
1066
1100
|
if (io === -1) {
|
|
1101
|
+
// --- 检查字段大小限制,防止畸形数据导致 buffer 无限增长 ---
|
|
1102
|
+
const maxField = limits.maxFieldSize ?? 1_048_576;
|
|
1103
|
+
if (buffer.length > maxField + boundary.length + 4) {
|
|
1104
|
+
rejected = true;
|
|
1105
|
+
return;
|
|
1106
|
+
}
|
|
1067
1107
|
return;
|
|
1068
1108
|
}
|
|
1069
1109
|
// --- 找到结束标语,写入 POST ---
|
|
@@ -1178,6 +1218,11 @@ export function getFormData(req, events = {}, limits = {}) {
|
|
|
1178
1218
|
}
|
|
1179
1219
|
});
|
|
1180
1220
|
req.on('error', function (e) {
|
|
1221
|
+
if (finished) {
|
|
1222
|
+
return;
|
|
1223
|
+
}
|
|
1224
|
+
finished = true;
|
|
1225
|
+
clearTimer();
|
|
1181
1226
|
if ((state === EState.FILE) && ftmpName) {
|
|
1182
1227
|
ftmpStream.destroy();
|
|
1183
1228
|
}
|
|
@@ -1186,8 +1231,26 @@ export function getFormData(req, events = {}, limits = {}) {
|
|
|
1186
1231
|
cleanupFiles();
|
|
1187
1232
|
resolve(false);
|
|
1188
1233
|
});
|
|
1234
|
+
// --- 监听连接关闭(HTTP/2 RST_STREAM、代理断连、或用户主动中断上传等场景) ---
|
|
1235
|
+
req.on('close', function () {
|
|
1236
|
+
if (finished) {
|
|
1237
|
+
return;
|
|
1238
|
+
}
|
|
1239
|
+
// --- 若数据未读完且连接已关闭,视为传输中断(多数是用户主动取消,无需记录错误) ---
|
|
1240
|
+
if (!readEnd && writeFileLength > 0) {
|
|
1241
|
+
finished = true;
|
|
1242
|
+
clearTimer();
|
|
1243
|
+
if ((state === EState.FILE) && ftmpName && ftmpStream) {
|
|
1244
|
+
ftmpStream.destroy();
|
|
1245
|
+
}
|
|
1246
|
+
lCore.debug('[ROUTE][GETFORMDATA] connection closed before formdata complete');
|
|
1247
|
+
cleanupFiles();
|
|
1248
|
+
resolve(false);
|
|
1249
|
+
}
|
|
1250
|
+
});
|
|
1189
1251
|
req.on('end', function () {
|
|
1190
1252
|
readEnd = true;
|
|
1253
|
+
clearTimer();
|
|
1191
1254
|
// --- 被拒绝则清理文件并 resolve(false) ---
|
|
1192
1255
|
if (rejected) {
|
|
1193
1256
|
finalize();
|
|
@@ -47,6 +47,8 @@ export default class extends sCtr.Ctr {
|
|
|
47
47
|
coreChecktype(): string;
|
|
48
48
|
coreCheckschema(): string;
|
|
49
49
|
coreMuid(): string;
|
|
50
|
+
coreIplimit(): string;
|
|
51
|
+
coreRealiplimit(): string;
|
|
50
52
|
coreGetlog(): Promise<string>;
|
|
51
53
|
coreLs(): Promise<string>;
|
|
52
54
|
coreUpdatecode(): Promise<string>;
|
package/www/example/ctr/test.js
CHANGED
|
@@ -153,6 +153,8 @@ export default class extends sCtr.Ctr {
|
|
|
153
153
|
`<br><a href="${this._config.const.urlBase}test/core-checktype">View "test/core-checktype"</a>`,
|
|
154
154
|
`<br><a href="${this._config.const.urlBase}test/core-checkschema">View "test/core-checkschema"</a>`,
|
|
155
155
|
`<br><a href="${this._config.const.urlBase}test/core-muid">View "test/core-muid"</a>`,
|
|
156
|
+
`<br><a href="${this._config.const.urlBase}test/core-iplimit">View "test/core-iplimit"</a>`,
|
|
157
|
+
`<br><a href="${this._config.const.urlBase}test/core-realiplimit">View "test/core-realiplimit"</a>`,
|
|
156
158
|
`<br><a href="${this._config.const.urlBase}test/core-getlog">View "test/core-getlog"</a>`,
|
|
157
159
|
`<br><a href="${this._config.const.urlBase}test/core-ls">View "test/core-ls"</a>`,
|
|
158
160
|
`<br><a href="${this._config.const.urlBase}test/core-reload">View "test/core-reload"</a>`,
|
|
@@ -213,6 +215,7 @@ export default class extends sCtr.Ctr {
|
|
|
213
215
|
`<br><a href="${this._config.const.urlBase}test/sql?type=having">View "test/sql?type=having"</a> <a href="${this._config.const.urlBase}test/sql?type=having&s=pgsql">pgsql</a>`,
|
|
214
216
|
`<br><a href="${this._config.const.urlBase}test/sql?type=by">View "test/sql?type=by"</a> <a href="${this._config.const.urlBase}test/sql?type=by&s=pgsql">pgsql</a>`,
|
|
215
217
|
`<br><a href="${this._config.const.urlBase}test/sql?type=field">View "test/sql?type=field"</a> <a href="${this._config.const.urlBase}test/sql?type=field&s=pgsql">pgsql</a>`,
|
|
218
|
+
`<br><a href="${this._config.const.urlBase}test/sql?type=hint">View "test/sql?type=hint"</a>`,
|
|
216
219
|
'<br><br><b>Consistent:</b>',
|
|
217
220
|
`<br><br><a href="${this._config.const.urlBase}test/consistent-hash">View "test/consistent-hash"</a>`,
|
|
218
221
|
`<br><a href="${this._config.const.urlBase}test/consistent-distributed">View "test/consistent-distributed"</a>`,
|
|
@@ -1367,6 +1370,24 @@ for (let i = 0; i < 30000; ++i) {
|
|
|
1367
1370
|
}
|
|
1368
1371
|
return echo.join('') + this._getEnd();
|
|
1369
1372
|
}
|
|
1373
|
+
coreIplimit() {
|
|
1374
|
+
const v6 = '2001:db8:85a3:8d3:1319:8a2e:370:7348';
|
|
1375
|
+
return '<pre>lCore.ipLimit(\'192.168.1.100\');</pre>' + lCore.ipLimit('192.168.1.100') +
|
|
1376
|
+
'<pre>lCore.ipLimit(\'2001:db8:85a3:8d3:1319:8a2e:370:7348\');</pre>' + lCore.ipLimit(v6) +
|
|
1377
|
+
'<pre>lCore.ipLimit(\'2001:db8:85a3:8d3:1319:8a2e:370:7348\', 48);</pre>' + lCore.ipLimit(v6, 48) +
|
|
1378
|
+
'<pre>lCore.ipLimit(\'2001:db8:85a3:8d3:1319:8a2e:370:7348\', 56);</pre>' + lCore.ipLimit(v6, 56) +
|
|
1379
|
+
'<pre>lCore.ipLimit(\'2001:db8:85a3:8d3:1319:8a2e:370:7348\', 128);</pre>' + lCore.ipLimit(v6, 128) +
|
|
1380
|
+
'<pre>lCore.ipLimit(\'::1\');</pre>' + lCore.ipLimit('::1') +
|
|
1381
|
+
'<pre>lCore.ipLimit(\'\');</pre>' + JSON.stringify(lCore.ipLimit('')) +
|
|
1382
|
+
'<br><br>' + this._getEnd();
|
|
1383
|
+
}
|
|
1384
|
+
coreRealiplimit() {
|
|
1385
|
+
return '<pre>lCore.realIP(this);</pre>' + lCore.realIP(this) +
|
|
1386
|
+
'<pre>lCore.realIPLimit(this);</pre>' + lCore.realIPLimit(this) +
|
|
1387
|
+
'<pre>lCore.realIPLimit(this, \'\', 48);</pre>' + lCore.realIPLimit(this, '', 48) +
|
|
1388
|
+
'<pre>lCore.realIPLimit(this, \'\', 56);</pre>' + lCore.realIPLimit(this, '', 56) +
|
|
1389
|
+
'<br><br>' + this._getEnd();
|
|
1390
|
+
}
|
|
1370
1391
|
async coreGetlog() {
|
|
1371
1392
|
const path = lTime.format(null, 'Y/m/d/H');
|
|
1372
1393
|
const log = await lCore.getLog({
|
|
@@ -3064,6 +3085,21 @@ Result:<pre id="result">Nothing.</pre>`);
|
|
|
3064
3085
|
echo.push(`<pre>sql.field('*');</pre>` + sql.field('*'));
|
|
3065
3086
|
break;
|
|
3066
3087
|
}
|
|
3088
|
+
case 'hint': {
|
|
3089
|
+
let s = sql.hint('INDEX(`supply_date_0_0` `idx_supply_date_query`)').select('*', 'supply_date_0_0').getSql();
|
|
3090
|
+
let sd = sql.getData();
|
|
3091
|
+
echo.push(`<pre>sql.hint('INDEX(\`supply_date_0_0\` \`idx_supply_date_query\`)').select('*', 'supply_date_0_0');</pre>
|
|
3092
|
+
<b>getSql() :</b> ${s}<br>
|
|
3093
|
+
<b>getData():</b> <pre>${JSON.stringify(sd, undefined, 4)}</pre>
|
|
3094
|
+
<b>format() :</b> ${sql.format(s, sd)}<hr>`);
|
|
3095
|
+
s = sql.hint('INDEX(`supply_date_0_0` `idx_supply_date_query`) NO_INDEX(`supply_date_0_0` `idx_old`)').select('*', 'supply_date_0_0').getSql();
|
|
3096
|
+
sd = sql.getData();
|
|
3097
|
+
echo.push(`<pre>sql.hint('INDEX(\`supply_date_0_0\` \`idx_supply_date_query\`) NO_INDEX(\`supply_date_0_0\` \`idx_old\`)').select('*', 'supply_date_0_0');</pre>
|
|
3098
|
+
<b>getSql() :</b> ${s}<br>
|
|
3099
|
+
<b>getData():</b> <pre>${JSON.stringify(sd, undefined, 4)}</pre>
|
|
3100
|
+
<b>format() :</b> ${sql.format(s, sd)}`);
|
|
3101
|
+
break;
|
|
3102
|
+
}
|
|
3067
3103
|
}
|
|
3068
3104
|
return echo.join('') + '<br><br>' + this._getEnd();
|
|
3069
3105
|
}
|