fulmine.js 5.19.3 → 5.19.4
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/package.json +1 -1
- package/src/application.js +25 -36
- package/src/cli.js +22 -16
- package/src/cluster.js +2 -2
- package/src/compression.js +102 -61
- package/src/declarative.js +47 -24
- package/src/hot-settings.js +5 -5
- package/src/lazy-readable.js +8 -6
- package/src/lazy-writable.js +3 -3
- package/src/middlewares.js +94 -55
- package/src/nest.js +3 -2
- package/src/node-shim.js +10 -5
- package/src/optimizer.js +9 -7
- package/src/options.d.ts +9 -4
- package/src/request-utils.js +3 -2
- package/src/request.js +49 -38
- package/src/response.js +145 -109
- package/src/route.js +3 -3
- package/src/router-utils.js +62 -14
- package/src/router.js +46 -28
- package/src/server-shape.js +14 -10
- package/src/server-timing.js +16 -4
- package/src/socket.js +3 -3
- package/src/testing.js +4 -3
- package/src/usage.js +10 -5
- package/src/utils.js +120 -23
- package/src/verify.js +4 -3
- package/src/view.js +1 -1
- package/src/walk.js +8 -7
- package/src/websocket.js +17 -8
- package/src/work.js +3 -3
package/src/request.js
CHANGED
|
@@ -47,7 +47,7 @@ const {
|
|
|
47
47
|
let currentRequest = null;
|
|
48
48
|
|
|
49
49
|
module.exports = class Request extends LazyReadable {
|
|
50
|
-
/** @type {
|
|
50
|
+
/** @type {import("http").IncomingHttpHeaders|null} */
|
|
51
51
|
#cachedHeaders = null;
|
|
52
52
|
|
|
53
53
|
/** @type {Record<string, string[]>|null} */
|
|
@@ -182,7 +182,7 @@ module.exports = class Request extends LazyReadable {
|
|
|
182
182
|
/**
|
|
183
183
|
* next() as the router means it: the rest of the route is skipped. res.sendFile reports its
|
|
184
184
|
* failures here, because express reports them to the router and not to the route.
|
|
185
|
-
* @type {((err?:
|
|
185
|
+
* @type {((err?: unknown) => void)|undefined}
|
|
186
186
|
*/
|
|
187
187
|
_leaveRoute;
|
|
188
188
|
|
|
@@ -268,13 +268,16 @@ module.exports = class Request extends LazyReadable {
|
|
|
268
268
|
* through the request. Declared rather than left to appear on assignment: runRoute sets it
|
|
269
269
|
* on every request, and an undeclared property is a shape change on each one.
|
|
270
270
|
*
|
|
271
|
+
* Typed loosely for the same reason as `res`: it is set by runRoute rather than here, and the
|
|
272
|
+
* honest `|undefined` would put a check in front of every call.
|
|
273
|
+
*
|
|
271
274
|
* @type {any}
|
|
272
275
|
*/
|
|
273
276
|
next;
|
|
274
277
|
|
|
275
278
|
/**
|
|
276
279
|
* What the chain threw or passed to next(err), waiting for an error handler.
|
|
277
|
-
* @type {
|
|
280
|
+
* @type {unknown}
|
|
278
281
|
*/
|
|
279
282
|
_error;
|
|
280
283
|
|
|
@@ -302,14 +305,15 @@ module.exports = class Request extends LazyReadable {
|
|
|
302
305
|
* because uWS only lends them for this call, everything derived from them waits until something
|
|
303
306
|
* asks, and the body is subscribed to only for the methods that carry one.
|
|
304
307
|
*
|
|
305
|
-
* @param {
|
|
306
|
-
* @param {
|
|
307
|
-
* @param {
|
|
308
|
-
* @param {
|
|
309
|
-
* byte against that exact pattern and dispatched by
|
|
310
|
-
* from them are known without asking
|
|
311
|
-
* @param {
|
|
312
|
-
* literal registration, a holder of its own for a
|
|
308
|
+
* @param {import("uWebSockets.js").HttpRequest} req the uWS request, readable only during this call
|
|
309
|
+
* @param {import("uWebSockets.js").HttpResponse} res the uWS response
|
|
310
|
+
* @param {import("./application.js").Application} app the application this request arrived at
|
|
311
|
+
* @param {import("./router-utils.js").NativePreset} [preset] a literal native registration's
|
|
312
|
+
* constants: uWS matched the URL byte for byte against that exact pattern and dispatched by
|
|
313
|
+
* method, so path, method and what derives from them are known without asking
|
|
314
|
+
* @param {import("./router-utils.js").SkipHolder} [skipHolder] where a granted header skip
|
|
315
|
+
* lives: the preset itself for a literal registration, a holder of its own for a
|
|
316
|
+
* parameterised one
|
|
313
317
|
*/
|
|
314
318
|
constructor(req, res, app, preset, skipHolder) {
|
|
315
319
|
// nothing: the stream is built on the first touch, see LazyReadable
|
|
@@ -495,7 +499,7 @@ module.exports = class Request extends LazyReadable {
|
|
|
495
499
|
// A body exists on the wire only when the request declares one, content-length or
|
|
496
500
|
// transfer-encoding, whatever the verb, and that was spotted during the header copy. The
|
|
497
501
|
// verb list this used to read said nothing the headers had not already said
|
|
498
|
-
if (
|
|
502
|
+
if (this._declaresBody) {
|
|
499
503
|
this._subscribeBody();
|
|
500
504
|
} else {
|
|
501
505
|
this.receivedData = true;
|
|
@@ -547,7 +551,8 @@ module.exports = class Request extends LazyReadable {
|
|
|
547
551
|
*/
|
|
548
552
|
_rawHeader(name) {
|
|
549
553
|
if (this.#cachedHeaders !== null) {
|
|
550
|
-
|
|
554
|
+
// a string for every name but set-cookie, which the callers never ask for
|
|
555
|
+
return /** @type {string|undefined} */ (this.#cachedHeaders[name]);
|
|
551
556
|
}
|
|
552
557
|
const entries = this.#rawHeadersEntries;
|
|
553
558
|
for (let i = 0, len = entries.length; i < len; i += 2) {
|
|
@@ -568,7 +573,7 @@ module.exports = class Request extends LazyReadable {
|
|
|
568
573
|
*/
|
|
569
574
|
_foldedHeader(name) {
|
|
570
575
|
if (this.#cachedHeaders !== null) {
|
|
571
|
-
return this.#cachedHeaders[name];
|
|
576
|
+
return /** @type {string|undefined} */ (this.#cachedHeaders[name]);
|
|
572
577
|
}
|
|
573
578
|
const entries = this.#rawHeadersEntries;
|
|
574
579
|
let value;
|
|
@@ -761,7 +766,7 @@ module.exports = class Request extends LazyReadable {
|
|
|
761
766
|
/**
|
|
762
767
|
* The authority, port included, from Host or from X-Forwarded-Host behind a trusted proxy.
|
|
763
768
|
* `hostname` is the same value without the port.
|
|
764
|
-
* @returns {string}
|
|
769
|
+
* @returns {string|undefined} undefined when the request carries no Host
|
|
765
770
|
*/
|
|
766
771
|
get host() {
|
|
767
772
|
return this.#authority;
|
|
@@ -769,7 +774,7 @@ module.exports = class Request extends LazyReadable {
|
|
|
769
774
|
|
|
770
775
|
/**
|
|
771
776
|
* The host without the port.
|
|
772
|
-
* @returns {string}
|
|
777
|
+
* @returns {string|undefined}
|
|
773
778
|
*/
|
|
774
779
|
get hostname() {
|
|
775
780
|
return this.#host;
|
|
@@ -840,7 +845,8 @@ module.exports = class Request extends LazyReadable {
|
|
|
840
845
|
if (!trust(this.parsedIp, 0)) {
|
|
841
846
|
return proto;
|
|
842
847
|
}
|
|
843
|
-
|
|
848
|
+
// folded to one string, as every header but set-cookie is
|
|
849
|
+
const header = /** @type {string|undefined} */ (this.headers["x-forwarded-proto"]) || proto;
|
|
844
850
|
const index = header.indexOf(",");
|
|
845
851
|
|
|
846
852
|
return index !== -1 ? header.slice(0, index).trim() : header.trim();
|
|
@@ -1109,7 +1115,7 @@ module.exports = class Request extends LazyReadable {
|
|
|
1109
1115
|
return ip;
|
|
1110
1116
|
}
|
|
1111
1117
|
|
|
1112
|
-
/** @type {
|
|
1118
|
+
/** @type {import("./socket.js")|null} */
|
|
1113
1119
|
#cachedConnection = null;
|
|
1114
1120
|
|
|
1115
1121
|
/**
|
|
@@ -1117,7 +1123,7 @@ module.exports = class Request extends LazyReadable {
|
|
|
1117
1123
|
* stand-in for the pair, as node has one socket for both. Built on first read and kept, so it
|
|
1118
1124
|
* keeps its identity across reads, and kept here as well so that it still answers once the
|
|
1119
1125
|
* response is over and `res.socket` has gone null.
|
|
1120
|
-
* @returns {
|
|
1126
|
+
* @returns {import("./socket.js")}
|
|
1121
1127
|
*/
|
|
1122
1128
|
get connection() {
|
|
1123
1129
|
return (this.#cachedConnection ??= this.res._socketShim());
|
|
@@ -1146,18 +1152,21 @@ module.exports = class Request extends LazyReadable {
|
|
|
1146
1152
|
}
|
|
1147
1153
|
const remotePort = uwsRes.getRemotePort();
|
|
1148
1154
|
const rawIp = this.rawIp;
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
|
|
1156
|
-
|
|
1157
|
-
|
|
1158
|
-
|
|
1159
|
-
|
|
1160
|
-
|
|
1155
|
+
// a stand-in with the members a detached request still asks for, told to the checker once
|
|
1156
|
+
this._res = /** @type {import("uWebSockets.js").HttpResponse} */ (
|
|
1157
|
+
/** @type {unknown} */ ({
|
|
1158
|
+
getRemoteAddress: () => rawIp,
|
|
1159
|
+
// whatever a preamble said is already in rawIp, and asking again is the use after free
|
|
1160
|
+
// this method exists to avoid
|
|
1161
|
+
getProxiedRemoteAddress: () => emptyAddress,
|
|
1162
|
+
getRemotePort: () => remotePort,
|
|
1163
|
+
// a body cannot arrive on an upgraded socket, and a stray reader must not reach µWS
|
|
1164
|
+
onData() {},
|
|
1165
|
+
pause() {},
|
|
1166
|
+
resume() {},
|
|
1167
|
+
close() {}
|
|
1168
|
+
})
|
|
1169
|
+
);
|
|
1161
1170
|
}
|
|
1162
1171
|
|
|
1163
1172
|
/**
|
|
@@ -1241,7 +1250,7 @@ module.exports = class Request extends LazyReadable {
|
|
|
1241
1250
|
* acceptable type when called with no arguments
|
|
1242
1251
|
*/
|
|
1243
1252
|
accepts(...types) {
|
|
1244
|
-
return accepts(asMessage(this)).types(.../** @type {
|
|
1253
|
+
return accepts(asMessage(this)).types(.../** @type {string[]} */ (types));
|
|
1245
1254
|
}
|
|
1246
1255
|
|
|
1247
1256
|
/**
|
|
@@ -1250,7 +1259,7 @@ module.exports = class Request extends LazyReadable {
|
|
|
1250
1259
|
* @returns {string|string[]|false}
|
|
1251
1260
|
*/
|
|
1252
1261
|
acceptsCharsets(...charsets) {
|
|
1253
|
-
return accepts(asMessage(this)).charsets(.../** @type {
|
|
1262
|
+
return accepts(asMessage(this)).charsets(.../** @type {string[]} */ (charsets));
|
|
1254
1263
|
}
|
|
1255
1264
|
|
|
1256
1265
|
/**
|
|
@@ -1259,7 +1268,7 @@ module.exports = class Request extends LazyReadable {
|
|
|
1259
1268
|
* @returns {string|string[]|false}
|
|
1260
1269
|
*/
|
|
1261
1270
|
acceptsEncodings(...encodings) {
|
|
1262
|
-
return accepts(asMessage(this)).encodings(.../** @type {
|
|
1271
|
+
return accepts(asMessage(this)).encodings(.../** @type {string[]} */ (encodings));
|
|
1263
1272
|
}
|
|
1264
1273
|
|
|
1265
1274
|
/**
|
|
@@ -1268,7 +1277,7 @@ module.exports = class Request extends LazyReadable {
|
|
|
1268
1277
|
* @returns {string|string[]|false}
|
|
1269
1278
|
*/
|
|
1270
1279
|
acceptsLanguages(...languages) {
|
|
1271
|
-
return accepts(asMessage(this)).languages(.../** @type {
|
|
1280
|
+
return accepts(asMessage(this)).languages(.../** @type {string[]} */ (languages));
|
|
1272
1281
|
}
|
|
1273
1282
|
|
|
1274
1283
|
/**
|
|
@@ -1351,7 +1360,7 @@ module.exports = class Request extends LazyReadable {
|
|
|
1351
1360
|
* Built on first read and cached: routing works from the raw entries and most requests never
|
|
1352
1361
|
* ask for this.
|
|
1353
1362
|
*
|
|
1354
|
-
* @returns {
|
|
1363
|
+
* @returns {import("http").IncomingHttpHeaders}
|
|
1355
1364
|
*/
|
|
1356
1365
|
get headers() {
|
|
1357
1366
|
// https://nodejs.org/api/http.html#messageheaders
|
|
@@ -1362,6 +1371,7 @@ module.exports = class Request extends LazyReadable {
|
|
|
1362
1371
|
// half-filled object cached. A plain object because node's is one and inspect prints the
|
|
1363
1372
|
// difference; Object.hasOwn keeps a header named "constructor" or "toString" from finding
|
|
1364
1373
|
// Object.prototype's member and folding a first value into it.
|
|
1374
|
+
/** @type {import("http").IncomingHttpHeaders} */
|
|
1365
1375
|
const headers = {};
|
|
1366
1376
|
const entries = this.#rawHeadersEntries;
|
|
1367
1377
|
for (let index = 0, len = entries.length; index < len; index += 2) {
|
|
@@ -1377,7 +1387,7 @@ module.exports = class Request extends LazyReadable {
|
|
|
1377
1387
|
if (key === "cookie") {
|
|
1378
1388
|
headers[key] += "; " + value;
|
|
1379
1389
|
} else if (key === "set-cookie") {
|
|
1380
|
-
headers[key].push(value);
|
|
1390
|
+
/** @type {string[]} */ (headers[key]).push(value);
|
|
1381
1391
|
} else {
|
|
1382
1392
|
headers[key] += ", " + value;
|
|
1383
1393
|
}
|
|
@@ -1465,4 +1475,5 @@ module.exports = class Request extends LazyReadable {
|
|
|
1465
1475
|
|
|
1466
1476
|
// req.header is req.get under Express's other name. On the prototype rather than an instance
|
|
1467
1477
|
// field, which wrote one own property per request in the constructor.
|
|
1468
|
-
/** @type {
|
|
1478
|
+
/** @type {{header?: typeof module.exports.prototype.get}} */ (module.exports.prototype).header =
|
|
1479
|
+
module.exports.prototype.get;
|