@nodefony/http 10.0.0-alpha.9 → 10.0.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +12 -3
- package/dist/_virtual/{_@oxc-project_runtime@0.151.0 → _@oxc-project_runtime@0.152.0}/helpers/esm/decorate.js +1 -1
- package/dist/_virtual/{_@oxc-project_runtime@0.151.0 → _@oxc-project_runtime@0.152.0}/helpers/esm/decorateMetadata.js +1 -1
- package/dist/_virtual/{_@oxc-project_runtime@0.151.0 → _@oxc-project_runtime@0.152.0}/helpers/esm/decorateParam.js +1 -1
- package/dist/index.js +6 -4
- package/dist/nodefony/command/assetsPublishCommand.js +1 -1
- package/dist/nodefony/command/certificatesCommand.js +1 -2
- package/dist/nodefony/command/networkCommand.js +1 -1
- package/dist/nodefony/command/proxyGenerateCommand.js +1 -1
- package/dist/nodefony/config/config.js +26 -4
- package/dist/nodefony/interfaces/IRouting.js +1 -0
- package/dist/nodefony/interfaces/ISecurity.js +1 -0
- package/dist/nodefony/service/ProfilerAdminApi.js +2 -1
- package/dist/nodefony/service/audit-logger.js +16 -13
- package/dist/nodefony/service/certificates.js +87 -144
- package/dist/nodefony/service/error-renderer.js +11 -8
- package/dist/nodefony/service/http-kernel.js +342 -165
- package/dist/nodefony/service/pretty-request-logger.js +3 -10
- package/dist/nodefony/service/servers/clientError.js +2 -2
- package/dist/nodefony/service/servers/server-http.js +23 -23
- package/dist/nodefony/service/servers/server-https.js +41 -42
- package/dist/nodefony/service/servers/server-static.js +13 -17
- package/dist/nodefony/service/servers/server-websocket-secure.js +11 -10
- package/dist/nodefony/service/servers/server-websocket.js +11 -10
- package/dist/nodefony/service/servers/wsHeartbeat.js +2 -2
- package/dist/nodefony/service/sessions/sessions-service.js +22 -15
- package/dist/nodefony/service/trace.js +3 -2
- package/dist/nodefony/service/upload/upload-service.js +11 -10
- package/dist/nodefony/service/x509.js +324 -0
- package/dist/nodefony/src/assets/prebuiltUi.js +1 -1
- package/dist/nodefony/src/context/Context.js +34 -19
- package/dist/nodefony/src/context/forwarded.js +4 -4
- package/dist/nodefony/src/context/http/HttpContext.js +133 -88
- package/dist/nodefony/src/context/http/Request.js +108 -46
- package/dist/nodefony/src/context/http/Response.js +134 -54
- package/dist/nodefony/src/context/http/parser.js +9 -10
- package/dist/nodefony/src/context/http/urlFastPath.js +35 -11
- package/dist/nodefony/src/context/http2/Response.js +53 -25
- package/dist/nodefony/src/context/metaData.js +1 -1
- package/dist/nodefony/src/context/trustProxy.js +4 -3
- package/dist/nodefony/src/context/websocket/Response.js +13 -6
- package/dist/nodefony/src/context/websocket/WebsocketContext.js +59 -26
- package/dist/nodefony/src/context/websocket/wsCloseReason.js +41 -0
- package/dist/nodefony/src/cookies/cookie.js +3 -3
- package/dist/nodefony/src/errors/httpError.js +6 -6
- package/dist/nodefony/src/errors/thrownMessage.js +27 -0
- package/dist/nodefony/src/profiler/FrameProfile.js +4 -3
- package/dist/nodefony/src/profiler/Profiler.js +4 -4
- package/dist/nodefony/src/servers/kernelServers.js +29 -0
- package/dist/nodefony/src/servers/portBinder.js +65 -23
- package/dist/nodefony/src/session/session.js +18 -10
- package/dist/nodefony/src/session/sessionStoreFailure.js +2 -1
- package/dist/nodefony/src/session/storage/RevocationGuardStorage.js +24 -9
- package/dist/types/index.d.ts +16 -0
- package/dist/types/nodefony/config/config.d.ts +23 -0
- package/dist/types/nodefony/interfaces/IContext.d.ts +24 -7
- package/dist/types/nodefony/interfaces/ICookie.d.ts +18 -18
- package/dist/types/nodefony/interfaces/IHttpKernel.d.ts +10 -4
- package/dist/types/nodefony/interfaces/IResponse.d.ts +1 -1
- package/dist/types/nodefony/interfaces/IRouting.d.ts +87 -0
- package/dist/types/nodefony/interfaces/ISecurity.d.ts +45 -0
- package/dist/types/nodefony/interfaces/ISession.d.ts +8 -8
- package/dist/types/nodefony/interfaces/IUpload.d.ts +9 -9
- package/dist/types/nodefony/interfaces/index.d.ts +2 -0
- package/dist/types/nodefony/service/audit-logger.d.ts +14 -10
- package/dist/types/nodefony/service/certificates.d.ts +42 -57
- package/dist/types/nodefony/service/http-kernel.d.ts +192 -42
- package/dist/types/nodefony/service/servers/server-http.d.ts +4 -1
- package/dist/types/nodefony/service/servers/server-https.d.ts +4 -1
- package/dist/types/nodefony/service/servers/server-websocket-secure.d.ts +4 -1
- package/dist/types/nodefony/service/servers/server-websocket.d.ts +4 -1
- package/dist/types/nodefony/service/sessions/sessions-service.d.ts +6 -2
- package/dist/types/nodefony/service/upload/upload-service.d.ts +1 -1
- package/dist/types/nodefony/service/x509.d.ts +86 -0
- package/dist/types/nodefony/src/context/Context.d.ts +21 -10
- package/dist/types/nodefony/src/context/forwarded.d.ts +3 -3
- package/dist/types/nodefony/src/context/http/HttpContext.d.ts +75 -18
- package/dist/types/nodefony/src/context/http/Request.d.ts +39 -2
- package/dist/types/nodefony/src/context/http/Response.d.ts +47 -7
- package/dist/types/nodefony/src/context/http/parser.d.ts +1 -1
- package/dist/types/nodefony/src/context/http2/Response.d.ts +32 -2
- package/dist/types/nodefony/src/context/websocket/Response.d.ts +4 -4
- package/dist/types/nodefony/src/context/websocket/WebsocketContext.d.ts +11 -2
- package/dist/types/nodefony/src/context/websocket/wsCloseReason.d.ts +21 -0
- package/dist/types/nodefony/src/cookies/cookie.d.ts +9 -9
- package/dist/types/nodefony/src/errors/httpError.d.ts +7 -7
- package/dist/types/nodefony/src/errors/thrownMessage.d.ts +12 -0
- package/dist/types/nodefony/src/profiler/Profiler.d.ts +28 -28
- package/dist/types/nodefony/src/servers/kernelServers.d.ts +20 -0
- package/dist/types/nodefony/src/servers/portBinder.d.ts +16 -65
- package/dist/types/nodefony/src/session/session.d.ts +12 -12
- package/dist/types/nodefony/src/session/storage/RevocationGuardStorage.d.ts +1 -1
- package/docs/cookies.md +25 -25
- package/docs/index.md +4 -2
- package/docs/observabilite.md +27 -27
- package/docs/rate-limit.md +20 -20
- package/docs/servers.md +82 -79
- package/docs/session.md +74 -69
- package/docs/upload.md +49 -43
- package/package.json +9 -12
|
@@ -1,18 +1,18 @@
|
|
|
1
|
-
import type pkg from "node-forge";
|
|
2
1
|
import { Service, Module } from "nodefony";
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
2
|
+
import { type KeyObject } from "node:crypto";
|
|
3
|
+
import { type ICertificateAttribute } from "./x509.js";
|
|
4
|
+
/** Paire de clés RSA du certificat auto-signé. */
|
|
5
|
+
export interface IRsaKeyPair {
|
|
6
|
+
privateKey: KeyObject;
|
|
7
|
+
publicKey: KeyObject;
|
|
8
|
+
}
|
|
9
9
|
/** Algorithmes de hachage de signature autorisés (SHA-1 banni). */
|
|
10
10
|
export type CertHash = "sha256" | "sha384" | "sha512";
|
|
11
11
|
/** Stratégie de fourniture du certificat exposée en configuration. */
|
|
12
12
|
export type CertStrategyConfig = "auto" | "mkcert" | "selfsigned" | "explicit";
|
|
13
13
|
/**
|
|
14
|
-
* Options de génération du certificat AUTO-SIGNÉ (node
|
|
15
|
-
*
|
|
14
|
+
* Options de génération du certificat AUTO-SIGNÉ (`node:crypto` — aucun
|
|
15
|
+
* binaire externe ni aucune dépendance tierce).
|
|
16
16
|
*
|
|
17
17
|
* ⚠️ Portée : ces réglages ne valent QUE pour la stratégie `selfsigned`. Sous
|
|
18
18
|
* `mkcert` (le défaut en développement) ils sont ignorés — mkcert ne reçoit que
|
|
@@ -29,7 +29,7 @@ export interface SelfSignedOptions {
|
|
|
29
29
|
/** Recul de `notBefore` (minutes) — tolérance au décalage d'horloge client. */
|
|
30
30
|
backdateMinutes: number;
|
|
31
31
|
/** Attributs du sujet/issuer (commonName, organizationName…). */
|
|
32
|
-
attrs:
|
|
32
|
+
attrs: ICertificateAttribute[];
|
|
33
33
|
}
|
|
34
34
|
/** Options de génération du certificat TLS en mode développement. */
|
|
35
35
|
export interface CertificateDevOptions {
|
|
@@ -37,7 +37,7 @@ export interface CertificateDevOptions {
|
|
|
37
37
|
* Préférer `mkcert` (CA locale ajoutée au trust store système) pour générer
|
|
38
38
|
* le certificat de dev. Donne un HTTPS sans erreur navigateur — indispensable
|
|
39
39
|
* pour les sous-ressources cross-origin (Vite) et le WSS du HMR.
|
|
40
|
-
* Si `mkcert` est absent, on retombe sur un auto-signé
|
|
40
|
+
* Si `mkcert` est absent, on retombe sur un auto-signé (non trusté).
|
|
41
41
|
* Ignoré hors `development`.
|
|
42
42
|
*/
|
|
43
43
|
useMkcert: boolean;
|
|
@@ -56,19 +56,19 @@ export interface CertificateOptions {
|
|
|
56
56
|
* est un confort de DÉVELOPPEMENT — en production, fournir un vrai certificat
|
|
57
57
|
* (Let's Encrypt, ingress, reverse-proxy) : Nodefony n'est pas une CA.
|
|
58
58
|
*/
|
|
59
|
-
strategy?: CertStrategyConfig;
|
|
59
|
+
strategy?: CertStrategyConfig | undefined;
|
|
60
60
|
selfSigned: SelfSignedOptions;
|
|
61
61
|
dev: CertificateDevOptions;
|
|
62
|
-
san?: CertificateSanOptions;
|
|
62
|
+
san?: CertificateSanOptions | undefined;
|
|
63
63
|
/** Permissions POSIX de la clé privée écrite (0600 = owner-only). */
|
|
64
|
-
privateKeyMode?: number;
|
|
65
|
-
path?: string;
|
|
66
|
-
keyPath?: string;
|
|
67
|
-
certPath?: string;
|
|
68
|
-
caPath?: string;
|
|
69
|
-
key?: string | Buffer;
|
|
70
|
-
cert?: string | Buffer;
|
|
71
|
-
ca?: string | Buffer;
|
|
64
|
+
privateKeyMode?: number | undefined;
|
|
65
|
+
path?: string | undefined;
|
|
66
|
+
keyPath?: string | undefined;
|
|
67
|
+
certPath?: string | undefined;
|
|
68
|
+
caPath?: string | undefined;
|
|
69
|
+
key?: string | Buffer | undefined;
|
|
70
|
+
cert?: string | Buffer | undefined;
|
|
71
|
+
ca?: string | Buffer | undefined;
|
|
72
72
|
}
|
|
73
73
|
interface filesCertType {
|
|
74
74
|
path: string;
|
|
@@ -96,7 +96,7 @@ export interface CertificateInfo {
|
|
|
96
96
|
*
|
|
97
97
|
* Trois stratégies : `explicit` (certificat fourni en config — le cas de
|
|
98
98
|
* PRODUCTION), `mkcert` (CA locale trustée, confort de dev) et `selfsigned`
|
|
99
|
-
* (auto-
|
|
99
|
+
* (auto-signé, secours). La génération est réservée au
|
|
100
100
|
* DÉVELOPPEMENT : en production sans certificat fourni, le service crie un
|
|
101
101
|
* avertissement (Nodefony n'est pas une autorité de certification).
|
|
102
102
|
*
|
|
@@ -108,8 +108,7 @@ export interface CertificateInfo {
|
|
|
108
108
|
declare class Certificate extends Service {
|
|
109
109
|
module: Module;
|
|
110
110
|
files: filesCertType[];
|
|
111
|
-
keysPair:
|
|
112
|
-
certForge: pkg.pki.Certificate | null;
|
|
111
|
+
keysPair: IRsaKeyPair | null;
|
|
113
112
|
ca: Buffer | string | null;
|
|
114
113
|
key: Buffer | string | null;
|
|
115
114
|
cert: Buffer | string | null;
|
|
@@ -119,13 +118,6 @@ declare class Certificate extends Service {
|
|
|
119
118
|
intermediateCertPem: Buffer | string | null;
|
|
120
119
|
/** CAROOT résolu de mkcert (null tant que non détecté / indisponible). */
|
|
121
120
|
private mkcertCaRoot;
|
|
122
|
-
/**
|
|
123
|
-
* Backend crypto node-forge, chargé PARESSEUSEMENT. La génération de
|
|
124
|
-
* certificat est un confort de DÉVELOPPEMENT : en production avec un
|
|
125
|
-
* certificat fourni (`strategy: "explicit"`), cette grosse dépendance n'est
|
|
126
|
-
* jamais importée (règle perf-mémoire — pas de dep chargée « au cas où »).
|
|
127
|
-
*/
|
|
128
|
-
private forge;
|
|
129
121
|
path: string;
|
|
130
122
|
serverPath: string;
|
|
131
123
|
caPath: string;
|
|
@@ -138,14 +130,6 @@ declare class Certificate extends Service {
|
|
|
138
130
|
private get certOptions();
|
|
139
131
|
/** Vrai en environnement de développement (mkcert réservé à ce mode). */
|
|
140
132
|
private isDev;
|
|
141
|
-
/**
|
|
142
|
-
* Charge node-forge à la demande (idempotent) — uniquement sur le chemin de
|
|
143
|
-
* GÉNÉRATION (selfsigned / mkcert / inspection). Le chemin `explicit` (prod)
|
|
144
|
-
* ne l'appelle jamais.
|
|
145
|
-
*/
|
|
146
|
-
loadForge(): Promise<ForgeModule>;
|
|
147
|
-
/** Accès au backend forge déjà chargé (lève si `loadForge` n'a pas été appelé). */
|
|
148
|
-
private get forgeLib();
|
|
149
133
|
/**
|
|
150
134
|
* Fabrique-t-on un certificat au démarrage ?
|
|
151
135
|
*
|
|
@@ -182,7 +166,7 @@ declare class Certificate extends Service {
|
|
|
182
166
|
/**
|
|
183
167
|
* Génère (ou recharge) le certificat serveur selon la stratégie résolue :
|
|
184
168
|
* `explicit` (fourni en config / prod), `mkcert` (dev, CA trustée) ou
|
|
185
|
-
* `selfsigned` (auto-
|
|
169
|
+
* `selfsigned` (auto-signé, secours). Régénère automatiquement si
|
|
186
170
|
* le certificat présent sur disque n'est pas adéquat pour la stratégie active
|
|
187
171
|
* (expiré, SHA-1, SAN incomplet).
|
|
188
172
|
*
|
|
@@ -195,7 +179,7 @@ declare class Certificate extends Service {
|
|
|
195
179
|
* erreur si absents.
|
|
196
180
|
* - `mkcert` : dev + binaire mkcert + CA locale présents. Forcé hors dev →
|
|
197
181
|
* retombe sur `selfsigned` avec avertissement.
|
|
198
|
-
* - `selfsigned` : auto-signé
|
|
182
|
+
* - `selfsigned` : auto-signé (fallback). En PRODUCTION, crie un
|
|
199
183
|
* avertissement : la génération n'est pas le rôle d'un serveur de prod.
|
|
200
184
|
*/
|
|
201
185
|
private resolveStrategy;
|
|
@@ -248,30 +232,31 @@ declare class Certificate extends Service {
|
|
|
248
232
|
* par mkcert passe aussi par ici). Échec silencieux hors POSIX.
|
|
249
233
|
*/
|
|
250
234
|
private restrictPrivateKey;
|
|
251
|
-
|
|
235
|
+
/** Génère la paire RSA (taille configurée) hors de la boucle d'événements. */
|
|
236
|
+
generateKeys(): Promise<IRsaKeyPair>;
|
|
237
|
+
/** Clé privée en PEM PKCS#1 (`BEGIN RSA PRIVATE KEY`). */
|
|
252
238
|
generatePrivateKeyPem(): Buffer;
|
|
239
|
+
/** Clé publique en PEM SPKI (`BEGIN PUBLIC KEY`). */
|
|
253
240
|
generatePublickeyPem(): Buffer;
|
|
254
|
-
generateCertPem(): Buffer;
|
|
255
|
-
createCertificate(): pkg.pki.Certificate;
|
|
256
|
-
/** subjectAltName de l'auto-signé : DNS + IP (config explicite sinon dérivé). */
|
|
257
|
-
private altNames;
|
|
258
|
-
setExtension(): void;
|
|
259
241
|
/**
|
|
260
|
-
*
|
|
261
|
-
*
|
|
262
|
-
*
|
|
263
|
-
*
|
|
242
|
+
* Fabrique et signe le certificat auto-signé avec la paire courante.
|
|
243
|
+
*
|
|
244
|
+
* Série aléatoire unique (RFC 5280 §4.1.2.2), `notBefore` reculé (décalage
|
|
245
|
+
* d'horloge du client), SAN DNS + IP (config explicite sinon dérivé), signé
|
|
246
|
+
* avec le hachage configuré — jamais SHA-1 (collision SHAttered 2017,
|
|
247
|
+
* CA/Browser Forum depuis 2016).
|
|
248
|
+
*
|
|
249
|
+
* @returns le certificat en PEM
|
|
250
|
+
* @throws Si la paire de clés n'a pas été générée
|
|
264
251
|
*/
|
|
265
|
-
|
|
252
|
+
createCertificate(): Promise<Buffer>;
|
|
266
253
|
/**
|
|
267
254
|
* Résumé introspectable du certificat serveur courant — réutilisé par la
|
|
268
255
|
* commande CLI `certificates` et un futur endpoint d'admin Studio (parité
|
|
269
|
-
* CLI ↔ Web).
|
|
256
|
+
* CLI ↔ Web).
|
|
270
257
|
*/
|
|
271
258
|
describe(): Promise<CertificateInfo>;
|
|
272
|
-
/**
|
|
273
|
-
private
|
|
274
|
-
/** Digest node-forge correspondant au hachage configuré (jamais SHA-1). */
|
|
275
|
-
private digestFor;
|
|
259
|
+
/** Hachage configuré, ramené à SHA-256 s'il sort du contrat (jamais SHA-1). */
|
|
260
|
+
private allowedHash;
|
|
276
261
|
}
|
|
277
262
|
export default Certificate;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Service, Module, Scope, EnvironmentType, DebugType, nodefonyError } from "nodefony";
|
|
2
|
-
import type {
|
|
3
|
-
import type {
|
|
2
|
+
import type { MaybePromise } from "nodefony";
|
|
3
|
+
import type { IRouteResolver, IRequestRouter } from "../interfaces/IRouting.js";
|
|
4
4
|
import HttpError from "../src/errors/httpError.js";
|
|
5
5
|
import { type TrustProxyChecker } from "../src/context/trustProxy.js";
|
|
6
6
|
import type { IRateLimitStore } from "../src/rateLimit/IRateLimitStore.js";
|
|
@@ -20,9 +20,11 @@ import Context, { HTTPMethod, WebSocketState } from "../src/context/Context.js";
|
|
|
20
20
|
import Certicates from "./certificates.js";
|
|
21
21
|
import SessionsService from "./sessions/sessions-service.js";
|
|
22
22
|
import Session from "../src/session/session.js";
|
|
23
|
-
import {
|
|
23
|
+
import type { IFirewallGate } from "../interfaces/ISecurity.js";
|
|
24
24
|
import type { IErrorRenderer } from "../interfaces/IErrorRenderer.js";
|
|
25
25
|
import type { IRequestLogger } from "../interfaces/IRequestLogger.js";
|
|
26
|
+
import type { DefaultOptionsService } from "nodefony";
|
|
27
|
+
import type { IHttpConfig } from "../config/config.js";
|
|
26
28
|
export type ProtocolType = "1.1" | "2.0" | "3.0";
|
|
27
29
|
export type httpRequest = http.IncomingMessage | http2.Http2ServerRequest;
|
|
28
30
|
export type httpResponse = http.ServerResponse | http2.Http2ServerResponse;
|
|
@@ -31,11 +33,11 @@ export type ServerType = "http" | "https" | "http2" | "http3" | "websocket" | "w
|
|
|
31
33
|
export type responseTimeoutType = "http" | "https" | "http2" | "http3";
|
|
32
34
|
export type SchemeType = "http" | "https" | "ws" | "wss";
|
|
33
35
|
export interface WsMetaData {
|
|
34
|
-
type?: "message" | "handshake";
|
|
35
|
-
state?: WebSocketState;
|
|
36
|
-
messageType?: "utf8" | "binary";
|
|
37
|
-
protocol?: string | null;
|
|
38
|
-
id?: string;
|
|
36
|
+
type?: "message" | "handshake" | undefined;
|
|
37
|
+
state?: WebSocketState | undefined;
|
|
38
|
+
messageType?: "utf8" | "binary" | undefined;
|
|
39
|
+
protocol?: string | null | undefined;
|
|
40
|
+
id?: string | undefined;
|
|
39
41
|
}
|
|
40
42
|
/**
|
|
41
43
|
* Vue minimale d'une route exposée dans l'enveloppe `nodefony.route` (frame WS
|
|
@@ -46,32 +48,33 @@ export interface WsMetaData {
|
|
|
46
48
|
*/
|
|
47
49
|
export interface RouteMetaData {
|
|
48
50
|
name: string;
|
|
49
|
-
path?: string;
|
|
51
|
+
path?: string | undefined;
|
|
50
52
|
variablesMap: Record<string, unknown>;
|
|
51
53
|
}
|
|
52
54
|
export interface MetaData {
|
|
53
|
-
name?: string;
|
|
54
|
-
version?: string;
|
|
55
|
-
url?: URL | string;
|
|
56
|
-
environment?: EnvironmentType;
|
|
57
|
-
debug?: DebugType;
|
|
58
|
-
token?: string;
|
|
59
|
-
method?: HTTPMethod;
|
|
60
|
-
scheme?: SchemeType;
|
|
61
|
-
requestId?: string;
|
|
62
|
-
websocket?: WsMetaData;
|
|
63
|
-
route?: RouteMetaData;
|
|
55
|
+
name?: string | undefined;
|
|
56
|
+
version?: string | undefined;
|
|
57
|
+
url?: URL | string | undefined;
|
|
58
|
+
environment?: EnvironmentType | undefined;
|
|
59
|
+
debug?: DebugType | undefined;
|
|
60
|
+
token?: string | undefined;
|
|
61
|
+
method?: HTTPMethod | undefined;
|
|
62
|
+
scheme?: SchemeType | undefined;
|
|
63
|
+
requestId?: string | undefined;
|
|
64
|
+
websocket?: WsMetaData | undefined;
|
|
65
|
+
route?: RouteMetaData | undefined;
|
|
64
66
|
}
|
|
65
67
|
export interface Data {
|
|
66
|
-
error?: Error;
|
|
68
|
+
error?: Error | undefined;
|
|
67
69
|
nodefony: MetaData;
|
|
68
70
|
message?: unknown;
|
|
69
|
-
code?: number;
|
|
71
|
+
code?: number | undefined;
|
|
70
72
|
result: unknown;
|
|
71
73
|
}
|
|
72
74
|
import type { IHttpKernel as IHttpKernelInterface } from "../interfaces/IHttpKernel.js";
|
|
73
75
|
declare class HttpKernel extends Service implements IHttpKernelInterface {
|
|
74
76
|
#private;
|
|
77
|
+
options: IHttpConfig & DefaultOptionsService;
|
|
75
78
|
certificates: unknown;
|
|
76
79
|
serviceCerticats: Certicates | null;
|
|
77
80
|
key: string;
|
|
@@ -79,12 +82,12 @@ declare class HttpKernel extends Service implements IHttpKernelInterface {
|
|
|
79
82
|
ca: string;
|
|
80
83
|
serverStatic: Statics | null;
|
|
81
84
|
domain: string;
|
|
82
|
-
trustedHosts?: ITrustedHostsConfig;
|
|
85
|
+
trustedHosts?: ITrustedHostsConfig | undefined;
|
|
83
86
|
domainCheck: boolean;
|
|
84
87
|
regAlias: RegExp[];
|
|
85
88
|
module: Module;
|
|
86
|
-
httpsPort?: number;
|
|
87
|
-
httpPort?: number;
|
|
89
|
+
httpsPort?: number | undefined;
|
|
90
|
+
httpPort?: number | undefined;
|
|
88
91
|
responseTimeout: {
|
|
89
92
|
http: number;
|
|
90
93
|
https: number;
|
|
@@ -98,9 +101,9 @@ declare class HttpKernel extends Service implements IHttpKernelInterface {
|
|
|
98
101
|
private secContentTypeOptions;
|
|
99
102
|
private secFrameOptions;
|
|
100
103
|
private secHsts;
|
|
101
|
-
sessionService?: SessionsService | null;
|
|
102
|
-
router?:
|
|
103
|
-
firewall?:
|
|
104
|
+
sessionService?: SessionsService | null | undefined;
|
|
105
|
+
router?: IRequestRouter | null | undefined;
|
|
106
|
+
firewall?: IFirewallGate | null | undefined;
|
|
104
107
|
private errorRenderer;
|
|
105
108
|
private requestLogger;
|
|
106
109
|
private profiler;
|
|
@@ -225,7 +228,17 @@ declare class HttpKernel extends Service implements IHttpKernelInterface {
|
|
|
225
228
|
* gagne toujours sur la config (idempotent — last setter wins).
|
|
226
229
|
*/
|
|
227
230
|
private applyRequestLoggerFromConfig;
|
|
228
|
-
|
|
231
|
+
/**
|
|
232
|
+
* Ouvre le scope `request` de la requête et la confie au pipeline HTTP.
|
|
233
|
+
*
|
|
234
|
+
* Pas `async` : rien n'y est attendu — la fonction rend directement ce que
|
|
235
|
+
* rend le pipeline, sans l'envelopper dans une promesse (#505).
|
|
236
|
+
*
|
|
237
|
+
* @returns le contexte servi, ou sa promesse (celle de {@link handleHttp}).
|
|
238
|
+
* @throws de façon synchrone si le scope `request` n'est pas déclaré — faute
|
|
239
|
+
* de configuration ; l'appelant ({@link onHttpRequest}) l'absorbe.
|
|
240
|
+
*/
|
|
241
|
+
handle(request: httpRequest, response: httpResponse | null, type: ServerType): MaybePromise<HttpContext>;
|
|
229
242
|
/**
|
|
230
243
|
* Arme le contexte pour l'exécution : zone firewall (`context.secure`) et
|
|
231
244
|
* résolveur de route — **sans instancier le controller**.
|
|
@@ -237,13 +250,16 @@ declare class HttpKernel extends Service implements IHttpKernelInterface {
|
|
|
237
250
|
* elle, exécute du code utilisateur (`initialize()`) et résout des dépendances
|
|
238
251
|
* DI : elle n'a rien à faire avant que la requête soit autorisée.
|
|
239
252
|
*
|
|
253
|
+
* Synchrone : le match est un calcul pur, rien n'y est attendu (#505).
|
|
254
|
+
*
|
|
240
255
|
* @param checkFirewall - calcule `context.secure` (zone protégée) ; laissé à
|
|
241
256
|
* `false` par un appelant qui l'a déjà tranché.
|
|
257
|
+
* @returns le résolveur de la route, posé sur `context.resolver`.
|
|
242
258
|
* @throws HttpError 404 quand aucune route ne matche, ou l'exception portée
|
|
243
|
-
* par le résolveur (405…) —
|
|
244
|
-
* route inexistante ne devient pas un 401.
|
|
259
|
+
* par le résolveur (405…) — de façon SYNCHRONE, et toujours avant le
|
|
260
|
+
* firewall : une route inexistante ne devient pas un 401.
|
|
245
261
|
*/
|
|
246
|
-
prepareFrontController(context: ContextType, checkFirewall?: boolean):
|
|
262
|
+
prepareFrontController(context: ContextType, checkFirewall?: boolean): IRouteResolver;
|
|
247
263
|
/**
|
|
248
264
|
* {@link prepareFrontController} + instanciation immédiate du controller
|
|
249
265
|
* (DI + hook `initialize()`).
|
|
@@ -254,7 +270,7 @@ declare class HttpKernel extends Service implements IHttpKernelInterface {
|
|
|
254
270
|
* est trop tard. Le HTTP, lui, arme la route ici et laisse
|
|
255
271
|
* `Resolver.executeAction` créer l'instance une fois la requête autorisée.
|
|
256
272
|
*/
|
|
257
|
-
handleFrontController(context: ContextType, checkFirewall?: boolean): Promise<
|
|
273
|
+
handleFrontController(context: ContextType, checkFirewall?: boolean): Promise<object>;
|
|
258
274
|
/**
|
|
259
275
|
* Handles errors by setting appropriate response codes and messages.
|
|
260
276
|
*
|
|
@@ -300,7 +316,29 @@ declare class HttpKernel extends Service implements IHttpKernelInterface {
|
|
|
300
316
|
getRequestLogger(): IRequestLogger;
|
|
301
317
|
onError(error: Error | HttpError | nodefonyError, context?: ContextType, _extraHeaders?: Record<string, unknown> | object): Promise<HttpContext | WebsocketContext>;
|
|
302
318
|
compileAlias(): RegExp[];
|
|
303
|
-
|
|
319
|
+
/**
|
|
320
|
+
* Point d'entrée d'une requête HTTP, appelé par les serveurs depuis leur
|
|
321
|
+
* écouteur `request`.
|
|
322
|
+
*
|
|
323
|
+
* Ne lève et ne rejette JAMAIS : dans un écouteur d'événement, une exception
|
|
324
|
+
* deviendrait une erreur non capturée du processus. Ce qui échappe au
|
|
325
|
+
* pipeline a déjà été traité — rendu au client par `onError`, qui journalise
|
|
326
|
+
* en CRITIC l'échec de son propre rendu avant de le relever. C'était le
|
|
327
|
+
* `.catch` vide des serveurs ; il vit désormais ici, une seule fois.
|
|
328
|
+
*
|
|
329
|
+
* @returns `undefined` quand la requête est servie sans pipeline (sonde de
|
|
330
|
+
* santé, 429) ; sinon la promesse de la fin du pipeline — elle ne rejette
|
|
331
|
+
* pas, et personne n'est tenu de l'attendre.
|
|
332
|
+
*/
|
|
333
|
+
onHttpRequest(request: httpRequest, response: httpResponse, type: ServerType): Promise<void> | undefined;
|
|
334
|
+
/**
|
|
335
|
+
* Le travail d'{@link onHttpRequest} : en-têtes de transport, sondes de
|
|
336
|
+
* santé, rate-limit, hook `onServerRequest`, puis le pipeline.
|
|
337
|
+
*
|
|
338
|
+
* @returns `undefined` quand la requête est servie ici ; sinon la promesse du
|
|
339
|
+
* pipeline.
|
|
340
|
+
*/
|
|
341
|
+
private dispatchHttpRequest;
|
|
304
342
|
initServers(): Promise<(httpServer | httpsServer | websocketServer | websocketSecureServer)[]>;
|
|
305
343
|
/**
|
|
306
344
|
* Publie les ports EFFECTIFS du runtime (state file), une fois l'écoute établie.
|
|
@@ -342,24 +380,136 @@ declare class HttpKernel extends Service implements IHttpKernelInterface {
|
|
|
342
380
|
* session (lazy). Remplace l'ancien `sessionAutoStart` global « démarre sur
|
|
343
381
|
* toutes les routes » (le moteur du ×23).
|
|
344
382
|
*
|
|
383
|
+
* Le contrat de retour suit ce qui est réellement attendu : `null` tout de
|
|
384
|
+
* suite quand aucune session n'est à ouvrir (le cas nominal — ni intent, ni
|
|
385
|
+
* cookie), la promesse de la session seulement quand le store est interrogé
|
|
386
|
+
* (#505).
|
|
387
|
+
*
|
|
345
388
|
* @param context - contexte HTTP/HTTP2/WS courant.
|
|
346
|
-
* @returns
|
|
389
|
+
* @returns `null` si la requête n'en requiert aucune ; sinon la promesse de
|
|
390
|
+
* la session active.
|
|
347
391
|
*/
|
|
348
|
-
startSession(context: WebsocketContext | HttpContext):
|
|
392
|
+
startSession(context: WebsocketContext | HttpContext): MaybePromise<Session | null>;
|
|
349
393
|
/**
|
|
350
|
-
* Teardown post-réponse — fire-and-forget depuis
|
|
351
|
-
* `createHttpContext
|
|
352
|
-
*
|
|
394
|
+
* Teardown post-réponse — fire-and-forget depuis l'écouteur `close` posé par
|
|
395
|
+
* `createHttpContext`. Loggue la requête, draine les hooks
|
|
396
|
+
* afterResponse/onFinish, libère le scope DI.
|
|
397
|
+
*
|
|
398
|
+
* Synchrone dans le cas nominal — aucun hook `onAfterResponse`, aucun écouteur
|
|
399
|
+
* `onFinish` : rien n'y est attendu (#505). Ne lève et ne rejette jamais —
|
|
400
|
+
* l'appelant est un écouteur d'événement : une faute est journalisée, et le
|
|
401
|
+
* scope TOUJOURS libéré.
|
|
402
|
+
*
|
|
403
|
+
* @returns `undefined` quand le démontage est terminé ; sinon la promesse de
|
|
404
|
+
* sa fin, qui ne rejette pas.
|
|
353
405
|
*/
|
|
354
406
|
private teardownHttp;
|
|
407
|
+
/**
|
|
408
|
+
* Suite ASYNCHRONE du démontage, quand il y a des hooks à attendre :
|
|
409
|
+
* `onAfterResponse` puis `onFinish`, avant de libérer le contexte. Ne rejette
|
|
410
|
+
* jamais (cf {@link teardownHttp}).
|
|
411
|
+
*/
|
|
412
|
+
private finishTeardownHttp;
|
|
413
|
+
/** Fin d'un contexte HTTP : marqué fini, scope DI libéré, contexte nettoyé. */
|
|
414
|
+
private releaseHttpContext;
|
|
415
|
+
/**
|
|
416
|
+
* R2 — le démontage est fire-and-forget : un throw (hook onFinish /
|
|
417
|
+
* afterResponse) serait une erreur non capturée du processus. On journalise,
|
|
418
|
+
* et on GARANTIT la libération du scope DI (sinon le scope `request` fuit à
|
|
419
|
+
* chaque hook qui lève).
|
|
420
|
+
*/
|
|
421
|
+
private failTeardownHttp;
|
|
355
422
|
createHttpContext(scope: Scope, request: httpRequest, response: httpResponse, type: ServerType): HttpContext;
|
|
356
|
-
|
|
357
|
-
|
|
423
|
+
/**
|
|
424
|
+
* Crée le contexte HTTP de la requête et la sert dans sa bulle ALS ; toute
|
|
425
|
+
* erreur — synchrone ou rejet — passe par {@link onError}.
|
|
426
|
+
*
|
|
427
|
+
* Pas `async` : un GET servi par une action synchrone traverse le pipeline
|
|
428
|
+
* sans une seule promesse (#505). Une promesse seulement quand une étape
|
|
429
|
+
* attend, ou quand l'erreur est rendue (`onError`).
|
|
430
|
+
*
|
|
431
|
+
* @returns le contexte servi, ou sa promesse.
|
|
432
|
+
*/
|
|
433
|
+
handleHttp(scope: Scope, request: httpRequest, response: httpResponse, type: ServerType): MaybePromise<HttpContext>;
|
|
434
|
+
/**
|
|
435
|
+
* Traceparent, tampon du profileur, puis le pipeline dans la bulle ALS de la
|
|
436
|
+
* requête (`RequestContext.run`).
|
|
437
|
+
*/
|
|
438
|
+
private serveHttpContext;
|
|
439
|
+
/**
|
|
440
|
+
* Chemin d'erreur de {@link handleHttp} : libère le scope d'un contexte qui
|
|
441
|
+
* n'a pas pu se construire, puis rend l'erreur au client (`onError`).
|
|
442
|
+
*/
|
|
443
|
+
private failHttp;
|
|
444
|
+
/**
|
|
445
|
+
* Le trajet d'une requête HTTP DANS la bulle ALS : CORS, calque de
|
|
446
|
+
* configuration, route, en-têtes de sécurité, repli statique, corps, gardes,
|
|
447
|
+
* action.
|
|
448
|
+
*
|
|
449
|
+
* Chaque étape rend sa valeur, ou une promesse quand elle attend réellement
|
|
450
|
+
* (préflight à terminer, hook asynchrone, fichier statique, corps à lire,
|
|
451
|
+
* session, pare-feu, action asynchrone) — et la suite ne s'enchaîne par
|
|
452
|
+
* `then` que dans ce cas. Un `await` sur une valeur déjà connue suspendait le
|
|
453
|
+
* pipeline pour rien : ~50 évènements asynchrones par GET (#505).
|
|
454
|
+
*
|
|
455
|
+
* @returns le contexte servi, ou la promesse de ce contexte.
|
|
456
|
+
* @throws l'erreur d'une étape synchrone — {@link handleHttp} la traite comme
|
|
457
|
+
* un rejet (même `catch`, même `onError`).
|
|
458
|
+
*/
|
|
459
|
+
private runHttpPipeline;
|
|
460
|
+
/**
|
|
461
|
+
* Route, en-têtes de sécurité applicatifs, repli statique — puis le corps.
|
|
462
|
+
* N'attend que le repli statique, et seulement quand aucune route ne matche.
|
|
463
|
+
*/
|
|
464
|
+
private routeHttpRequest;
|
|
465
|
+
/**
|
|
466
|
+
* Le corps — lu seulement s'il y en a un à lire —, puis les gardes
|
|
467
|
+
* ({@link onRequestEnd}) et l'action. Chacun n'est attendu que s'il attend.
|
|
468
|
+
*/
|
|
469
|
+
private serveHttpRequest;
|
|
470
|
+
/**
|
|
471
|
+
* Les gardes d'une requête HTTP, corps lu : en-têtes de scheme, domaine, hook
|
|
472
|
+
* `beforeResolve`, armement de la route, CSRF, session, pare-feu — dans cet
|
|
473
|
+
* ordre.
|
|
474
|
+
*
|
|
475
|
+
* Synchrone tant qu'aucune garde n'attend (#505) : le hook `beforeResolve`
|
|
476
|
+
* n'est attendu que s'il a un écouteur, la session que si la requête en
|
|
477
|
+
* ouvre une, le pare-feu que sur une zone protégée ou à accès contrôlé.
|
|
478
|
+
*
|
|
479
|
+
* @param context - le contexte de la requête.
|
|
480
|
+
* @param error - une erreur survenue en amont : relevée telle quelle.
|
|
481
|
+
* @returns le contexte une fois les gardes passées, ou la promesse de ce
|
|
482
|
+
* contexte quand une garde attend.
|
|
483
|
+
* @throws de façon SYNCHRONE l'erreur reçue, l'exception du résolveur (404,
|
|
484
|
+
* 405…) et le refus CSRF ; un refus du pare-feu ou de session rompt la
|
|
485
|
+
* promesse rendue.
|
|
486
|
+
*/
|
|
487
|
+
onRequestEnd(context: HttpContext, error?: Error | null): MaybePromise<HttpContext>;
|
|
488
|
+
/**
|
|
489
|
+
* Suite d'{@link onRequestEnd} : armement de la route, CSRF, session, puis
|
|
490
|
+
* pare-feu. Synchrone tant que ni la session ni le pare-feu n'attendent.
|
|
491
|
+
*/
|
|
492
|
+
private armAndGuard;
|
|
493
|
+
/**
|
|
494
|
+
* Le pare-feu d'une requête en zone protégée : `handleSecurity`, puis les
|
|
495
|
+
* hooks `afterAuth` (succès) ou `onAuthFailure` (refus, relevé ensuite).
|
|
496
|
+
*
|
|
497
|
+
* @returns la promesse du contexte autorisé.
|
|
498
|
+
* @throws (rejet) le refus du pare-feu, après `onAuthFailure`.
|
|
499
|
+
*/
|
|
500
|
+
private runFirewall;
|
|
358
501
|
createWebsocketContext(scope: Scope, req: IncomingMessage, ws: Ws, type: ServerType): WebsocketContext;
|
|
502
|
+
/**
|
|
503
|
+
* Teardown d'une connexion WS à sa fermeture : signal d'abandon, hooks
|
|
504
|
+
* post-réponse, persistance de la session, puis libération du scope.
|
|
505
|
+
* Ne rejette jamais : toute erreur est journalisée (l'appelant est un
|
|
506
|
+
* écouteur d'événement synchrone, qui n'attend rien).
|
|
507
|
+
*/
|
|
508
|
+
private finishWebsocket;
|
|
359
509
|
onWebsocketRequest(ws: Ws, req: IncomingMessage, type: ServerType): Promise<unknown>;
|
|
360
510
|
handleWebsocket(scope: Scope, ws: Ws, req: IncomingMessage, type: ServerType): Promise<unknown>;
|
|
361
511
|
private releaseOrphanWsScope;
|
|
362
|
-
onConnect(context: WebsocketContext, error?:
|
|
512
|
+
onConnect(context: WebsocketContext | null, error?: unknown): Promise<Ws | number>;
|
|
363
513
|
checkValidDomain(context: ContextType): number;
|
|
364
514
|
isValidDomain(context: ContextType): boolean;
|
|
365
515
|
/**
|
|
@@ -4,8 +4,11 @@ import http from "node:http";
|
|
|
4
4
|
import http2 from "node:http2";
|
|
5
5
|
import { AddressInfo } from "node:net";
|
|
6
6
|
import { HttpTerminator } from "./serverShutdown.js";
|
|
7
|
+
import type { IHttpConfig } from "../../config/config.js";
|
|
8
|
+
import type { DefaultOptionsService } from "nodefony";
|
|
7
9
|
declare class ServerHttp extends Service {
|
|
8
|
-
private httpKernel;
|
|
10
|
+
private readonly httpKernel;
|
|
11
|
+
options: IHttpConfig["http"] & DefaultOptionsService;
|
|
9
12
|
module: Module;
|
|
10
13
|
server: http.Server | http2.Http2Server | null;
|
|
11
14
|
httpTerminator: HttpTerminator | null;
|
|
@@ -4,8 +4,11 @@ import https from "node:https";
|
|
|
4
4
|
import http2 from "node:http2";
|
|
5
5
|
import { HttpTerminator } from "./serverShutdown.js";
|
|
6
6
|
import { AddressInfo } from "node:net";
|
|
7
|
+
import type { IHttpConfig } from "../../config/config.js";
|
|
8
|
+
import type { DefaultOptionsService } from "nodefony";
|
|
7
9
|
declare class ServerHttps extends Service {
|
|
8
|
-
private httpKernel;
|
|
10
|
+
private readonly httpKernel;
|
|
11
|
+
options: IHttpConfig["https"] & DefaultOptionsService;
|
|
9
12
|
httpTerminator: HttpTerminator | null;
|
|
10
13
|
module: Module;
|
|
11
14
|
server: https.Server | http2.Http2SecureServer | null;
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import Ws, { WebSocketServer } from "ws";
|
|
2
2
|
import { Service, Module, FamilyType } from "nodefony";
|
|
3
|
+
import type { DefaultOptionsService } from "nodefony";
|
|
4
|
+
import type { IHttpConfig } from "../../config/config.js";
|
|
3
5
|
import HttpKernel, { ProtocolType, ServerType, SchemeType } from "../http-kernel.js";
|
|
4
6
|
import { AddressInfo } from "node:net";
|
|
5
7
|
import type { IncomingMessage } from "node:http";
|
|
6
8
|
import httpsServers from "./server-https.js";
|
|
7
9
|
declare class WebsocketSecure extends Service {
|
|
8
|
-
private httpKernel;
|
|
10
|
+
private readonly httpKernel;
|
|
11
|
+
options: IHttpConfig["websocketSecure"] & DefaultOptionsService;
|
|
9
12
|
module: Module;
|
|
10
13
|
ready: boolean;
|
|
11
14
|
server: WebSocketServer | null;
|
|
@@ -1,11 +1,14 @@
|
|
|
1
1
|
import Ws, { WebSocketServer } from "ws";
|
|
2
2
|
import { Service, Module, FamilyType } from "nodefony";
|
|
3
|
+
import type { DefaultOptionsService } from "nodefony";
|
|
4
|
+
import type { IHttpConfig } from "../../config/config.js";
|
|
3
5
|
import HttpKernel, { ProtocolType, ServerType, SchemeType } from "../http-kernel.js";
|
|
4
6
|
import { AddressInfo } from "node:net";
|
|
5
7
|
import type { IncomingMessage } from "node:http";
|
|
6
8
|
import httpServer from "./server-http.js";
|
|
7
9
|
declare class Websocket extends Service {
|
|
8
|
-
private httpKernel;
|
|
10
|
+
private readonly httpKernel;
|
|
11
|
+
options: IHttpConfig["websocket"] & DefaultOptionsService;
|
|
9
12
|
module: Module;
|
|
10
13
|
ready: boolean;
|
|
11
14
|
server: WebSocketServer | null;
|
|
@@ -3,6 +3,8 @@ import type { IPage } from "nodefony";
|
|
|
3
3
|
import type { ISessionStorage, ISessionSummary, ISessionRecord, ISessionListQuery } from "../../interfaces/ISession.js";
|
|
4
4
|
import HttpKernel, { ContextType } from "../http-kernel.js";
|
|
5
5
|
import Session, { OptionsSessionType } from "../../src/session/session.js";
|
|
6
|
+
import type { IHttpConfig } from "../../config/config.js";
|
|
7
|
+
import type { DefaultOptionsService } from "nodefony";
|
|
6
8
|
import Certificate from "../../service/certificates.js";
|
|
7
9
|
import type { ISessionCounts } from "../../src/session/storage/sessionFilters.js";
|
|
8
10
|
export type sessionStrategyType = "none" | "migrate" | "invalidate";
|
|
@@ -25,6 +27,7 @@ export declare function computeSessionRef(secret: Buffer, id: string): string;
|
|
|
25
27
|
* testée isolément).
|
|
26
28
|
*/
|
|
27
29
|
export declare function toSessionSummary(rec: ISessionRecord, ref: string, currentRef?: string | null): ISessionSummary;
|
|
30
|
+
export type ISessionServiceOptions = IHttpConfig["session"] & DefaultOptionsService;
|
|
28
31
|
declare class SessionsService extends Service {
|
|
29
32
|
httpKernel: HttpKernel;
|
|
30
33
|
/**
|
|
@@ -48,12 +51,13 @@ declare class SessionsService extends Service {
|
|
|
48
51
|
static getStorage(name: string): SessionStorageCtor | undefined;
|
|
49
52
|
/** Noms des handlers de session enregistrés. */
|
|
50
53
|
static storageHandlers(): string[];
|
|
54
|
+
options: ISessionServiceOptions;
|
|
51
55
|
sessionStrategy: sessionStrategyType;
|
|
52
56
|
storage: ISessionStorage | null;
|
|
53
57
|
module: Module;
|
|
54
58
|
defaultSessionName: string;
|
|
55
|
-
secret?: Buffer;
|
|
56
|
-
iv?: Buffer;
|
|
59
|
+
secret?: Buffer | undefined;
|
|
60
|
+
iv?: Buffer | undefined;
|
|
57
61
|
certificates: Certificate | null;
|
|
58
62
|
private gcScheduler;
|
|
59
63
|
constructor(module: Module, httpKernel: HttpKernel);
|
|
@@ -4,7 +4,7 @@ import fs from "node:fs";
|
|
|
4
4
|
import type { IParsedUploadFile } from "../../interfaces/IUpload.js";
|
|
5
5
|
export declare class upload extends Service {
|
|
6
6
|
httpKernel: HttpKernel;
|
|
7
|
-
path?: string | fs.PathLike;
|
|
7
|
+
path?: string | fs.PathLike | undefined;
|
|
8
8
|
module: Module;
|
|
9
9
|
constructor(module: Module, httpKernel: HttpKernel);
|
|
10
10
|
/**
|