dynapm 1.0.13 → 1.0.14
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/CHANGELOG.md +32 -13
- package/CLAUDE.md +8 -16
- package/README.md +18 -22
- package/README_zh.md +19 -16
- package/TASK.md +53 -0
- package/dist/src/core/admin-api.d.ts +4 -0
- package/dist/src/core/gateway.d.ts +12 -16
- package/dist/src/index.js +650 -614
- package/package.json +9 -9
package/dist/src/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
var __webpack_modules__ = {
|
|
3
|
-
"./node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/buffer-util.js"
|
|
3
|
+
"./node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/buffer-util.js" (module, __unused_rspack_exports, __webpack_require__) {
|
|
4
4
|
const { EMPTY_BUFFER } = __webpack_require__("./node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/constants.js");
|
|
5
5
|
const FastBuffer = Buffer[Symbol.species];
|
|
6
6
|
function concat(list, totalLength) {
|
|
@@ -61,13 +61,13 @@ var __webpack_modules__ = {
|
|
|
61
61
|
};
|
|
62
62
|
} catch (e) {}
|
|
63
63
|
},
|
|
64
|
-
"./node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/constants.js"
|
|
64
|
+
"./node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/constants.js" (module) {
|
|
65
65
|
const BINARY_TYPES = [
|
|
66
66
|
'nodebuffer',
|
|
67
67
|
'arraybuffer',
|
|
68
68
|
'fragments'
|
|
69
69
|
];
|
|
70
|
-
const hasBlob =
|
|
70
|
+
const hasBlob = "u" > typeof Blob;
|
|
71
71
|
if (hasBlob) BINARY_TYPES.push('blob');
|
|
72
72
|
module.exports = {
|
|
73
73
|
BINARY_TYPES,
|
|
@@ -82,7 +82,7 @@ var __webpack_modules__ = {
|
|
|
82
82
|
NOOP: ()=>{}
|
|
83
83
|
};
|
|
84
84
|
},
|
|
85
|
-
"./node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/event-target.js"
|
|
85
|
+
"./node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/event-target.js" (module, __unused_rspack_exports, __webpack_require__) {
|
|
86
86
|
const { kForOnEventAttribute, kListener } = __webpack_require__("./node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/constants.js");
|
|
87
87
|
const kCode = Symbol('kCode');
|
|
88
88
|
const kData = Symbol('kData');
|
|
@@ -227,7 +227,7 @@ var __webpack_modules__ = {
|
|
|
227
227
|
else listener.call(thisArg, event);
|
|
228
228
|
}
|
|
229
229
|
},
|
|
230
|
-
"./node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/extension.js"
|
|
230
|
+
"./node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/extension.js" (module, __unused_rspack_exports, __webpack_require__) {
|
|
231
231
|
const { tokenChars } = __webpack_require__("./node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/validation.js");
|
|
232
232
|
function push(dest, name, elem) {
|
|
233
233
|
if (void 0 === dest[name]) dest[name] = [
|
|
@@ -249,54 +249,51 @@ var __webpack_modules__ = {
|
|
|
249
249
|
let i = 0;
|
|
250
250
|
for(; i < header.length; i++){
|
|
251
251
|
code = header.charCodeAt(i);
|
|
252
|
-
if (void 0 === extensionName) {
|
|
253
|
-
if (-1 ===
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
push(
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
} else throw new SyntaxError(`Unexpected character at index ${i}`);
|
|
286
|
-
} else if (isEscaping) {
|
|
252
|
+
if (void 0 === extensionName) if (-1 === end && 1 === tokenChars[code]) {
|
|
253
|
+
if (-1 === start) start = i;
|
|
254
|
+
} else if (0 !== i && (0x20 === code || 0x09 === code)) {
|
|
255
|
+
if (-1 === end && -1 !== start) end = i;
|
|
256
|
+
} else if (0x3b === code || 0x2c === code) {
|
|
257
|
+
if (-1 === start) throw new SyntaxError(`Unexpected character at index ${i}`);
|
|
258
|
+
if (-1 === end) end = i;
|
|
259
|
+
const name = header.slice(start, end);
|
|
260
|
+
if (0x2c === code) {
|
|
261
|
+
push(offers, name, params);
|
|
262
|
+
params = Object.create(null);
|
|
263
|
+
} else extensionName = name;
|
|
264
|
+
start = end = -1;
|
|
265
|
+
} else throw new SyntaxError(`Unexpected character at index ${i}`);
|
|
266
|
+
else if (void 0 === paramName) if (-1 === end && 1 === tokenChars[code]) {
|
|
267
|
+
if (-1 === start) start = i;
|
|
268
|
+
} else if (0x20 === code || 0x09 === code) {
|
|
269
|
+
if (-1 === end && -1 !== start) end = i;
|
|
270
|
+
} else if (0x3b === code || 0x2c === code) {
|
|
271
|
+
if (-1 === start) throw new SyntaxError(`Unexpected character at index ${i}`);
|
|
272
|
+
if (-1 === end) end = i;
|
|
273
|
+
push(params, header.slice(start, end), true);
|
|
274
|
+
if (0x2c === code) {
|
|
275
|
+
push(offers, extensionName, params);
|
|
276
|
+
params = Object.create(null);
|
|
277
|
+
extensionName = void 0;
|
|
278
|
+
}
|
|
279
|
+
start = end = -1;
|
|
280
|
+
} else if (0x3d === code && -1 !== start && -1 === end) {
|
|
281
|
+
paramName = header.slice(start, i);
|
|
282
|
+
start = end = -1;
|
|
283
|
+
} else throw new SyntaxError(`Unexpected character at index ${i}`);
|
|
284
|
+
else if (isEscaping) {
|
|
287
285
|
if (1 !== tokenChars[code]) throw new SyntaxError(`Unexpected character at index ${i}`);
|
|
288
286
|
if (-1 === start) start = i;
|
|
289
287
|
else if (!mustUnescape) mustUnescape = true;
|
|
290
288
|
isEscaping = false;
|
|
291
|
-
} else if (inQuotes) {
|
|
292
|
-
if (1 ===
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
} else if (0x22 === code && 0x3d === header.charCodeAt(i - 1)) inQuotes = true;
|
|
289
|
+
} else if (inQuotes) if (1 === tokenChars[code]) {
|
|
290
|
+
if (-1 === start) start = i;
|
|
291
|
+
} else if (0x22 === code && -1 !== start) {
|
|
292
|
+
inQuotes = false;
|
|
293
|
+
end = i;
|
|
294
|
+
} else if (0x5c === code) isEscaping = true;
|
|
295
|
+
else throw new SyntaxError(`Unexpected character at index ${i}`);
|
|
296
|
+
else if (0x22 === code && 0x3d === header.charCodeAt(i - 1)) inQuotes = true;
|
|
300
297
|
else if (-1 === end && 1 === tokenChars[code]) {
|
|
301
298
|
if (-1 === start) start = i;
|
|
302
299
|
} else if (-1 !== start && (0x20 === code || 0x09 === code)) {
|
|
@@ -352,7 +349,7 @@ var __webpack_modules__ = {
|
|
|
352
349
|
parse
|
|
353
350
|
};
|
|
354
351
|
},
|
|
355
|
-
"./node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/limiter.js"
|
|
352
|
+
"./node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/limiter.js" (module) {
|
|
356
353
|
const kDone = Symbol('kDone');
|
|
357
354
|
const kRun = Symbol('kRun');
|
|
358
355
|
class Limiter {
|
|
@@ -380,7 +377,7 @@ var __webpack_modules__ = {
|
|
|
380
377
|
}
|
|
381
378
|
module.exports = Limiter;
|
|
382
379
|
},
|
|
383
|
-
"./node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/permessage-deflate.js"
|
|
380
|
+
"./node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/permessage-deflate.js" (module, __unused_rspack_exports, __webpack_require__) {
|
|
384
381
|
const zlib = __webpack_require__("zlib");
|
|
385
382
|
const bufferUtil = __webpack_require__("./node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/buffer-util.js");
|
|
386
383
|
const Limiter = __webpack_require__("./node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/limiter.js");
|
|
@@ -575,10 +572,7 @@ var __webpack_modules__ = {
|
|
|
575
572
|
}
|
|
576
573
|
function inflateOnData(chunk) {
|
|
577
574
|
this[kTotalLength] += chunk.length;
|
|
578
|
-
if (this[kPerMessageDeflate]._maxPayload < 1 || this[kTotalLength] <= this[kPerMessageDeflate]._maxPayload)
|
|
579
|
-
this[kBuffers].push(chunk);
|
|
580
|
-
return;
|
|
581
|
-
}
|
|
575
|
+
if (this[kPerMessageDeflate]._maxPayload < 1 || this[kTotalLength] <= this[kPerMessageDeflate]._maxPayload) return void this[kBuffers].push(chunk);
|
|
582
576
|
this[kError] = new RangeError('Max payload size exceeded');
|
|
583
577
|
this[kError].code = 'WS_ERR_UNSUPPORTED_MESSAGE_LENGTH';
|
|
584
578
|
this[kError][kStatusCode] = 1009;
|
|
@@ -587,15 +581,12 @@ var __webpack_modules__ = {
|
|
|
587
581
|
}
|
|
588
582
|
function inflateOnError(err) {
|
|
589
583
|
this[kPerMessageDeflate]._inflate = null;
|
|
590
|
-
if (this[kError])
|
|
591
|
-
this[kCallback](this[kError]);
|
|
592
|
-
return;
|
|
593
|
-
}
|
|
584
|
+
if (this[kError]) return void this[kCallback](this[kError]);
|
|
594
585
|
err[kStatusCode] = 1007;
|
|
595
586
|
this[kCallback](err);
|
|
596
587
|
}
|
|
597
588
|
},
|
|
598
|
-
"./node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/receiver.js"
|
|
589
|
+
"./node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/receiver.js" (module, __unused_rspack_exports, __webpack_require__) {
|
|
599
590
|
const { Writable } = __webpack_require__("stream");
|
|
600
591
|
const PerMessageDeflate = __webpack_require__("./node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/permessage-deflate.js");
|
|
601
592
|
const { BINARY_TYPES, EMPTY_BUFFER, kStatusCode, kWebSocket } = __webpack_require__("./node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/constants.js");
|
|
@@ -818,10 +809,7 @@ var __webpack_modules__ = {
|
|
|
818
809
|
data = this.consume(this._payloadLength);
|
|
819
810
|
if (this._masked && (this._mask[0] | this._mask[1] | this._mask[2] | this._mask[3]) !== 0) unmask(data, this._mask);
|
|
820
811
|
}
|
|
821
|
-
if (this._opcode > 0x07)
|
|
822
|
-
this.controlMessage(data, cb);
|
|
823
|
-
return;
|
|
824
|
-
}
|
|
812
|
+
if (this._opcode > 0x07) return void this.controlMessage(data, cb);
|
|
825
813
|
if (this._compressed) {
|
|
826
814
|
this._state = INFLATING;
|
|
827
815
|
this.decompress(data, cb);
|
|
@@ -945,7 +933,7 @@ var __webpack_modules__ = {
|
|
|
945
933
|
}
|
|
946
934
|
module.exports = Receiver;
|
|
947
935
|
},
|
|
948
|
-
"./node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/sender.js"
|
|
936
|
+
"./node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/sender.js" (module, __unused_rspack_exports, __webpack_require__) {
|
|
949
937
|
const { Duplex } = __webpack_require__("stream");
|
|
950
938
|
const { randomFillSync } = __webpack_require__("crypto");
|
|
951
939
|
const PerMessageDeflate = __webpack_require__("./node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/permessage-deflate.js");
|
|
@@ -999,13 +987,12 @@ var __webpack_modules__ = {
|
|
|
999
987
|
offset = 6;
|
|
1000
988
|
}
|
|
1001
989
|
let dataLength;
|
|
1002
|
-
if ('string' == typeof data)
|
|
1003
|
-
|
|
1004
|
-
|
|
1005
|
-
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
} else {
|
|
990
|
+
if ('string' == typeof data) if ((!options.mask || skipMasking) && void 0 !== options[kByteLength]) dataLength = options[kByteLength];
|
|
991
|
+
else {
|
|
992
|
+
data = Buffer.from(data);
|
|
993
|
+
dataLength = data.length;
|
|
994
|
+
}
|
|
995
|
+
else {
|
|
1009
996
|
dataLength = data.length;
|
|
1010
997
|
merge = options.mask && options.readOnly && !skipMasking;
|
|
1011
998
|
}
|
|
@@ -1054,19 +1041,18 @@ var __webpack_modules__ = {
|
|
|
1054
1041
|
close(code, data, mask, cb) {
|
|
1055
1042
|
let buf;
|
|
1056
1043
|
if (void 0 === code) buf = EMPTY_BUFFER;
|
|
1057
|
-
else if ('number' == typeof code && isValidStatusCode(code)) {
|
|
1058
|
-
|
|
1059
|
-
|
|
1060
|
-
|
|
1061
|
-
|
|
1062
|
-
|
|
1063
|
-
|
|
1064
|
-
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
} else throw new TypeError('First argument must be a valid error code number');
|
|
1044
|
+
else if ('number' == typeof code && isValidStatusCode(code)) if (void 0 !== data && data.length) {
|
|
1045
|
+
const length = Buffer.byteLength(data);
|
|
1046
|
+
if (length > 123) throw new RangeError('The message must not be greater than 123 bytes');
|
|
1047
|
+
buf = Buffer.allocUnsafe(2 + length);
|
|
1048
|
+
buf.writeUInt16BE(code, 0);
|
|
1049
|
+
if ('string' == typeof data) buf.write(data, 2);
|
|
1050
|
+
else buf.set(data, 2);
|
|
1051
|
+
} else {
|
|
1052
|
+
buf = Buffer.allocUnsafe(2);
|
|
1053
|
+
buf.writeUInt16BE(code, 0);
|
|
1054
|
+
}
|
|
1055
|
+
else throw new TypeError('First argument must be a valid error code number');
|
|
1070
1056
|
const options = {
|
|
1071
1057
|
[kByteLength]: buf.length,
|
|
1072
1058
|
fin: true,
|
|
@@ -1111,16 +1097,15 @@ var __webpack_modules__ = {
|
|
|
1111
1097
|
readOnly,
|
|
1112
1098
|
rsv1: false
|
|
1113
1099
|
};
|
|
1114
|
-
if (isBlob(data))
|
|
1115
|
-
|
|
1116
|
-
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
|
|
1120
|
-
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
} else if (this._state !== DEFAULT) this.enqueue([
|
|
1100
|
+
if (isBlob(data)) if (this._state !== DEFAULT) this.enqueue([
|
|
1101
|
+
this.getBlobData,
|
|
1102
|
+
data,
|
|
1103
|
+
false,
|
|
1104
|
+
options,
|
|
1105
|
+
cb
|
|
1106
|
+
]);
|
|
1107
|
+
else this.getBlobData(data, false, options, cb);
|
|
1108
|
+
else if (this._state !== DEFAULT) this.enqueue([
|
|
1124
1109
|
this.dispatch,
|
|
1125
1110
|
data,
|
|
1126
1111
|
false,
|
|
@@ -1154,16 +1139,15 @@ var __webpack_modules__ = {
|
|
|
1154
1139
|
readOnly,
|
|
1155
1140
|
rsv1: false
|
|
1156
1141
|
};
|
|
1157
|
-
if (isBlob(data))
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
} else if (this._state !== DEFAULT) this.enqueue([
|
|
1142
|
+
if (isBlob(data)) if (this._state !== DEFAULT) this.enqueue([
|
|
1143
|
+
this.getBlobData,
|
|
1144
|
+
data,
|
|
1145
|
+
false,
|
|
1146
|
+
options,
|
|
1147
|
+
cb
|
|
1148
|
+
]);
|
|
1149
|
+
else this.getBlobData(data, false, options, cb);
|
|
1150
|
+
else if (this._state !== DEFAULT) this.enqueue([
|
|
1167
1151
|
this.dispatch,
|
|
1168
1152
|
data,
|
|
1169
1153
|
false,
|
|
@@ -1208,16 +1192,15 @@ var __webpack_modules__ = {
|
|
|
1208
1192
|
readOnly,
|
|
1209
1193
|
rsv1
|
|
1210
1194
|
};
|
|
1211
|
-
if (isBlob(data))
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
|
|
1215
|
-
|
|
1216
|
-
|
|
1217
|
-
|
|
1218
|
-
|
|
1219
|
-
|
|
1220
|
-
} else if (this._state !== DEFAULT) this.enqueue([
|
|
1195
|
+
if (isBlob(data)) if (this._state !== DEFAULT) this.enqueue([
|
|
1196
|
+
this.getBlobData,
|
|
1197
|
+
data,
|
|
1198
|
+
this._compress,
|
|
1199
|
+
opts,
|
|
1200
|
+
cb
|
|
1201
|
+
]);
|
|
1202
|
+
else this.getBlobData(data, this._compress, opts, cb);
|
|
1203
|
+
else if (this._state !== DEFAULT) this.enqueue([
|
|
1221
1204
|
this.dispatch,
|
|
1222
1205
|
data,
|
|
1223
1206
|
this._compress,
|
|
@@ -1248,10 +1231,7 @@ var __webpack_modules__ = {
|
|
|
1248
1231
|
});
|
|
1249
1232
|
}
|
|
1250
1233
|
dispatch(data, compress, options, cb) {
|
|
1251
|
-
if (!compress)
|
|
1252
|
-
this.sendFrame(Sender.frame(data, options), cb);
|
|
1253
|
-
return;
|
|
1254
|
-
}
|
|
1234
|
+
if (!compress) return void this.sendFrame(Sender.frame(data, options), cb);
|
|
1255
1235
|
const perMessageDeflate = this._extensions[PerMessageDeflate.extensionName];
|
|
1256
1236
|
this._bufferedBytes += options[kByteLength];
|
|
1257
1237
|
this._state = DEFLATING;
|
|
@@ -1302,7 +1282,7 @@ var __webpack_modules__ = {
|
|
|
1302
1282
|
sender.onerror(err);
|
|
1303
1283
|
}
|
|
1304
1284
|
},
|
|
1305
|
-
"./node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/stream.js"
|
|
1285
|
+
"./node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/stream.js" (module, __unused_rspack_exports, __webpack_require__) {
|
|
1306
1286
|
__webpack_require__("./node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/websocket.js");
|
|
1307
1287
|
const { Duplex } = __webpack_require__("stream");
|
|
1308
1288
|
function emitClose(stream) {
|
|
@@ -1356,12 +1336,9 @@ var __webpack_modules__ = {
|
|
|
1356
1336
|
if (terminateOnDestroy) ws.terminate();
|
|
1357
1337
|
};
|
|
1358
1338
|
duplex._final = function(callback) {
|
|
1359
|
-
if (ws.readyState === ws.CONNECTING) {
|
|
1360
|
-
|
|
1361
|
-
|
|
1362
|
-
});
|
|
1363
|
-
return;
|
|
1364
|
-
}
|
|
1339
|
+
if (ws.readyState === ws.CONNECTING) return void ws.once('open', function() {
|
|
1340
|
+
duplex._final(callback);
|
|
1341
|
+
});
|
|
1365
1342
|
if (null === ws._socket) return;
|
|
1366
1343
|
if (ws._socket._writableState.finished) {
|
|
1367
1344
|
callback();
|
|
@@ -1377,12 +1354,9 @@ var __webpack_modules__ = {
|
|
|
1377
1354
|
if (ws.isPaused) ws.resume();
|
|
1378
1355
|
};
|
|
1379
1356
|
duplex._write = function(chunk, encoding, callback) {
|
|
1380
|
-
if (ws.readyState === ws.CONNECTING) {
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
});
|
|
1384
|
-
return;
|
|
1385
|
-
}
|
|
1357
|
+
if (ws.readyState === ws.CONNECTING) return void ws.once('open', function() {
|
|
1358
|
+
duplex._write(chunk, encoding, callback);
|
|
1359
|
+
});
|
|
1386
1360
|
ws.send(chunk, callback);
|
|
1387
1361
|
};
|
|
1388
1362
|
duplex.on('end', duplexOnEnd);
|
|
@@ -1391,7 +1365,7 @@ var __webpack_modules__ = {
|
|
|
1391
1365
|
}
|
|
1392
1366
|
module.exports = createWebSocketStream;
|
|
1393
1367
|
},
|
|
1394
|
-
"./node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/subprotocol.js"
|
|
1368
|
+
"./node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/subprotocol.js" (module, __unused_rspack_exports, __webpack_require__) {
|
|
1395
1369
|
const { tokenChars } = __webpack_require__("./node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/validation.js");
|
|
1396
1370
|
function parse(header) {
|
|
1397
1371
|
const protocols = new Set();
|
|
@@ -1423,7 +1397,7 @@ var __webpack_modules__ = {
|
|
|
1423
1397
|
parse
|
|
1424
1398
|
};
|
|
1425
1399
|
},
|
|
1426
|
-
"./node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/validation.js"
|
|
1400
|
+
"./node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/validation.js" (module, __unused_rspack_exports, __webpack_require__) {
|
|
1427
1401
|
const { isUtf8 } = __webpack_require__("buffer");
|
|
1428
1402
|
const { hasBlob } = __webpack_require__("./node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/constants.js");
|
|
1429
1403
|
const tokenChars = [
|
|
@@ -1599,7 +1573,7 @@ var __webpack_modules__ = {
|
|
|
1599
1573
|
};
|
|
1600
1574
|
} catch (e) {}
|
|
1601
1575
|
},
|
|
1602
|
-
"./node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/websocket-server.js"
|
|
1576
|
+
"./node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/websocket-server.js" (module, __unused_rspack_exports, __webpack_require__) {
|
|
1603
1577
|
const EventEmitter = __webpack_require__("events");
|
|
1604
1578
|
const http = __webpack_require__("http");
|
|
1605
1579
|
const { Duplex } = __webpack_require__("stream");
|
|
@@ -1686,10 +1660,9 @@ var __webpack_modules__ = {
|
|
|
1686
1660
|
this._removeListeners();
|
|
1687
1661
|
this._removeListeners = this._server = null;
|
|
1688
1662
|
}
|
|
1689
|
-
if (this.clients)
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
} else process.nextTick(emitClose, this);
|
|
1663
|
+
if (this.clients) if (this.clients.size) this._shouldEmitClose = true;
|
|
1664
|
+
else process.nextTick(emitClose, this);
|
|
1665
|
+
else process.nextTick(emitClose, this);
|
|
1693
1666
|
} else {
|
|
1694
1667
|
const server = this._server;
|
|
1695
1668
|
this._removeListeners();
|
|
@@ -1734,10 +1707,7 @@ var __webpack_modules__ = {
|
|
|
1734
1707
|
});
|
|
1735
1708
|
return;
|
|
1736
1709
|
}
|
|
1737
|
-
if (!this.shouldHandle(req))
|
|
1738
|
-
abortHandshake(socket, 400);
|
|
1739
|
-
return;
|
|
1740
|
-
}
|
|
1710
|
+
if (!this.shouldHandle(req)) return void abortHandshake(socket, 400);
|
|
1741
1711
|
const secWebSocketProtocol = req.headers['sec-websocket-protocol'];
|
|
1742
1712
|
let protocols = new Set();
|
|
1743
1713
|
if (void 0 !== secWebSocketProtocol) try {
|
|
@@ -1769,13 +1739,10 @@ var __webpack_modules__ = {
|
|
|
1769
1739
|
secure: !!(req.socket.authorized || req.socket.encrypted),
|
|
1770
1740
|
req
|
|
1771
1741
|
};
|
|
1772
|
-
if (2 === this.options.verifyClient.length) {
|
|
1773
|
-
|
|
1774
|
-
|
|
1775
|
-
|
|
1776
|
-
});
|
|
1777
|
-
return;
|
|
1778
|
-
}
|
|
1742
|
+
if (2 === this.options.verifyClient.length) return void this.options.verifyClient(info, (verified, code, message, headers)=>{
|
|
1743
|
+
if (!verified) return abortHandshake(socket, code || 401, message, headers);
|
|
1744
|
+
this.completeUpgrade(extensions, key, protocols, req, socket, head, cb);
|
|
1745
|
+
});
|
|
1779
1746
|
if (!this.options.verifyClient(info)) return abortHandshake(socket, 401);
|
|
1780
1747
|
}
|
|
1781
1748
|
this.completeUpgrade(extensions, key, protocols, req, socket, head, cb);
|
|
@@ -1860,7 +1827,7 @@ var __webpack_modules__ = {
|
|
|
1860
1827
|
} else abortHandshake(socket, code, message, headers);
|
|
1861
1828
|
}
|
|
1862
1829
|
},
|
|
1863
|
-
"./node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/websocket.js"
|
|
1830
|
+
"./node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/websocket.js" (module, __unused_rspack_exports, __webpack_require__) {
|
|
1864
1831
|
const EventEmitter = __webpack_require__("events");
|
|
1865
1832
|
const https = __webpack_require__("https");
|
|
1866
1833
|
const http = __webpack_require__("http");
|
|
@@ -1911,14 +1878,12 @@ var __webpack_modules__ = {
|
|
|
1911
1878
|
this._isServer = false;
|
|
1912
1879
|
this._redirects = 0;
|
|
1913
1880
|
if (void 0 === protocols) protocols = [];
|
|
1914
|
-
else if (!Array.isArray(protocols)) {
|
|
1915
|
-
|
|
1916
|
-
|
|
1917
|
-
|
|
1918
|
-
|
|
1919
|
-
|
|
1920
|
-
];
|
|
1921
|
-
}
|
|
1881
|
+
else if (!Array.isArray(protocols)) if ('object' == typeof protocols && null !== protocols) {
|
|
1882
|
+
options = protocols;
|
|
1883
|
+
protocols = [];
|
|
1884
|
+
} else protocols = [
|
|
1885
|
+
protocols
|
|
1886
|
+
];
|
|
1922
1887
|
initAsClient(this, address, protocols, options);
|
|
1923
1888
|
} else {
|
|
1924
1889
|
this._autoPong = options.autoPong;
|
|
@@ -2043,10 +2008,7 @@ var __webpack_modules__ = {
|
|
|
2043
2008
|
mask = void 0;
|
|
2044
2009
|
}
|
|
2045
2010
|
if ('number' == typeof data) data = data.toString();
|
|
2046
|
-
if (this.readyState !== WebSocket.OPEN)
|
|
2047
|
-
sendAfterClose(this, data, cb);
|
|
2048
|
-
return;
|
|
2049
|
-
}
|
|
2011
|
+
if (this.readyState !== WebSocket.OPEN) return void sendAfterClose(this, data, cb);
|
|
2050
2012
|
if (void 0 === mask) mask = !this._isServer;
|
|
2051
2013
|
this._sender.ping(data || EMPTY_BUFFER, mask, cb);
|
|
2052
2014
|
}
|
|
@@ -2060,10 +2022,7 @@ var __webpack_modules__ = {
|
|
|
2060
2022
|
mask = void 0;
|
|
2061
2023
|
}
|
|
2062
2024
|
if ('number' == typeof data) data = data.toString();
|
|
2063
|
-
if (this.readyState !== WebSocket.OPEN)
|
|
2064
|
-
sendAfterClose(this, data, cb);
|
|
2065
|
-
return;
|
|
2066
|
-
}
|
|
2025
|
+
if (this.readyState !== WebSocket.OPEN) return void sendAfterClose(this, data, cb);
|
|
2067
2026
|
if (void 0 === mask) mask = !this._isServer;
|
|
2068
2027
|
this._sender.pong(data || EMPTY_BUFFER, mask, cb);
|
|
2069
2028
|
}
|
|
@@ -2079,10 +2038,7 @@ var __webpack_modules__ = {
|
|
|
2079
2038
|
options = {};
|
|
2080
2039
|
}
|
|
2081
2040
|
if ('number' == typeof data) data = data.toString();
|
|
2082
|
-
if (this.readyState !== WebSocket.OPEN)
|
|
2083
|
-
sendAfterClose(this, data, cb);
|
|
2084
|
-
return;
|
|
2085
|
-
}
|
|
2041
|
+
if (this.readyState !== WebSocket.OPEN) return void sendAfterClose(this, data, cb);
|
|
2086
2042
|
const opts = {
|
|
2087
2043
|
binary: 'string' != typeof data,
|
|
2088
2044
|
mask: !this._isServer,
|
|
@@ -2221,9 +2177,8 @@ var __webpack_modules__ = {
|
|
|
2221
2177
|
} else invalidUrlMessage = 'The URL\'s protocol must be one of "ws:", "wss:", "http:", "https:", or "ws+unix:"';
|
|
2222
2178
|
if (invalidUrlMessage) {
|
|
2223
2179
|
const err = new SyntaxError(invalidUrlMessage);
|
|
2224
|
-
if (0
|
|
2225
|
-
|
|
2226
|
-
return;
|
|
2180
|
+
if (0 !== websocket._redirects) return void emitErrorAndClose(websocket, err);
|
|
2181
|
+
throw err;
|
|
2227
2182
|
}
|
|
2228
2183
|
const defaultPort = isSecure ? 443 : 80;
|
|
2229
2184
|
const key = randomBytes(16).toString('base64');
|
|
@@ -2256,10 +2211,8 @@ var __webpack_modules__ = {
|
|
|
2256
2211
|
}
|
|
2257
2212
|
opts.headers['Sec-WebSocket-Protocol'] = protocols.join(',');
|
|
2258
2213
|
}
|
|
2259
|
-
if (opts.origin)
|
|
2260
|
-
|
|
2261
|
-
else opts.headers.Origin = opts.origin;
|
|
2262
|
-
}
|
|
2214
|
+
if (opts.origin) if (opts.protocolVersion < 13) opts.headers['Sec-WebSocket-Origin'] = opts.origin;
|
|
2215
|
+
else opts.headers.Origin = opts.origin;
|
|
2263
2216
|
if (parsedUrl.username || parsedUrl.password) opts.auth = `${parsedUrl.username}:${parsedUrl.password}`;
|
|
2264
2217
|
if (isIpcUrl) {
|
|
2265
2218
|
const parts = opts.path.split(':');
|
|
@@ -2303,10 +2256,7 @@ var __webpack_modules__ = {
|
|
|
2303
2256
|
const location = res.headers.location;
|
|
2304
2257
|
const statusCode = res.statusCode;
|
|
2305
2258
|
if (location && opts.followRedirects && statusCode >= 300 && statusCode < 400) {
|
|
2306
|
-
if (++websocket._redirects > opts.maxRedirects)
|
|
2307
|
-
abortHandshake(websocket, req, 'Maximum redirects exceeded');
|
|
2308
|
-
return;
|
|
2309
|
-
}
|
|
2259
|
+
if (++websocket._redirects > opts.maxRedirects) return void abortHandshake(websocket, req, 'Maximum redirects exceeded');
|
|
2310
2260
|
req.abort();
|
|
2311
2261
|
let addr;
|
|
2312
2262
|
try {
|
|
@@ -2324,26 +2274,16 @@ var __webpack_modules__ = {
|
|
|
2324
2274
|
if (websocket.readyState !== WebSocket.CONNECTING) return;
|
|
2325
2275
|
req = websocket._req = null;
|
|
2326
2276
|
const upgrade = res.headers.upgrade;
|
|
2327
|
-
if (void 0 === upgrade || 'websocket' !== upgrade.toLowerCase())
|
|
2328
|
-
abortHandshake(websocket, socket, 'Invalid Upgrade header');
|
|
2329
|
-
return;
|
|
2330
|
-
}
|
|
2277
|
+
if (void 0 === upgrade || 'websocket' !== upgrade.toLowerCase()) return void abortHandshake(websocket, socket, 'Invalid Upgrade header');
|
|
2331
2278
|
const digest = createHash('sha1').update(key + GUID).digest('base64');
|
|
2332
|
-
if (res.headers['sec-websocket-accept'] !== digest)
|
|
2333
|
-
abortHandshake(websocket, socket, 'Invalid Sec-WebSocket-Accept header');
|
|
2334
|
-
return;
|
|
2335
|
-
}
|
|
2279
|
+
if (res.headers['sec-websocket-accept'] !== digest) return void abortHandshake(websocket, socket, 'Invalid Sec-WebSocket-Accept header');
|
|
2336
2280
|
const serverProt = res.headers['sec-websocket-protocol'];
|
|
2337
2281
|
let protError;
|
|
2338
|
-
if (void 0 !== serverProt) {
|
|
2339
|
-
if (protocolSet.
|
|
2340
|
-
|
|
2341
|
-
|
|
2342
|
-
|
|
2343
|
-
if (protError) {
|
|
2344
|
-
abortHandshake(websocket, socket, protError);
|
|
2345
|
-
return;
|
|
2346
|
-
}
|
|
2282
|
+
if (void 0 !== serverProt) if (protocolSet.size) {
|
|
2283
|
+
if (!protocolSet.has(serverProt)) protError = 'Server sent an invalid subprotocol';
|
|
2284
|
+
} else protError = 'Server sent a subprotocol but none was requested';
|
|
2285
|
+
else if (protocolSet.size) protError = 'Server sent no subprotocol';
|
|
2286
|
+
if (protError) return void abortHandshake(websocket, socket, protError);
|
|
2347
2287
|
if (serverProt) websocket._protocol = serverProt;
|
|
2348
2288
|
const secWebSocketExtensions = res.headers['sec-websocket-extensions'];
|
|
2349
2289
|
if (void 0 !== secWebSocketExtensions) {
|
|
@@ -2524,43 +2464,34 @@ var __webpack_modules__ = {
|
|
|
2524
2464
|
}
|
|
2525
2465
|
}
|
|
2526
2466
|
},
|
|
2527
|
-
buffer
|
|
2467
|
+
buffer (module) {
|
|
2528
2468
|
module.exports = require("buffer");
|
|
2529
2469
|
},
|
|
2530
|
-
crypto
|
|
2470
|
+
crypto (module) {
|
|
2531
2471
|
module.exports = require("crypto");
|
|
2532
2472
|
},
|
|
2533
|
-
events
|
|
2473
|
+
events (module) {
|
|
2534
2474
|
module.exports = require("events");
|
|
2535
2475
|
},
|
|
2536
|
-
http
|
|
2476
|
+
http (module) {
|
|
2537
2477
|
module.exports = require("http");
|
|
2538
2478
|
},
|
|
2539
|
-
https
|
|
2479
|
+
https (module) {
|
|
2540
2480
|
module.exports = require("https");
|
|
2541
2481
|
},
|
|
2542
|
-
net
|
|
2482
|
+
net (module) {
|
|
2543
2483
|
module.exports = require("net");
|
|
2544
2484
|
},
|
|
2545
|
-
|
|
2546
|
-
module.exports = require("node:net");
|
|
2547
|
-
},
|
|
2548
|
-
"node:url": function(module) {
|
|
2549
|
-
module.exports = require("node:url");
|
|
2550
|
-
},
|
|
2551
|
-
stream: function(module) {
|
|
2485
|
+
stream (module) {
|
|
2552
2486
|
module.exports = require("stream");
|
|
2553
2487
|
},
|
|
2554
|
-
tls
|
|
2488
|
+
tls (module) {
|
|
2555
2489
|
module.exports = require("tls");
|
|
2556
2490
|
},
|
|
2557
|
-
|
|
2558
|
-
module.exports = require("uWebSockets.js");
|
|
2559
|
-
},
|
|
2560
|
-
url: function(module) {
|
|
2491
|
+
url (module) {
|
|
2561
2492
|
module.exports = require("url");
|
|
2562
2493
|
},
|
|
2563
|
-
zlib
|
|
2494
|
+
zlib (module) {
|
|
2564
2495
|
module.exports = require("zlib");
|
|
2565
2496
|
}
|
|
2566
2497
|
};
|
|
@@ -2575,12 +2506,8 @@ function __webpack_require__(moduleId) {
|
|
|
2575
2506
|
return module.exports;
|
|
2576
2507
|
}
|
|
2577
2508
|
(()=>{
|
|
2578
|
-
__webpack_require__.n =
|
|
2579
|
-
var getter = module && module.__esModule ?
|
|
2580
|
-
return module['default'];
|
|
2581
|
-
} : function() {
|
|
2582
|
-
return module;
|
|
2583
|
-
};
|
|
2509
|
+
__webpack_require__.n = (module)=>{
|
|
2510
|
+
var getter = module && module.__esModule ? ()=>module['default'] : ()=>module;
|
|
2584
2511
|
__webpack_require__.d(getter, {
|
|
2585
2512
|
a: getter
|
|
2586
2513
|
});
|
|
@@ -2588,42 +2515,7 @@ function __webpack_require__(moduleId) {
|
|
|
2588
2515
|
};
|
|
2589
2516
|
})();
|
|
2590
2517
|
(()=>{
|
|
2591
|
-
|
|
2592
|
-
return Object.getPrototypeOf(obj);
|
|
2593
|
-
} : function(obj) {
|
|
2594
|
-
return obj.__proto__;
|
|
2595
|
-
};
|
|
2596
|
-
var leafPrototypes;
|
|
2597
|
-
__webpack_require__.t = function(value, mode) {
|
|
2598
|
-
if (1 & mode) value = this(value);
|
|
2599
|
-
if (8 & mode) return value;
|
|
2600
|
-
if ('object' == typeof value && value) {
|
|
2601
|
-
if (4 & mode && value.__esModule) return value;
|
|
2602
|
-
if (16 & mode && 'function' == typeof value.then) return value;
|
|
2603
|
-
}
|
|
2604
|
-
var ns = Object.create(null);
|
|
2605
|
-
__webpack_require__.r(ns);
|
|
2606
|
-
var def = {};
|
|
2607
|
-
leafPrototypes = leafPrototypes || [
|
|
2608
|
-
null,
|
|
2609
|
-
getProto({}),
|
|
2610
|
-
getProto([]),
|
|
2611
|
-
getProto(getProto)
|
|
2612
|
-
];
|
|
2613
|
-
for(var current = 2 & mode && value; 'object' == typeof current && !~leafPrototypes.indexOf(current); current = getProto(current))Object.getOwnPropertyNames(current).forEach(function(key) {
|
|
2614
|
-
def[key] = function() {
|
|
2615
|
-
return value[key];
|
|
2616
|
-
};
|
|
2617
|
-
});
|
|
2618
|
-
def['default'] = function() {
|
|
2619
|
-
return value;
|
|
2620
|
-
};
|
|
2621
|
-
__webpack_require__.d(ns, def);
|
|
2622
|
-
return ns;
|
|
2623
|
-
};
|
|
2624
|
-
})();
|
|
2625
|
-
(()=>{
|
|
2626
|
-
__webpack_require__.d = function(exports1, definition) {
|
|
2518
|
+
__webpack_require__.d = (exports1, definition)=>{
|
|
2627
2519
|
for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
|
|
2628
2520
|
enumerable: true,
|
|
2629
2521
|
get: definition[key]
|
|
@@ -2631,19 +2523,7 @@ function __webpack_require__(moduleId) {
|
|
|
2631
2523
|
};
|
|
2632
2524
|
})();
|
|
2633
2525
|
(()=>{
|
|
2634
|
-
__webpack_require__.o =
|
|
2635
|
-
return Object.prototype.hasOwnProperty.call(obj, prop);
|
|
2636
|
-
};
|
|
2637
|
-
})();
|
|
2638
|
-
(()=>{
|
|
2639
|
-
__webpack_require__.r = function(exports1) {
|
|
2640
|
-
if ('undefined' != typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
|
|
2641
|
-
value: 'Module'
|
|
2642
|
-
});
|
|
2643
|
-
Object.defineProperty(exports1, '__esModule', {
|
|
2644
|
-
value: true
|
|
2645
|
-
});
|
|
2646
|
-
};
|
|
2526
|
+
__webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
|
|
2647
2527
|
})();
|
|
2648
2528
|
var __webpack_exports__ = {};
|
|
2649
2529
|
(()=>{
|
|
@@ -2691,24 +2571,20 @@ var __webpack_exports__ = {};
|
|
|
2691
2571
|
}
|
|
2692
2572
|
async start(service) {
|
|
2693
2573
|
let lock = this.startingLocks.get(service.name);
|
|
2694
|
-
|
|
2574
|
+
while(lock)try {
|
|
2695
2575
|
await lock;
|
|
2696
2576
|
const isRunning = await this.isRunning(service);
|
|
2697
|
-
if (
|
|
2698
|
-
|
|
2699
|
-
|
|
2700
|
-
}
|
|
2701
|
-
return;
|
|
2577
|
+
if (isRunning) return;
|
|
2578
|
+
this.startingLocks.delete(service.name);
|
|
2579
|
+
break;
|
|
2702
2580
|
} catch {
|
|
2703
2581
|
this.startingLocks.delete(service.name);
|
|
2582
|
+
break;
|
|
2704
2583
|
}
|
|
2705
2584
|
lock = (async ()=>{
|
|
2706
2585
|
try {
|
|
2707
2586
|
const alreadyRunning = await this.isRunning(service);
|
|
2708
|
-
if (alreadyRunning) {
|
|
2709
|
-
console.log(`[${service.name}] 服务已在运行,跳过启动`);
|
|
2710
|
-
return;
|
|
2711
|
-
}
|
|
2587
|
+
if (alreadyRunning) return void console.log(`[${service.name}] 服务已在运行,跳过启动`);
|
|
2712
2588
|
console.log(`[${service.name}] 正在启动...`);
|
|
2713
2589
|
const result = await this.executor.execute(service.commands.start, {
|
|
2714
2590
|
cwd: service.commands.cwd,
|
|
@@ -2739,11 +2615,13 @@ var __webpack_exports__ = {};
|
|
|
2739
2615
|
service._state.status = 'offline';
|
|
2740
2616
|
}
|
|
2741
2617
|
}
|
|
2742
|
-
|
|
2743
|
-
var external_uWebSockets_js_default = /*#__PURE__*/ __webpack_require__.n(
|
|
2744
|
-
|
|
2745
|
-
var external_node_net_default = /*#__PURE__*/ __webpack_require__.n(
|
|
2746
|
-
|
|
2618
|
+
const external_uWebSockets_js_namespaceObject = require("uWebSockets.js");
|
|
2619
|
+
var external_uWebSockets_js_default = /*#__PURE__*/ __webpack_require__.n(external_uWebSockets_js_namespaceObject);
|
|
2620
|
+
const external_node_net_namespaceObject = require("node:net");
|
|
2621
|
+
var external_node_net_default = /*#__PURE__*/ __webpack_require__.n(external_node_net_namespaceObject);
|
|
2622
|
+
const external_node_url_namespaceObject = require("node:url");
|
|
2623
|
+
const external_node_http_namespaceObject = require("node:http");
|
|
2624
|
+
var external_node_http_default = /*#__PURE__*/ __webpack_require__.n(external_node_http_namespaceObject);
|
|
2747
2625
|
__webpack_require__("./node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/stream.js");
|
|
2748
2626
|
__webpack_require__("./node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/receiver.js");
|
|
2749
2627
|
__webpack_require__("./node_modules/.pnpm/ws@8.19.0/node_modules/ws/lib/sender.js");
|
|
@@ -2777,6 +2655,10 @@ var __webpack_exports__ = {};
|
|
|
2777
2655
|
if ('online' === service._state.status && service._state.startTime) return service._state.totalUptime + (Date.now() - service._state.startTime);
|
|
2778
2656
|
return service._state.totalUptime;
|
|
2779
2657
|
}
|
|
2658
|
+
findServiceMapping(serviceName) {
|
|
2659
|
+
for (const mapping of this.hostnameRoutes.values())if (mapping.service.name === serviceName) return mapping;
|
|
2660
|
+
for (const mapping of this.portRoutes.values())if (mapping.service.name === serviceName) return mapping;
|
|
2661
|
+
}
|
|
2780
2662
|
handleAdminApi(res, req) {
|
|
2781
2663
|
const ip = req.getHeader('x-forwarded-for')?.split(',')[0]?.trim() || req.getHeader('cf-connecting-ip') || '127.0.0.1';
|
|
2782
2664
|
if (!this.isIpAllowed(ip)) {
|
|
@@ -2790,14 +2672,11 @@ var __webpack_exports__ = {};
|
|
|
2790
2672
|
return;
|
|
2791
2673
|
}
|
|
2792
2674
|
const authHeader = req.getHeader('authorization');
|
|
2793
|
-
if (!this.isAuthenticated(authHeader)) {
|
|
2794
|
-
res.
|
|
2795
|
-
|
|
2796
|
-
|
|
2797
|
-
|
|
2798
|
-
});
|
|
2799
|
-
return;
|
|
2800
|
-
}
|
|
2675
|
+
if (!this.isAuthenticated(authHeader)) return void res.cork(()=>{
|
|
2676
|
+
res.writeStatus('401 Unauthorized');
|
|
2677
|
+
res.writeHeader('WWW-Authenticate', 'Bearer');
|
|
2678
|
+
res.end('Unauthorized');
|
|
2679
|
+
});
|
|
2801
2680
|
const url = req.getUrl();
|
|
2802
2681
|
const method = req.getMethod();
|
|
2803
2682
|
if ('/_dynapm/api/services' === url && 'get' === method.toLowerCase()) this.getServicesList(res);
|
|
@@ -2841,19 +2720,16 @@ var __webpack_exports__ = {};
|
|
|
2841
2720
|
});
|
|
2842
2721
|
}
|
|
2843
2722
|
getServiceDetail(res, serviceName) {
|
|
2844
|
-
const mapping =
|
|
2723
|
+
const mapping = this.findServiceMapping(serviceName);
|
|
2845
2724
|
this.logger.info({
|
|
2846
2725
|
msg: `🔍 [Admin API] 查找服务: ${serviceName}, 找到: ${mapping?.service.name || 'null'}`
|
|
2847
2726
|
});
|
|
2848
|
-
if (!mapping) {
|
|
2849
|
-
res.
|
|
2850
|
-
|
|
2851
|
-
|
|
2852
|
-
|
|
2853
|
-
|
|
2854
|
-
});
|
|
2855
|
-
return;
|
|
2856
|
-
}
|
|
2727
|
+
if (!mapping) return void res.cork(()=>{
|
|
2728
|
+
res.writeStatus('404 Not Found');
|
|
2729
|
+
res.end(JSON.stringify({
|
|
2730
|
+
error: 'Service not found'
|
|
2731
|
+
}));
|
|
2732
|
+
});
|
|
2857
2733
|
const service = mapping.service;
|
|
2858
2734
|
const detail = {
|
|
2859
2735
|
name: service.name,
|
|
@@ -2878,9 +2754,13 @@ var __webpack_exports__ = {};
|
|
|
2878
2754
|
});
|
|
2879
2755
|
}
|
|
2880
2756
|
async stopService(res, serviceName) {
|
|
2881
|
-
|
|
2757
|
+
let aborted = false;
|
|
2758
|
+
res.onAborted(()=>{
|
|
2759
|
+
aborted = true;
|
|
2760
|
+
});
|
|
2761
|
+
const mapping = this.findServiceMapping(serviceName);
|
|
2882
2762
|
if (!mapping) {
|
|
2883
|
-
res.cork(()=>{
|
|
2763
|
+
if (!aborted) res.cork(()=>{
|
|
2884
2764
|
res.writeStatus('404 Not Found');
|
|
2885
2765
|
res.end(JSON.stringify({
|
|
2886
2766
|
error: 'Service not found'
|
|
@@ -2890,7 +2770,7 @@ var __webpack_exports__ = {};
|
|
|
2890
2770
|
}
|
|
2891
2771
|
const service = mapping.service;
|
|
2892
2772
|
if ('online' !== service._state.status) {
|
|
2893
|
-
res.cork(()=>{
|
|
2773
|
+
if (!aborted) res.cork(()=>{
|
|
2894
2774
|
res.writeStatus('400 Bad Request');
|
|
2895
2775
|
res.end(JSON.stringify({
|
|
2896
2776
|
error: 'Service is not online'
|
|
@@ -2906,7 +2786,7 @@ var __webpack_exports__ = {};
|
|
|
2906
2786
|
}
|
|
2907
2787
|
await this.serviceManager.stop(service);
|
|
2908
2788
|
service._state.status = 'offline';
|
|
2909
|
-
res.cork(()=>{
|
|
2789
|
+
if (!aborted) res.cork(()=>{
|
|
2910
2790
|
res.writeHeader('Content-Type', 'application/json');
|
|
2911
2791
|
res.end(JSON.stringify({
|
|
2912
2792
|
success: true,
|
|
@@ -2916,7 +2796,7 @@ var __webpack_exports__ = {};
|
|
|
2916
2796
|
} catch (error) {
|
|
2917
2797
|
const message = error instanceof Error ? error.message : String(error);
|
|
2918
2798
|
service._state.status = 'online';
|
|
2919
|
-
res.cork(()=>{
|
|
2799
|
+
if (!aborted) res.cork(()=>{
|
|
2920
2800
|
res.writeStatus('500 Internal Server Error');
|
|
2921
2801
|
res.end(JSON.stringify({
|
|
2922
2802
|
error: message
|
|
@@ -2925,9 +2805,13 @@ var __webpack_exports__ = {};
|
|
|
2925
2805
|
}
|
|
2926
2806
|
}
|
|
2927
2807
|
async startService(res, serviceName) {
|
|
2928
|
-
|
|
2808
|
+
let aborted = false;
|
|
2809
|
+
res.onAborted(()=>{
|
|
2810
|
+
aborted = true;
|
|
2811
|
+
});
|
|
2812
|
+
const mapping = this.findServiceMapping(serviceName);
|
|
2929
2813
|
if (!mapping) {
|
|
2930
|
-
res.cork(()=>{
|
|
2814
|
+
if (!aborted) res.cork(()=>{
|
|
2931
2815
|
res.writeStatus('404 Not Found');
|
|
2932
2816
|
res.end(JSON.stringify({
|
|
2933
2817
|
error: 'Service not found'
|
|
@@ -2937,7 +2821,7 @@ var __webpack_exports__ = {};
|
|
|
2937
2821
|
}
|
|
2938
2822
|
const service = mapping.service;
|
|
2939
2823
|
if ('online' === service._state.status || 'starting' === service._state.status) {
|
|
2940
|
-
res.cork(()=>{
|
|
2824
|
+
if (!aborted) res.cork(()=>{
|
|
2941
2825
|
res.writeStatus('400 Bad Request');
|
|
2942
2826
|
res.end(JSON.stringify({
|
|
2943
2827
|
error: 'Service is already running or starting'
|
|
@@ -2963,7 +2847,7 @@ var __webpack_exports__ = {};
|
|
|
2963
2847
|
}
|
|
2964
2848
|
if (!isReady) {
|
|
2965
2849
|
service._state.status = 'offline';
|
|
2966
|
-
res.cork(()=>{
|
|
2850
|
+
if (!aborted) res.cork(()=>{
|
|
2967
2851
|
res.writeStatus('503 Service Unavailable');
|
|
2968
2852
|
res.end(JSON.stringify({
|
|
2969
2853
|
error: 'Service start timeout'
|
|
@@ -2974,7 +2858,7 @@ var __webpack_exports__ = {};
|
|
|
2974
2858
|
service._state.status = 'online';
|
|
2975
2859
|
service._state.startTime = Date.now();
|
|
2976
2860
|
service._state.startCount++;
|
|
2977
|
-
res.cork(()=>{
|
|
2861
|
+
if (!aborted) res.cork(()=>{
|
|
2978
2862
|
res.writeHeader('Content-Type', 'application/json');
|
|
2979
2863
|
res.end(JSON.stringify({
|
|
2980
2864
|
success: true,
|
|
@@ -2984,7 +2868,7 @@ var __webpack_exports__ = {};
|
|
|
2984
2868
|
} catch (error) {
|
|
2985
2869
|
const message = error instanceof Error ? error.message : String(error);
|
|
2986
2870
|
service._state.status = 'offline';
|
|
2987
|
-
res.cork(()=>{
|
|
2871
|
+
if (!aborted) res.cork(()=>{
|
|
2988
2872
|
res.writeStatus('500 Internal Server Error');
|
|
2989
2873
|
res.end(JSON.stringify({
|
|
2990
2874
|
error: message
|
|
@@ -3006,13 +2890,11 @@ var __webpack_exports__ = {};
|
|
|
3006
2890
|
}
|
|
3007
2891
|
}
|
|
3008
2892
|
function checkTcpPort(url) {
|
|
3009
|
-
const
|
|
3010
|
-
const net = __webpack_require__("node:net");
|
|
3011
|
-
const parsed = new URL(url);
|
|
2893
|
+
const parsed = new external_node_url_namespaceObject.URL(url);
|
|
3012
2894
|
const host = parsed.hostname;
|
|
3013
2895
|
const port = parseInt(parsed.port || ('https:' === parsed.protocol ? '443' : '80'));
|
|
3014
2896
|
return new Promise((resolve)=>{
|
|
3015
|
-
const socket =
|
|
2897
|
+
const socket = external_node_net_default().createConnection({
|
|
3016
2898
|
host,
|
|
3017
2899
|
port,
|
|
3018
2900
|
timeout: 100
|
|
@@ -3034,14 +2916,75 @@ var __webpack_exports__ = {};
|
|
|
3034
2916
|
if (ms < 1000) return `${ms}ms`;
|
|
3035
2917
|
return `${(ms / 1000).toFixed(2)}s`;
|
|
3036
2918
|
}
|
|
3037
|
-
|
|
2919
|
+
function collectRequestBody(res) {
|
|
2920
|
+
return new Promise((resolve)=>{
|
|
2921
|
+
const chunks = [];
|
|
2922
|
+
let totalSize = 0;
|
|
2923
|
+
let resolved = false;
|
|
2924
|
+
res.onData((ab, isLast)=>{
|
|
2925
|
+
if (resolved) return;
|
|
2926
|
+
const chunk = Buffer.alloc(ab.byteLength);
|
|
2927
|
+
Buffer.from(ab).copy(chunk);
|
|
2928
|
+
totalSize += chunk.length;
|
|
2929
|
+
if (totalSize > GatewayConstants.MAX_REQUEST_BODY_SIZE) {
|
|
2930
|
+
resolved = true;
|
|
2931
|
+
resolve(Buffer.concat(chunks));
|
|
2932
|
+
return;
|
|
2933
|
+
}
|
|
2934
|
+
chunks.push(chunk);
|
|
2935
|
+
if (isLast) {
|
|
2936
|
+
resolved = true;
|
|
2937
|
+
resolve(Buffer.concat(chunks));
|
|
2938
|
+
}
|
|
2939
|
+
});
|
|
2940
|
+
res.onAborted(()=>{
|
|
2941
|
+
if (resolved) return;
|
|
2942
|
+
resolved = true;
|
|
2943
|
+
resolve(Buffer.concat(chunks));
|
|
2944
|
+
});
|
|
2945
|
+
});
|
|
2946
|
+
}
|
|
2947
|
+
function getStatusMessage(statusCode) {
|
|
2948
|
+
const messages = {
|
|
2949
|
+
200: 'OK',
|
|
2950
|
+
201: 'Created',
|
|
2951
|
+
204: 'No Content',
|
|
2952
|
+
301: 'Moved Permanently',
|
|
2953
|
+
302: 'Found',
|
|
2954
|
+
304: 'Not Modified',
|
|
2955
|
+
400: 'Bad Request',
|
|
2956
|
+
401: 'Unauthorized',
|
|
2957
|
+
403: 'Forbidden',
|
|
2958
|
+
404: 'Not Found',
|
|
2959
|
+
405: 'Method Not Allowed',
|
|
2960
|
+
409: 'Conflict',
|
|
2961
|
+
500: 'Internal Server Error',
|
|
2962
|
+
502: 'Bad Gateway',
|
|
2963
|
+
503: 'Service Unavailable'
|
|
2964
|
+
};
|
|
2965
|
+
return messages[statusCode] || 'Unknown';
|
|
2966
|
+
}
|
|
3038
2967
|
const GatewayConstants = {
|
|
3039
2968
|
IDLE_CHECK_INTERVAL: 3000,
|
|
3040
2969
|
TCP_CHECK_TIMEOUT: 100,
|
|
3041
|
-
BACKEND_READY_CHECK_DELAY: 50
|
|
2970
|
+
BACKEND_READY_CHECK_DELAY: 50,
|
|
2971
|
+
SKIP_RESPONSE_HEADERS: new Set([
|
|
2972
|
+
'connection',
|
|
2973
|
+
'transfer-encoding',
|
|
2974
|
+
'keep-alive',
|
|
2975
|
+
'content-length'
|
|
2976
|
+
]),
|
|
2977
|
+
CRLF_REGEX: /[\r\n]/g,
|
|
2978
|
+
SKIP_REQUEST_HEADERS: new Set([
|
|
2979
|
+
'connection',
|
|
2980
|
+
'keep-alive',
|
|
2981
|
+
'content-length'
|
|
2982
|
+
]),
|
|
2983
|
+
MAX_REQUEST_BODY_SIZE: 10485760,
|
|
2984
|
+
MAX_WS_MESSAGE_QUEUE_SIZE: 1000
|
|
3042
2985
|
};
|
|
3043
2986
|
function gateway_checkTcpPort(url) {
|
|
3044
|
-
const parsed = new
|
|
2987
|
+
const parsed = new external_node_url_namespaceObject.URL(url);
|
|
3045
2988
|
const host = parsed.hostname;
|
|
3046
2989
|
const port = parseInt(parsed.port || ('https:' === parsed.protocol ? '443' : '80'));
|
|
3047
2990
|
return new Promise((resolve)=>{
|
|
@@ -3065,17 +3008,15 @@ var __webpack_exports__ = {};
|
|
|
3065
3008
|
}
|
|
3066
3009
|
class Gateway {
|
|
3067
3010
|
config;
|
|
3068
|
-
serviceManager;
|
|
3069
|
-
hostnameRoutes;
|
|
3070
|
-
portRoutes;
|
|
3011
|
+
serviceManager = new ServiceManager();
|
|
3012
|
+
hostnameRoutes = new Map();
|
|
3013
|
+
portRoutes = new Map();
|
|
3071
3014
|
logger;
|
|
3072
3015
|
logging;
|
|
3073
3016
|
adminApi;
|
|
3017
|
+
startingPromises = new Map();
|
|
3074
3018
|
constructor(config, logger){
|
|
3075
3019
|
this.config = config;
|
|
3076
|
-
this.serviceManager = new ServiceManager();
|
|
3077
|
-
this.hostnameRoutes = new Map();
|
|
3078
|
-
this.portRoutes = new Map();
|
|
3079
3020
|
this.logger = logger;
|
|
3080
3021
|
this.logging = {
|
|
3081
3022
|
enableRequestLog: config.logging?.enableRequestLog ?? false,
|
|
@@ -3105,16 +3046,11 @@ var __webpack_exports__ = {};
|
|
|
3105
3046
|
}
|
|
3106
3047
|
console.log(`[DynaPM] ✅ [${service.name}] 配置了 ${routes.length} 个路由:`);
|
|
3107
3048
|
for (const route of routes){
|
|
3108
|
-
const targetUrl = new
|
|
3109
|
-
const undiciClient = new external_undici_namespaceObject.Client(route.target, {
|
|
3110
|
-
keepAliveTimeout: 60000,
|
|
3111
|
-
pipelining: 1
|
|
3112
|
-
});
|
|
3049
|
+
const targetUrl = new external_node_url_namespaceObject.URL(route.target);
|
|
3113
3050
|
const mapping = {
|
|
3114
3051
|
service,
|
|
3115
3052
|
target: route.target,
|
|
3116
|
-
targetUrl
|
|
3117
|
-
undiciClient
|
|
3053
|
+
targetUrl
|
|
3118
3054
|
};
|
|
3119
3055
|
if ('host' === route.type) {
|
|
3120
3056
|
const hostname = route.value;
|
|
@@ -3178,12 +3114,20 @@ var __webpack_exports__ = {};
|
|
|
3178
3114
|
const fullUrl = queryString ? `${url}?${queryString}` : url;
|
|
3179
3115
|
const headers = {};
|
|
3180
3116
|
req.forEach((key, value)=>{
|
|
3181
|
-
const safeValue = value.replace(
|
|
3117
|
+
const safeValue = value.replace(GatewayConstants.CRLF_REGEX, '');
|
|
3182
3118
|
headers[key] = safeValue;
|
|
3183
3119
|
});
|
|
3184
3120
|
service._state.lastAccessTime = Date.now();
|
|
3185
|
-
const
|
|
3186
|
-
if (
|
|
3121
|
+
const status = service._state.status;
|
|
3122
|
+
if ('starting' === status) {
|
|
3123
|
+
const startPromise = this.startingPromises.get(service.name);
|
|
3124
|
+
if (startPromise) this.handleServiceWithStartPromise(res, mapping, fullUrl, startTime, method, headers, startPromise);
|
|
3125
|
+
else this.handleDirectProxy(res, mapping, fullUrl, startTime, method, headers);
|
|
3126
|
+
return;
|
|
3127
|
+
}
|
|
3128
|
+
const needsStart = 'offline' === status || 'stopping' === status;
|
|
3129
|
+
if (needsStart) if ('stopping' === status) this.handleServiceWithWait(res, mapping, fullUrl, startTime, method, headers);
|
|
3130
|
+
else this.handleServiceStart(res, mapping, fullUrl, startTime, method, headers);
|
|
3187
3131
|
else this.handleDirectProxy(res, mapping, fullUrl, startTime, method, headers);
|
|
3188
3132
|
}
|
|
3189
3133
|
handleRequest(res, req) {
|
|
@@ -3200,11 +3144,7 @@ var __webpack_exports__ = {};
|
|
|
3200
3144
|
const fullUrl = queryString ? url + '?' + queryString : url;
|
|
3201
3145
|
const headers = {};
|
|
3202
3146
|
req.forEach((key, value)=>{
|
|
3203
|
-
|
|
3204
|
-
const crIndex = value.indexOf('\r');
|
|
3205
|
-
const lfIndex = value.indexOf('\n');
|
|
3206
|
-
if (-1 !== crIndex || -1 !== lfIndex) safeValue = value.replace(/[\r\n]/g, '');
|
|
3207
|
-
headers[key] = safeValue;
|
|
3147
|
+
headers[key] = value.replace(GatewayConstants.CRLF_REGEX, '');
|
|
3208
3148
|
});
|
|
3209
3149
|
const mapping = this.hostnameRoutes.get(hostname);
|
|
3210
3150
|
if (!mapping) {
|
|
@@ -3220,11 +3160,16 @@ var __webpack_exports__ = {};
|
|
|
3220
3160
|
const service = mapping.service;
|
|
3221
3161
|
service._state.lastAccessTime = Date.now();
|
|
3222
3162
|
const status = service._state.status;
|
|
3163
|
+
if ('starting' === status) {
|
|
3164
|
+
const startPromise = this.startingPromises.get(service.name);
|
|
3165
|
+
if (startPromise) this.handleServiceWithStartPromise(res, mapping, fullUrl, startTime, method, headers, startPromise);
|
|
3166
|
+
else this.handleDirectProxy(res, mapping, fullUrl, startTime, method, headers);
|
|
3167
|
+
return;
|
|
3168
|
+
}
|
|
3223
3169
|
const needsStart = 'offline' === status || 'stopping' === status;
|
|
3224
|
-
if (needsStart)
|
|
3225
|
-
|
|
3226
|
-
|
|
3227
|
-
} else this.handleDirectProxy(res, mapping, fullUrl, startTime, method, headers);
|
|
3170
|
+
if (needsStart) if ('stopping' === status) this.handleServiceWithWait(res, mapping, fullUrl, startTime, method, headers);
|
|
3171
|
+
else this.handleServiceStart(res, mapping, fullUrl, startTime, method, headers);
|
|
3172
|
+
else this.handleDirectProxy(res, mapping, fullUrl, startTime, method, headers);
|
|
3228
3173
|
}
|
|
3229
3174
|
async startServiceAndProxy(res, mapping, fullUrl, startTime, method, headers, body) {
|
|
3230
3175
|
const service = mapping.service;
|
|
@@ -3233,6 +3178,13 @@ var __webpack_exports__ = {};
|
|
|
3233
3178
|
msg: `🚀 [${service.name}] ${method} ${fullUrl} - 启动服务...`
|
|
3234
3179
|
});
|
|
3235
3180
|
service._state.status = 'starting';
|
|
3181
|
+
let resolveStartPromise;
|
|
3182
|
+
let rejectStartPromise;
|
|
3183
|
+
const startPromise = new Promise((resolve, reject)=>{
|
|
3184
|
+
resolveStartPromise = resolve;
|
|
3185
|
+
rejectStartPromise = reject;
|
|
3186
|
+
});
|
|
3187
|
+
this.startingPromises.set(service.name, startPromise);
|
|
3236
3188
|
try {
|
|
3237
3189
|
await this.serviceManager.start(service);
|
|
3238
3190
|
const waitStartTime = Date.now();
|
|
@@ -3254,10 +3206,14 @@ var __webpack_exports__ = {};
|
|
|
3254
3206
|
service._state.status = 'online';
|
|
3255
3207
|
service._state.startTime = Date.now();
|
|
3256
3208
|
service._state.startCount++;
|
|
3209
|
+
resolveStartPromise();
|
|
3210
|
+
this.startingPromises.delete(service.name);
|
|
3257
3211
|
await this.forwardProxyRequest(res, mapping, fullUrl, startTime, method, headers, body);
|
|
3258
3212
|
} catch (error) {
|
|
3213
|
+
this.startingPromises.delete(service.name);
|
|
3259
3214
|
const message = error instanceof Error ? error.message : String(error);
|
|
3260
|
-
if ('Client aborted' === message) return;
|
|
3215
|
+
if ('Client aborted' === message) return void resolveStartPromise();
|
|
3216
|
+
rejectStartPromise(error instanceof Error ? error : new Error(message));
|
|
3261
3217
|
this.logger.error({
|
|
3262
3218
|
msg: `❌ [${service.name}] 启动失败`,
|
|
3263
3219
|
error: message
|
|
@@ -3267,13 +3223,7 @@ var __webpack_exports__ = {};
|
|
|
3267
3223
|
res.writeStatus('503 Service Unavailable');
|
|
3268
3224
|
res.end('Service Unavailable');
|
|
3269
3225
|
});
|
|
3270
|
-
} catch
|
|
3271
|
-
const sendErrMsg = sendErr instanceof Error ? sendErr.message : String(sendErr);
|
|
3272
|
-
this.logger.error({
|
|
3273
|
-
msg: `❌ [${service.name}] 发送错误响应失败`,
|
|
3274
|
-
error: sendErrMsg
|
|
3275
|
-
});
|
|
3276
|
-
}
|
|
3226
|
+
} catch {}
|
|
3277
3227
|
}
|
|
3278
3228
|
}
|
|
3279
3229
|
handleServiceWithWait(res, mapping, fullUrl, startTime, method, headers) {
|
|
@@ -3281,96 +3231,193 @@ var __webpack_exports__ = {};
|
|
|
3281
3231
|
this.logger.info({
|
|
3282
3232
|
msg: `⏳ [${service.name}] ${method} ${fullUrl} - 等待服务停止完成...`
|
|
3283
3233
|
});
|
|
3284
|
-
const
|
|
3285
|
-
|
|
3286
|
-
|
|
3287
|
-
|
|
3288
|
-
|
|
3289
|
-
|
|
3290
|
-
|
|
3291
|
-
|
|
3292
|
-
|
|
3293
|
-
if (isLast) {
|
|
3294
|
-
const fullBody = Buffer.concat(chunks);
|
|
3295
|
-
if (aborted) return;
|
|
3296
|
-
(async ()=>{
|
|
3297
|
-
const maxWaitTime = 30000;
|
|
3298
|
-
const checkInterval = 100;
|
|
3299
|
-
const waitStartTime = Date.now();
|
|
3300
|
-
while('stopping' === service._state.status){
|
|
3301
|
-
if (Date.now() - waitStartTime > maxWaitTime) {
|
|
3302
|
-
this.logger.error({
|
|
3303
|
-
msg: `❌ [${service.name}] 等待服务停止超时`
|
|
3304
|
-
});
|
|
3305
|
-
res.cork(()=>{
|
|
3306
|
-
res.writeStatus('503 Service Unavailable');
|
|
3307
|
-
res.end('Service stopping timeout');
|
|
3308
|
-
});
|
|
3309
|
-
return;
|
|
3310
|
-
}
|
|
3311
|
-
await new Promise((resolve)=>setTimeout(resolve, checkInterval));
|
|
3312
|
-
}
|
|
3313
|
-
if (aborted) return;
|
|
3314
|
-
this.logger.info({
|
|
3315
|
-
msg: `✅ [${service.name}] 服务已停止,开始启动...`
|
|
3234
|
+
const bodyPromise = collectRequestBody(res);
|
|
3235
|
+
(async ()=>{
|
|
3236
|
+
const maxWaitTime = 30000;
|
|
3237
|
+
const checkInterval = 100;
|
|
3238
|
+
const waitStartTime = Date.now();
|
|
3239
|
+
while('stopping' === service._state.status){
|
|
3240
|
+
if (Date.now() - waitStartTime > maxWaitTime) {
|
|
3241
|
+
this.logger.error({
|
|
3242
|
+
msg: `❌ [${service.name}] 等待服务停止超时`
|
|
3316
3243
|
});
|
|
3317
|
-
|
|
3318
|
-
|
|
3244
|
+
try {
|
|
3245
|
+
res.cork(()=>{
|
|
3246
|
+
res.writeStatus('503 Service Unavailable');
|
|
3247
|
+
res.end('Service stopping timeout');
|
|
3248
|
+
});
|
|
3249
|
+
} catch {}
|
|
3250
|
+
return;
|
|
3251
|
+
}
|
|
3252
|
+
await new Promise((resolve)=>setTimeout(resolve, checkInterval));
|
|
3319
3253
|
}
|
|
3320
|
-
|
|
3254
|
+
this.logger.info({
|
|
3255
|
+
msg: `✅ [${service.name}] 服务已停止,开始启动...`
|
|
3256
|
+
});
|
|
3257
|
+
const body = await bodyPromise;
|
|
3258
|
+
await this.startServiceAndProxy(res, mapping, fullUrl, startTime, method, headers, body);
|
|
3259
|
+
})();
|
|
3321
3260
|
}
|
|
3322
|
-
|
|
3323
|
-
|
|
3324
|
-
|
|
3325
|
-
|
|
3326
|
-
|
|
3327
|
-
|
|
3328
|
-
|
|
3329
|
-
|
|
3330
|
-
|
|
3331
|
-
|
|
3332
|
-
|
|
3333
|
-
|
|
3334
|
-
|
|
3335
|
-
|
|
3336
|
-
this.startServiceAndProxy(res, mapping, fullUrl, startTime, method, headers, fullBody);
|
|
3261
|
+
handleServiceWithStartPromise(res, mapping, fullUrl, startTime, method, headers, startPromise) {
|
|
3262
|
+
const bodyPromise = collectRequestBody(res);
|
|
3263
|
+
(async ()=>{
|
|
3264
|
+
try {
|
|
3265
|
+
await startPromise;
|
|
3266
|
+
} catch {
|
|
3267
|
+
await bodyPromise;
|
|
3268
|
+
try {
|
|
3269
|
+
res.cork(()=>{
|
|
3270
|
+
res.writeStatus('503 Service Unavailable');
|
|
3271
|
+
res.end('Service start failed');
|
|
3272
|
+
});
|
|
3273
|
+
} catch {}
|
|
3274
|
+
return;
|
|
3337
3275
|
}
|
|
3338
|
-
|
|
3276
|
+
const body = await bodyPromise;
|
|
3277
|
+
await this.forwardProxyRequest(res, mapping, fullUrl, startTime, method, headers, body);
|
|
3278
|
+
})();
|
|
3279
|
+
}
|
|
3280
|
+
handleServiceStart(res, mapping, fullUrl, startTime, method, headers) {
|
|
3281
|
+
const bodyPromise = collectRequestBody(res);
|
|
3282
|
+
(async ()=>{
|
|
3283
|
+
const body = await bodyPromise;
|
|
3284
|
+
await this.startServiceAndProxy(res, mapping, fullUrl, startTime, method, headers, body);
|
|
3285
|
+
})();
|
|
3339
3286
|
}
|
|
3340
3287
|
handleDirectProxy(res, mapping, fullUrl, startTime, method, headers) {
|
|
3341
3288
|
const service = mapping.service;
|
|
3342
|
-
const
|
|
3343
|
-
|
|
3289
|
+
const targetUrl = mapping.targetUrl;
|
|
3290
|
+
const proxyHeaders = {};
|
|
3291
|
+
for(const key in headers)if (!GatewayConstants.SKIP_REQUEST_HEADERS.has(key.toLowerCase())) proxyHeaders[key] = headers[key];
|
|
3292
|
+
proxyHeaders['host'] = targetUrl.host;
|
|
3293
|
+
const state = {
|
|
3294
|
+
aborted: false,
|
|
3295
|
+
responded: false
|
|
3296
|
+
};
|
|
3297
|
+
service._state.activeConnections++;
|
|
3298
|
+
const cleanup = ()=>{
|
|
3299
|
+
service._state.activeConnections--;
|
|
3300
|
+
};
|
|
3344
3301
|
res.onAborted(()=>{
|
|
3345
|
-
aborted = true;
|
|
3302
|
+
state.aborted = true;
|
|
3303
|
+
cleanup();
|
|
3346
3304
|
});
|
|
3347
|
-
|
|
3348
|
-
|
|
3349
|
-
|
|
3350
|
-
|
|
3351
|
-
|
|
3352
|
-
|
|
3353
|
-
|
|
3354
|
-
|
|
3355
|
-
|
|
3356
|
-
|
|
3357
|
-
|
|
3358
|
-
|
|
3305
|
+
const proxyReq = external_node_http_default().request({
|
|
3306
|
+
hostname: targetUrl.hostname,
|
|
3307
|
+
port: parseInt(targetUrl.port || ('https:' === targetUrl.protocol ? '443' : '80')),
|
|
3308
|
+
path: fullUrl,
|
|
3309
|
+
method: method.toUpperCase(),
|
|
3310
|
+
headers: proxyHeaders,
|
|
3311
|
+
timeout: 30000
|
|
3312
|
+
}, (proxyRes)=>{
|
|
3313
|
+
if (state.aborted) {
|
|
3314
|
+
proxyRes.destroy();
|
|
3315
|
+
cleanup();
|
|
3316
|
+
return;
|
|
3317
|
+
}
|
|
3318
|
+
const statusCode = proxyRes.statusCode || 200;
|
|
3319
|
+
const statusMessage = getStatusMessage(statusCode);
|
|
3320
|
+
if (101 === statusCode) {
|
|
3321
|
+
res.cork(()=>{
|
|
3322
|
+
if (state.aborted) return;
|
|
3323
|
+
res.writeStatus(`${statusCode} ${statusMessage}`);
|
|
3324
|
+
for (const [key, value] of Object.entries(proxyRes.headers))if (!GatewayConstants.SKIP_RESPONSE_HEADERS.has(key.toLowerCase())) {
|
|
3325
|
+
if (value) res.writeHeader(key, Array.isArray(value) ? value.join(', ') : value);
|
|
3326
|
+
}
|
|
3327
|
+
res.end();
|
|
3328
|
+
state.responded = true;
|
|
3329
|
+
});
|
|
3330
|
+
cleanup();
|
|
3331
|
+
return;
|
|
3332
|
+
}
|
|
3333
|
+
res.cork(()=>{
|
|
3334
|
+
if (state.aborted) return;
|
|
3335
|
+
res.writeStatus(`${statusCode} ${statusMessage}`);
|
|
3336
|
+
for (const [key, value] of Object.entries(proxyRes.headers))if (!GatewayConstants.SKIP_RESPONSE_HEADERS.has(key.toLowerCase())) {
|
|
3337
|
+
if (value) res.writeHeader(key, Array.isArray(value) ? value.join(', ') : value);
|
|
3338
|
+
}
|
|
3339
|
+
});
|
|
3340
|
+
proxyRes.on('data', (chunk)=>{
|
|
3341
|
+
if (state.aborted) return void proxyRes.destroy();
|
|
3342
|
+
let writeSuccess = false;
|
|
3343
|
+
res.cork(()=>{
|
|
3344
|
+
if (state.aborted) return;
|
|
3345
|
+
writeSuccess = res.write(chunk);
|
|
3346
|
+
});
|
|
3347
|
+
if (!writeSuccess) {
|
|
3348
|
+
proxyRes.pause();
|
|
3349
|
+
res.onWritable(()=>{
|
|
3350
|
+
if (state.aborted) {
|
|
3351
|
+
proxyRes.destroy();
|
|
3352
|
+
return false;
|
|
3353
|
+
}
|
|
3354
|
+
proxyRes.resume();
|
|
3355
|
+
return true;
|
|
3359
3356
|
});
|
|
3360
|
-
|
|
3361
|
-
|
|
3362
|
-
|
|
3363
|
-
|
|
3364
|
-
|
|
3365
|
-
|
|
3366
|
-
|
|
3367
|
-
|
|
3368
|
-
|
|
3369
|
-
|
|
3357
|
+
}
|
|
3358
|
+
});
|
|
3359
|
+
proxyRes.on('end', ()=>{
|
|
3360
|
+
if (state.aborted) return void cleanup();
|
|
3361
|
+
res.cork(()=>{
|
|
3362
|
+
if (state.aborted) return;
|
|
3363
|
+
res.end();
|
|
3364
|
+
state.responded = true;
|
|
3365
|
+
if (this.logging.enableRequestLog) {
|
|
3366
|
+
const responseTime = Date.now() - startTime;
|
|
3367
|
+
this.logger.info({
|
|
3368
|
+
msg: `📤 [${service.name}] ${method} ${fullUrl} - ${statusCode} - ${formatTime(responseTime)}`,
|
|
3369
|
+
service: service.name,
|
|
3370
|
+
method,
|
|
3371
|
+
path: fullUrl,
|
|
3372
|
+
statusCode,
|
|
3373
|
+
responseTime
|
|
3370
3374
|
});
|
|
3371
3375
|
}
|
|
3372
3376
|
});
|
|
3377
|
+
cleanup();
|
|
3378
|
+
});
|
|
3379
|
+
proxyRes.on('error', (err)=>{
|
|
3380
|
+
if (state.aborted) return void cleanup();
|
|
3381
|
+
this.logger.error({
|
|
3382
|
+
msg: `❌ [${service.name}] 代理响应错误`,
|
|
3383
|
+
error: err.message
|
|
3384
|
+
});
|
|
3385
|
+
if (!state.responded) {
|
|
3386
|
+
state.responded = true;
|
|
3387
|
+
res.cork(()=>{
|
|
3388
|
+
res.writeStatus('502 Bad Gateway');
|
|
3389
|
+
res.end('Bad Gateway');
|
|
3390
|
+
});
|
|
3391
|
+
}
|
|
3392
|
+
cleanup();
|
|
3393
|
+
});
|
|
3394
|
+
});
|
|
3395
|
+
proxyReq.on('error', (err)=>{
|
|
3396
|
+
if (state.aborted) return void cleanup();
|
|
3397
|
+
this.logger.error({
|
|
3398
|
+
msg: `❌ [${service.name}] 代理请求错误`,
|
|
3399
|
+
error: err.message
|
|
3400
|
+
});
|
|
3401
|
+
if (!state.responded) {
|
|
3402
|
+
state.responded = true;
|
|
3403
|
+
res.cork(()=>{
|
|
3404
|
+
res.writeStatus('502 Bad Gateway');
|
|
3405
|
+
res.end('Bad Gateway');
|
|
3406
|
+
});
|
|
3373
3407
|
}
|
|
3408
|
+
if (!service.proxyOnly && 'online' === service._state.status) {
|
|
3409
|
+
this.logger.info({
|
|
3410
|
+
msg: `🔄 [${service.name}] 后端不可达,重置状态为 offline`
|
|
3411
|
+
});
|
|
3412
|
+
service._state.status = 'offline';
|
|
3413
|
+
}
|
|
3414
|
+
cleanup();
|
|
3415
|
+
});
|
|
3416
|
+
res.onData((ab, isLast)=>{
|
|
3417
|
+
if (state.aborted) return void proxyReq.destroy();
|
|
3418
|
+
const chunk = Buffer.from(ab);
|
|
3419
|
+
if (isLast) proxyReq.end(chunk);
|
|
3420
|
+
else proxyReq.write(chunk);
|
|
3374
3421
|
});
|
|
3375
3422
|
}
|
|
3376
3423
|
async forwardProxyRequest(res, mapping, path, startTime, method, headers, body) {
|
|
@@ -3378,232 +3425,215 @@ var __webpack_exports__ = {};
|
|
|
3378
3425
|
const perfLog = this.logging.enablePerformanceLog;
|
|
3379
3426
|
const perfPrepStart = perfLog ? performance.now() : 0;
|
|
3380
3427
|
const targetUrl = mapping.targetUrl;
|
|
3381
|
-
const perfUrlTime = perfLog ? performance.now() - perfPrepStart : 0;
|
|
3382
3428
|
const proxyHeaders = {};
|
|
3383
|
-
for(const key in headers)
|
|
3429
|
+
for(const key in headers){
|
|
3430
|
+
const keyLower = key.toLowerCase();
|
|
3431
|
+
if ('connection' !== keyLower && 'keep-alive' !== keyLower && 'content-length' !== keyLower && 'transfer-encoding' !== keyLower) proxyHeaders[key] = headers[key];
|
|
3432
|
+
}
|
|
3384
3433
|
proxyHeaders['host'] = targetUrl.host;
|
|
3385
|
-
|
|
3434
|
+
if (body.length > 0) proxyHeaders['content-length'] = String(body.length);
|
|
3435
|
+
const perfPrepTime = perfLog ? performance.now() - perfPrepStart : 0;
|
|
3386
3436
|
const state = {
|
|
3387
3437
|
aborted: false,
|
|
3388
3438
|
responded: false
|
|
3389
3439
|
};
|
|
3390
3440
|
service._state.activeConnections++;
|
|
3391
|
-
const
|
|
3441
|
+
const cleanup = ()=>{
|
|
3442
|
+
service._state.activeConnections--;
|
|
3443
|
+
};
|
|
3444
|
+
res.onAborted(()=>{
|
|
3445
|
+
state.aborted = true;
|
|
3446
|
+
cleanup();
|
|
3447
|
+
});
|
|
3448
|
+
const perfHttpStart = perfLog ? performance.now() : 0;
|
|
3449
|
+
let perfTtfb = 0;
|
|
3450
|
+
let perfStreamStart = 0;
|
|
3451
|
+
let chunkCount = 0;
|
|
3452
|
+
let totalBytes = 0;
|
|
3392
3453
|
return new Promise((resolve, reject)=>{
|
|
3393
|
-
let
|
|
3394
|
-
|
|
3395
|
-
|
|
3396
|
-
|
|
3397
|
-
|
|
3398
|
-
|
|
3399
|
-
|
|
3400
|
-
|
|
3401
|
-
|
|
3402
|
-
|
|
3403
|
-
|
|
3404
|
-
|
|
3405
|
-
|
|
3406
|
-
let perfTtfb = 0;
|
|
3407
|
-
let perfStreamStart = 0;
|
|
3408
|
-
let chunkCount = 0;
|
|
3409
|
-
let totalBytes = 0;
|
|
3410
|
-
const undiciClient = mapping.undiciClient;
|
|
3411
|
-
undiciClient.request({
|
|
3412
|
-
path,
|
|
3413
|
-
method,
|
|
3414
|
-
headers: proxyHeaders,
|
|
3415
|
-
body
|
|
3416
|
-
}).then(({ statusCode, headers, body })=>{
|
|
3417
|
-
if (perfLog && 0 === perfTtfb) {
|
|
3418
|
-
perfTtfb = performance.now() - perfHttpStart;
|
|
3419
|
-
perfStreamStart = performance.now();
|
|
3420
|
-
}
|
|
3421
|
-
const statusMessage = 'OK';
|
|
3422
|
-
if (state.aborted) {
|
|
3423
|
-
body.destroy();
|
|
3424
|
-
cleanup();
|
|
3425
|
-
resolve();
|
|
3426
|
-
return;
|
|
3427
|
-
}
|
|
3428
|
-
if (101 === statusCode) {
|
|
3429
|
-
res.cork(()=>{
|
|
3430
|
-
if (state.aborted) return;
|
|
3431
|
-
res.writeStatus(`${statusCode} ${statusMessage}`);
|
|
3432
|
-
for(const key in headers){
|
|
3433
|
-
const keyLower = key.toLowerCase();
|
|
3434
|
-
if ('connection' === keyLower || 'transfer-encoding' === keyLower || 'keep-alive' === keyLower) continue;
|
|
3435
|
-
const value = headers[key];
|
|
3436
|
-
if (Array.isArray(value)) for (const v of value)res.writeHeader(key, v);
|
|
3437
|
-
else if (void 0 !== value) res.writeHeader(key, value);
|
|
3438
|
-
}
|
|
3439
|
-
res.end();
|
|
3440
|
-
state.responded = true;
|
|
3441
|
-
});
|
|
3442
|
-
cleanup();
|
|
3443
|
-
resolve();
|
|
3444
|
-
return;
|
|
3445
|
-
}
|
|
3446
|
-
res.cork(()=>{
|
|
3447
|
-
if (state.aborted) return;
|
|
3448
|
-
res.writeStatus(`${statusCode} ${statusMessage}`);
|
|
3449
|
-
for(const key in headers){
|
|
3450
|
-
const keyLower = key.toLowerCase();
|
|
3451
|
-
if ('connection' === keyLower || 'transfer-encoding' === keyLower || 'keep-alive' === keyLower) continue;
|
|
3452
|
-
const value = headers[key];
|
|
3453
|
-
if (Array.isArray(value)) for (const v of value)res.writeHeader(key, v);
|
|
3454
|
-
else if (void 0 !== value) res.writeHeader(key, value);
|
|
3454
|
+
let proxyReq;
|
|
3455
|
+
try {
|
|
3456
|
+
proxyReq = external_node_http_default().request({
|
|
3457
|
+
hostname: targetUrl.hostname,
|
|
3458
|
+
port: parseInt(targetUrl.port || ('https:' === targetUrl.protocol ? '443' : '80')),
|
|
3459
|
+
path,
|
|
3460
|
+
method: method.toUpperCase(),
|
|
3461
|
+
headers: proxyHeaders,
|
|
3462
|
+
timeout: 30000
|
|
3463
|
+
}, (proxyRes)=>{
|
|
3464
|
+
if (perfLog && 0 === perfTtfb) {
|
|
3465
|
+
perfTtfb = performance.now() - perfHttpStart;
|
|
3466
|
+
perfStreamStart = performance.now();
|
|
3455
3467
|
}
|
|
3456
|
-
|
|
3457
|
-
|
|
3468
|
+
const statusCode = proxyRes.statusCode || 200;
|
|
3469
|
+
const statusMessage = getStatusMessage(statusCode);
|
|
3458
3470
|
if (state.aborted) {
|
|
3459
|
-
|
|
3471
|
+
proxyRes.destroy();
|
|
3472
|
+
cleanup();
|
|
3473
|
+
resolve();
|
|
3460
3474
|
return;
|
|
3461
3475
|
}
|
|
3462
|
-
if (
|
|
3463
|
-
|
|
3464
|
-
|
|
3465
|
-
|
|
3466
|
-
|
|
3467
|
-
|
|
3468
|
-
if (state.aborted) return;
|
|
3469
|
-
writeSuccess = res.write(chunk);
|
|
3470
|
-
});
|
|
3471
|
-
if (!writeSuccess) {
|
|
3472
|
-
body.pause();
|
|
3473
|
-
res.onWritable(()=>{
|
|
3474
|
-
if (state.aborted) {
|
|
3475
|
-
body.destroy();
|
|
3476
|
-
return false;
|
|
3476
|
+
if (101 === statusCode) {
|
|
3477
|
+
res.cork(()=>{
|
|
3478
|
+
if (state.aborted) return;
|
|
3479
|
+
res.writeStatus(`${statusCode} ${statusMessage}`);
|
|
3480
|
+
for (const [key, value] of Object.entries(proxyRes.headers))if (!GatewayConstants.SKIP_RESPONSE_HEADERS.has(key.toLowerCase())) {
|
|
3481
|
+
if (value) res.writeHeader(key, Array.isArray(value) ? value.join(', ') : value);
|
|
3477
3482
|
}
|
|
3478
|
-
|
|
3479
|
-
|
|
3483
|
+
res.end();
|
|
3484
|
+
state.responded = true;
|
|
3480
3485
|
});
|
|
3481
|
-
}
|
|
3482
|
-
});
|
|
3483
|
-
body.on('end', ()=>{
|
|
3484
|
-
if (state.aborted) {
|
|
3485
3486
|
cleanup();
|
|
3486
3487
|
resolve();
|
|
3487
3488
|
return;
|
|
3488
3489
|
}
|
|
3489
|
-
const perfStreamTime = perfLog ? performance.now() - perfStreamStart : 0;
|
|
3490
|
-
const perfTotalTime = perfLog ? performance.now() - perfPrepStart : 0;
|
|
3491
3490
|
res.cork(()=>{
|
|
3492
3491
|
if (state.aborted) return;
|
|
3493
|
-
res.
|
|
3494
|
-
|
|
3495
|
-
|
|
3496
|
-
|
|
3497
|
-
|
|
3498
|
-
|
|
3499
|
-
|
|
3492
|
+
res.writeStatus(`${statusCode} ${statusMessage}`);
|
|
3493
|
+
for (const [key, value] of Object.entries(proxyRes.headers))if (!GatewayConstants.SKIP_RESPONSE_HEADERS.has(key.toLowerCase())) {
|
|
3494
|
+
if (value) res.writeHeader(key, Array.isArray(value) ? value.join(', ') : value);
|
|
3495
|
+
}
|
|
3496
|
+
});
|
|
3497
|
+
proxyRes.on('data', (chunk)=>{
|
|
3498
|
+
if (state.aborted) return void proxyRes.destroy();
|
|
3499
|
+
if (perfLog) {
|
|
3500
|
+
chunkCount++;
|
|
3501
|
+
totalBytes += chunk.length;
|
|
3502
|
+
}
|
|
3503
|
+
let writeSuccess = false;
|
|
3504
|
+
res.cork(()=>{
|
|
3505
|
+
if (state.aborted) return;
|
|
3506
|
+
writeSuccess = res.write(chunk);
|
|
3507
|
+
});
|
|
3508
|
+
if (!writeSuccess) {
|
|
3509
|
+
proxyRes.pause();
|
|
3510
|
+
res.onWritable(()=>{
|
|
3511
|
+
if (state.aborted) {
|
|
3512
|
+
proxyRes.destroy();
|
|
3513
|
+
return false;
|
|
3514
|
+
}
|
|
3515
|
+
proxyRes.resume();
|
|
3516
|
+
return true;
|
|
3517
|
+
});
|
|
3518
|
+
}
|
|
3519
|
+
});
|
|
3520
|
+
proxyRes.on('end', ()=>{
|
|
3521
|
+
if (state.aborted) {
|
|
3522
|
+
cleanup();
|
|
3523
|
+
resolve();
|
|
3524
|
+
return;
|
|
3525
|
+
}
|
|
3526
|
+
const perfStreamTime = perfLog ? performance.now() - perfStreamStart : 0;
|
|
3527
|
+
const perfTotalTime = perfLog ? performance.now() - perfPrepStart : 0;
|
|
3528
|
+
res.cork(()=>{
|
|
3529
|
+
if (state.aborted) return;
|
|
3530
|
+
res.end();
|
|
3531
|
+
state.responded = true;
|
|
3532
|
+
if (this.logging.enableRequestLog) {
|
|
3533
|
+
const responseTime = Date.now() - startTime;
|
|
3534
|
+
this.logger.info({
|
|
3535
|
+
msg: `📤 [${service.name}] ${method} ${path} - ${statusCode} - ${formatTime(responseTime)}`,
|
|
3536
|
+
service: service.name,
|
|
3537
|
+
method,
|
|
3538
|
+
path,
|
|
3539
|
+
statusCode,
|
|
3540
|
+
responseTime
|
|
3541
|
+
});
|
|
3542
|
+
}
|
|
3543
|
+
if (perfLog) console.error(`⚡ [${service.name}] 性能分析:`, {
|
|
3500
3544
|
method,
|
|
3501
3545
|
path,
|
|
3502
3546
|
statusCode,
|
|
3503
|
-
|
|
3547
|
+
prepTime: perfPrepTime.toFixed(3) + 'ms',
|
|
3548
|
+
ttfb: perfTtfb.toFixed(3) + 'ms',
|
|
3549
|
+
streamTime: perfStreamTime.toFixed(3) + 'ms',
|
|
3550
|
+
totalTime: perfTotalTime.toFixed(3) + 'ms',
|
|
3551
|
+
chunkCount,
|
|
3552
|
+
totalBytes,
|
|
3553
|
+
avgChunkSize: chunkCount > 0 ? (totalBytes / chunkCount).toFixed(1) + 'B' : '0B'
|
|
3504
3554
|
});
|
|
3555
|
+
});
|
|
3556
|
+
cleanup();
|
|
3557
|
+
resolve();
|
|
3558
|
+
});
|
|
3559
|
+
proxyRes.on('error', (err)=>{
|
|
3560
|
+
if (state.aborted) {
|
|
3561
|
+
cleanup();
|
|
3562
|
+
resolve();
|
|
3563
|
+
return;
|
|
3505
3564
|
}
|
|
3506
|
-
|
|
3507
|
-
|
|
3508
|
-
|
|
3509
|
-
statusCode,
|
|
3510
|
-
prepTime: perfPrepTime.toFixed(3) + 'ms',
|
|
3511
|
-
urlTime: perfUrlTime.toFixed(3) + 'ms',
|
|
3512
|
-
headersTime: perfHeadersTime.toFixed(3) + 'ms',
|
|
3513
|
-
ttfb: perfTtfb.toFixed(3) + 'ms',
|
|
3514
|
-
streamTime: perfStreamTime.toFixed(3) + 'ms',
|
|
3515
|
-
totalTime: perfTotalTime.toFixed(3) + 'ms',
|
|
3516
|
-
chunkCount,
|
|
3517
|
-
totalBytes,
|
|
3518
|
-
avgChunkSize: chunkCount > 0 ? (totalBytes / chunkCount).toFixed(1) + 'B' : '0B'
|
|
3565
|
+
this.logger.error({
|
|
3566
|
+
msg: `❌ [${service.name}] 代理响应错误`,
|
|
3567
|
+
error: err.message
|
|
3519
3568
|
});
|
|
3569
|
+
if (!state.responded) {
|
|
3570
|
+
state.responded = true;
|
|
3571
|
+
res.cork(()=>{
|
|
3572
|
+
res.writeStatus('502 Bad Gateway');
|
|
3573
|
+
res.end('Bad Gateway');
|
|
3574
|
+
});
|
|
3575
|
+
}
|
|
3576
|
+
cleanup();
|
|
3577
|
+
reject(err);
|
|
3520
3578
|
});
|
|
3521
|
-
cleanup();
|
|
3522
|
-
resolve();
|
|
3523
3579
|
});
|
|
3524
|
-
|
|
3580
|
+
proxyReq.on('error', (err)=>{
|
|
3525
3581
|
if (state.aborted) {
|
|
3526
3582
|
cleanup();
|
|
3527
3583
|
resolve();
|
|
3528
3584
|
return;
|
|
3529
3585
|
}
|
|
3530
3586
|
this.logger.error({
|
|
3531
|
-
msg: `❌ [${service.name}]
|
|
3587
|
+
msg: `❌ [${service.name}] 代理请求错误`,
|
|
3532
3588
|
error: err.message
|
|
3533
3589
|
});
|
|
3534
|
-
if (!state.responded
|
|
3590
|
+
if (!state.responded) {
|
|
3535
3591
|
state.responded = true;
|
|
3536
|
-
|
|
3537
|
-
res.
|
|
3538
|
-
|
|
3539
|
-
|
|
3540
|
-
res.end('Bad Gateway');
|
|
3541
|
-
}
|
|
3542
|
-
});
|
|
3543
|
-
} catch (sendErr) {
|
|
3544
|
-
const sendErrMsg = sendErr instanceof Error ? sendErr.message : String(sendErr);
|
|
3545
|
-
this.logger.error({
|
|
3546
|
-
msg: `❌ [${service.name}] 发送错误响应失败`,
|
|
3547
|
-
error: sendErrMsg
|
|
3548
|
-
});
|
|
3549
|
-
}
|
|
3592
|
+
res.cork(()=>{
|
|
3593
|
+
res.writeStatus('502 Bad Gateway');
|
|
3594
|
+
res.end('Bad Gateway');
|
|
3595
|
+
});
|
|
3550
3596
|
}
|
|
3551
3597
|
cleanup();
|
|
3552
3598
|
reject(err);
|
|
3553
3599
|
});
|
|
3554
|
-
|
|
3555
|
-
|
|
3556
|
-
|
|
3557
|
-
|
|
3558
|
-
return;
|
|
3559
|
-
}
|
|
3600
|
+
if (body.length > 0) proxyReq.end(body);
|
|
3601
|
+
else proxyReq.end();
|
|
3602
|
+
} catch (err) {
|
|
3603
|
+
const message = err instanceof Error ? err.message : String(err);
|
|
3560
3604
|
this.logger.error({
|
|
3561
|
-
msg: `❌ [${service.name}]
|
|
3562
|
-
error:
|
|
3605
|
+
msg: `❌ [${service.name}] 创建代理请求失败`,
|
|
3606
|
+
error: message
|
|
3563
3607
|
});
|
|
3564
|
-
if (!state.responded
|
|
3608
|
+
if (!state.responded) {
|
|
3565
3609
|
state.responded = true;
|
|
3566
|
-
|
|
3567
|
-
res.
|
|
3568
|
-
|
|
3569
|
-
|
|
3570
|
-
res.end('Bad Gateway');
|
|
3571
|
-
}
|
|
3572
|
-
});
|
|
3573
|
-
} catch (sendErr) {
|
|
3574
|
-
const sendErrMsg = sendErr instanceof Error ? sendErr.message : String(sendErr);
|
|
3575
|
-
this.logger.error({
|
|
3576
|
-
msg: `❌ [${service.name}] 发送错误响应失败`,
|
|
3577
|
-
error: sendErrMsg
|
|
3578
|
-
});
|
|
3579
|
-
}
|
|
3610
|
+
res.cork(()=>{
|
|
3611
|
+
res.writeStatus('502 Bad Gateway');
|
|
3612
|
+
res.end('Bad Gateway');
|
|
3613
|
+
});
|
|
3580
3614
|
}
|
|
3581
3615
|
cleanup();
|
|
3582
|
-
reject(
|
|
3583
|
-
}
|
|
3616
|
+
reject(new Error(message));
|
|
3617
|
+
}
|
|
3584
3618
|
});
|
|
3585
3619
|
}
|
|
3586
3620
|
async start() {
|
|
3587
|
-
const uWS = await Promise.resolve().then(__webpack_require__.t.bind(__webpack_require__, "uWebSockets.js", 23));
|
|
3588
3621
|
const host = this.config.host || '127.0.0.1';
|
|
3589
3622
|
const port = this.config.port || 3000;
|
|
3590
|
-
const app =
|
|
3623
|
+
const app = external_uWebSockets_js_default().App();
|
|
3591
3624
|
app.ws('/*', {
|
|
3592
3625
|
upgrade: (res, req, context)=>{
|
|
3593
3626
|
const hostname = req.getHeader('host')?.split(':')[0] || '';
|
|
3594
3627
|
const mapping = this.hostnameRoutes.get(hostname);
|
|
3595
|
-
if (!mapping) {
|
|
3596
|
-
res.
|
|
3597
|
-
|
|
3598
|
-
|
|
3599
|
-
});
|
|
3600
|
-
return;
|
|
3601
|
-
}
|
|
3628
|
+
if (!mapping) return void res.cork(()=>{
|
|
3629
|
+
res.writeStatus('404 Not Found');
|
|
3630
|
+
res.end(`Service not found: ${hostname}`);
|
|
3631
|
+
});
|
|
3602
3632
|
const { service, target } = mapping;
|
|
3603
3633
|
service._state.lastAccessTime = Date.now();
|
|
3604
3634
|
const clientHeaders = {};
|
|
3605
3635
|
req.forEach((key, value)=>{
|
|
3606
|
-
const safeValue = value.replace(
|
|
3636
|
+
const safeValue = value.replace(GatewayConstants.CRLF_REGEX, '');
|
|
3607
3637
|
clientHeaders[key] = safeValue;
|
|
3608
3638
|
});
|
|
3609
3639
|
const clientPath = req.getUrl() + (req.getQuery() ? `?${req.getQuery()}` : '');
|
|
@@ -3667,10 +3697,10 @@ var __webpack_exports__ = {};
|
|
|
3667
3697
|
service._state.startTime = Date.now();
|
|
3668
3698
|
service._state.startCount++;
|
|
3669
3699
|
}
|
|
3670
|
-
const targetUrl = new
|
|
3671
|
-
const
|
|
3672
|
-
const clientPath =
|
|
3673
|
-
const clientHeaders =
|
|
3700
|
+
const targetUrl = new external_node_url_namespaceObject.URL(target);
|
|
3701
|
+
const wsUserData = ws.getUserData();
|
|
3702
|
+
const clientPath = wsUserData.clientPath;
|
|
3703
|
+
const clientHeaders = wsUserData.clientHeaders;
|
|
3674
3704
|
const wsUrl = `${'https:' === targetUrl.protocol ? 'wss:' : 'ws:'}//${targetUrl.host}${clientPath}`;
|
|
3675
3705
|
if (this.logging.enableWebSocketLog) this.logger.info({
|
|
3676
3706
|
msg: `🔌 [${service.name}] 连接后端 WebSocket: ${wsUrl}`
|
|
@@ -3780,7 +3810,7 @@ var __webpack_exports__ = {};
|
|
|
3780
3810
|
if (this.logging.enableWebSocketLog) this.logger.info({
|
|
3781
3811
|
msg: `📦 [${service.name}] 消息加入队列`
|
|
3782
3812
|
});
|
|
3783
|
-
wsState.messageQueue.push(Buffer.from(message));
|
|
3813
|
+
if (wsState.messageQueue.length < GatewayConstants.MAX_WS_MESSAGE_QUEUE_SIZE) wsState.messageQueue.push(Buffer.from(message));
|
|
3784
3814
|
}
|
|
3785
3815
|
},
|
|
3786
3816
|
close: (ws)=>{
|
|
@@ -3834,7 +3864,7 @@ var __webpack_exports__ = {};
|
|
|
3834
3864
|
service._state.lastAccessTime = Date.now();
|
|
3835
3865
|
const clientHeaders = {};
|
|
3836
3866
|
req.forEach((key, value)=>{
|
|
3837
|
-
const safeValue = value.replace(
|
|
3867
|
+
const safeValue = value.replace(GatewayConstants.CRLF_REGEX, '');
|
|
3838
3868
|
clientHeaders[key] = safeValue;
|
|
3839
3869
|
});
|
|
3840
3870
|
const clientPath = req.getUrl() + (req.getQuery() ? `?${req.getQuery()}` : '');
|
|
@@ -3897,10 +3927,10 @@ var __webpack_exports__ = {};
|
|
|
3897
3927
|
svc._state.startTime = Date.now();
|
|
3898
3928
|
svc._state.startCount++;
|
|
3899
3929
|
}
|
|
3900
|
-
const targetUrl = new
|
|
3901
|
-
const
|
|
3902
|
-
const clientPath =
|
|
3903
|
-
const clientHeaders =
|
|
3930
|
+
const targetUrl = new external_node_url_namespaceObject.URL(backendTarget);
|
|
3931
|
+
const wsUserData = ws.getUserData();
|
|
3932
|
+
const clientPath = wsUserData.clientPath;
|
|
3933
|
+
const clientHeaders = wsUserData.clientHeaders;
|
|
3904
3934
|
const wsUrl = `${'https:' === targetUrl.protocol ? 'wss:' : 'ws:'}//${targetUrl.host}${clientPath}`;
|
|
3905
3935
|
if (this.logging.enableWebSocketLog) this.logger.info({
|
|
3906
3936
|
msg: `🔌 [${svc.name}] 端口${portNum} 连接后端 WebSocket: ${wsUrl}`
|
|
@@ -3959,12 +3989,17 @@ var __webpack_exports__ = {};
|
|
|
3959
3989
|
if (wsState.backendReady && wsState.backendWs && wsState.backendWs.readyState === wrapper.OPEN) {
|
|
3960
3990
|
wsState.backendWs.send(Buffer.from(message));
|
|
3961
3991
|
svc._state.lastAccessTime = Date.now();
|
|
3962
|
-
} else wsState.messageQueue.push(Buffer.from(message));
|
|
3992
|
+
} else if (wsState.messageQueue.length < GatewayConstants.MAX_WS_MESSAGE_QUEUE_SIZE) wsState.messageQueue.push(Buffer.from(message));
|
|
3963
3993
|
},
|
|
3964
3994
|
close: (ws)=>{
|
|
3965
3995
|
const userData = ws.getUserData();
|
|
3966
3996
|
const svc = userData.service;
|
|
3967
3997
|
svc._state.activeConnections--;
|
|
3998
|
+
const wsState = ws.wsState;
|
|
3999
|
+
if (wsState?.backendWs && wsState.backendWs.readyState === wrapper.OPEN) {
|
|
4000
|
+
wsState.closing = true;
|
|
4001
|
+
wsState.backendWs.close();
|
|
4002
|
+
}
|
|
3968
4003
|
}
|
|
3969
4004
|
});
|
|
3970
4005
|
app.any('/*', (res, req)=>{
|
|
@@ -4001,8 +4036,10 @@ var __webpack_exports__ = {};
|
|
|
4001
4036
|
}
|
|
4002
4037
|
const external_c12_namespaceObject = require("c12");
|
|
4003
4038
|
async function loadDynaPMConfig() {
|
|
4039
|
+
const configFile = process.env.DYNAPM_CONFIG || void 0;
|
|
4004
4040
|
const { config } = await (0, external_c12_namespaceObject.loadConfig)({
|
|
4005
4041
|
name: 'dynapm',
|
|
4042
|
+
configFile,
|
|
4006
4043
|
defaultConfig: {
|
|
4007
4044
|
port: 3000,
|
|
4008
4045
|
host: '127.0.0.1',
|
|
@@ -4144,8 +4181,7 @@ var __webpack_exports__ = {};
|
|
|
4144
4181
|
}
|
|
4145
4182
|
main();
|
|
4146
4183
|
})();
|
|
4147
|
-
var
|
|
4148
|
-
|
|
4149
|
-
if (__webpack_exports__.__esModule) Object.defineProperty(__webpack_export_target__, '__esModule', {
|
|
4184
|
+
for(var __rspack_i in __webpack_exports__)exports[__rspack_i] = __webpack_exports__[__rspack_i];
|
|
4185
|
+
Object.defineProperty(exports, '__esModule', {
|
|
4150
4186
|
value: true
|
|
4151
4187
|
});
|