@morojs/moro 1.8.12 → 1.8.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/README.md +4 -2
- package/dist/core/cluster/thread-cluster.d.ts +25 -0
- package/dist/core/cluster/thread-cluster.js +95 -3
- package/dist/core/cluster/thread-cluster.js.map +1 -1
- package/dist/core/config/config-validator.js +20 -0
- package/dist/core/config/config-validator.js.map +1 -1
- package/dist/core/config/index.js +19 -2
- package/dist/core/config/index.js.map +1 -1
- package/dist/core/config/schema.js +1 -0
- package/dist/core/config/schema.js.map +1 -1
- package/dist/core/framework.d.ts +26 -0
- package/dist/core/framework.js +195 -6
- package/dist/core/framework.js.map +1 -1
- package/dist/core/http/http-server.d.ts +19 -0
- package/dist/core/http/http-server.js +75 -1
- package/dist/core/http/http-server.js.map +1 -1
- package/dist/core/http/http2-server.d.ts +15 -0
- package/dist/core/http/http2-server.js +36 -3
- package/dist/core/http/http2-server.js.map +1 -1
- package/dist/core/http/moro-engine-server.d.ts +28 -0
- package/dist/core/http/moro-engine-server.js +138 -12
- package/dist/core/http/moro-engine-server.js.map +1 -1
- package/dist/core/http/utils/body-type.d.ts +12 -0
- package/dist/core/http/utils/body-type.js +70 -0
- package/dist/core/http/utils/body-type.js.map +1 -0
- package/dist/core/http/utils/compression.d.ts +21 -0
- package/dist/core/http/utils/compression.js +53 -7
- package/dist/core/http/utils/compression.js.map +1 -1
- package/dist/core/http/utils/ssl-config.d.ts +11 -0
- package/dist/core/http/utils/ssl-config.js +3 -0
- package/dist/core/http/utils/ssl-config.js.map +1 -1
- package/dist/core/http/utils/uws-worker-clustering.js +5 -4
- package/dist/core/http/utils/uws-worker-clustering.js.map +1 -1
- package/dist/core/http/uws-http-server.d.ts +3 -0
- package/dist/core/http/uws-http-server.js +47 -2
- package/dist/core/http/uws-http-server.js.map +1 -1
- package/dist/core/middleware/built-in/body-parsers/index.d.ts +18 -0
- package/dist/core/middleware/built-in/body-parsers/index.js +41 -0
- package/dist/core/middleware/built-in/body-parsers/index.js.map +1 -1
- package/dist/core/middleware/built-in/cache/adapters/cache/redis.d.ts +32 -8
- package/dist/core/middleware/built-in/cache/adapters/cache/redis.js +117 -25
- package/dist/core/middleware/built-in/cache/adapters/cache/redis.js.map +1 -1
- package/dist/core/middleware/built-in/compression/core.d.ts +7 -0
- package/dist/core/middleware/built-in/compression/core.js +32 -1
- package/dist/core/middleware/built-in/compression/core.js.map +1 -1
- package/dist/core/middleware/built-in/session/core.d.ts +1 -0
- package/dist/core/middleware/built-in/session/core.js.map +1 -1
- package/dist/core/middleware/built-in/static/core.d.ts +18 -0
- package/dist/core/middleware/built-in/static/core.js +128 -7
- package/dist/core/middleware/built-in/static/core.js.map +1 -1
- package/dist/core/networking/adapters/engine-adapter.d.ts +2 -2
- package/dist/core/networking/adapters/engine-adapter.js +40 -1
- package/dist/core/networking/adapters/engine-adapter.js.map +1 -1
- package/dist/core/networking/adapters/socketio-adapter.d.ts +2 -2
- package/dist/core/networking/adapters/socketio-adapter.js +10 -1
- package/dist/core/networking/adapters/socketio-adapter.js.map +1 -1
- package/dist/core/networking/adapters/uws-adapter.d.ts +2 -2
- package/dist/core/networking/adapters/uws-adapter.js +54 -3
- package/dist/core/networking/adapters/uws-adapter.js.map +1 -1
- package/dist/core/networking/adapters/ws-adapter.d.ts +9 -2
- package/dist/core/networking/adapters/ws-adapter.js +97 -12
- package/dist/core/networking/adapters/ws-adapter.js.map +1 -1
- package/dist/core/networking/websocket-adapter.d.ts +19 -1
- package/dist/core/networking/websocket-adapter.js.map +1 -1
- package/dist/core/routing/index.d.ts +12 -8
- package/dist/core/routing/index.js +7 -2
- package/dist/core/routing/index.js.map +1 -1
- package/dist/core/routing/unified-router.d.ts +46 -8
- package/dist/core/routing/unified-router.js +108 -32
- package/dist/core/routing/unified-router.js.map +1 -1
- package/dist/core/utilities/package-utils.d.ts +8 -1
- package/dist/core/utilities/package-utils.js +2 -0
- package/dist/core/utilities/package-utils.js.map +1 -1
- package/dist/core/workers/worker-manager.js +2 -2
- package/dist/core/workers/worker-manager.js.map +1 -1
- package/dist/index.d.ts +4 -3
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/moro.d.ts +12 -1
- package/dist/moro.js +63 -7
- package/dist/moro.js.map +1 -1
- package/dist/types/cache.d.ts +2 -0
- package/dist/types/cache.js.map +1 -1
- package/dist/types/config.d.ts +16 -0
- package/dist/types/config.js.map +1 -1
- package/dist/types/http.d.ts +6 -0
- package/dist/types/http.js.map +1 -1
- package/dist/types/session.d.ts +1 -0
- package/dist/types/session.js.map +1 -1
- package/package.json +1 -1
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { bodyIsText } from './utils/body-type.js';
|
|
1
2
|
import { createRequire } from 'module';
|
|
2
3
|
import { promisify } from 'util';
|
|
3
4
|
import { randomUUID } from 'crypto';
|
|
@@ -24,15 +25,21 @@ const http = requireBuiltin('http');
|
|
|
24
25
|
const createServer = http.createServer;
|
|
25
26
|
let gzipFn;
|
|
26
27
|
let deflateFn;
|
|
28
|
+
let gzipSyncFn;
|
|
29
|
+
let deflateSyncFn;
|
|
27
30
|
function compressors() {
|
|
28
31
|
if (!gzipFn) {
|
|
29
32
|
const zlib = requireBuiltin('zlib');
|
|
30
33
|
gzipFn = promisify(zlib.gzip);
|
|
31
34
|
deflateFn = promisify(zlib.deflate);
|
|
35
|
+
gzipSyncFn = (buf) => zlib.gzipSync(buf);
|
|
36
|
+
deflateSyncFn = (buf) => zlib.deflateSync(buf);
|
|
32
37
|
}
|
|
33
38
|
return {
|
|
34
39
|
gzip: gzipFn,
|
|
35
40
|
deflate: deflateFn,
|
|
41
|
+
gzipSync: gzipSyncFn,
|
|
42
|
+
deflateSync: deflateSyncFn,
|
|
36
43
|
};
|
|
37
44
|
}
|
|
38
45
|
const JSON_CONTENT_TYPE = 'application/json; charset=utf-8';
|
|
@@ -115,6 +122,10 @@ export class MoroIncomingMessage extends http.IncomingMessage {
|
|
|
115
122
|
body = null;
|
|
116
123
|
path = '';
|
|
117
124
|
_queryString = null;
|
|
125
|
+
/** The request body exactly as received, before any parsing; null when empty. */
|
|
126
|
+
get rawBody() {
|
|
127
|
+
return this._rawBody ?? null;
|
|
128
|
+
}
|
|
118
129
|
// Single slot for every lazily-computed/assigned helper value (query,
|
|
119
130
|
// cookies, requestId, hostname, ...). Allocated on first access - a plain
|
|
120
131
|
// JSON GET that never touches the helpers never allocates it, and the
|
|
@@ -378,6 +389,28 @@ export class MoroServerResponse extends http.ServerResponse {
|
|
|
378
389
|
const acceptEncoding = this.req?.headers['accept-encoding'];
|
|
379
390
|
if (acceptEncoding && acceptEncoding.includes('gzip')) {
|
|
380
391
|
const buffer = Buffer.from(jsonString, 'utf8');
|
|
392
|
+
// A small body is compressed here and now rather than on the threadpool
|
|
393
|
+
// (see compressionMaxInlineBytes); a failure takes the async path below.
|
|
394
|
+
if (server.compressionMaxInlineBytes > 0 &&
|
|
395
|
+
buffer.length <= server.compressionMaxInlineBytes) {
|
|
396
|
+
let compressed;
|
|
397
|
+
try {
|
|
398
|
+
compressed = compressors().gzipSync(buffer);
|
|
399
|
+
}
|
|
400
|
+
catch {
|
|
401
|
+
compressed = undefined;
|
|
402
|
+
}
|
|
403
|
+
if (compressed !== undefined) {
|
|
404
|
+
this.writeHead(this.statusCode || 200, {
|
|
405
|
+
'Content-Type': JSON_CONTENT_TYPE,
|
|
406
|
+
'Content-Encoding': 'gzip',
|
|
407
|
+
Vary: 'Accept-Encoding',
|
|
408
|
+
'Content-Length': compressed.length,
|
|
409
|
+
});
|
|
410
|
+
this.end(compressed);
|
|
411
|
+
return;
|
|
412
|
+
}
|
|
413
|
+
}
|
|
381
414
|
compressors()
|
|
382
415
|
.gzip(buffer)
|
|
383
416
|
.then(compressed => {
|
|
@@ -410,6 +443,26 @@ export class MoroServerResponse extends http.ServerResponse {
|
|
|
410
443
|
}
|
|
411
444
|
else if (acceptEncoding && acceptEncoding.includes('deflate')) {
|
|
412
445
|
const buffer = Buffer.from(jsonString, 'utf8');
|
|
446
|
+
if (server.compressionMaxInlineBytes > 0 &&
|
|
447
|
+
buffer.length <= server.compressionMaxInlineBytes) {
|
|
448
|
+
let compressed;
|
|
449
|
+
try {
|
|
450
|
+
compressed = compressors().deflateSync(buffer);
|
|
451
|
+
}
|
|
452
|
+
catch {
|
|
453
|
+
compressed = undefined;
|
|
454
|
+
}
|
|
455
|
+
if (compressed !== undefined) {
|
|
456
|
+
this.writeHead(this.statusCode || 200, {
|
|
457
|
+
'Content-Type': JSON_CONTENT_TYPE,
|
|
458
|
+
'Content-Encoding': 'deflate',
|
|
459
|
+
Vary: 'Accept-Encoding',
|
|
460
|
+
'Content-Length': compressed.length,
|
|
461
|
+
});
|
|
462
|
+
this.end(compressed);
|
|
463
|
+
return;
|
|
464
|
+
}
|
|
465
|
+
}
|
|
413
466
|
compressors()
|
|
414
467
|
.deflate(buffer)
|
|
415
468
|
.then(compressed => {
|
|
@@ -899,6 +952,9 @@ export class MoroHttpServer {
|
|
|
899
952
|
compressionEnabled = true;
|
|
900
953
|
/** @internal read by MoroServerResponse prototype methods */
|
|
901
954
|
compressionThreshold = 1024;
|
|
955
|
+
// Bodies at or below this size compress on the calling thread (Content-Length
|
|
956
|
+
// response); larger ones on the threadpool. 0 sends everything to the pool.
|
|
957
|
+
compressionMaxInlineBytes = 16384;
|
|
902
958
|
/** @internal read by MoroIncomingMessage prototype methods */
|
|
903
959
|
requestTrackingEnabled = true; // Generate request IDs
|
|
904
960
|
/** @internal read by MoroServerResponse prototype methods */
|
|
@@ -1007,6 +1063,9 @@ export class MoroHttpServer {
|
|
|
1007
1063
|
if (config.compression.threshold !== undefined) {
|
|
1008
1064
|
this.compressionThreshold = config.compression.threshold;
|
|
1009
1065
|
}
|
|
1066
|
+
if (config.compression.maxInlineBytes !== undefined) {
|
|
1067
|
+
this.compressionMaxInlineBytes = config.compression.maxInlineBytes;
|
|
1068
|
+
}
|
|
1010
1069
|
}
|
|
1011
1070
|
// Minimal mode - disable ALL overhead for pure speed
|
|
1012
1071
|
if (config.minimal) {
|
|
@@ -1562,6 +1621,8 @@ export class MoroHttpServer {
|
|
|
1562
1621
|
const body = chunks.length === 1 && firstChunk !== undefined
|
|
1563
1622
|
? firstChunk
|
|
1564
1623
|
: Buffer.concat(chunks, totalLength);
|
|
1624
|
+
if (totalLength > 0)
|
|
1625
|
+
req._rawBody = body;
|
|
1565
1626
|
if (contentType.includes('application/json')) {
|
|
1566
1627
|
// Empty JSON body -> null (parity with the engine/uWS servers, and
|
|
1567
1628
|
// avoids JSON.parse('') throwing and 500ing an empty POST).
|
|
@@ -1574,7 +1635,9 @@ export class MoroHttpServer {
|
|
|
1574
1635
|
resolve(this.parseMultipart(body, contentType));
|
|
1575
1636
|
}
|
|
1576
1637
|
else {
|
|
1577
|
-
|
|
1638
|
+
// Text decodes to a string; binary (octet-stream, images, protobuf,
|
|
1639
|
+
// ...) stays a Buffer - decoding it would corrupt it irreversibly.
|
|
1640
|
+
resolve(bodyIsText(contentType) ? body.toString() : body);
|
|
1578
1641
|
}
|
|
1579
1642
|
}
|
|
1580
1643
|
catch (error) {
|
|
@@ -1788,6 +1851,17 @@ export class MoroHttpServer {
|
|
|
1788
1851
|
forceCleanup() {
|
|
1789
1852
|
this.forceCleanupPools();
|
|
1790
1853
|
}
|
|
1854
|
+
/**
|
|
1855
|
+
* Replace the TLS certificate/key for new handshakes (node's
|
|
1856
|
+
* tls.Server#setSecureContext). Throws when the server is plain HTTP.
|
|
1857
|
+
*/
|
|
1858
|
+
updateSsl(ssl) {
|
|
1859
|
+
const server = this.server;
|
|
1860
|
+
if (typeof server.setSecureContext !== 'function') {
|
|
1861
|
+
throw new Error('updateSsl: this server was not started with TLS (server.ssl)');
|
|
1862
|
+
}
|
|
1863
|
+
server.setSecureContext(ssl);
|
|
1864
|
+
}
|
|
1791
1865
|
getServer() {
|
|
1792
1866
|
return this.server;
|
|
1793
1867
|
}
|