@nodefony/http 10.0.0-beta.2 → 10.0.0-beta.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/dist/_virtual/{_@oxc-project_runtime@0.152.0 → _@oxc-project_runtime@0.155.0}/helpers/esm/decorate.js +1 -2
- package/dist/_virtual/{_@oxc-project_runtime@0.152.0 → _@oxc-project_runtime@0.155.0}/helpers/esm/decorateParam.js +1 -2
- package/dist/index.js +19 -11
- package/dist/nodefony/command/assetsPublishCommand.js +5 -3
- package/dist/nodefony/command/certificatesCommand.js +5 -3
- package/dist/nodefony/command/networkCommand.js +5 -3
- package/dist/nodefony/command/proxyGenerateCommand.js +8 -3
- package/dist/nodefony/config/config.js +45 -6
- package/dist/nodefony/config/defineModuleConfig.js +2 -3
- package/dist/nodefony/interfaces/IReverseProxy.js +1 -0
- package/dist/nodefony/service/HttpAdminApi.js +2 -3
- package/dist/nodefony/service/ProfilerAdminApi.js +1 -2
- package/dist/nodefony/service/audit-logger.js +22 -16
- package/dist/nodefony/service/certificates.js +228 -19
- package/dist/nodefony/service/error-renderer.js +30 -13
- package/dist/nodefony/service/http-kernel.js +331 -82
- package/dist/nodefony/service/pretty-request-logger.js +5 -4
- package/dist/nodefony/service/request-logger.js +24 -16
- package/dist/nodefony/service/reverse-proxy.js +336 -0
- package/dist/nodefony/service/servers/clientError.js +22 -3
- package/dist/nodefony/service/servers/server-h2c.js +126 -0
- package/dist/nodefony/service/servers/server-http.js +5 -8
- package/dist/nodefony/service/servers/server-https.js +12 -24
- package/dist/nodefony/service/servers/server-static.js +7 -10
- package/dist/nodefony/service/servers/server-websocket-secure.js +18 -18
- package/dist/nodefony/service/servers/server-websocket.js +18 -18
- package/dist/nodefony/service/servers/serverShutdown.js +78 -18
- package/dist/nodefony/service/servers/wsHeartbeat.js +32 -17
- package/dist/nodefony/service/sessions/sessions-service.js +34 -20
- package/dist/nodefony/service/trace.js +1 -2
- package/dist/nodefony/service/upload/upload-service.js +5 -8
- package/dist/nodefony/service/x509.js +1 -2
- package/dist/nodefony/src/assets/collectAssets.js +1 -2
- package/dist/nodefony/src/assets/prebuiltUi.js +1 -2
- package/dist/nodefony/src/context/Context.js +51 -32
- package/dist/nodefony/src/context/domainMatcher.js +21 -4
- package/dist/nodefony/src/context/forwarded.js +3 -4
- package/dist/nodefony/src/context/http/HttpContext.js +98 -46
- package/dist/nodefony/src/context/http/Request.js +34 -38
- package/dist/nodefony/src/context/http/Response.js +39 -7
- package/dist/nodefony/src/context/http/SseStream.js +349 -0
- package/dist/nodefony/src/context/http/parser.js +36 -10
- package/dist/nodefony/src/context/http/urlFastPath.js +1 -2
- package/dist/nodefony/src/context/http2/Request.js +4 -8
- package/dist/nodefony/src/context/http2/Response.js +22 -9
- package/dist/nodefony/src/context/metaData.js +1 -2
- package/dist/nodefony/src/context/requestId.js +1 -2
- package/dist/nodefony/src/context/responseEnded.js +26 -0
- package/dist/nodefony/src/context/transport.js +45 -0
- package/dist/nodefony/src/context/trustProxy.js +1 -2
- package/dist/nodefony/src/context/websocket/Response.js +42 -6
- package/dist/nodefony/src/context/websocket/WebsocketContext.js +94 -20
- package/dist/nodefony/src/context/websocket/isWebsocketContext.js +17 -0
- package/dist/nodefony/src/context/websocket/websocketUrl.js +20 -0
- package/dist/nodefony/src/context/websocket/wsBackpressure.js +1 -2
- package/dist/nodefony/src/context/websocket/wsCloseReason.js +1 -2
- package/dist/nodefony/src/context/websocket/wsLogContent.js +1 -2
- package/dist/nodefony/src/cookies/cookie.js +3 -7
- package/dist/nodefony/src/errors/httpError.js +1 -2
- package/dist/nodefony/src/errors/thrownMessage.js +1 -2
- package/dist/nodefony/src/profiler/FrameProfile.js +1 -2
- package/dist/nodefony/src/profiler/Profiler.js +108 -30
- package/dist/nodefony/src/profiler/aggregate.js +422 -0
- package/dist/nodefony/src/proxy/forward.js +500 -0
- package/dist/nodefony/src/proxy/generateProxyConfig.js +14 -6
- package/dist/nodefony/src/proxy/rules.js +188 -0
- package/dist/nodefony/src/rateLimit/MemoryRateLimitStore.js +1 -2
- package/dist/nodefony/src/rateLimit/WsConnectionCounter.js +1 -2
- package/dist/nodefony/src/rateLimit/rateLimitFilters.js +1 -2
- package/dist/nodefony/src/servers/http2Limits.js +50 -0
- package/dist/nodefony/src/servers/kernelServers.js +12 -3
- package/dist/nodefony/src/servers/portBinder.js +41 -10
- package/dist/nodefony/src/servers/upgradeDispatch.js +128 -0
- package/dist/nodefony/src/session/session.js +30 -15
- package/dist/nodefony/src/session/sessionStoreFailure.js +1 -2
- package/dist/nodefony/src/session/storage/MemorySessionStorage.js +1 -2
- package/dist/nodefony/src/session/storage/RevocationGuardStorage.js +1 -2
- package/dist/nodefony/src/session/storage/sessionFilters.js +1 -2
- package/dist/nodefony/src/session/storage/sessionSort.js +1 -2
- package/dist/types/index.d.ts +12 -3
- package/dist/types/nodefony/config/config.d.ts +16 -0
- package/dist/types/nodefony/interfaces/IContext.d.ts +65 -4
- package/dist/types/nodefony/interfaces/IErrorRenderer.d.ts +1 -1
- package/dist/types/nodefony/interfaces/IRequest.d.ts +9 -4
- package/dist/types/nodefony/interfaces/IReverseProxy.d.ts +67 -0
- package/dist/types/nodefony/interfaces/IRouting.d.ts +26 -0
- package/dist/types/nodefony/interfaces/ISecurity.d.ts +6 -0
- package/dist/types/nodefony/interfaces/index.d.ts +3 -2
- package/dist/types/nodefony/service/audit-logger.d.ts +2 -1
- package/dist/types/nodefony/service/certificates.d.ts +147 -5
- package/dist/types/nodefony/service/error-renderer.d.ts +32 -1
- package/dist/types/nodefony/service/http-kernel.d.ts +157 -15
- package/dist/types/nodefony/service/reverse-proxy.d.ts +156 -0
- package/dist/types/nodefony/service/servers/clientError.d.ts +16 -0
- package/dist/types/nodefony/service/servers/server-h2c.d.ts +51 -0
- package/dist/types/nodefony/service/servers/server-http.d.ts +3 -3
- package/dist/types/nodefony/service/servers/server-https.d.ts +4 -4
- package/dist/types/nodefony/service/servers/server-websocket-secure.d.ts +2 -3
- package/dist/types/nodefony/service/servers/server-websocket.d.ts +2 -3
- package/dist/types/nodefony/service/servers/serverShutdown.d.ts +30 -16
- package/dist/types/nodefony/service/servers/wsHeartbeat.d.ts +26 -0
- package/dist/types/nodefony/service/sessions/sessions-service.d.ts +19 -1
- package/dist/types/nodefony/src/context/Context.d.ts +35 -6
- package/dist/types/nodefony/src/context/domainMatcher.d.ts +11 -1
- package/dist/types/nodefony/src/context/http/HttpContext.d.ts +48 -1
- package/dist/types/nodefony/src/context/http/Request.d.ts +20 -15
- package/dist/types/nodefony/src/context/http/Response.d.ts +14 -0
- package/dist/types/nodefony/src/context/http/SseStream.d.ts +155 -0
- package/dist/types/nodefony/src/context/http/parser.d.ts +18 -2
- package/dist/types/nodefony/src/context/http2/Request.d.ts +1 -1
- package/dist/types/nodefony/src/context/http2/Response.d.ts +15 -5
- package/dist/types/nodefony/src/context/responseEnded.d.ts +20 -0
- package/dist/types/nodefony/src/context/transport.d.ts +53 -0
- package/dist/types/nodefony/src/context/websocket/Response.d.ts +18 -2
- package/dist/types/nodefony/src/context/websocket/WebsocketContext.d.ts +57 -7
- package/dist/types/nodefony/src/context/websocket/isWebsocketContext.d.ts +15 -0
- package/dist/types/nodefony/src/context/websocket/websocketUrl.d.ts +16 -0
- package/dist/types/nodefony/src/profiler/FrameProfile.d.ts +13 -12
- package/dist/types/nodefony/src/profiler/Profiler.d.ts +69 -15
- package/dist/types/nodefony/src/profiler/aggregate.d.ts +215 -0
- package/dist/types/nodefony/src/proxy/forward.d.ts +168 -0
- package/dist/types/nodefony/src/proxy/generateProxyConfig.d.ts +16 -0
- package/dist/types/nodefony/src/proxy/rules.d.ts +88 -0
- package/dist/types/nodefony/src/servers/http2Limits.d.ts +37 -0
- package/dist/types/nodefony/src/servers/kernelServers.d.ts +10 -1
- package/dist/types/nodefony/src/servers/portBinder.d.ts +29 -5
- package/dist/types/nodefony/src/servers/upgradeDispatch.d.ts +69 -0
- package/dist/types/nodefony/src/session/session.d.ts +2 -0
- package/docs/cookies.md +85 -78
- package/docs/index.md +5 -1
- package/docs/observabilite.md +81 -81
- package/docs/rate-limit.md +83 -83
- package/docs/reverse-proxy.md +522 -0
- package/docs/servers.md +378 -230
- package/docs/session.md +180 -180
- package/docs/sse.md +287 -0
- package/docs/upload.md +120 -117
- package/package.json +10 -11
- package/dist/_virtual/_@oxc-project_runtime@0.152.0/helpers/esm/decorateMetadata.js +0 -6
|
@@ -1,16 +1,14 @@
|
|
|
1
1
|
import { asServersConfig, configuredServerPort } from "../../src/servers/kernelServers.js";
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import http_kernel_default from "../http-kernel.js";
|
|
5
|
-
import { handleClientError } from "./clientError.js";
|
|
2
|
+
import __decorate from "../../../_virtual/_@oxc-project_runtime@0.155.0/helpers/esm/decorate.js";
|
|
3
|
+
import { handleClientError, handleSessionError } from "./clientError.js";
|
|
6
4
|
import { createDrainTerminator } from "./serverShutdown.js";
|
|
7
5
|
import { bindWithFallback, buildBindPlan } from "../../src/servers/portBinder.js";
|
|
8
|
-
import __decorateParam from "../../../_virtual/_@oxc-project_runtime@0.
|
|
9
|
-
import {
|
|
6
|
+
import __decorateParam from "../../../_virtual/_@oxc-project_runtime@0.155.0/helpers/esm/decorateParam.js";
|
|
7
|
+
import { http2ServerLimits, setHttp2SessionTimeout } from "../../src/servers/http2Limits.js";
|
|
8
|
+
import { Inject, Service, extend, nodefonyError } from "nodefony";
|
|
10
9
|
import http2 from "node:http2";
|
|
11
10
|
import https from "node:https";
|
|
12
|
-
|
|
13
|
-
//#region nodefony/service/servers/server-https.ts
|
|
11
|
+
// nodefony/service/servers/server-https.ts
|
|
14
12
|
let ServerHttps = class ServerHttps extends Service {
|
|
15
13
|
httpKernel;
|
|
16
14
|
httpTerminator = null;
|
|
@@ -98,7 +96,6 @@ let ServerHttps = class ServerHttps extends Service {
|
|
|
98
96
|
createServerH2() {
|
|
99
97
|
return new Promise((resolve, reject) => {
|
|
100
98
|
try {
|
|
101
|
-
const h2Cfg = this.module.options.http2 ?? {};
|
|
102
99
|
const opt = extend({
|
|
103
100
|
allowHTTP1: true,
|
|
104
101
|
rejectUnauthorized: this.options.rejectUnauthorized,
|
|
@@ -106,23 +103,14 @@ let ServerHttps = class ServerHttps extends Service {
|
|
|
106
103
|
cert: this.httpKernel.serviceCerticats?.cert,
|
|
107
104
|
ca: this.httpKernel.serviceCerticats?.ca ? this.httpKernel.serviceCerticats.ca : void 0
|
|
108
105
|
});
|
|
109
|
-
|
|
110
|
-
if (h2Cfg.maxConcurrentStreams) opt.settings = {
|
|
111
|
-
...opt.settings,
|
|
112
|
-
maxConcurrentStreams: h2Cfg.maxConcurrentStreams
|
|
113
|
-
};
|
|
106
|
+
Object.assign(opt, http2ServerLimits(this.module.options.http2));
|
|
114
107
|
this.server = http2.createSecureServer(opt);
|
|
115
108
|
this.httpTerminator = this.terminator();
|
|
116
|
-
|
|
109
|
+
setHttp2SessionTimeout(this.server, this.options.timeout, () => {
|
|
117
110
|
this.fire("onTimeout", this);
|
|
118
111
|
});
|
|
119
112
|
this.server.on("request", (request, response) => {
|
|
120
|
-
|
|
121
|
-
const sessionSocket = request.stream?.session?.socket;
|
|
122
|
-
if (sessionSocket instanceof TLSSocket) alpnProtocol = sessionSocket.alpnProtocol;
|
|
123
|
-
if (request.socket instanceof TLSSocket) alpnProtocol = request.socket.alpnProtocol;
|
|
124
|
-
if (alpnProtocol === "h2") this.httpKernel.onHttpRequest(request, response, "http2");
|
|
125
|
-
else this.httpKernel.onHttpRequest(request, response, "https");
|
|
113
|
+
this.httpKernel.onHttpRequest(request, response, this.type);
|
|
126
114
|
});
|
|
127
115
|
this.listenWithPolicy().then(() => resolve(this.server)).catch((e) => {
|
|
128
116
|
const error = e instanceof Error ? e : new Error(String(e));
|
|
@@ -139,7 +127,7 @@ let ServerHttps = class ServerHttps extends Service {
|
|
|
139
127
|
}
|
|
140
128
|
});
|
|
141
129
|
this.server.on("sessionError", (error) => {
|
|
142
|
-
this.log(
|
|
130
|
+
handleSessionError(error, (e) => this.log(e, "ERROR", "HTTP2 Server sessionError"));
|
|
143
131
|
});
|
|
144
132
|
this.server.on("streamError", (error) => {
|
|
145
133
|
this.log(error, "ERROR", "HTTP2 Server streamError");
|
|
@@ -157,6 +145,7 @@ let ServerHttps = class ServerHttps extends Service {
|
|
|
157
145
|
* `EADDRINUSE` de repli, qui ne sont pas des pannes).
|
|
158
146
|
*/
|
|
159
147
|
async listenWithPolicy() {
|
|
148
|
+
if (this.server === null) throw new Error("Server https not created");
|
|
160
149
|
const { address, shiftedFrom } = await bindWithFallback(this.server, this.domain, buildBindPlan("https", asServersConfig(this.module.kernel?.options.servers), this.module.kernel?.environment));
|
|
161
150
|
this.infos = address;
|
|
162
151
|
this.port = address.port;
|
|
@@ -197,7 +186,6 @@ let ServerHttps = class ServerHttps extends Service {
|
|
|
197
186
|
if (this.infos) this.log(`Server Listen on ${this.scheme}://${this.infos.address}:${this.infos.port} Family: ${this.infos.family} Protocol : ${this.protocol}`);
|
|
198
187
|
}
|
|
199
188
|
};
|
|
200
|
-
ServerHttps = __decorate([__decorateParam(1,
|
|
189
|
+
ServerHttps = __decorate([__decorateParam(1, Inject("HttpKernel"))], ServerHttps);
|
|
201
190
|
var server_https_default = ServerHttps;
|
|
202
|
-
//#endregion
|
|
203
191
|
export { server_https_default as default };
|
|
@@ -1,13 +1,15 @@
|
|
|
1
|
+
import { normalizePrefix } from "../../src/proxy/rules.js";
|
|
2
|
+
import { requestAuthority } from "../../src/context/transport.js";
|
|
1
3
|
import { Service, extend } from "nodefony";
|
|
2
4
|
import http from "node:http";
|
|
5
|
+
import http2 from "node:http2";
|
|
3
6
|
import { URL } from "node:url";
|
|
4
7
|
import { existsSync } from "node:fs";
|
|
5
8
|
import { join } from "node:path";
|
|
6
9
|
import mime from "mime-types";
|
|
7
|
-
import http2 from "node:http2";
|
|
8
10
|
import tls from "node:tls";
|
|
9
11
|
import serveStatic from "serve-static";
|
|
10
|
-
|
|
12
|
+
// nodefony/service/servers/server-static.ts
|
|
11
13
|
const defaultOptions = {
|
|
12
14
|
cacheControl: true,
|
|
13
15
|
maxAge: 345600
|
|
@@ -109,14 +111,10 @@ var Statics = class extends Service {
|
|
|
109
111
|
* @param dir dossier absolu à servir
|
|
110
112
|
*/
|
|
111
113
|
addMount(prefix, dir) {
|
|
112
|
-
|
|
113
|
-
if (!p.startsWith("/")) p = `/${p}`;
|
|
114
|
-
if (!p.endsWith("/")) p = `${p}/`;
|
|
115
|
-
p = p.replace(/\/{2,}/g, "/");
|
|
116
|
-
const server = serveStatic(dir, extend({}, this.defaultOptions));
|
|
114
|
+
const p = normalizePrefix(prefix);
|
|
117
115
|
const entry = {
|
|
118
116
|
prefix: p,
|
|
119
|
-
server,
|
|
117
|
+
server: serveStatic(dir, extend({}, this.defaultOptions)),
|
|
120
118
|
dir
|
|
121
119
|
};
|
|
122
120
|
const i = this.mounts.findIndex((m) => m.prefix === p);
|
|
@@ -151,7 +149,7 @@ var Statics = class extends Service {
|
|
|
151
149
|
return scheme + "://" + host;
|
|
152
150
|
} else if (request instanceof http2.Http2ServerRequest) {
|
|
153
151
|
scheme = request.socket instanceof tls.TLSSocket ? "https" : "http";
|
|
154
|
-
host = request.headers
|
|
152
|
+
host = requestAuthority(request.headers);
|
|
155
153
|
return scheme + "://" + host;
|
|
156
154
|
}
|
|
157
155
|
throw new Error(`Bad request type`);
|
|
@@ -184,5 +182,4 @@ var Statics = class extends Service {
|
|
|
184
182
|
return Promise.resolve(response);
|
|
185
183
|
}
|
|
186
184
|
};
|
|
187
|
-
//#endregion
|
|
188
185
|
export { Statics as default };
|
|
@@ -1,24 +1,25 @@
|
|
|
1
|
+
import { startHeartbeat } from "./wsHeartbeat.js";
|
|
1
2
|
import { asServersConfig, configuredServerPort } from "../../src/servers/kernelServers.js";
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
import { startHeartbeat, trackPong } from "./wsHeartbeat.js";
|
|
7
|
-
import { Module, Service, inject } from "nodefony";
|
|
3
|
+
import __decorate from "../../../_virtual/_@oxc-project_runtime@0.155.0/helpers/esm/decorate.js";
|
|
4
|
+
import __decorateParam from "../../../_virtual/_@oxc-project_runtime@0.155.0/helpers/esm/decorateParam.js";
|
|
5
|
+
import { attachUpgradeDispatch } from "../../src/servers/upgradeDispatch.js";
|
|
6
|
+
import { Inject, Service } from "nodefony";
|
|
8
7
|
import Ws, { WebSocketServer } from "ws";
|
|
9
|
-
|
|
8
|
+
// nodefony/service/servers/server-websocket-secure.ts
|
|
10
9
|
let WebsocketSecure = class WebsocketSecure extends Service {
|
|
11
10
|
httpKernel;
|
|
12
11
|
module;
|
|
13
12
|
ready = false;
|
|
14
13
|
server = null;
|
|
14
|
+
/** Retire l'écouteur `upgrade` posé par {@link attachUpgradeDispatch}. */
|
|
15
|
+
#detachUpgrade = null;
|
|
15
16
|
port;
|
|
16
17
|
domain;
|
|
17
18
|
protocol = "1.1";
|
|
18
19
|
family = null;
|
|
19
20
|
scheme = "wss";
|
|
20
21
|
address = null;
|
|
21
|
-
type = "
|
|
22
|
+
type = "wss";
|
|
22
23
|
infos = null;
|
|
23
24
|
/** Timer keep-alive (UN par serveur). `null` si désactivé ou pas démarré. */
|
|
24
25
|
heartbeatTimer = null;
|
|
@@ -46,10 +47,12 @@ let WebsocketSecure = class WebsocketSecure extends Service {
|
|
|
46
47
|
}
|
|
47
48
|
this.server = new WebSocketServer({
|
|
48
49
|
...this.options,
|
|
49
|
-
|
|
50
|
+
noServer: true,
|
|
50
51
|
clientTracking: true
|
|
51
52
|
});
|
|
52
|
-
this.server.
|
|
53
|
+
this.#detachUpgrade = attachUpgradeDispatch(serverHttps.server, this.server, () => this.httpKernel.reverseProxy, (req) => this.httpKernel.websocketUpgradeRefusal(req), (req, admission) => {
|
|
54
|
+
this.httpKernel.onWebsocketUpgrade(req, admission, this.type).catch(() => {});
|
|
55
|
+
});
|
|
53
56
|
this.heartbeatTimer = startHeartbeat(this.server, this.options);
|
|
54
57
|
this.kernel?.prependOnceListener("onTerminate", this.terminate.bind(this));
|
|
55
58
|
this.ready = true;
|
|
@@ -61,12 +64,6 @@ let WebsocketSecure = class WebsocketSecure extends Service {
|
|
|
61
64
|
}
|
|
62
65
|
});
|
|
63
66
|
}
|
|
64
|
-
onConnection(ws, req) {
|
|
65
|
-
trackPong(ws);
|
|
66
|
-
this.httpKernel.onWebsocketRequest(ws, req, this.type).catch(() => {
|
|
67
|
-
process.nextTick(() => {});
|
|
68
|
-
});
|
|
69
|
-
}
|
|
70
67
|
terminate() {
|
|
71
68
|
return new Promise((resolve, reject) => {
|
|
72
69
|
if (this.heartbeatTimer) {
|
|
@@ -83,6 +80,8 @@ let WebsocketSecure = class WebsocketSecure extends Service {
|
|
|
83
80
|
});
|
|
84
81
|
setTimeout(() => {
|
|
85
82
|
try {
|
|
83
|
+
this.#detachUpgrade?.();
|
|
84
|
+
this.#detachUpgrade = null;
|
|
86
85
|
this.server?.close();
|
|
87
86
|
this.log(` SHUTDOWN WEBSOCKET Server is listening on DOMAIN : ${this.domain} PORT : ${this.port}`, "INFO");
|
|
88
87
|
return resolve(true);
|
|
@@ -92,6 +91,8 @@ let WebsocketSecure = class WebsocketSecure extends Service {
|
|
|
92
91
|
}, 300);
|
|
93
92
|
return;
|
|
94
93
|
}
|
|
94
|
+
this.#detachUpgrade?.();
|
|
95
|
+
this.#detachUpgrade = null;
|
|
95
96
|
return resolve(true);
|
|
96
97
|
});
|
|
97
98
|
}
|
|
@@ -99,7 +100,6 @@ let WebsocketSecure = class WebsocketSecure extends Service {
|
|
|
99
100
|
if (this.infos) this.log(`Server Listen on ${this.scheme}://${this.infos.address}:${this.infos.port} Family: ${this.infos.family} Protocol : ${this.protocol}`);
|
|
100
101
|
}
|
|
101
102
|
};
|
|
102
|
-
WebsocketSecure = __decorate([__decorateParam(1,
|
|
103
|
+
WebsocketSecure = __decorate([__decorateParam(1, Inject("HttpKernel"))], WebsocketSecure);
|
|
103
104
|
var server_websocket_secure_default = WebsocketSecure;
|
|
104
|
-
//#endregion
|
|
105
105
|
export { server_websocket_secure_default as default };
|
|
@@ -1,24 +1,25 @@
|
|
|
1
|
+
import { startHeartbeat } from "./wsHeartbeat.js";
|
|
1
2
|
import { asServersConfig, configuredServerPort } from "../../src/servers/kernelServers.js";
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import
|
|
5
|
-
import
|
|
6
|
-
import { startHeartbeat, trackPong } from "./wsHeartbeat.js";
|
|
7
|
-
import { Module, Service, inject } from "nodefony";
|
|
3
|
+
import __decorate from "../../../_virtual/_@oxc-project_runtime@0.155.0/helpers/esm/decorate.js";
|
|
4
|
+
import __decorateParam from "../../../_virtual/_@oxc-project_runtime@0.155.0/helpers/esm/decorateParam.js";
|
|
5
|
+
import { attachUpgradeDispatch } from "../../src/servers/upgradeDispatch.js";
|
|
6
|
+
import { Inject, Service } from "nodefony";
|
|
8
7
|
import Ws, { WebSocketServer } from "ws";
|
|
9
|
-
|
|
8
|
+
// nodefony/service/servers/server-websocket.ts
|
|
10
9
|
let Websocket = class Websocket extends Service {
|
|
11
10
|
httpKernel;
|
|
12
11
|
module;
|
|
13
12
|
ready = false;
|
|
14
13
|
server = null;
|
|
14
|
+
/** Retire l'écouteur `upgrade` posé par {@link attachUpgradeDispatch}. */
|
|
15
|
+
#detachUpgrade = null;
|
|
15
16
|
port;
|
|
16
17
|
domain;
|
|
17
18
|
protocol = "1.1";
|
|
18
19
|
family = null;
|
|
19
20
|
scheme = "ws";
|
|
20
21
|
address = null;
|
|
21
|
-
type = "
|
|
22
|
+
type = "ws";
|
|
22
23
|
infos = null;
|
|
23
24
|
/** Timer keep-alive (UN par serveur). `null` si désactivé ou pas démarré. */
|
|
24
25
|
heartbeatTimer = null;
|
|
@@ -46,10 +47,12 @@ let Websocket = class Websocket extends Service {
|
|
|
46
47
|
}
|
|
47
48
|
this.server = new WebSocketServer({
|
|
48
49
|
...this.options,
|
|
49
|
-
|
|
50
|
+
noServer: true,
|
|
50
51
|
clientTracking: true
|
|
51
52
|
});
|
|
52
|
-
this.server.
|
|
53
|
+
this.#detachUpgrade = attachUpgradeDispatch(serverHttp.server, this.server, () => this.httpKernel.reverseProxy, (req) => this.httpKernel.websocketUpgradeRefusal(req), (req, admission) => {
|
|
54
|
+
this.httpKernel.onWebsocketUpgrade(req, admission, this.type).catch(() => {});
|
|
55
|
+
});
|
|
53
56
|
this.heartbeatTimer = startHeartbeat(this.server, this.options);
|
|
54
57
|
this.kernel?.prependOnceListener("onTerminate", this.terminate.bind(this));
|
|
55
58
|
this.ready = true;
|
|
@@ -61,12 +64,6 @@ let Websocket = class Websocket extends Service {
|
|
|
61
64
|
}
|
|
62
65
|
});
|
|
63
66
|
}
|
|
64
|
-
onConnection(ws, req) {
|
|
65
|
-
trackPong(ws);
|
|
66
|
-
this.httpKernel.onWebsocketRequest(ws, req, this.type).catch(() => {
|
|
67
|
-
process.nextTick(() => {});
|
|
68
|
-
});
|
|
69
|
-
}
|
|
70
67
|
terminate() {
|
|
71
68
|
return new Promise((resolve, reject) => {
|
|
72
69
|
if (this.heartbeatTimer) {
|
|
@@ -83,6 +80,8 @@ let Websocket = class Websocket extends Service {
|
|
|
83
80
|
});
|
|
84
81
|
setTimeout(() => {
|
|
85
82
|
try {
|
|
83
|
+
this.#detachUpgrade?.();
|
|
84
|
+
this.#detachUpgrade = null;
|
|
86
85
|
this.server?.close();
|
|
87
86
|
this.log(` SHUTDOWN WEBSOCKET Server is listening on DOMAIN : ${this.domain} PORT : ${this.port}`, "INFO");
|
|
88
87
|
return resolve(true);
|
|
@@ -92,6 +91,8 @@ let Websocket = class Websocket extends Service {
|
|
|
92
91
|
}, 300);
|
|
93
92
|
return;
|
|
94
93
|
}
|
|
94
|
+
this.#detachUpgrade?.();
|
|
95
|
+
this.#detachUpgrade = null;
|
|
95
96
|
return resolve(true);
|
|
96
97
|
});
|
|
97
98
|
}
|
|
@@ -99,7 +100,6 @@ let Websocket = class Websocket extends Service {
|
|
|
99
100
|
if (this.infos) this.log(`Server Listen on ${this.scheme}://${this.infos.address}:${this.infos.port} Family: ${this.infos.family} Protocol : ${this.protocol}`);
|
|
100
101
|
}
|
|
101
102
|
};
|
|
102
|
-
Websocket = __decorate([__decorateParam(1,
|
|
103
|
+
Websocket = __decorate([__decorateParam(1, Inject("HttpKernel"))], Websocket);
|
|
103
104
|
var server_websocket_default = Websocket;
|
|
104
|
-
//#endregion
|
|
105
105
|
export { server_websocket_default as default };
|
|
@@ -1,31 +1,91 @@
|
|
|
1
|
-
import
|
|
2
|
-
|
|
1
|
+
import http from "node:http";
|
|
2
|
+
import https from "node:https";
|
|
3
|
+
import tls from "node:tls";
|
|
4
|
+
// nodefony/service/servers/serverShutdown.ts
|
|
3
5
|
/**
|
|
4
|
-
* Fabrique
|
|
6
|
+
* Fabrique l'arrêt gracieux d'un serveur HTTP/1.1, HTTPS, HTTP/2 sur TLS ou h2c.
|
|
5
7
|
*
|
|
6
|
-
* Au `terminate()` (
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
10
|
-
*
|
|
8
|
+
* Au `terminate()` (SIGTERM, `docker stop`), le serveur cesse d'accepter, puis :
|
|
9
|
+
* - **HTTP/2** : chaque session reçoit un GOAWAY (`session.close()`) — les flux
|
|
10
|
+
* en vol se terminent, les nouveaux sont refusés, et le client sait qu'il doit
|
|
11
|
+
* rouvrir ailleurs au lieu de constater une coupure ;
|
|
12
|
+
* - **HTTP/1.1** : la réponse en vol part avec `Connection: close`, la socket
|
|
13
|
+
* inactive est fermée tout de suite, une requête qui arrive encore sur une
|
|
14
|
+
* socket gardée ouverte reçoit aussi `Connection: close`.
|
|
15
|
+
*
|
|
16
|
+
* Ce qui reste après `shutdownTimeout` ms est détruit. `server.close()` est
|
|
17
|
+
* appelé ici : ne pas le rappeler derrière.
|
|
11
18
|
*
|
|
12
19
|
* ⚠️ Les sockets WebSocket upgradées (sans réponse HTTP en cours) sont détruites
|
|
13
|
-
* SANS frame Close
|
|
14
|
-
*
|
|
15
|
-
*
|
|
16
|
-
* HTTP en `once`.
|
|
20
|
+
* SANS frame Close → les serveurs WS doivent fermer leurs clients (close 1001)
|
|
21
|
+
* AVANT ce drain. Garanti par l'ordre des listeners `onTerminate` : WS/WSS
|
|
22
|
+
* s'attachent en `prependOnceListener`, les serveurs HTTP en `once`.
|
|
17
23
|
*
|
|
18
|
-
* @param server - serveur Node à drainer (
|
|
24
|
+
* @param server - serveur Node à drainer, créé AVANT son `listen` (le suivi des
|
|
25
|
+
* connexions commence ici)
|
|
19
26
|
* @param shutdownTimeout - délai de drain en ms avant destruction forcée
|
|
20
|
-
* @returns
|
|
27
|
+
* @returns l'arrêt à invoquer au shutdown
|
|
21
28
|
*/
|
|
22
29
|
function createDrainTerminator(server, shutdownTimeout) {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
30
|
+
const timeout = shutdownTimeout ?? 5e3;
|
|
31
|
+
const emitter = server;
|
|
32
|
+
const speaksHttp2 = !(server instanceof http.Server || server instanceof https.Server);
|
|
33
|
+
const overTls = server instanceof tls.Server;
|
|
34
|
+
const sockets = /* @__PURE__ */ new Set();
|
|
35
|
+
emitter.on("connection", (socket) => track(sockets, socket));
|
|
36
|
+
let http1Sockets = null;
|
|
37
|
+
if (!speaksHttp2) http1Sockets = overTls ? /* @__PURE__ */ new Set() : sockets;
|
|
38
|
+
else if (overTls) http1Sockets = /* @__PURE__ */ new Set();
|
|
39
|
+
if (overTls && http1Sockets !== null) {
|
|
40
|
+
const set = http1Sockets;
|
|
41
|
+
emitter.on("secureConnection", (socket) => {
|
|
42
|
+
if (socket.alpnProtocol !== "h2") track(set, socket);
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
let draining = false;
|
|
46
|
+
const sessions = speaksHttp2 ? /* @__PURE__ */ new Set() : null;
|
|
47
|
+
if (sessions !== null) emitter.on("session", (session) => {
|
|
48
|
+
if (draining) {
|
|
49
|
+
session.close();
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
sessions.add(session);
|
|
53
|
+
session.once("close", () => sessions.delete(session));
|
|
54
|
+
});
|
|
55
|
+
let terminating = null;
|
|
56
|
+
const drain = () => new Promise((resolve) => {
|
|
57
|
+
draining = true;
|
|
58
|
+
const deadline = setTimeout(() => {
|
|
59
|
+
if (sessions !== null) for (const s of sessions) s.destroy();
|
|
60
|
+
for (const socket of sockets) socket.destroy();
|
|
61
|
+
}, timeout);
|
|
62
|
+
server.close(() => {
|
|
63
|
+
clearTimeout(deadline);
|
|
64
|
+
resolve();
|
|
65
|
+
});
|
|
66
|
+
if (sessions !== null) for (const s of sessions) s.close();
|
|
67
|
+
if (http1Sockets !== null) {
|
|
68
|
+
emitter.on("request", closeAfterResponse);
|
|
69
|
+
for (const socket of http1Sockets) {
|
|
70
|
+
const response = socket._httpMessage;
|
|
71
|
+
if (!response) socket.destroy();
|
|
72
|
+
else if (!response.headersSent) response.setHeader("connection", "close");
|
|
73
|
+
}
|
|
74
|
+
}
|
|
26
75
|
});
|
|
76
|
+
return { terminate() {
|
|
77
|
+
terminating ??= drain();
|
|
78
|
+
return terminating;
|
|
79
|
+
} };
|
|
80
|
+
}
|
|
81
|
+
function track(set, socket) {
|
|
82
|
+
set.add(socket);
|
|
83
|
+
socket.once("close", () => set.delete(socket));
|
|
84
|
+
}
|
|
85
|
+
/** Requête HTTP/1.1 reçue pendant le drain : la connexion ne survivra pas à sa réponse. */
|
|
86
|
+
function closeAfterResponse(request, response) {
|
|
87
|
+
if (request.httpVersionMajor === 1 && !response.headersSent) response.setHeader("connection", "close");
|
|
27
88
|
}
|
|
28
89
|
/** Drain par défaut (ms) — même valeur que le défaut Zod `servers.*.shutdownTimeout`. */
|
|
29
90
|
const DEFAULT_SHUTDOWN_TIMEOUT = 5e3;
|
|
30
|
-
//#endregion
|
|
31
91
|
export { DEFAULT_SHUTDOWN_TIMEOUT, createDrainTerminator };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import Ws from "ws";
|
|
2
|
-
|
|
2
|
+
// nodefony/service/servers/wsHeartbeat.ts
|
|
3
3
|
/**
|
|
4
4
|
* Arme le suivi keep-alive d'UNE connexion : initialise l'horodatage de vie et
|
|
5
5
|
* attache l'unique listener `pong` qui le rafraîchit.
|
|
@@ -19,6 +19,35 @@ const trackPong = (ws) => {
|
|
|
19
19
|
});
|
|
20
20
|
};
|
|
21
21
|
/**
|
|
22
|
+
* Un tick du keep-alive : pingue les connexions muettes depuis `interval`, et
|
|
23
|
+
* coupe celles dont le ping attend sa réponse depuis plus de `grace`.
|
|
24
|
+
*
|
|
25
|
+
* Fonction PURE du temps : l'horloge est passée en argument, si bien que la
|
|
26
|
+
* règle se prouve pas à pas, sans minuteur réel — un banc qui la prouverait à
|
|
27
|
+
* l'horloge murale confondrait une boucle d'événements chargée avec un zombie.
|
|
28
|
+
*
|
|
29
|
+
* @param clients - les connexions du serveur
|
|
30
|
+
* @param now - l'instant du tick (`performance.now()` en production)
|
|
31
|
+
* @param interval - délai sans signe de vie avant un ping, ms
|
|
32
|
+
* @param grace - délai accordé au pong avant de couper, ms
|
|
33
|
+
*/
|
|
34
|
+
const heartbeatTick = (clients, now, interval, grace) => {
|
|
35
|
+
for (const client of clients) {
|
|
36
|
+
if (client.readyState !== Ws.OPEN) continue;
|
|
37
|
+
const sock = client;
|
|
38
|
+
sock._nfLastPong ??= now;
|
|
39
|
+
const pingedAt = sock._nfPingedAt ?? 0;
|
|
40
|
+
if (pingedAt > sock._nfLastPong) {
|
|
41
|
+
if (now - pingedAt > grace) client.terminate();
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
if (now - sock._nfLastPong >= interval) {
|
|
45
|
+
sock._nfPingedAt = now;
|
|
46
|
+
client.ping();
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
22
51
|
* Démarre le heartbeat keep-alive du serveur : détecte les connexions zombies
|
|
23
52
|
* (half-open — TCP encore ouvert mais le pair a disparu sans frame Close) et les
|
|
24
53
|
* `terminate()` pour libérer slot mémoire + descripteur de fichier.
|
|
@@ -42,23 +71,9 @@ const startHeartbeat = (server, options) => {
|
|
|
42
71
|
if (interval <= 0) return null;
|
|
43
72
|
const grace = options.keepaliveGracePeriod ?? 0;
|
|
44
73
|
const timer = setInterval(() => {
|
|
45
|
-
|
|
46
|
-
for (const client of server.clients) {
|
|
47
|
-
if (client.readyState !== Ws.OPEN) continue;
|
|
48
|
-
const sock = client;
|
|
49
|
-
sock._nfLastPong ??= now;
|
|
50
|
-
if ((sock._nfPingedAt ?? 0) > sock._nfLastPong) {
|
|
51
|
-
if (now - sock._nfPingedAt > grace) client.terminate();
|
|
52
|
-
continue;
|
|
53
|
-
}
|
|
54
|
-
if (now - sock._nfLastPong >= interval) {
|
|
55
|
-
sock._nfPingedAt = now;
|
|
56
|
-
client.ping();
|
|
57
|
-
}
|
|
58
|
-
}
|
|
74
|
+
heartbeatTick(server.clients, performance.now(), interval, grace);
|
|
59
75
|
}, Math.max(250, grace > 0 ? Math.min(interval, grace) : interval));
|
|
60
76
|
timer.unref();
|
|
61
77
|
return timer;
|
|
62
78
|
};
|
|
63
|
-
|
|
64
|
-
export { startHeartbeat, trackPong };
|
|
79
|
+
export { heartbeatTick, startHeartbeat, trackPong };
|
|
@@ -1,14 +1,12 @@
|
|
|
1
1
|
import { SESSION_FACETS } from "../../src/session/storage/sessionFilters.js";
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import http_kernel_default from "../http-kernel.js";
|
|
5
|
-
import __decorateParam from "../../../_virtual/_@oxc-project_runtime@0.152.0/helpers/esm/decorateParam.js";
|
|
2
|
+
import __decorate from "../../../_virtual/_@oxc-project_runtime@0.155.0/helpers/esm/decorate.js";
|
|
3
|
+
import __decorateParam from "../../../_virtual/_@oxc-project_runtime@0.155.0/helpers/esm/decorateParam.js";
|
|
6
4
|
import Session from "../../src/session/session.js";
|
|
7
5
|
import MemorySessionStorage from "../../src/session/storage/MemorySessionStorage.js";
|
|
8
6
|
import RevocationGuardStorage from "../../src/session/storage/RevocationGuardStorage.js";
|
|
9
|
-
import { AUTO_STORE, EMPTY_INFRA, GcScheduler,
|
|
7
|
+
import { AUTO_STORE, EMPTY_INFRA, GcScheduler, Inject, Nodefony, RequestContext, Service, countFacets, extend, injectable, readStoreConnector, readStoreLocation, resolveAutoStore, storeConnectivity } from "nodefony";
|
|
10
8
|
import { createHash, createHmac } from "node:crypto";
|
|
11
|
-
|
|
9
|
+
// nodefony/service/sessions/sessions-service.ts
|
|
12
10
|
var _SessionsService;
|
|
13
11
|
/**
|
|
14
12
|
* Convertit un timestamp de session (`Date` en mémoire, **string ISO** après
|
|
@@ -143,7 +141,7 @@ let SessionsService = class SessionsService extends Service {
|
|
|
143
141
|
const configured = storeName;
|
|
144
142
|
let reason = `store explicitement configuré ("${configured}")`;
|
|
145
143
|
if (storeName === AUTO_STORE) {
|
|
146
|
-
const auto = resolveAutoStore("session", this.kernel?.infra ?? EMPTY_INFRA, _SessionsService.storageHandlers(), "memory",
|
|
144
|
+
const auto = resolveAutoStore("session", this.kernel?.infra ?? EMPTY_INFRA, _SessionsService.storageHandlers(), "memory", storeConnectivity(this.kernel));
|
|
147
145
|
storeName = auto.store;
|
|
148
146
|
reason = auto.reason;
|
|
149
147
|
this.log(`session.store "auto" → "${storeName}" (${auto.reason})`, "INFO");
|
|
@@ -219,7 +217,7 @@ let SessionsService = class SessionsService extends Service {
|
|
|
219
217
|
return resolve(context.session);
|
|
220
218
|
}
|
|
221
219
|
}
|
|
222
|
-
let inst
|
|
220
|
+
let inst;
|
|
223
221
|
try {
|
|
224
222
|
context.sessionStarting = true;
|
|
225
223
|
inst = this.createSession(this.defaultSessionName);
|
|
@@ -481,23 +479,44 @@ let SessionsService = class SessionsService extends Service {
|
|
|
481
479
|
return destroyed;
|
|
482
480
|
}
|
|
483
481
|
/**
|
|
484
|
-
*
|
|
485
|
-
*
|
|
482
|
+
* Détruit TOUTES les sessions dont le contenu satisfait `match` — la primitive
|
|
483
|
+
* des révocations groupées (« déconnecter partout », déconnexion demandée par
|
|
484
|
+
* un fournisseur d'identité). Ni journal ni audit : l'appelant, qui connaît le
|
|
485
|
+
* motif, les émet.
|
|
486
|
+
*
|
|
487
|
+
* @remarks Quand la méthode rend la main, il ne reste AUCUNE session qui
|
|
488
|
+
* satisfait `match` (au plus `MAX_LOGOUT_PASSES` passages). Une révocation qui
|
|
489
|
+
* en laisse une seule n'est pas une imprécision, c'est une faille.
|
|
490
|
+
*
|
|
491
|
+
* @param filter - restriction poussée au store (`user` : WHERE indexable) ;
|
|
492
|
+
* `undefined` parcourt tout le parc.
|
|
493
|
+
* @param match - prédicat sur la session sérialisée — il doit RE-VÉRIFIER ce
|
|
494
|
+
* que `filter` exprime, un store pouvant l'ignorer.
|
|
495
|
+
* @returns le nombre de sessions détruites.
|
|
496
|
+
* @throws Error si le store actif ne sait pas énumérer ses sessions.
|
|
486
497
|
*/
|
|
487
|
-
async
|
|
498
|
+
async destroyWhere(filter, match) {
|
|
488
499
|
const storage = this.enumerable();
|
|
489
500
|
let destroyed = 0;
|
|
490
501
|
for (let pass = 0; pass < MAX_LOGOUT_PASSES; pass += 1) {
|
|
491
502
|
let destroyedThisPass = 0;
|
|
492
|
-
await this.eachSessionRecord(
|
|
493
|
-
if (rec.data
|
|
503
|
+
await this.eachSessionRecord(filter, async (rec) => {
|
|
504
|
+
if (!match(rec.data)) return false;
|
|
494
505
|
if (await storage.destroy(rec.id)) destroyedThisPass += 1;
|
|
495
506
|
return false;
|
|
496
507
|
});
|
|
497
508
|
destroyed += destroyedThisPass;
|
|
498
509
|
if (destroyedThisPass === 0) break;
|
|
499
|
-
if (pass === 9) this.log(`sessions:
|
|
510
|
+
if (pass === 9) this.log(`sessions: révocation groupée interrompue après ${MAX_LOGOUT_PASSES} passages — filtre=${JSON.stringify(filter ?? {})} (révocation potentiellement incomplète)`, "WARNING");
|
|
500
511
|
}
|
|
512
|
+
return destroyed;
|
|
513
|
+
}
|
|
514
|
+
/**
|
|
515
|
+
* « Déconnexion partout » : détruit TOUTES les sessions d'un utilisateur (scan
|
|
516
|
+
* O(N) — pas d'index inverse, acceptable en admin). Renvoie le nombre détruit.
|
|
517
|
+
*/
|
|
518
|
+
async destroyByUser(identifier, actor) {
|
|
519
|
+
const destroyed = await this.destroyWhere({ user: identifier }, (data) => data.user === identifier);
|
|
501
520
|
if (destroyed > 0) {
|
|
502
521
|
this.log(`sessions revoked by admin (logout-all) — user=${identifier} count=${destroyed} actor=${actor ?? "admin"}`, "INFO");
|
|
503
522
|
this.emitAudit({
|
|
@@ -577,12 +596,7 @@ let SessionsService = class SessionsService extends Service {
|
|
|
577
596
|
this.get("auditService")?.record(event);
|
|
578
597
|
}
|
|
579
598
|
};
|
|
580
|
-
SessionsService = _SessionsService = __decorate([
|
|
581
|
-
injectable(),
|
|
582
|
-
__decorateParam(1, inject("HttpKernel")),
|
|
583
|
-
__decorateMetadata("design:paramtypes", [typeof Module === "undefined" ? Object : Module, typeof http_kernel_default === "undefined" ? Object : http_kernel_default])
|
|
584
|
-
], SessionsService);
|
|
599
|
+
SessionsService = _SessionsService = __decorate([injectable(), __decorateParam(1, Inject("HttpKernel"))], SessionsService);
|
|
585
600
|
SessionsService.registerStorage("memory", MemorySessionStorage);
|
|
586
601
|
var sessions_service_default = SessionsService;
|
|
587
|
-
//#endregion
|
|
588
602
|
export { computeSessionRef, sessions_service_default as default, toSessionSummary };
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { randomFillSync } from "node:crypto";
|
|
2
|
-
|
|
2
|
+
// nodefony/service/trace.ts
|
|
3
3
|
/**
|
|
4
4
|
* W3C Trace Context — parse + generate `traceparent` headers (P2.7).
|
|
5
5
|
*
|
|
@@ -69,5 +69,4 @@ function resolveTraceparent(header) {
|
|
|
69
69
|
const hex = randomHex(24);
|
|
70
70
|
return `00-${hex.slice(0, 32)}-${hex.slice(32)}-01`;
|
|
71
71
|
}
|
|
72
|
-
//#endregion
|
|
73
72
|
export { parseTraceparent, resolveTraceparent };
|
|
@@ -1,12 +1,10 @@
|
|
|
1
|
-
import
|
|
2
|
-
import
|
|
3
|
-
import
|
|
4
|
-
import __decorateParam from "../../../_virtual/_@oxc-project_runtime@0.152.0/helpers/esm/decorateParam.js";
|
|
5
|
-
import { Cli, FileClass, Module, Service, inject } from "nodefony";
|
|
1
|
+
import __decorate from "../../../_virtual/_@oxc-project_runtime@0.155.0/helpers/esm/decorate.js";
|
|
2
|
+
import __decorateParam from "../../../_virtual/_@oxc-project_runtime@0.155.0/helpers/esm/decorateParam.js";
|
|
3
|
+
import { Cli, FileClass, Inject, Service } from "nodefony";
|
|
6
4
|
import fs from "node:fs";
|
|
7
5
|
import fsp from "node:fs/promises";
|
|
8
6
|
import path from "node:path";
|
|
9
|
-
|
|
7
|
+
// nodefony/service/upload/upload-service.ts
|
|
10
8
|
/** Test d'existence non bloquant (`fsp.access`) — remplace `existsSync`. */
|
|
11
9
|
const existsAsync = async (p) => {
|
|
12
10
|
try {
|
|
@@ -58,7 +56,7 @@ let upload = class upload extends Service {
|
|
|
58
56
|
throw new Error(`Syslog not ready`);
|
|
59
57
|
}
|
|
60
58
|
};
|
|
61
|
-
upload = __decorate([__decorateParam(1,
|
|
59
|
+
upload = __decorate([__decorateParam(1, Inject("HttpKernel"))], upload);
|
|
62
60
|
var UploadedFile = class UploadedFile extends FileClass {
|
|
63
61
|
parsedFile;
|
|
64
62
|
size;
|
|
@@ -168,5 +166,4 @@ var UploadedFile = class UploadedFile extends FileClass {
|
|
|
168
166
|
}
|
|
169
167
|
};
|
|
170
168
|
var upload_service_default = upload;
|
|
171
|
-
//#endregion
|
|
172
169
|
export { UploadedFile, upload_service_default as default, upload };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { isIPv4, isIPv6 } from "node:net";
|
|
2
2
|
import { createHash, sign } from "node:crypto";
|
|
3
|
-
|
|
3
|
+
// nodefony/service/x509.ts
|
|
4
4
|
/**
|
|
5
5
|
* Fabrique et lecture de certificats X.509 par `node:crypto` seul — aucune
|
|
6
6
|
* dépendance tierce.
|
|
@@ -320,5 +320,4 @@ async function createSelfSignedCertificate(spec) {
|
|
|
320
320
|
const signature = await signAsync(spec.hash, tbs, spec.privateKey);
|
|
321
321
|
return toPem(sequence(tbs, algorithm, bitString(signature)));
|
|
322
322
|
}
|
|
323
|
-
//#endregion
|
|
324
323
|
export { SHA1_WITH_RSA_OID, createSelfSignedCertificate, distinguishedNameField, ipAddressBytes, parseSubjectAltName, signatureAlgorithmName, signatureAlgorithmOid };
|