@camstack/system 1.2.131 → 1.2.132
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/builtins/local-network/local-network.addon.js +18 -18
- package/dist/builtins/local-network/local-network.addon.mjs +1 -1
- package/dist/http/data-plane-registry.d.ts +25 -0
- package/dist/index.d.ts +3 -3
- package/dist/index.js +43 -24
- package/dist/index.mjs +20 -2
- package/dist/{lan-http-bind-jKrj6OjQ.mjs → tls-CQhPGSJm.mjs} +134 -134
- package/package.json +1 -1
- package/dist/{lan-http-bind-DmgpFP6_.js → tls-u8QCJCFE.js} +133 -133
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
2
|
const require_chunk = require("../../chunk-Cek0wNdY.js");
|
|
3
3
|
const require_dist = require("../../dist-DqcaE-k1.js");
|
|
4
|
-
const
|
|
4
|
+
const require_tls = require("../../tls-u8QCJCFE.js");
|
|
5
5
|
let node_fs_promises = require("node:fs/promises");
|
|
6
6
|
let node_path = require("node:path");
|
|
7
7
|
let node_os = require("node:os");
|
|
@@ -202,7 +202,7 @@ var LocalNetworkAddon = class extends require_dist.BaseAddon {
|
|
|
202
202
|
notificationBaseUrl: "",
|
|
203
203
|
viewerBaseUrls: [],
|
|
204
204
|
httpEnabled: true,
|
|
205
|
-
httpPort:
|
|
205
|
+
httpPort: require_tls.DEFAULT_LAN_HTTP_PORT,
|
|
206
206
|
localHostname: ""
|
|
207
207
|
});
|
|
208
208
|
}
|
|
@@ -237,7 +237,7 @@ var LocalNetworkAddon = class extends require_dist.BaseAddon {
|
|
|
237
237
|
const allow = this.config.allowedAddresses;
|
|
238
238
|
const interfaces = applyAllowlist(this.enumerate(), allow);
|
|
239
239
|
await this.reconcileMeshEndpoint();
|
|
240
|
-
const httpState =
|
|
240
|
+
const httpState = require_tls.readLanHttpState();
|
|
241
241
|
return buildEndpoints(interfaces, httpsPort, includeLoopback, ipv4Only, this.publicHostname, scheme, this.meshEndpoint, {
|
|
242
242
|
enabled: this.config.httpEnabled !== false,
|
|
243
243
|
listening: httpState.listening,
|
|
@@ -320,29 +320,29 @@ var LocalNetworkAddon = class extends require_dist.BaseAddon {
|
|
|
320
320
|
},
|
|
321
321
|
getTlsStatus: async () => this.snapshotTls(false),
|
|
322
322
|
regenerateCertificate: async (_input) => {
|
|
323
|
-
if (
|
|
324
|
-
const extraSans = [...
|
|
325
|
-
await
|
|
323
|
+
if (require_tls.readTlsMode(this.tlsDataDir()) === "uploaded") throw new Error("Cannot regenerate an uploaded certificate — revert to generated first.");
|
|
324
|
+
const extraSans = [...require_tls.readExtraSans(this.tlsDataDir())];
|
|
325
|
+
await require_tls.reissueTlsLeaf(this.tlsDataDir(), { extraSans });
|
|
326
326
|
return this.snapshotTls(true);
|
|
327
327
|
},
|
|
328
328
|
uploadCertificate: async ({ certPem, keyPem, caPem }) => {
|
|
329
|
-
const valid =
|
|
329
|
+
const valid = require_tls.validateUploadedTls(certPem, keyPem);
|
|
330
330
|
if (!valid.ok) throw new Error(valid.error);
|
|
331
331
|
const dir = (0, node_path.join)(this.tlsDataDir(), "tls");
|
|
332
332
|
await (0, node_fs_promises.mkdir)(dir, { recursive: true });
|
|
333
333
|
await (0, node_fs_promises.writeFile)((0, node_path.join)(dir, "camstack.crt"), certPem.endsWith("\n") ? certPem : `${certPem}\n`);
|
|
334
334
|
await (0, node_fs_promises.writeFile)((0, node_path.join)(dir, "camstack.key"), keyPem.endsWith("\n") ? keyPem : `${keyPem}\n`, { mode: 384 });
|
|
335
335
|
if (caPem && caPem.trim() !== "") await (0, node_fs_promises.writeFile)((0, node_path.join)(dir, "camstack-ca.crt"), caPem.endsWith("\n") ? caPem : `${caPem}\n`);
|
|
336
|
-
|
|
336
|
+
require_tls.writeTlsMode(this.tlsDataDir(), "uploaded");
|
|
337
337
|
return this.snapshotTls(true);
|
|
338
338
|
},
|
|
339
339
|
downloadCa: async () => {
|
|
340
340
|
return { pem: this.snapshotTls(false).caCertPem ?? "" };
|
|
341
341
|
},
|
|
342
342
|
revertToGeneratedCertificate: async () => {
|
|
343
|
-
|
|
344
|
-
const extraSans = [...
|
|
345
|
-
await
|
|
343
|
+
require_tls.writeTlsMode(this.tlsDataDir(), "generated");
|
|
344
|
+
const extraSans = [...require_tls.readExtraSans(this.tlsDataDir())];
|
|
345
|
+
await require_tls.ensureTlsCert(this.tlsDataDir(), { extraSans });
|
|
346
346
|
return this.snapshotTls(true);
|
|
347
347
|
}
|
|
348
348
|
};
|
|
@@ -403,7 +403,7 @@ var LocalNetworkAddon = class extends require_dist.BaseAddon {
|
|
|
403
403
|
min: 1,
|
|
404
404
|
max: 65535,
|
|
405
405
|
step: 1,
|
|
406
|
-
default:
|
|
406
|
+
default: require_tls.DEFAULT_LAN_HTTP_PORT,
|
|
407
407
|
showWhen: {
|
|
408
408
|
field: "httpEnabled",
|
|
409
409
|
equals: true
|
|
@@ -497,13 +497,13 @@ var LocalNetworkAddon = class extends require_dist.BaseAddon {
|
|
|
497
497
|
}
|
|
498
498
|
resolvedHttpPort() {
|
|
499
499
|
const port = this.config.httpPort;
|
|
500
|
-
return Number.isInteger(port) && port >= 1 && port <= 65535 ? port :
|
|
500
|
+
return Number.isInteger(port) && port >= 1 && port <= 65535 ? port : require_tls.DEFAULT_LAN_HTTP_PORT;
|
|
501
501
|
}
|
|
502
502
|
tlsDataDir() {
|
|
503
503
|
return this.ctx.nodeDataDir ?? this.ctx.dataDir;
|
|
504
504
|
}
|
|
505
505
|
snapshotTls(restartRequired) {
|
|
506
|
-
const status =
|
|
506
|
+
const status = require_tls.readTlsAccessStatus(this.tlsDataDir(), restartRequired);
|
|
507
507
|
return {
|
|
508
508
|
...status,
|
|
509
509
|
sans: [...status.sans]
|
|
@@ -521,15 +521,15 @@ var LocalNetworkAddon = class extends require_dist.BaseAddon {
|
|
|
521
521
|
const httpsPort = (await this.resolveAdvertisedListenPort(null)).port;
|
|
522
522
|
const httpPort = this.resolvedHttpPort();
|
|
523
523
|
if (this.config.httpEnabled !== false && httpPort === httpsPort) throw new Error(`HTTP port ${httpPort} cannot equal the HTTPS listen port`);
|
|
524
|
-
await
|
|
524
|
+
await require_tls.applyLanHttp({
|
|
525
525
|
enabled: this.config.httpEnabled !== false,
|
|
526
526
|
port: httpPort,
|
|
527
527
|
host: "0.0.0.0"
|
|
528
528
|
});
|
|
529
529
|
if (hostname !== "") {
|
|
530
|
-
|
|
531
|
-
if (
|
|
532
|
-
} else
|
|
530
|
+
require_tls.writeExtraSans(this.tlsDataDir(), [hostname]);
|
|
531
|
+
if (require_tls.readTlsMode(this.tlsDataDir()) === "generated") await require_tls.ensureTlsCert(this.tlsDataDir(), { extraSans: [hostname] });
|
|
532
|
+
} else require_tls.writeExtraSans(this.tlsDataDir(), []);
|
|
533
533
|
}
|
|
534
534
|
/**
|
|
535
535
|
* The port this hub is actually listening on, plus the provenance of the
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { Gt as EventCategory, Y as localNetworkCapability, yt as BaseAddon } from "../../dist-BUEU7B1V.mjs";
|
|
2
|
-
import {
|
|
2
|
+
import { S as readLanHttpState, _ as DEFAULT_LAN_HTTP_PORT, a as writeTlsMode, i as writeExtraSans, l as reissueTlsLeaf, n as readTlsAccessStatus, o as validateUploadedTls, r as readTlsMode, s as ensureTlsCert, t as readExtraSans, y as applyLanHttp } from "../../tls-CQhPGSJm.mjs";
|
|
3
3
|
import { mkdir, writeFile } from "node:fs/promises";
|
|
4
4
|
import { join } from "node:path";
|
|
5
5
|
import * as os from "node:os";
|
|
@@ -21,3 +21,28 @@ export declare class DataPlaneRegistry {
|
|
|
21
21
|
*/
|
|
22
22
|
match(addonId: string, subPath: string): DataPlaneMatch | null;
|
|
23
23
|
}
|
|
24
|
+
/** What the hub knows about an addon when it re-evaluates its data-planes. */
|
|
25
|
+
export interface DataPlaneEligibility {
|
|
26
|
+
/** The addon still has an entry in the registry service. */
|
|
27
|
+
readonly hasEntry: boolean;
|
|
28
|
+
/** That entry is a FORKED addon — the only kind that serves a data-plane today. */
|
|
29
|
+
readonly isForked: boolean;
|
|
30
|
+
/** The child process is currently known to the child registry. */
|
|
31
|
+
readonly childKnown: boolean;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Whether an addon can serve a data-plane RIGHT NOW.
|
|
35
|
+
*
|
|
36
|
+
* Extracted as a predicate because the three ways of answering "no" used to be
|
|
37
|
+
* three early `return`s inside the mount path, and every one of them left the
|
|
38
|
+
* PREVIOUS registration standing. The registry then held a `baseUrl` pointing
|
|
39
|
+
* at the port of a process that no longer existed, and `/addon/:addonId/*` kept
|
|
40
|
+
* reverse-proxying to it — a 502 per request until a replacement child finished
|
|
41
|
+
* handshaking, and forever for an addon removed from disk. `unregisterAddon`
|
|
42
|
+
* existed for exactly this and had no call site anywhere in the repo.
|
|
43
|
+
*
|
|
44
|
+
* A `false` here means UNREGISTER, never "leave it alone". Dropping is the safe
|
|
45
|
+
* direction: an absent data-plane falls through to the control-route path,
|
|
46
|
+
* while a stale one sends live traffic at a dead socket.
|
|
47
|
+
*/
|
|
48
|
+
export declare function canServeDataPlane(state: DataPlaneEligibility): boolean;
|
package/dist/index.d.ts
CHANGED
|
@@ -39,10 +39,11 @@ export type { FeatureConfigReader, FeatureFlag, FeatureManifest, } from './featu
|
|
|
39
39
|
export { FeatureManager } from './feature/feature-manager.js';
|
|
40
40
|
export type { AuthenticatedFileServerOptions, ByteRange, FileResolveResult, FileServerHandle, FileServerTokenVerifier, } from './http/authenticated-file-server.js';
|
|
41
41
|
export { contentTypeFor, createAuthenticatedFileServer, parseRangeHeader, parseTokenizedUrl, resolveFilePath, } from './http/authenticated-file-server.js';
|
|
42
|
-
export type { DataPlaneMatch } from './http/data-plane-registry.js';
|
|
43
|
-
export { DataPlaneRegistry } from './http/data-plane-registry.js';
|
|
42
|
+
export type { DataPlaneEligibility, DataPlaneMatch } from './http/data-plane-registry.js';
|
|
43
|
+
export { canServeDataPlane, DataPlaneRegistry } from './http/data-plane-registry.js';
|
|
44
44
|
export type { FileDataPlaneOptions } from './http/file-data-plane.js';
|
|
45
45
|
export { createFileDataPlaneHandler } from './http/file-data-plane.js';
|
|
46
|
+
export { allFamiliesListenHost, applyLanHttp, bindPendingLanHttp, closeLanHttp, DEFAULT_LAN_HTTP_PORT, readLanHttpState, registerLanHttpHandler, } from './http/lan-http-bind.js';
|
|
46
47
|
export type { ReverseProxyOptions } from './http/reverse-proxy.js';
|
|
47
48
|
export { proxyToUpstream } from './http/reverse-proxy.js';
|
|
48
49
|
export type { HeapReclaimer, HeapReclaimOptions, HeapSample, HeapWatchSink, RunnerHeapWatchOptions, } from './kernel/heap-watch.js';
|
|
@@ -80,7 +81,6 @@ export { StorageLocationManager } from './storage/storage-location-manager.js';
|
|
|
80
81
|
export type { IFileStorage, IStorageLocation, IStorageProvider as ICoreStorageProvider, IStructuredStorage, QueryFilter, StorageRecord, } from './storage/storage-manager.js';
|
|
81
82
|
export { StorageManager } from './storage/storage-manager.js';
|
|
82
83
|
export * from './tls/index.js';
|
|
83
|
-
export { applyLanHttp, allFamiliesListenHost, bindPendingLanHttp, closeLanHttp, DEFAULT_LAN_HTTP_PORT, readLanHttpState, registerLanHttpHandler, } from './http/lan-http-bind.js';
|
|
84
84
|
export { IntegrationRegistry } from './builtins/sqlite-storage/integration-registry.js';
|
|
85
85
|
export { type EnsureAddonNativePrebuildsOptions, ensureAddonNativePrebuilds, type NativeEnsureOutcome, type NativeEnsureResult, } from './kernel/deps/ensure-addon-natives.js';
|
|
86
86
|
export { type EnsureNativePrebuildsOptions, ensureNativePrebuilds, hasDotNode, NATIVE_SCAN_DEPTH, type PrebuildFetchFn, type PrebuildTarget, TRADITIONAL_NATIVE_PACKAGES, } from './kernel/deps/ensure-native-prebuilds.js';
|
package/dist/index.js
CHANGED
|
@@ -25,9 +25,9 @@ const require_builtins_system_config_system_config_addon = require("./builtins/s
|
|
|
25
25
|
require("./builtins/system-config/index.js");
|
|
26
26
|
const require_builtins_winston_logging_index = require("./builtins/winston-logging/index.js");
|
|
27
27
|
const require_file_data_plane = require("./file-data-plane-DO8KbxCe.js");
|
|
28
|
+
const require_tls$1 = require("./tls-u8QCJCFE.js");
|
|
28
29
|
const require_manifest_python_deps = require("./manifest-python-deps-BTkFwAk_.js");
|
|
29
30
|
const require_resource_monitor = require("./resource-monitor-CdnzxBLP.js");
|
|
30
|
-
const require_lan_http_bind = require("./lan-http-bind-DmgpFP6_.js");
|
|
31
31
|
const require_custom_action_registry = require("./custom-action-registry-jY0NOZK8.js");
|
|
32
32
|
let zod = require("zod");
|
|
33
33
|
let node_crypto = require("node:crypto");
|
|
@@ -373,6 +373,24 @@ var DataPlaneRegistry = class {
|
|
|
373
373
|
};
|
|
374
374
|
}
|
|
375
375
|
};
|
|
376
|
+
/**
|
|
377
|
+
* Whether an addon can serve a data-plane RIGHT NOW.
|
|
378
|
+
*
|
|
379
|
+
* Extracted as a predicate because the three ways of answering "no" used to be
|
|
380
|
+
* three early `return`s inside the mount path, and every one of them left the
|
|
381
|
+
* PREVIOUS registration standing. The registry then held a `baseUrl` pointing
|
|
382
|
+
* at the port of a process that no longer existed, and `/addon/:addonId/*` kept
|
|
383
|
+
* reverse-proxying to it — a 502 per request until a replacement child finished
|
|
384
|
+
* handshaking, and forever for an addon removed from disk. `unregisterAddon`
|
|
385
|
+
* existed for exactly this and had no call site anywhere in the repo.
|
|
386
|
+
*
|
|
387
|
+
* A `false` here means UNREGISTER, never "leave it alone". Dropping is the safe
|
|
388
|
+
* direction: an absent data-plane falls through to the control-route path,
|
|
389
|
+
* while a stale one sends live traffic at a dead socket.
|
|
390
|
+
*/
|
|
391
|
+
function canServeDataPlane(state) {
|
|
392
|
+
return state.hasEntry && state.isForked && state.childKnown;
|
|
393
|
+
}
|
|
376
394
|
//#endregion
|
|
377
395
|
//#region src/http/reverse-proxy.ts
|
|
378
396
|
/**
|
|
@@ -95060,8 +95078,8 @@ exports.AddonRouteRegistry = AddonRouteRegistry;
|
|
|
95060
95078
|
exports.AlertCenterAddon = require_builtins_alerts_alerts_addon.AlertCenterAddon;
|
|
95061
95079
|
exports.ApiKeyManager = require_builtins_local_auth_local_auth_addon.ApiKeyManager;
|
|
95062
95080
|
exports.AuthManager = require_builtins_local_auth_local_auth_addon.AuthManager;
|
|
95063
|
-
exports.CA_COMMON_NAME =
|
|
95064
|
-
exports.CA_VALIDITY_DAYS =
|
|
95081
|
+
exports.CA_COMMON_NAME = require_tls$1.CA_COMMON_NAME;
|
|
95082
|
+
exports.CA_VALIDITY_DAYS = require_tls$1.CA_VALIDITY_DAYS;
|
|
95065
95083
|
exports.CLUSTER_SECRET_MISMATCH_TYPE = CLUSTER_SECRET_MISMATCH_TYPE;
|
|
95066
95084
|
exports.CLUSTER_SECRET_REJECTED_EXIT_CODE = CLUSTER_SECRET_REJECTED_EXIT_CODE;
|
|
95067
95085
|
exports.CORE_CAP_SERVICE_NAME = CORE_CAP_SERVICE_NAME;
|
|
@@ -95078,7 +95096,7 @@ exports.ConsoleLoggingAddon = require_builtins_console_logging_index.ConsoleLogg
|
|
|
95078
95096
|
exports.CoreBlocksAddon = require_builtins_core_blocks_core_blocks_addon.CoreBlocksAddon;
|
|
95079
95097
|
exports.CustomActionRegistry = require_custom_action_registry.CustomActionRegistry;
|
|
95080
95098
|
exports.DEFAULT_DATA_PATH = DEFAULT_DATA_PATH;
|
|
95081
|
-
exports.DEFAULT_LAN_HTTP_PORT =
|
|
95099
|
+
exports.DEFAULT_LAN_HTTP_PORT = require_tls$1.DEFAULT_LAN_HTTP_PORT;
|
|
95082
95100
|
exports.DEVICE_SETTINGS_CONTRIBUTION_METHODS = require_dist.DEVICE_SETTINGS_CONTRIBUTION_METHODS;
|
|
95083
95101
|
exports.DEVICE_STATUS_METHOD = require_dist.DEVICE_STATUS_METHOD;
|
|
95084
95102
|
exports.DataPlaneRegistry = DataPlaneRegistry;
|
|
@@ -95109,7 +95127,7 @@ exports.HubNodeRegistry = HubNodeRegistry;
|
|
|
95109
95127
|
exports.INFRA_CAPABILITIES = INFRA_CAPABILITIES;
|
|
95110
95128
|
exports.IntegrationRegistry = IntegrationRegistry;
|
|
95111
95129
|
exports.JobJournal = JobJournal;
|
|
95112
|
-
exports.LEAF_RENEWAL_WINDOW_DAYS =
|
|
95130
|
+
exports.LEAF_RENEWAL_WINDOW_DAYS = require_tls$1.LEAF_RENEWAL_WINDOW_DAYS;
|
|
95113
95131
|
exports.LifecycleJobEngine = LifecycleJobEngine;
|
|
95114
95132
|
exports.LifecycleStateMachine = LifecycleStateMachine;
|
|
95115
95133
|
exports.LivenessMonitorAddon = require_builtins_liveness_monitor_liveness_monitor_addon.LivenessMonitorAddon;
|
|
@@ -95120,7 +95138,7 @@ exports.LogManager = LogManager;
|
|
|
95120
95138
|
exports.LogRingBuffer = LogRingBuffer;
|
|
95121
95139
|
exports.LokiDestination = require_builtins_loki_logging_index.LokiDestination$1;
|
|
95122
95140
|
exports.LokiLoggingAddon = require_builtins_loki_logging_index.LokiLoggingAddon$1;
|
|
95123
|
-
exports.MAX_LEAF_VALIDITY_DAYS =
|
|
95141
|
+
exports.MAX_LEAF_VALIDITY_DAYS = require_tls$1.MAX_LEAF_VALIDITY_DAYS;
|
|
95124
95142
|
exports.METHOD_ACCESS_MAP = require_dist.METHOD_ACCESS_MAP;
|
|
95125
95143
|
exports.ModelDownloadService = require_file_data_plane.ModelDownloadService;
|
|
95126
95144
|
exports.NATIVE_PROVIDER_SERVICE_INFIX = require_manifest_python_deps.NATIVE_PROVIDER_SERVICE_INFIX;
|
|
@@ -95146,7 +95164,7 @@ exports.ReadinessRegistry = require_dist.ReadinessRegistry;
|
|
|
95146
95164
|
exports.ReadinessTimeoutError = require_dist.ReadinessTimeoutError;
|
|
95147
95165
|
exports.ReplEngine = ReplEngine;
|
|
95148
95166
|
exports.RingBuffer = RingBuffer;
|
|
95149
|
-
exports.SERVER_AUTH_OID =
|
|
95167
|
+
exports.SERVER_AUTH_OID = require_tls$1.SERVER_AUTH_OID;
|
|
95150
95168
|
exports.ScopedLogger = ScopedLogger;
|
|
95151
95169
|
exports.ScopedTokenManager = require_builtins_local_auth_local_auth_addon.ScopedTokenManager;
|
|
95152
95170
|
exports.SocketChannel = require_manifest_python_deps.SocketChannel;
|
|
@@ -95170,9 +95188,9 @@ exports.WinstonLoggingAddon = require_builtins_winston_logging_index.WinstonLogg
|
|
|
95170
95188
|
exports.__resetCapUsageRegistryForTests = require_manifest_python_deps.__resetCapUsageRegistryForTests;
|
|
95171
95189
|
exports.adaptBrokerToCluster = require_manifest_python_deps.adaptBrokerToCluster;
|
|
95172
95190
|
exports.addonSettingsCapability = require_dist.addonSettingsCapability;
|
|
95173
|
-
exports.allFamiliesListenHost =
|
|
95174
|
-
exports.applyLanHttp =
|
|
95175
|
-
exports.bindPendingLanHttp =
|
|
95191
|
+
exports.allFamiliesListenHost = require_tls$1.allFamiliesListenHost;
|
|
95192
|
+
exports.applyLanHttp = require_tls$1.applyLanHttp;
|
|
95193
|
+
exports.bindPendingLanHttp = require_tls$1.bindPendingLanHttp;
|
|
95176
95194
|
exports.bootstrapSchema = bootstrapSchema;
|
|
95177
95195
|
exports.brokerCallForCap = require_manifest_python_deps.brokerCallForCap;
|
|
95178
95196
|
exports.brokerTransportLink = require_manifest_python_deps.brokerTransportLink;
|
|
@@ -95192,6 +95210,7 @@ exports.buildUdsNativeCapProxy = require_manifest_python_deps.buildUdsNativeCapP
|
|
|
95192
95210
|
exports.builderMountedCapNames = builderMountedCapNames;
|
|
95193
95211
|
exports.callRegisterNodeWithRetry = callRegisterNodeWithRetry;
|
|
95194
95212
|
exports.callWithServiceDiscovery = require_manifest_python_deps.callWithServiceDiscovery;
|
|
95213
|
+
exports.canServeDataPlane = canServeDataPlane;
|
|
95195
95214
|
exports.capActionName = require_manifest_python_deps.capActionName;
|
|
95196
95215
|
exports.capActionSuffix = require_manifest_python_deps.capActionSuffix;
|
|
95197
95216
|
exports.capBareAction = require_manifest_python_deps.capBareAction;
|
|
@@ -95199,10 +95218,10 @@ exports.capServiceName = require_manifest_python_deps.capServiceName;
|
|
|
95199
95218
|
exports.classifyAddonDir = classifyAddonDir;
|
|
95200
95219
|
exports.classifyCapRoute = require_manifest_python_deps.classifyCapRoute;
|
|
95201
95220
|
exports.clearPendingRestart = clearPendingRestart;
|
|
95202
|
-
exports.closeLanHttp =
|
|
95221
|
+
exports.closeLanHttp = require_tls$1.closeLanHttp;
|
|
95203
95222
|
exports.clusterEventTopic = require_manifest_python_deps.clusterEventTopic;
|
|
95204
95223
|
exports.clusterSecretMatches = clusterSecretMatches;
|
|
95205
|
-
exports.collectCertIdentity =
|
|
95224
|
+
exports.collectCertIdentity = require_tls$1.collectCertIdentity;
|
|
95206
95225
|
exports.collectModelFiles = require_file_data_plane.collectModelFiles;
|
|
95207
95226
|
exports.contentTypeFor = require_file_data_plane.contentTypeFor;
|
|
95208
95227
|
exports.copyDirRecursive = copyDirRecursive;
|
|
@@ -95269,8 +95288,8 @@ Object.defineProperty(exports, "ensurePython", {
|
|
|
95269
95288
|
return _camstack_types_node.ensurePython;
|
|
95270
95289
|
}
|
|
95271
95290
|
});
|
|
95272
|
-
exports.ensureTlsCert =
|
|
95273
|
-
exports.evaluateExistingCert =
|
|
95291
|
+
exports.ensureTlsCert = require_tls$1.ensureTlsCert;
|
|
95292
|
+
exports.evaluateExistingCert = require_tls$1.evaluateExistingCert;
|
|
95274
95293
|
exports.expandCapMethods = require_dist.expandCapMethods;
|
|
95275
95294
|
exports.fetchJson = require_file_data_plane.fetchJson;
|
|
95276
95295
|
Object.defineProperty(exports, "findInPath", {
|
|
@@ -95335,7 +95354,7 @@ exports.isInfraCapability = isInfraCapability;
|
|
|
95335
95354
|
exports.isModelDownloaded = require_file_data_plane.isModelDownloaded;
|
|
95336
95355
|
exports.isSourceNewer = isSourceNewer;
|
|
95337
95356
|
exports.isolatedBuiltinPhase = isolatedBuiltinPhase;
|
|
95338
|
-
exports.loadTlsCert =
|
|
95357
|
+
exports.loadTlsCert = require_tls$1.loadTlsCert;
|
|
95339
95358
|
exports.localEndpointPath = require_manifest_python_deps.localEndpointPath;
|
|
95340
95359
|
exports.localProviderLink = require_manifest_python_deps.localProviderLink;
|
|
95341
95360
|
exports.mountNativeCapService = require_manifest_python_deps.mountNativeCapService;
|
|
@@ -95345,15 +95364,15 @@ exports.parseTokenizedUrl = require_file_data_plane.parseTokenizedUrl;
|
|
|
95345
95364
|
exports.partitionIsolatedBuiltinIds = partitionIsolatedBuiltinIds;
|
|
95346
95365
|
exports.proxyToUpstream = proxyToUpstream;
|
|
95347
95366
|
exports.quarantineAddonResidue = quarantineAddonResidue;
|
|
95348
|
-
exports.readExtraSans =
|
|
95349
|
-
exports.readLanHttpState =
|
|
95367
|
+
exports.readExtraSans = require_tls$1.readExtraSans;
|
|
95368
|
+
exports.readLanHttpState = require_tls$1.readLanHttpState;
|
|
95350
95369
|
exports.readPendingRestart = readPendingRestart;
|
|
95351
|
-
exports.readTlsAccessStatus =
|
|
95352
|
-
exports.readTlsMode =
|
|
95370
|
+
exports.readTlsAccessStatus = require_tls$1.readTlsAccessStatus;
|
|
95371
|
+
exports.readTlsMode = require_tls$1.readTlsMode;
|
|
95353
95372
|
exports.readinessKey = require_dist.readinessKey;
|
|
95354
95373
|
exports.registerEventBusService = require_manifest_python_deps.registerEventBusService;
|
|
95355
|
-
exports.registerLanHttpHandler =
|
|
95356
|
-
exports.reissueTlsLeaf =
|
|
95374
|
+
exports.registerLanHttpHandler = require_tls$1.registerLanHttpHandler;
|
|
95375
|
+
exports.reissueTlsLeaf = require_tls$1.reissueTlsLeaf;
|
|
95357
95376
|
exports.resolveFilePath = require_file_data_plane.resolveFilePath;
|
|
95358
95377
|
exports.resolveHwAccel = require_manifest_python_deps.resolveHwAccel;
|
|
95359
95378
|
exports.resolveNpmInvocation = require_manifest_python_deps.resolveNpmInvocation;
|
|
@@ -95375,8 +95394,8 @@ exports.stripCamstackDeps = stripCamstackDeps;
|
|
|
95375
95394
|
exports.subscribePassthrough = require_manifest_python_deps.subscribePassthrough;
|
|
95376
95395
|
exports.udsChildLogToWorkerEntry = require_manifest_python_deps.udsChildLogToWorkerEntry;
|
|
95377
95396
|
exports.validateProviderRegistrations = require_manifest_python_deps.validateProviderRegistrations;
|
|
95378
|
-
exports.validateUploadedTls =
|
|
95397
|
+
exports.validateUploadedTls = require_tls$1.validateUploadedTls;
|
|
95379
95398
|
exports.waitUntilReady = waitUntilReady;
|
|
95380
|
-
exports.writeExtraSans =
|
|
95399
|
+
exports.writeExtraSans = require_tls$1.writeExtraSans;
|
|
95381
95400
|
exports.writePendingRestart = writePendingRestart;
|
|
95382
|
-
exports.writeTlsMode =
|
|
95401
|
+
exports.writeTlsMode = require_tls$1.writeTlsMode;
|
package/dist/index.mjs
CHANGED
|
@@ -24,9 +24,9 @@ import { SystemConfigAddon } from "./builtins/system-config/system-config.addon.
|
|
|
24
24
|
import "./builtins/system-config/index.mjs";
|
|
25
25
|
import { WinstonDestination, WinstonLoggingAddon } from "./builtins/winston-logging/index.mjs";
|
|
26
26
|
import { a as parseTokenizedUrl, c as collectModelFiles, d as downloadModel, f as ensureModel, h as isModelDownloaded, i as parseRangeHeader, l as deleteModelFromDisk, m as getModelFilePath, n as contentTypeFor, o as resolveFilePath, p as fetchJson, r as createAuthenticatedFileServer, s as ModelDownloadService, t as createFileDataPlaneHandler, u as downloadFile } from "./file-data-plane-BhKdxJgf.mjs";
|
|
27
|
+
import { C as registerLanHttpHandler, S as readLanHttpState, _ as DEFAULT_LAN_HTTP_PORT, a as writeTlsMode, b as bindPendingLanHttp, c as loadTlsCert, d as collectCertIdentity, f as CA_VALIDITY_DAYS, g as evaluateExistingCert, h as SERVER_AUTH_OID, i as writeExtraSans, l as reissueTlsLeaf, m as MAX_LEAF_VALIDITY_DAYS, n as readTlsAccessStatus, o as validateUploadedTls, p as LEAF_RENEWAL_WINDOW_DAYS, r as readTlsMode, s as ensureTlsCert, t as readExtraSans, u as CA_COMMON_NAME, v as allFamiliesListenHost, x as closeLanHttp, y as applyLanHttp } from "./tls-CQhPGSJm.mjs";
|
|
27
28
|
import { $ as buildNativeCapProxy, A as createHubCapForwardService, At as buildHeapSample, B as AGENT_CAP_FWD_ACTION, C as brokerTransportLink, Ct as runNpm, D as localProviderLink, Dt as HEAP_WATCH_INTERVAL_MS, E as ipcParentLink, Et as HEAP_RECLAIM_TRIGGER_MB, F as createUdsLogger, Ft as strandedMb, G as callWithServiceDiscovery, H as CapRouteResolver, I as createUdsLoggerWithControl, J as UdsLocalTransportServer, K as createLocalTransport, L as LocalChildClient, M as createUdsEventBridge, Mt as shouldReclaim, N as createUdsEventBus, Nt as startHeapWatch, O as HUB_CAP_FWD_ACTION, Ot as HEAP_WATCH_WARN_RATIO, P as udsChildLogToWorkerEntry, Pt as startRunnerHeapWatch, Q as encodeFrame, R as LocalChildRegistry, S as brokerCallForCap, St as resolveNpmInvocation, T as ipcChildLink, Tt as HEAP_RECLAIM_MIN_INTERVAL_MS, U as CapRouteError, V as AGENT_CAP_FWD_SERVICE, W as classifyCapRoute, X as localEndpointPath, Y as SocketChannel, Z as FrameDecoder, _ as createKernelHwAccel, _t as CapabilityHandle, a as getWorkerDeviceRegistry, b as __resetCapUsageRegistryForTests, bt as installManifestNativeDeps, c as setHubConnected, ct as NATIVE_PROVIDER_SERVICE_INFIX, d as getBrokerEventBus, dt as capBareAction, et as buildUdsNativeCapProxy, f as getMoleculerEventStats, ft as capServiceName, g as AddonDepsManager, gt as DeviceRegistry, h as subscribePassthrough, ht as serializeTypedArrays, i as createUdsAddonContext, it as mountNativeCapService, j as createParentUnownedCallHandler, jt as createV8Reclaimer, k as HUB_CAP_FWD_SERVICE, kt as RUNNER_HEAP_WATCH_INTERVAL_MS, l as EVENT_TOPIC_PREFIX, lt as capActionName, m as setNodeEventInterest, mt as deserializeTypedArrays, n as adaptBrokerToCluster, o as getOrInitReadinessRegistry, ot as createAddonService, p as registerEventBusService, pt as parseCapAction, q as UdsLocalTransportClient, r as createAddonContext, s as getOrInitReadinessRegistryForClient, st as validateProviderRegistrations, t as installManifestPythonDeps, tt as createBrokerDeviceManagerApi, u as clusterEventTopic, ut as capActionSuffix, v as resolveHwAccel, vt as CapabilityUnavailableError, w as buildLinkChain, wt as createAddonDataPlaneFacility, x as getCapUsageRegistry, xt as resolveAddonClass, y as CapUsageRegistry, yt as copyBundledNativeModules, z as UDS_NO_ROUTE_PREFIX } from "./manifest-python-deps-Dmcnb287.mjs";
|
|
28
29
|
import { n as getSinglePidStats, t as getPidStats } from "./resource-monitor-BWmQ5i-o.mjs";
|
|
29
|
-
import { C as evaluateExistingCert, S as SERVER_AUTH_OID, _ as CA_COMMON_NAME, a as closeLanHttp, b as LEAF_RENEWAL_WINDOW_DAYS, c as readExtraSans, d as writeExtraSans, f as writeTlsMode, g as reissueTlsLeaf, h as loadTlsCert, i as bindPendingLanHttp, l as readTlsAccessStatus, m as ensureTlsCert, n as allFamiliesListenHost, o as readLanHttpState, p as validateUploadedTls, r as applyLanHttp, s as registerLanHttpHandler, t as DEFAULT_LAN_HTTP_PORT, u as readTlsMode, v as collectCertIdentity, x as MAX_LEAF_VALIDITY_DAYS, y as CA_VALIDITY_DAYS } from "./lan-http-bind-jKrj6OjQ.mjs";
|
|
30
30
|
import { t as CustomActionRegistry } from "./custom-action-registry-F__gp_VX.mjs";
|
|
31
31
|
import { z } from "zod";
|
|
32
32
|
import { createHash, randomUUID, timingSafeEqual } from "node:crypto";
|
|
@@ -366,6 +366,24 @@ var DataPlaneRegistry = class {
|
|
|
366
366
|
};
|
|
367
367
|
}
|
|
368
368
|
};
|
|
369
|
+
/**
|
|
370
|
+
* Whether an addon can serve a data-plane RIGHT NOW.
|
|
371
|
+
*
|
|
372
|
+
* Extracted as a predicate because the three ways of answering "no" used to be
|
|
373
|
+
* three early `return`s inside the mount path, and every one of them left the
|
|
374
|
+
* PREVIOUS registration standing. The registry then held a `baseUrl` pointing
|
|
375
|
+
* at the port of a process that no longer existed, and `/addon/:addonId/*` kept
|
|
376
|
+
* reverse-proxying to it — a 502 per request until a replacement child finished
|
|
377
|
+
* handshaking, and forever for an addon removed from disk. `unregisterAddon`
|
|
378
|
+
* existed for exactly this and had no call site anywhere in the repo.
|
|
379
|
+
*
|
|
380
|
+
* A `false` here means UNREGISTER, never "leave it alone". Dropping is the safe
|
|
381
|
+
* direction: an absent data-plane falls through to the control-route path,
|
|
382
|
+
* while a stale one sends live traffic at a dead socket.
|
|
383
|
+
*/
|
|
384
|
+
function canServeDataPlane(state) {
|
|
385
|
+
return state.hasEntry && state.isForked && state.childKnown;
|
|
386
|
+
}
|
|
369
387
|
//#endregion
|
|
370
388
|
//#region src/http/reverse-proxy.ts
|
|
371
389
|
/**
|
|
@@ -95038,4 +95056,4 @@ var LifecycleJobEngine = class {
|
|
|
95038
95056
|
}
|
|
95039
95057
|
};
|
|
95040
95058
|
//#endregion
|
|
95041
|
-
export { AGENT_CAP_FWD_ACTION, AGENT_CAP_FWD_SERVICE, AGENT_READINESS_SERVICE_NAME, ALL_CAPABILITY_DEFINITIONS, AddonApiFactory, AddonDepsManager, AddonEngineManager, AddonHealthMonitor, AddonInstaller, AddonLoader, AddonManifest, AddonRouteRegistry, AlertCenterAddon, ApiKeyManager, AuthManager, CA_COMMON_NAME, CA_VALIDITY_DAYS, CLUSTER_SECRET_MISMATCH_TYPE, CLUSTER_SECRET_REJECTED_EXIT_CODE, CORE_CAP_SERVICE_NAME, CapRouteError, CapRouteResolver, CapUsageRegistry, CapabilityHandle, CapabilityRegistry, CapabilityUnavailableError, ConfigManager, ConfigStore, ConsoleDestination, ConsoleLoggingAddon, CoreBlocksAddon, CustomActionRegistry, DEFAULT_DATA_PATH, DEFAULT_LAN_HTTP_PORT, DEVICE_SETTINGS_CONTRIBUTION_METHODS, DEVICE_STATUS_METHOD, DataPlaneRegistry, DeviceManagerAddon, DeviceRegistry, DeviceStore, EVENT_TOPIC_PREFIX, EngineManagerResolver, EventBus, FeatureManager, FilesystemStorageAddon, FilesystemStorageProvider, FrameDecoder, FsStorageBackend, HEALTH_MONITOR_GRACE_PERIOD_MS, HEALTH_MONITOR_RETRY_INTERVALS_MS, HEALTH_MONITOR_TICK_MS, HEAP_RECLAIM_MIN_INTERVAL_MS, HEAP_RECLAIM_TRIGGER_MB, HEAP_WATCH_INTERVAL_MS, HEAP_WATCH_WARN_RATIO, HUB_CAP_FWD_ACTION, HUB_CAP_FWD_SERVICE, HubForwarderAddon, HubForwarderDestination, HubLogForwarder, HubNodeRegistry, INFRA_CAPABILITIES, IntegrationRegistry, JobJournal, LEAF_RENEWAL_WINDOW_DAYS, LifecycleJobEngine, LifecycleStateMachine, LivenessMonitorAddon, LocalAuthAddon, LocalChildClient, LocalChildRegistry, LogManager, LogRingBuffer, LokiDestination, LokiLoggingAddon, MAX_LEAF_VALIDITY_DAYS, METHOD_ACCESS_MAP, ModelDownloadService, NATIVE_PROVIDER_SERVICE_INFIX, NATIVE_SCAN_DEPTH, NativeMetricsAddon, NativeMetricsProvider, NetworkQualityTracker, NotificationService, PYTHON_VERSION, PipelineRunner, PipelineValidator, PythonEnvManager, QUARANTINE_DIRNAME, RESTART_MARKER_FILE, RUNNER_HEAP_WATCH_INTERVAL_MS, RUNTIME_DEFAULTS, ReadinessRegistry, ReadinessTimeoutError, ReplEngine, RingBuffer, SERVER_AUTH_OID, ScopedLogger, ScopedTokenManager, SocketChannel, SqliteSettingsAddon, SqliteSettingsBackend, StagingArea, StorageLocationManager, StorageManager, StorageOrchestratorAddon, StorageOrchestratorService, SystemConfigAddon, SystemEventBus, TRADITIONAL_NATIVE_PACKAGES, ToastService, UDS_NO_ROUTE_PREFIX, UdsLocalTransportClient, UdsLocalTransportServer, UserManager, WinstonDestination, WinstonLoggingAddon, __resetCapUsageRegistryForTests, adaptBrokerToCluster, addonSettingsCapability, allFamiliesListenHost, applyLanHttp, bindPendingLanHttp, bootstrapSchema, brokerCallForCap, brokerTransportLink, buildBinaryPath, buildCapRouters, buildHeapSample, buildLinkChain, buildNativeCapProxy, buildNodeManifest, buildStorageLocationRegistry, buildUdsNativeCapProxy, builderMountedCapNames, callRegisterNodeWithRetry, callWithServiceDiscovery, capActionName, capActionSuffix, capBareAction, capServiceName, classifyAddonDir, classifyCapRoute, clearPendingRestart, closeLanHttp, clusterEventTopic, clusterSecretMatches, collectCertIdentity, collectModelFiles, contentTypeFor, copyDirRecursive, copyExtraFileDirs, createAddonContext, createAddonDataPlaneFacility, createAddonService, createAuthenticatedFileServer, createBroker, createBrokerDeviceManagerApi, createCoreCapService, createDoorSettingsView, createFileDataPlaneHandler, createHubCapForwardService, createHubService, createKernelHwAccel, createLocalTransport, createParentUnownedCallHandler, createProcessService, createReadinessService, createReadinessServiceForRegistry, createScopedProcessManager, createStreamProbeBrokerService, createUdsAddonContext, createUdsEventBridge, createUdsEventBus, createUdsLogger, createUdsLoggerWithControl, createV8Reclaimer, deleteModelFromDisk, deriveAgentListenPort, describeProviderKindDrift, detectWorkspacePackagesDir, downloadBinary, downloadFile, downloadModel, emitDownForOwnedCaps, encodeFrame, ensureAddonNativePrebuilds, ensureBinary, ensureDir, ensureFfmpeg, ensureLibraryBuilt, ensureModel, ensureNativePrebuilds, ensurePython, ensureTlsCert, evaluateExistingCert, expandCapMethods, fetchJson, findInPath, formatLogLine, getBrokerEventBus, getCapUsageRegistry, getFfmpegDownloadUrl, getModelFilePath, getMoleculerEventStats, getOrInitReadinessRegistry, getOrInitReadinessRegistryForClient, getPidStats, getPlatformInfo, getPythonDownloadUrl, getRestartMarkerPath, getSinglePidStats, getWorkerDeviceRegistry, hasDotNode, hashClusterSecret, installManifestNativeDeps, installManifestPythonDeps, installPackageFromNpm, installPythonPackages, installPythonRequirements, ipcChildLink, ipcParentLink, isAddonDeploySource, isArrayOutputSchema, isClusterSecretMismatchError, isCollectionArrayMethod, isInfraCapability, isModelDownloaded, isSourceNewer, isolatedBuiltinPhase, loadTlsCert, localEndpointPath, localProviderLink, mountNativeCapService, parseCapAction, parseRangeHeader, parseTokenizedUrl, partitionIsolatedBuiltinIds, proxyToUpstream, quarantineAddonResidue, readExtraSans, readLanHttpState, readPendingRestart, readTlsAccessStatus, readTlsMode, readinessKey, registerEventBusService, registerLanHttpHandler, reissueTlsLeaf, resolveFilePath, resolveHwAccel, resolveNpmInvocation, runHubAddonBoot, runNpm, scheduleSelfRestart, scopeKey, scopesAllowAddon, scopesAllowDeviceCap, selectAddonResidue, serializeTypedArrays, setHubConnected, setNodeEventInterest, shouldReclaim, startHeapWatch, startRunnerHeapWatch, strandedMb, stripCamstackDeps, subscribePassthrough, udsChildLogToWorkerEntry, validateProviderRegistrations, validateUploadedTls, waitUntilReady, writeExtraSans, writePendingRestart, writeTlsMode };
|
|
95059
|
+
export { AGENT_CAP_FWD_ACTION, AGENT_CAP_FWD_SERVICE, AGENT_READINESS_SERVICE_NAME, ALL_CAPABILITY_DEFINITIONS, AddonApiFactory, AddonDepsManager, AddonEngineManager, AddonHealthMonitor, AddonInstaller, AddonLoader, AddonManifest, AddonRouteRegistry, AlertCenterAddon, ApiKeyManager, AuthManager, CA_COMMON_NAME, CA_VALIDITY_DAYS, CLUSTER_SECRET_MISMATCH_TYPE, CLUSTER_SECRET_REJECTED_EXIT_CODE, CORE_CAP_SERVICE_NAME, CapRouteError, CapRouteResolver, CapUsageRegistry, CapabilityHandle, CapabilityRegistry, CapabilityUnavailableError, ConfigManager, ConfigStore, ConsoleDestination, ConsoleLoggingAddon, CoreBlocksAddon, CustomActionRegistry, DEFAULT_DATA_PATH, DEFAULT_LAN_HTTP_PORT, DEVICE_SETTINGS_CONTRIBUTION_METHODS, DEVICE_STATUS_METHOD, DataPlaneRegistry, DeviceManagerAddon, DeviceRegistry, DeviceStore, EVENT_TOPIC_PREFIX, EngineManagerResolver, EventBus, FeatureManager, FilesystemStorageAddon, FilesystemStorageProvider, FrameDecoder, FsStorageBackend, HEALTH_MONITOR_GRACE_PERIOD_MS, HEALTH_MONITOR_RETRY_INTERVALS_MS, HEALTH_MONITOR_TICK_MS, HEAP_RECLAIM_MIN_INTERVAL_MS, HEAP_RECLAIM_TRIGGER_MB, HEAP_WATCH_INTERVAL_MS, HEAP_WATCH_WARN_RATIO, HUB_CAP_FWD_ACTION, HUB_CAP_FWD_SERVICE, HubForwarderAddon, HubForwarderDestination, HubLogForwarder, HubNodeRegistry, INFRA_CAPABILITIES, IntegrationRegistry, JobJournal, LEAF_RENEWAL_WINDOW_DAYS, LifecycleJobEngine, LifecycleStateMachine, LivenessMonitorAddon, LocalAuthAddon, LocalChildClient, LocalChildRegistry, LogManager, LogRingBuffer, LokiDestination, LokiLoggingAddon, MAX_LEAF_VALIDITY_DAYS, METHOD_ACCESS_MAP, ModelDownloadService, NATIVE_PROVIDER_SERVICE_INFIX, NATIVE_SCAN_DEPTH, NativeMetricsAddon, NativeMetricsProvider, NetworkQualityTracker, NotificationService, PYTHON_VERSION, PipelineRunner, PipelineValidator, PythonEnvManager, QUARANTINE_DIRNAME, RESTART_MARKER_FILE, RUNNER_HEAP_WATCH_INTERVAL_MS, RUNTIME_DEFAULTS, ReadinessRegistry, ReadinessTimeoutError, ReplEngine, RingBuffer, SERVER_AUTH_OID, ScopedLogger, ScopedTokenManager, SocketChannel, SqliteSettingsAddon, SqliteSettingsBackend, StagingArea, StorageLocationManager, StorageManager, StorageOrchestratorAddon, StorageOrchestratorService, SystemConfigAddon, SystemEventBus, TRADITIONAL_NATIVE_PACKAGES, ToastService, UDS_NO_ROUTE_PREFIX, UdsLocalTransportClient, UdsLocalTransportServer, UserManager, WinstonDestination, WinstonLoggingAddon, __resetCapUsageRegistryForTests, adaptBrokerToCluster, addonSettingsCapability, allFamiliesListenHost, applyLanHttp, bindPendingLanHttp, bootstrapSchema, brokerCallForCap, brokerTransportLink, buildBinaryPath, buildCapRouters, buildHeapSample, buildLinkChain, buildNativeCapProxy, buildNodeManifest, buildStorageLocationRegistry, buildUdsNativeCapProxy, builderMountedCapNames, callRegisterNodeWithRetry, callWithServiceDiscovery, canServeDataPlane, capActionName, capActionSuffix, capBareAction, capServiceName, classifyAddonDir, classifyCapRoute, clearPendingRestart, closeLanHttp, clusterEventTopic, clusterSecretMatches, collectCertIdentity, collectModelFiles, contentTypeFor, copyDirRecursive, copyExtraFileDirs, createAddonContext, createAddonDataPlaneFacility, createAddonService, createAuthenticatedFileServer, createBroker, createBrokerDeviceManagerApi, createCoreCapService, createDoorSettingsView, createFileDataPlaneHandler, createHubCapForwardService, createHubService, createKernelHwAccel, createLocalTransport, createParentUnownedCallHandler, createProcessService, createReadinessService, createReadinessServiceForRegistry, createScopedProcessManager, createStreamProbeBrokerService, createUdsAddonContext, createUdsEventBridge, createUdsEventBus, createUdsLogger, createUdsLoggerWithControl, createV8Reclaimer, deleteModelFromDisk, deriveAgentListenPort, describeProviderKindDrift, detectWorkspacePackagesDir, downloadBinary, downloadFile, downloadModel, emitDownForOwnedCaps, encodeFrame, ensureAddonNativePrebuilds, ensureBinary, ensureDir, ensureFfmpeg, ensureLibraryBuilt, ensureModel, ensureNativePrebuilds, ensurePython, ensureTlsCert, evaluateExistingCert, expandCapMethods, fetchJson, findInPath, formatLogLine, getBrokerEventBus, getCapUsageRegistry, getFfmpegDownloadUrl, getModelFilePath, getMoleculerEventStats, getOrInitReadinessRegistry, getOrInitReadinessRegistryForClient, getPidStats, getPlatformInfo, getPythonDownloadUrl, getRestartMarkerPath, getSinglePidStats, getWorkerDeviceRegistry, hasDotNode, hashClusterSecret, installManifestNativeDeps, installManifestPythonDeps, installPackageFromNpm, installPythonPackages, installPythonRequirements, ipcChildLink, ipcParentLink, isAddonDeploySource, isArrayOutputSchema, isClusterSecretMismatchError, isCollectionArrayMethod, isInfraCapability, isModelDownloaded, isSourceNewer, isolatedBuiltinPhase, loadTlsCert, localEndpointPath, localProviderLink, mountNativeCapService, parseCapAction, parseRangeHeader, parseTokenizedUrl, partitionIsolatedBuiltinIds, proxyToUpstream, quarantineAddonResidue, readExtraSans, readLanHttpState, readPendingRestart, readTlsAccessStatus, readTlsMode, readinessKey, registerEventBusService, registerLanHttpHandler, reissueTlsLeaf, resolveFilePath, resolveHwAccel, resolveNpmInvocation, runHubAddonBoot, runNpm, scheduleSelfRestart, scopeKey, scopesAllowAddon, scopesAllowDeviceCap, selectAddonResidue, serializeTypedArrays, setHubConnected, setNodeEventInterest, shouldReclaim, startHeapWatch, startRunnerHeapWatch, strandedMb, stripCamstackDeps, subscribePassthrough, udsChildLogToWorkerEntry, validateProviderRegistrations, validateUploadedTls, waitUntilReady, writeExtraSans, writePendingRestart, writeTlsMode };
|
|
@@ -8,6 +8,139 @@ import { tmpdir } from "node:os";
|
|
|
8
8
|
import { existsSync, mkdirSync, readFileSync, renameSync, writeFileSync } from "node:fs";
|
|
9
9
|
import { createServer } from "node:http";
|
|
10
10
|
import { isIP } from "node:net";
|
|
11
|
+
//#region src/http/lan-http-bind.ts
|
|
12
|
+
/**
|
|
13
|
+
* Second HTTP listener that shares the hub's existing request handler.
|
|
14
|
+
*
|
|
15
|
+
* Fastify is one protocol per instance; HTTPS stays on :4443 and this
|
|
16
|
+
* binds a plain `http.Server` that emits `request` AND `upgrade` onto the
|
|
17
|
+
* same handler graph (tRPC HTTP, cookies, data-plane, static, tRPC WS).
|
|
18
|
+
*
|
|
19
|
+
* Forwarding only `request` is not enough: the viewer speaks tRPC exclusively
|
|
20
|
+
* over WebSocket (`wsLink`). `/health` wins the LAN race, then `ws://…/trpc`
|
|
21
|
+
* hangs because nobody handles the upgrade on this socket.
|
|
22
|
+
*/
|
|
23
|
+
var DEFAULT_HTTP_PORT = 4480;
|
|
24
|
+
var handlers = null;
|
|
25
|
+
var server = null;
|
|
26
|
+
var pending = null;
|
|
27
|
+
var state = {
|
|
28
|
+
listening: false,
|
|
29
|
+
error: null,
|
|
30
|
+
port: DEFAULT_HTTP_PORT
|
|
31
|
+
};
|
|
32
|
+
var boundRequestedHost = null;
|
|
33
|
+
var DEFAULT_LAN_HTTP_PORT = DEFAULT_HTTP_PORT;
|
|
34
|
+
/** Map "all IPv4" to dual-stack IPv6 (`::`, ipv6Only false) so IPv4 still works. */
|
|
35
|
+
function allFamiliesListenHost(host) {
|
|
36
|
+
if (host === "0.0.0.0" || host === "*" || host === "") return {
|
|
37
|
+
host: "::",
|
|
38
|
+
ipv6Only: false
|
|
39
|
+
};
|
|
40
|
+
return {
|
|
41
|
+
host,
|
|
42
|
+
ipv6Only: false
|
|
43
|
+
};
|
|
44
|
+
}
|
|
45
|
+
function registerLanHttpHandler(next) {
|
|
46
|
+
handlers = next;
|
|
47
|
+
}
|
|
48
|
+
function readLanHttpState() {
|
|
49
|
+
return state;
|
|
50
|
+
}
|
|
51
|
+
async function applyLanHttp(options) {
|
|
52
|
+
pending = options;
|
|
53
|
+
if (!options.enabled) {
|
|
54
|
+
await closeLanHttp();
|
|
55
|
+
state = {
|
|
56
|
+
listening: false,
|
|
57
|
+
error: null,
|
|
58
|
+
port: options.port
|
|
59
|
+
};
|
|
60
|
+
return state;
|
|
61
|
+
}
|
|
62
|
+
if (handlers === null) {
|
|
63
|
+
state = {
|
|
64
|
+
listening: false,
|
|
65
|
+
error: "HTTP listener is not registered yet",
|
|
66
|
+
port: options.port
|
|
67
|
+
};
|
|
68
|
+
return state;
|
|
69
|
+
}
|
|
70
|
+
if (server !== null && state.listening && (options.port === 0 || state.port === options.port) && boundRequestedHost === options.host) return state;
|
|
71
|
+
await closeLanHttp();
|
|
72
|
+
try {
|
|
73
|
+
const bound = await listenHttp(options.port, options.host, handlers);
|
|
74
|
+
server = bound;
|
|
75
|
+
boundRequestedHost = options.host;
|
|
76
|
+
const addr = bound.address();
|
|
77
|
+
state = {
|
|
78
|
+
listening: true,
|
|
79
|
+
error: null,
|
|
80
|
+
port: typeof addr === "object" && addr !== null ? addr.port : options.port
|
|
81
|
+
};
|
|
82
|
+
return state;
|
|
83
|
+
} catch (err) {
|
|
84
|
+
server = null;
|
|
85
|
+
state = {
|
|
86
|
+
listening: false,
|
|
87
|
+
error: err instanceof Error ? err.message : String(err),
|
|
88
|
+
port: options.port
|
|
89
|
+
};
|
|
90
|
+
return state;
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
/** After the hub registers the Fastify request handler, bind whatever was pending. */
|
|
94
|
+
async function bindPendingLanHttp() {
|
|
95
|
+
if (pending === null) return applyLanHttp({
|
|
96
|
+
enabled: true,
|
|
97
|
+
port: DEFAULT_HTTP_PORT,
|
|
98
|
+
host: "0.0.0.0"
|
|
99
|
+
});
|
|
100
|
+
return applyLanHttp(pending);
|
|
101
|
+
}
|
|
102
|
+
async function closeLanHttp() {
|
|
103
|
+
const current = server;
|
|
104
|
+
server = null;
|
|
105
|
+
boundRequestedHost = null;
|
|
106
|
+
if (current === null) return;
|
|
107
|
+
await new Promise((resolve) => {
|
|
108
|
+
current.close(() => resolve());
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
function listenHttp(port, host, next) {
|
|
112
|
+
const resolved = allFamiliesListenHost(host);
|
|
113
|
+
return listenOn(port, resolved, next).catch((err) => {
|
|
114
|
+
if (resolved.host === "::" && host !== "::") return listenOn(port, {
|
|
115
|
+
host: "0.0.0.0",
|
|
116
|
+
ipv6Only: false
|
|
117
|
+
}, next);
|
|
118
|
+
throw err;
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
function listenOn(port, bind, next) {
|
|
122
|
+
return new Promise((resolve, reject) => {
|
|
123
|
+
const created = createServer(next.onRequest);
|
|
124
|
+
created.on("upgrade", next.onUpgrade);
|
|
125
|
+
const onError = (err) => {
|
|
126
|
+
created.off("listening", onListening);
|
|
127
|
+
created.close();
|
|
128
|
+
reject(err);
|
|
129
|
+
};
|
|
130
|
+
const onListening = () => {
|
|
131
|
+
created.off("error", onError);
|
|
132
|
+
resolve(created);
|
|
133
|
+
};
|
|
134
|
+
created.once("error", onError);
|
|
135
|
+
created.once("listening", onListening);
|
|
136
|
+
created.listen({
|
|
137
|
+
port,
|
|
138
|
+
host: bind.host,
|
|
139
|
+
ipv6Only: bind.ipv6Only
|
|
140
|
+
});
|
|
141
|
+
});
|
|
142
|
+
}
|
|
143
|
+
//#endregion
|
|
11
144
|
//#region src/tls/cert-evaluation.ts
|
|
12
145
|
/**
|
|
13
146
|
* The regeneration rule (D227), as a pure function.
|
|
@@ -616,137 +749,4 @@ function readTlsAccessStatus(dataDir, restartRequired = false) {
|
|
|
616
749
|
}
|
|
617
750
|
}
|
|
618
751
|
//#endregion
|
|
619
|
-
|
|
620
|
-
/**
|
|
621
|
-
* Second HTTP listener that shares the hub's existing request handler.
|
|
622
|
-
*
|
|
623
|
-
* Fastify is one protocol per instance; HTTPS stays on :4443 and this
|
|
624
|
-
* binds a plain `http.Server` that emits `request` AND `upgrade` onto the
|
|
625
|
-
* same handler graph (tRPC HTTP, cookies, data-plane, static, tRPC WS).
|
|
626
|
-
*
|
|
627
|
-
* Forwarding only `request` is not enough: the viewer speaks tRPC exclusively
|
|
628
|
-
* over WebSocket (`wsLink`). `/health` wins the LAN race, then `ws://…/trpc`
|
|
629
|
-
* hangs because nobody handles the upgrade on this socket.
|
|
630
|
-
*/
|
|
631
|
-
var DEFAULT_HTTP_PORT = 4480;
|
|
632
|
-
var handlers = null;
|
|
633
|
-
var server = null;
|
|
634
|
-
var pending = null;
|
|
635
|
-
var state = {
|
|
636
|
-
listening: false,
|
|
637
|
-
error: null,
|
|
638
|
-
port: DEFAULT_HTTP_PORT
|
|
639
|
-
};
|
|
640
|
-
var boundRequestedHost = null;
|
|
641
|
-
var DEFAULT_LAN_HTTP_PORT = DEFAULT_HTTP_PORT;
|
|
642
|
-
/** Map "all IPv4" to dual-stack IPv6 (`::`, ipv6Only false) so IPv4 still works. */
|
|
643
|
-
function allFamiliesListenHost(host) {
|
|
644
|
-
if (host === "0.0.0.0" || host === "*" || host === "") return {
|
|
645
|
-
host: "::",
|
|
646
|
-
ipv6Only: false
|
|
647
|
-
};
|
|
648
|
-
return {
|
|
649
|
-
host,
|
|
650
|
-
ipv6Only: false
|
|
651
|
-
};
|
|
652
|
-
}
|
|
653
|
-
function registerLanHttpHandler(next) {
|
|
654
|
-
handlers = next;
|
|
655
|
-
}
|
|
656
|
-
function readLanHttpState() {
|
|
657
|
-
return state;
|
|
658
|
-
}
|
|
659
|
-
async function applyLanHttp(options) {
|
|
660
|
-
pending = options;
|
|
661
|
-
if (!options.enabled) {
|
|
662
|
-
await closeLanHttp();
|
|
663
|
-
state = {
|
|
664
|
-
listening: false,
|
|
665
|
-
error: null,
|
|
666
|
-
port: options.port
|
|
667
|
-
};
|
|
668
|
-
return state;
|
|
669
|
-
}
|
|
670
|
-
if (handlers === null) {
|
|
671
|
-
state = {
|
|
672
|
-
listening: false,
|
|
673
|
-
error: "HTTP listener is not registered yet",
|
|
674
|
-
port: options.port
|
|
675
|
-
};
|
|
676
|
-
return state;
|
|
677
|
-
}
|
|
678
|
-
if (server !== null && state.listening && (options.port === 0 || state.port === options.port) && boundRequestedHost === options.host) return state;
|
|
679
|
-
await closeLanHttp();
|
|
680
|
-
try {
|
|
681
|
-
const bound = await listenHttp(options.port, options.host, handlers);
|
|
682
|
-
server = bound;
|
|
683
|
-
boundRequestedHost = options.host;
|
|
684
|
-
const addr = bound.address();
|
|
685
|
-
state = {
|
|
686
|
-
listening: true,
|
|
687
|
-
error: null,
|
|
688
|
-
port: typeof addr === "object" && addr !== null ? addr.port : options.port
|
|
689
|
-
};
|
|
690
|
-
return state;
|
|
691
|
-
} catch (err) {
|
|
692
|
-
server = null;
|
|
693
|
-
state = {
|
|
694
|
-
listening: false,
|
|
695
|
-
error: err instanceof Error ? err.message : String(err),
|
|
696
|
-
port: options.port
|
|
697
|
-
};
|
|
698
|
-
return state;
|
|
699
|
-
}
|
|
700
|
-
}
|
|
701
|
-
/** After the hub registers the Fastify request handler, bind whatever was pending. */
|
|
702
|
-
async function bindPendingLanHttp() {
|
|
703
|
-
if (pending === null) return applyLanHttp({
|
|
704
|
-
enabled: true,
|
|
705
|
-
port: DEFAULT_HTTP_PORT,
|
|
706
|
-
host: "0.0.0.0"
|
|
707
|
-
});
|
|
708
|
-
return applyLanHttp(pending);
|
|
709
|
-
}
|
|
710
|
-
async function closeLanHttp() {
|
|
711
|
-
const current = server;
|
|
712
|
-
server = null;
|
|
713
|
-
boundRequestedHost = null;
|
|
714
|
-
if (current === null) return;
|
|
715
|
-
await new Promise((resolve) => {
|
|
716
|
-
current.close(() => resolve());
|
|
717
|
-
});
|
|
718
|
-
}
|
|
719
|
-
function listenHttp(port, host, next) {
|
|
720
|
-
const resolved = allFamiliesListenHost(host);
|
|
721
|
-
return listenOn(port, resolved, next).catch((err) => {
|
|
722
|
-
if (resolved.host === "::" && host !== "::") return listenOn(port, {
|
|
723
|
-
host: "0.0.0.0",
|
|
724
|
-
ipv6Only: false
|
|
725
|
-
}, next);
|
|
726
|
-
throw err;
|
|
727
|
-
});
|
|
728
|
-
}
|
|
729
|
-
function listenOn(port, bind, next) {
|
|
730
|
-
return new Promise((resolve, reject) => {
|
|
731
|
-
const created = createServer(next.onRequest);
|
|
732
|
-
created.on("upgrade", next.onUpgrade);
|
|
733
|
-
const onError = (err) => {
|
|
734
|
-
created.off("listening", onListening);
|
|
735
|
-
created.close();
|
|
736
|
-
reject(err);
|
|
737
|
-
};
|
|
738
|
-
const onListening = () => {
|
|
739
|
-
created.off("error", onError);
|
|
740
|
-
resolve(created);
|
|
741
|
-
};
|
|
742
|
-
created.once("error", onError);
|
|
743
|
-
created.once("listening", onListening);
|
|
744
|
-
created.listen({
|
|
745
|
-
port,
|
|
746
|
-
host: bind.host,
|
|
747
|
-
ipv6Only: bind.ipv6Only
|
|
748
|
-
});
|
|
749
|
-
});
|
|
750
|
-
}
|
|
751
|
-
//#endregion
|
|
752
|
-
export { evaluateExistingCert as C, SERVER_AUTH_OID as S, CA_COMMON_NAME as _, closeLanHttp as a, LEAF_RENEWAL_WINDOW_DAYS as b, readExtraSans as c, writeExtraSans as d, writeTlsMode as f, reissueTlsLeaf as g, loadTlsCert as h, bindPendingLanHttp as i, readTlsAccessStatus as l, ensureTlsCert as m, allFamiliesListenHost as n, readLanHttpState as o, validateUploadedTls as p, applyLanHttp as r, registerLanHttpHandler as s, DEFAULT_LAN_HTTP_PORT as t, readTlsMode as u, collectCertIdentity as v, MAX_LEAF_VALIDITY_DAYS as x, CA_VALIDITY_DAYS as y };
|
|
752
|
+
export { registerLanHttpHandler as C, readLanHttpState as S, DEFAULT_LAN_HTTP_PORT as _, writeTlsMode as a, bindPendingLanHttp as b, loadTlsCert as c, collectCertIdentity as d, CA_VALIDITY_DAYS as f, evaluateExistingCert as g, SERVER_AUTH_OID as h, writeExtraSans as i, reissueTlsLeaf as l, MAX_LEAF_VALIDITY_DAYS as m, readTlsAccessStatus as n, validateUploadedTls as o, LEAF_RENEWAL_WINDOW_DAYS as p, readTlsMode as r, ensureTlsCert as s, readExtraSans as t, CA_COMMON_NAME as u, allFamiliesListenHost as v, closeLanHttp as x, applyLanHttp as y };
|
package/package.json
CHANGED
|
@@ -9,6 +9,139 @@ node_os = require_chunk.__toESM(node_os);
|
|
|
9
9
|
let node_fs = require("node:fs");
|
|
10
10
|
let node_http = require("node:http");
|
|
11
11
|
let node_net = require("node:net");
|
|
12
|
+
//#region src/http/lan-http-bind.ts
|
|
13
|
+
/**
|
|
14
|
+
* Second HTTP listener that shares the hub's existing request handler.
|
|
15
|
+
*
|
|
16
|
+
* Fastify is one protocol per instance; HTTPS stays on :4443 and this
|
|
17
|
+
* binds a plain `http.Server` that emits `request` AND `upgrade` onto the
|
|
18
|
+
* same handler graph (tRPC HTTP, cookies, data-plane, static, tRPC WS).
|
|
19
|
+
*
|
|
20
|
+
* Forwarding only `request` is not enough: the viewer speaks tRPC exclusively
|
|
21
|
+
* over WebSocket (`wsLink`). `/health` wins the LAN race, then `ws://…/trpc`
|
|
22
|
+
* hangs because nobody handles the upgrade on this socket.
|
|
23
|
+
*/
|
|
24
|
+
var DEFAULT_HTTP_PORT = 4480;
|
|
25
|
+
var handlers = null;
|
|
26
|
+
var server = null;
|
|
27
|
+
var pending = null;
|
|
28
|
+
var state = {
|
|
29
|
+
listening: false,
|
|
30
|
+
error: null,
|
|
31
|
+
port: DEFAULT_HTTP_PORT
|
|
32
|
+
};
|
|
33
|
+
var boundRequestedHost = null;
|
|
34
|
+
var DEFAULT_LAN_HTTP_PORT = DEFAULT_HTTP_PORT;
|
|
35
|
+
/** Map "all IPv4" to dual-stack IPv6 (`::`, ipv6Only false) so IPv4 still works. */
|
|
36
|
+
function allFamiliesListenHost(host) {
|
|
37
|
+
if (host === "0.0.0.0" || host === "*" || host === "") return {
|
|
38
|
+
host: "::",
|
|
39
|
+
ipv6Only: false
|
|
40
|
+
};
|
|
41
|
+
return {
|
|
42
|
+
host,
|
|
43
|
+
ipv6Only: false
|
|
44
|
+
};
|
|
45
|
+
}
|
|
46
|
+
function registerLanHttpHandler(next) {
|
|
47
|
+
handlers = next;
|
|
48
|
+
}
|
|
49
|
+
function readLanHttpState() {
|
|
50
|
+
return state;
|
|
51
|
+
}
|
|
52
|
+
async function applyLanHttp(options) {
|
|
53
|
+
pending = options;
|
|
54
|
+
if (!options.enabled) {
|
|
55
|
+
await closeLanHttp();
|
|
56
|
+
state = {
|
|
57
|
+
listening: false,
|
|
58
|
+
error: null,
|
|
59
|
+
port: options.port
|
|
60
|
+
};
|
|
61
|
+
return state;
|
|
62
|
+
}
|
|
63
|
+
if (handlers === null) {
|
|
64
|
+
state = {
|
|
65
|
+
listening: false,
|
|
66
|
+
error: "HTTP listener is not registered yet",
|
|
67
|
+
port: options.port
|
|
68
|
+
};
|
|
69
|
+
return state;
|
|
70
|
+
}
|
|
71
|
+
if (server !== null && state.listening && (options.port === 0 || state.port === options.port) && boundRequestedHost === options.host) return state;
|
|
72
|
+
await closeLanHttp();
|
|
73
|
+
try {
|
|
74
|
+
const bound = await listenHttp(options.port, options.host, handlers);
|
|
75
|
+
server = bound;
|
|
76
|
+
boundRequestedHost = options.host;
|
|
77
|
+
const addr = bound.address();
|
|
78
|
+
state = {
|
|
79
|
+
listening: true,
|
|
80
|
+
error: null,
|
|
81
|
+
port: typeof addr === "object" && addr !== null ? addr.port : options.port
|
|
82
|
+
};
|
|
83
|
+
return state;
|
|
84
|
+
} catch (err) {
|
|
85
|
+
server = null;
|
|
86
|
+
state = {
|
|
87
|
+
listening: false,
|
|
88
|
+
error: err instanceof Error ? err.message : String(err),
|
|
89
|
+
port: options.port
|
|
90
|
+
};
|
|
91
|
+
return state;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
/** After the hub registers the Fastify request handler, bind whatever was pending. */
|
|
95
|
+
async function bindPendingLanHttp() {
|
|
96
|
+
if (pending === null) return applyLanHttp({
|
|
97
|
+
enabled: true,
|
|
98
|
+
port: DEFAULT_HTTP_PORT,
|
|
99
|
+
host: "0.0.0.0"
|
|
100
|
+
});
|
|
101
|
+
return applyLanHttp(pending);
|
|
102
|
+
}
|
|
103
|
+
async function closeLanHttp() {
|
|
104
|
+
const current = server;
|
|
105
|
+
server = null;
|
|
106
|
+
boundRequestedHost = null;
|
|
107
|
+
if (current === null) return;
|
|
108
|
+
await new Promise((resolve) => {
|
|
109
|
+
current.close(() => resolve());
|
|
110
|
+
});
|
|
111
|
+
}
|
|
112
|
+
function listenHttp(port, host, next) {
|
|
113
|
+
const resolved = allFamiliesListenHost(host);
|
|
114
|
+
return listenOn(port, resolved, next).catch((err) => {
|
|
115
|
+
if (resolved.host === "::" && host !== "::") return listenOn(port, {
|
|
116
|
+
host: "0.0.0.0",
|
|
117
|
+
ipv6Only: false
|
|
118
|
+
}, next);
|
|
119
|
+
throw err;
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
function listenOn(port, bind, next) {
|
|
123
|
+
return new Promise((resolve, reject) => {
|
|
124
|
+
const created = (0, node_http.createServer)(next.onRequest);
|
|
125
|
+
created.on("upgrade", next.onUpgrade);
|
|
126
|
+
const onError = (err) => {
|
|
127
|
+
created.off("listening", onListening);
|
|
128
|
+
created.close();
|
|
129
|
+
reject(err);
|
|
130
|
+
};
|
|
131
|
+
const onListening = () => {
|
|
132
|
+
created.off("error", onError);
|
|
133
|
+
resolve(created);
|
|
134
|
+
};
|
|
135
|
+
created.once("error", onError);
|
|
136
|
+
created.once("listening", onListening);
|
|
137
|
+
created.listen({
|
|
138
|
+
port,
|
|
139
|
+
host: bind.host,
|
|
140
|
+
ipv6Only: bind.ipv6Only
|
|
141
|
+
});
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
//#endregion
|
|
12
145
|
//#region src/tls/cert-evaluation.ts
|
|
13
146
|
/**
|
|
14
147
|
* The regeneration rule (D227), as a pure function.
|
|
@@ -617,139 +750,6 @@ function readTlsAccessStatus(dataDir, restartRequired = false) {
|
|
|
617
750
|
}
|
|
618
751
|
}
|
|
619
752
|
//#endregion
|
|
620
|
-
//#region src/http/lan-http-bind.ts
|
|
621
|
-
/**
|
|
622
|
-
* Second HTTP listener that shares the hub's existing request handler.
|
|
623
|
-
*
|
|
624
|
-
* Fastify is one protocol per instance; HTTPS stays on :4443 and this
|
|
625
|
-
* binds a plain `http.Server` that emits `request` AND `upgrade` onto the
|
|
626
|
-
* same handler graph (tRPC HTTP, cookies, data-plane, static, tRPC WS).
|
|
627
|
-
*
|
|
628
|
-
* Forwarding only `request` is not enough: the viewer speaks tRPC exclusively
|
|
629
|
-
* over WebSocket (`wsLink`). `/health` wins the LAN race, then `ws://…/trpc`
|
|
630
|
-
* hangs because nobody handles the upgrade on this socket.
|
|
631
|
-
*/
|
|
632
|
-
var DEFAULT_HTTP_PORT = 4480;
|
|
633
|
-
var handlers = null;
|
|
634
|
-
var server = null;
|
|
635
|
-
var pending = null;
|
|
636
|
-
var state = {
|
|
637
|
-
listening: false,
|
|
638
|
-
error: null,
|
|
639
|
-
port: DEFAULT_HTTP_PORT
|
|
640
|
-
};
|
|
641
|
-
var boundRequestedHost = null;
|
|
642
|
-
var DEFAULT_LAN_HTTP_PORT = DEFAULT_HTTP_PORT;
|
|
643
|
-
/** Map "all IPv4" to dual-stack IPv6 (`::`, ipv6Only false) so IPv4 still works. */
|
|
644
|
-
function allFamiliesListenHost(host) {
|
|
645
|
-
if (host === "0.0.0.0" || host === "*" || host === "") return {
|
|
646
|
-
host: "::",
|
|
647
|
-
ipv6Only: false
|
|
648
|
-
};
|
|
649
|
-
return {
|
|
650
|
-
host,
|
|
651
|
-
ipv6Only: false
|
|
652
|
-
};
|
|
653
|
-
}
|
|
654
|
-
function registerLanHttpHandler(next) {
|
|
655
|
-
handlers = next;
|
|
656
|
-
}
|
|
657
|
-
function readLanHttpState() {
|
|
658
|
-
return state;
|
|
659
|
-
}
|
|
660
|
-
async function applyLanHttp(options) {
|
|
661
|
-
pending = options;
|
|
662
|
-
if (!options.enabled) {
|
|
663
|
-
await closeLanHttp();
|
|
664
|
-
state = {
|
|
665
|
-
listening: false,
|
|
666
|
-
error: null,
|
|
667
|
-
port: options.port
|
|
668
|
-
};
|
|
669
|
-
return state;
|
|
670
|
-
}
|
|
671
|
-
if (handlers === null) {
|
|
672
|
-
state = {
|
|
673
|
-
listening: false,
|
|
674
|
-
error: "HTTP listener is not registered yet",
|
|
675
|
-
port: options.port
|
|
676
|
-
};
|
|
677
|
-
return state;
|
|
678
|
-
}
|
|
679
|
-
if (server !== null && state.listening && (options.port === 0 || state.port === options.port) && boundRequestedHost === options.host) return state;
|
|
680
|
-
await closeLanHttp();
|
|
681
|
-
try {
|
|
682
|
-
const bound = await listenHttp(options.port, options.host, handlers);
|
|
683
|
-
server = bound;
|
|
684
|
-
boundRequestedHost = options.host;
|
|
685
|
-
const addr = bound.address();
|
|
686
|
-
state = {
|
|
687
|
-
listening: true,
|
|
688
|
-
error: null,
|
|
689
|
-
port: typeof addr === "object" && addr !== null ? addr.port : options.port
|
|
690
|
-
};
|
|
691
|
-
return state;
|
|
692
|
-
} catch (err) {
|
|
693
|
-
server = null;
|
|
694
|
-
state = {
|
|
695
|
-
listening: false,
|
|
696
|
-
error: err instanceof Error ? err.message : String(err),
|
|
697
|
-
port: options.port
|
|
698
|
-
};
|
|
699
|
-
return state;
|
|
700
|
-
}
|
|
701
|
-
}
|
|
702
|
-
/** After the hub registers the Fastify request handler, bind whatever was pending. */
|
|
703
|
-
async function bindPendingLanHttp() {
|
|
704
|
-
if (pending === null) return applyLanHttp({
|
|
705
|
-
enabled: true,
|
|
706
|
-
port: DEFAULT_HTTP_PORT,
|
|
707
|
-
host: "0.0.0.0"
|
|
708
|
-
});
|
|
709
|
-
return applyLanHttp(pending);
|
|
710
|
-
}
|
|
711
|
-
async function closeLanHttp() {
|
|
712
|
-
const current = server;
|
|
713
|
-
server = null;
|
|
714
|
-
boundRequestedHost = null;
|
|
715
|
-
if (current === null) return;
|
|
716
|
-
await new Promise((resolve) => {
|
|
717
|
-
current.close(() => resolve());
|
|
718
|
-
});
|
|
719
|
-
}
|
|
720
|
-
function listenHttp(port, host, next) {
|
|
721
|
-
const resolved = allFamiliesListenHost(host);
|
|
722
|
-
return listenOn(port, resolved, next).catch((err) => {
|
|
723
|
-
if (resolved.host === "::" && host !== "::") return listenOn(port, {
|
|
724
|
-
host: "0.0.0.0",
|
|
725
|
-
ipv6Only: false
|
|
726
|
-
}, next);
|
|
727
|
-
throw err;
|
|
728
|
-
});
|
|
729
|
-
}
|
|
730
|
-
function listenOn(port, bind, next) {
|
|
731
|
-
return new Promise((resolve, reject) => {
|
|
732
|
-
const created = (0, node_http.createServer)(next.onRequest);
|
|
733
|
-
created.on("upgrade", next.onUpgrade);
|
|
734
|
-
const onError = (err) => {
|
|
735
|
-
created.off("listening", onListening);
|
|
736
|
-
created.close();
|
|
737
|
-
reject(err);
|
|
738
|
-
};
|
|
739
|
-
const onListening = () => {
|
|
740
|
-
created.off("error", onError);
|
|
741
|
-
resolve(created);
|
|
742
|
-
};
|
|
743
|
-
created.once("error", onError);
|
|
744
|
-
created.once("listening", onListening);
|
|
745
|
-
created.listen({
|
|
746
|
-
port,
|
|
747
|
-
host: bind.host,
|
|
748
|
-
ipv6Only: bind.ipv6Only
|
|
749
|
-
});
|
|
750
|
-
});
|
|
751
|
-
}
|
|
752
|
-
//#endregion
|
|
753
753
|
Object.defineProperty(exports, "CA_COMMON_NAME", {
|
|
754
754
|
enumerable: true,
|
|
755
755
|
get: function() {
|