diff --git a/server/bild-calls.mjs b/server/bild-calls.mjs index b617216b..f5b6549f 100644 --- a/server/bild-calls.mjs +++ b/server/bild-calls.mjs @@ -9,8 +9,15 @@ import { heuteLokal } from "./helfer-zeit.mjs"; const ordner = mkdtempSync(join(tmpdir(), "ws-callbild-")); process.env.WORKSPACE_DB = join(ordner, "workspace.db"); const { portMussFreiSein } = await import("./helfer-port.mjs"); -await portMussFreiSein(4319, "das Bildwerkzeug"); -process.env.PORT = "4319"; +/* DIE ANTWORT DES WAECHTERS WIRD BENUTZT (01.10.2026). Hier + stand die Zahl dreimal, und der Rueckgabewert wurde + weggeworfen. Gibt das System den Port dauerhaft nicht her, + weicht `portMussFreiSein` auf Port + 4000 aus und meldet die + neue Nummer -- dieses Werkzeug lauschte danach trotzdem auf + der alten und stuerzte mit `listen EACCES` ab. Genau der + Fall ist am 23.09. auf Port 5040 eingetreten. */ +const PORT = await portMussFreiSein(4319, "das Bildwerkzeug"); +process.env.PORT = String(PORT); process.env.SITE_ACCESS_SECRET = "lokaler-test"; process.env.SITE_PUBLIC_LAUNCH_AT = "2020-01-01T00:00:00+01:00"; @@ -19,7 +26,7 @@ const ec = express.response.cookie; express.response.cookie = function (n, w, o) { return ec.call(this, n, w, { ...(o || {}), secure: false }); }; await import("./index.js"); await new Promise((r) => setTimeout(r, 1000)); -const BASIS = "http://127.0.0.1:4319"; +const BASIS = `http://127.0.0.1:${PORT}`; const { DatabaseSync } = await import("node:sqlite"); const { scryptSync, randomBytes } = await import("node:crypto"); diff --git a/server/bild-chat.mjs b/server/bild-chat.mjs index 4df2170d..d664652c 100644 --- a/server/bild-chat.mjs +++ b/server/bild-chat.mjs @@ -7,8 +7,15 @@ import { join } from "node:path"; const ordner = mkdtempSync(join(tmpdir(), "ws-chatbild-")); process.env.WORKSPACE_DB = join(ordner, "workspace.db"); const { portMussFreiSein } = await import("./helfer-port.mjs"); -await portMussFreiSein(4315, "das Bildwerkzeug"); -process.env.PORT = "4315"; +/* DIE ANTWORT DES WAECHTERS WIRD BENUTZT (01.10.2026). Hier + stand die Zahl dreimal, und der Rueckgabewert wurde + weggeworfen. Gibt das System den Port dauerhaft nicht her, + weicht `portMussFreiSein` auf Port + 4000 aus und meldet die + neue Nummer -- dieses Werkzeug lauschte danach trotzdem auf + der alten und stuerzte mit `listen EACCES` ab. Genau der + Fall ist am 23.09. auf Port 5040 eingetreten. */ +const PORT = await portMussFreiSein(4315, "das Bildwerkzeug"); +process.env.PORT = String(PORT); process.env.SITE_ACCESS_SECRET = "lokaler-test"; process.env.SITE_PUBLIC_LAUNCH_AT = "2020-01-01T00:00:00+01:00"; @@ -17,7 +24,7 @@ const ec = express.response.cookie; express.response.cookie = function (n, w, o) { return ec.call(this, n, w, { ...(o || {}), secure: false }); }; await import("./index.js"); await new Promise((r) => setTimeout(r, 1000)); -const BASIS = "http://127.0.0.1:4315"; +const BASIS = `http://127.0.0.1:${PORT}`; const { DatabaseSync } = await import("node:sqlite"); const { scryptSync, randomBytes } = await import("node:crypto"); diff --git a/server/bild-checkliste-stufen.mjs b/server/bild-checkliste-stufen.mjs index aa9892ac..10633a3a 100644 --- a/server/bild-checkliste-stufen.mjs +++ b/server/bild-checkliste-stufen.mjs @@ -18,8 +18,15 @@ import { join } from "node:path"; const ordner = mkdtempSync(join(tmpdir(), "ws-bild-st-")); process.env.WORKSPACE_DB = join(ordner, "workspace.db"); const { portMussFreiSein } = await import("./helfer-port.mjs"); -await portMussFreiSein(4333, "das Bildwerkzeug fuer die Stufen"); -process.env.PORT = "4333"; +/* DIE ANTWORT DES WAECHTERS WIRD BENUTZT (01.10.2026). Hier + stand die Zahl dreimal, und der Rueckgabewert wurde + weggeworfen. Gibt das System den Port dauerhaft nicht her, + weicht `portMussFreiSein` auf Port + 4000 aus und meldet die + neue Nummer -- dieses Werkzeug lauschte danach trotzdem auf + der alten und stuerzte mit `listen EACCES` ab. Genau der + Fall ist am 23.09. auf Port 5040 eingetreten. */ +const PORT = await portMussFreiSein(4333, "das Bildwerkzeug fuer die Stufen"); +process.env.PORT = String(PORT); process.env.SITE_ACCESS_SECRET = "lokaler-test"; process.env.SITE_PUBLIC_LAUNCH_AT = "2020-01-01T00:00:00+01:00"; @@ -28,7 +35,7 @@ const ec = express.response.cookie; express.response.cookie = function (n, w, o) { return ec.call(this, n, w, { ...(o || {}), secure: false }); }; await import("./index.js"); await new Promise((r) => setTimeout(r, 1200)); -const BASIS = "http://127.0.0.1:4333"; +const BASIS = `http://127.0.0.1:${PORT}`; const { DatabaseSync } = await import("node:sqlite"); const { scryptSync, randomBytes } = await import("node:crypto"); diff --git a/server/bild-sicht.mjs b/server/bild-sicht.mjs index 875ed389..6bd9bef0 100644 --- a/server/bild-sicht.mjs +++ b/server/bild-sicht.mjs @@ -9,8 +9,15 @@ import { join } from "node:path"; const ordner = mkdtempSync(join(tmpdir(), "ws-sicht-")); process.env.WORKSPACE_DB = join(ordner, "workspace.db"); const { portMussFreiSein } = await import("./helfer-port.mjs"); -await portMussFreiSein(4329, "das Bildwerkzeug"); -process.env.PORT = "4329"; +/* DIE ANTWORT DES WAECHTERS WIRD BENUTZT (01.10.2026). Hier + stand die Zahl dreimal, und der Rueckgabewert wurde + weggeworfen. Gibt das System den Port dauerhaft nicht her, + weicht `portMussFreiSein` auf Port + 4000 aus und meldet die + neue Nummer -- dieses Werkzeug lauschte danach trotzdem auf + der alten und stuerzte mit `listen EACCES` ab. Genau der + Fall ist am 23.09. auf Port 5040 eingetreten. */ +const PORT = await portMussFreiSein(4329, "das Bildwerkzeug"); +process.env.PORT = String(PORT); process.env.SITE_ACCESS_SECRET = "lokaler-test"; process.env.SITE_PUBLIC_LAUNCH_AT = "2020-01-01T00:00:00+01:00"; @@ -19,7 +26,7 @@ const ec = express.response.cookie; express.response.cookie = function (n, w, o) { return ec.call(this, n, w, { ...(o || {}), secure: false }); }; await import("./index.js"); await new Promise((r) => setTimeout(r, 1000)); -const BASIS = "http://127.0.0.1:4329"; +const BASIS = `http://127.0.0.1:${PORT}`; const { DatabaseSync } = await import("node:sqlite"); const { scryptSync, randomBytes } = await import("node:crypto"); diff --git a/server/bild-stufen.mjs b/server/bild-stufen.mjs index 1274f1d3..fc50512c 100644 --- a/server/bild-stufen.mjs +++ b/server/bild-stufen.mjs @@ -15,8 +15,15 @@ import { join } from "node:path"; const ordner = mkdtempSync(join(tmpdir(), "ws-bild-")); process.env.WORKSPACE_DB = join(ordner, "workspace.db"); const { portMussFreiSein } = await import("./helfer-port.mjs"); -await portMussFreiSein(4331, "das Bildwerkzeug"); -process.env.PORT = "4331"; +/* DIE ANTWORT DES WAECHTERS WIRD BENUTZT (01.10.2026). Hier + stand die Zahl dreimal, und der Rueckgabewert wurde + weggeworfen. Gibt das System den Port dauerhaft nicht her, + weicht `portMussFreiSein` auf Port + 4000 aus und meldet die + neue Nummer -- dieses Werkzeug lauschte danach trotzdem auf + der alten und stuerzte mit `listen EACCES` ab. Genau der + Fall ist am 23.09. auf Port 5040 eingetreten. */ +const PORT = await portMussFreiSein(4331, "das Bildwerkzeug"); +process.env.PORT = String(PORT); process.env.SITE_ACCESS_SECRET = "lokaler-test"; process.env.SITE_PUBLIC_LAUNCH_AT = "2020-01-01T00:00:00+01:00"; @@ -25,7 +32,7 @@ const ec = express.response.cookie; express.response.cookie = function (n, w, o) { return ec.call(this, n, w, { ...(o || {}), secure: false }); }; await import("./index.js"); await new Promise((r) => setTimeout(r, 1200)); -const BASIS = "http://127.0.0.1:4331"; +const BASIS = `http://127.0.0.1:${PORT}`; const { DatabaseSync } = await import("node:sqlite"); const { scryptSync, randomBytes } = await import("node:crypto"); diff --git a/server/bild-tagesblick.mjs b/server/bild-tagesblick.mjs index a3cc1a30..a75fb02d 100644 --- a/server/bild-tagesblick.mjs +++ b/server/bild-tagesblick.mjs @@ -7,8 +7,15 @@ import { join } from "node:path"; const ordner = mkdtempSync(join(tmpdir(), "ws-bild-")); process.env.WORKSPACE_DB = join(ordner, "workspace.db"); const { portMussFreiSein } = await import("./helfer-port.mjs"); -await portMussFreiSein(4307, "das Bildwerkzeug"); -process.env.PORT = "4307"; +/* DIE ANTWORT DES WAECHTERS WIRD BENUTZT (01.10.2026). Hier + stand die Zahl dreimal, und der Rueckgabewert wurde + weggeworfen. Gibt das System den Port dauerhaft nicht her, + weicht `portMussFreiSein` auf Port + 4000 aus und meldet die + neue Nummer -- dieses Werkzeug lauschte danach trotzdem auf + der alten und stuerzte mit `listen EACCES` ab. Genau der + Fall ist am 23.09. auf Port 5040 eingetreten. */ +const PORT = await portMussFreiSein(4307, "das Bildwerkzeug"); +process.env.PORT = String(PORT); process.env.SITE_ACCESS_SECRET = "lokaler-test"; process.env.SITE_PUBLIC_LAUNCH_AT = "2020-01-01T00:00:00+01:00"; @@ -17,7 +24,7 @@ const ec = express.response.cookie; express.response.cookie = function (n, w, o) { return ec.call(this, n, w, { ...(o || {}), secure: false }); }; await import("./index.js"); await new Promise((r) => setTimeout(r, 900)); -const BASIS = "http://127.0.0.1:4307"; +const BASIS = `http://127.0.0.1:${PORT}`; const { DatabaseSync } = await import("node:sqlite"); const { scryptSync, randomBytes } = await import("node:crypto"); diff --git a/server/helfer-port.mjs b/server/helfer-port.mjs index bc115e80..c1f2700f 100644 --- a/server/helfer-port.mjs +++ b/server/helfer-port.mjs @@ -180,6 +180,33 @@ import { basename, dirname } from "node:path"; * werden: "irgendwo ueber 4400" haette plausibel geklungen. */ const BASIS = 5000; const PRO_DATEI = 2; + +/** Ab hier die MESSDATEIEN (01.10.2026). + * + * Sie hatten ihre Nummern von Hand. Nachgemessen lagen ACHT davon + * IM abgeleiteten Bereich der Pruefungen: Der ist bei 204 Dateien + * dicht von 5000 bis 5409 belegt, und 5387/5397/5399/5401/5403/5405 + * liegen mittendrin. Zwei Laeufe konnten also denselben Port + * bekommen, ohne dass es jemand merkt. Untereinander war fuenfmal + * dieselbe Nummer doppelt vergeben (5397, 5399, 5461, 5483, 5491). + * + * Aufgefallen ist es, weil mess-reaktion und mess-buehne beide auf + * 5483 lagen und ein haengengebliebener Lauf einen ganzen Messlauf + * gekostet hat. + * + * 5900 UND NICHT 5500: Zwischen dem Ende der Pruefungen (5409) und + * hier bleibt Platz fuer 245 weitere Pruefdateien -- bei 5500 waeren + * es nur 45, und die waeren in einem Jahr aufgebraucht. Nach oben: + * 5900 + 24 Dateien * 2 = 5948; plus AUSWEICHEN (4000) sind das + * 9948, also unter 10080, der naechsten gesperrten Nummer. Beides + * nachgerechnet, nicht geschaetzt -- dieselbe Ueberlegung wie bei + * BASIS, wo eine geschaetzte 4500 danebengelegen haette. + * + * AUSGELEITET aus demselben Grund wie AUSWEICHEN und GESPERRT: + * pruef-portnummern.mjs weist nach, dass die beiden Bereiche sich + * nicht beruehren -- und muss dafuer DIESE Zahl ansehen, nicht eine + * Abschrift, die beim naechsten Verschieben stehen bleibt. */ +export const MESS_BASIS = 5900; /** Um wie viel ausgewichen wird, wenn das System einen Port nicht * hergibt. 4000 liegt sicher oberhalb des ganzen abgeleiteten * Bereichs (BASIS bis BASIS+5000 in Schritten von 2, bei derzeit @@ -244,8 +271,8 @@ export const GESPERRT = new Set([ * Ausnahmen musste dafuer niemand pflegen: Uebersprungen wird nach * der Regel, nicht nach einer Tabelle von Sonderfaellen. */ -export function portNummer(nte) { - let p = BASIS; +export function portNummer(nte, basis = BASIS) { + let p = basis; let uebrig = nte; while (true) { if (!GESPERRT.has(p)) { @@ -253,8 +280,8 @@ export function portNummer(nte) { uebrig -= 1; } p += 1; - if (p > BASIS + 5000) { - throw new Error("[Port] Kein freier Nummernbereich mehr oberhalb von " + BASIS + "."); + if (p > basis + 5000) { + throw new Error("[Port] Kein freier Nummernbereich mehr oberhalb von " + basis + "."); } } } @@ -263,18 +290,40 @@ export async function eigenerPort(meta, wer = null, nr = 0) { const pfad = fileURLToPath(meta.url); const mein = basename(pfad); const ordner = dirname(pfad); + /* ZWEI SORTEN, ZWEI BEREICHE (01.10.2026). Eine Messdatei zaehlt + unter ihresgleichen, eine Pruefdatei unter ihresgleichen -- sonst + verschoebe eine neue Pruefung die Nummern aller Messungen und + umgekehrt. Welche Sorte es ist, sagt der Dateiname. */ + const istMess = mein.startsWith("mess-"); + const vorsilbe = istMess ? "mess-" : "pruef-"; const alle = readdirSync(ordner) - .filter((f) => f.startsWith("pruef-") && f.endsWith(".mjs")) + .filter((f) => f.startsWith(vorsilbe) && f.endsWith(".mjs")) .sort(); const stelle = alle.indexOf(mein); if (stelle < 0) { throw new Error( - `[Port] ${mein} steht nicht in der Liste der Pruefdateien in ${ordner}.\n` + `[Port] ${mein} steht nicht in der Liste der ${vorsilbe}Dateien in ${ordner}.\n` + " Die Nummer wird aus der Stelle im Alphabet abgeleitet -- ohne\n" + " Stelle gibt es keine Nummer, und geraten wird nicht."); } if (nr < 0 || nr >= PRO_DATEI) { throw new Error(`[Port] Es gibt ${PRO_DATEI} Nummern je Datei (0 und 1), nicht ${nr}.`); } - return portMussFreiSein(portNummer(stelle * PRO_DATEI + nr), wer || mein.replace(/\.mjs$/, "")); + const port = istMess + ? portNummer(stelle * PRO_DATEI + nr, MESS_BASIS) + : portNummer(stelle * PRO_DATEI + nr); + + /* DIE WACHE GEGEN DAS ZUSAMMENWACHSEN. Kommen so viele + Pruefdateien dazu, dass ihr Bereich den der Messungen erreicht, + bekaemen zwei Laeufe still dieselbe Nummer -- genau der Fehler, + den diese Ableitung beseitigt. Dann lieber ein lauter Abbruch + mit Anleitung. */ + if (!istMess && port >= MESS_BASIS) { + throw new Error( + `[Port] Der Bereich der Pruefungen ist bei ${port} angekommen und\n` + + ` stoesst an den der Messdateien (ab ${MESS_BASIS}).\n` + + " MESS_BASIS in helfer-port.mjs hochsetzen -- und dabei nachsehen,\n" + + " dass MESS_BASIS + 4000 (AUSWEICHEN) unter 10080 bleibt."); + } + return portMussFreiSein(port, wer || mein.replace(/\.mjs$/, "")); } diff --git a/server/mess-alle-einzelsicht.mjs b/server/mess-alle-einzelsicht.mjs index 9ca35eb8..f8d00e79 100644 --- a/server/mess-alle-einzelsicht.mjs +++ b/server/mess-alle-einzelsicht.mjs @@ -15,9 +15,11 @@ ist die Karte 380 px breit, nicht 400. SIE PRUEFT NICHTS und meldet keinen Fehlschlag. Sie macht ein Bild, - auf dem man nachsehen kann. Deshalb `mess-` und nicht `pruef-`: Die - Portvergabe leitet sich aus den `pruef-`-Namen ab, und eine - Messdatei darf die Nummern der Pruefungen nicht verschieben. + auf dem man nachsehen kann. Sie heisst `mess-` und nicht `pruef-`: Beide Sorten leiten ihre + Portnummer aus der Stelle im Alphabet ab, aber jede aus IHRER + eigenen Liste und in ihrem eigenen Bereich (Pruefungen ab 5000, + Messungen ab 5900). So verschiebt eine neue Messdatei die Nummern + der Pruefungen nicht -- und umgekehrt. --------------------------------------------------------------------- EIGENE WEGWERF-DATENBANK, NIE DIE ECHTE @@ -36,7 +38,9 @@ import { execFileSync } from "node:child_process"; import { request as httpAnfrage } from "node:http"; import { createServer as httpsServer } from "node:https"; -const PORT = 5397, HP = 5398; +import { eigenerPort } from "./helfer-port.mjs"; +const PORT = await eigenerPort(import.meta); +const HP = await eigenerPort(import.meta, "mess-alle-einzelsicht (HTTPS)", 1); const CREW = "crew.dogfather-universe.com"; const ordner = mkdtempSync(join(tmpdir(), "ws-alle-sicht-")); process.env.WORKSPACE_DB = join(ordner, "workspace.db"); diff --git a/server/mess-aushang.mjs b/server/mess-aushang.mjs index e200a794..e89bb00d 100644 --- a/server/mess-aushang.mjs +++ b/server/mess-aushang.mjs @@ -25,7 +25,9 @@ import { execFileSync } from "node:child_process"; import { request as httpAnfrage } from "node:http"; import { createServer as httpsServer } from "node:https"; -const PORT = 5481, HP = 5482; +import { eigenerPort } from "./helfer-port.mjs"; +const PORT = await eigenerPort(import.meta); +const HP = await eigenerPort(import.meta, "mess-aushang (HTTPS)", 1); const CREW = "crew.dogfather-universe.com"; const ordner = mkdtempSync(join(tmpdir(), "ws-aushang-")); process.env.WORKSPACE_DB = join(ordner, "workspace.db"); diff --git a/server/mess-buehne.mjs b/server/mess-buehne.mjs index 3f35c61b..8fe04dc2 100644 --- a/server/mess-buehne.mjs +++ b/server/mess-buehne.mjs @@ -42,8 +42,9 @@ const HIER = dirname(fileURLToPath(import.meta.url)); const ordner = mkdtempSync(join(tmpdir(), "mess-buehne-")); process.env.WORKSPACE_DB = join(ordner, "workspace.db"); -const PORT = 5483; -const HTTPS_PORT = PORT + 1; +import { eigenerPort } from "./helfer-port.mjs"; +const PORT = await eigenerPort(import.meta); +const HTTPS_PORT = await eigenerPort(import.meta, "mess-buehne (HTTPS)", 1); process.env.PORT = `${PORT}`; process.env.SITE_ACCESS_SECRET = "lokaler-test"; process.env.SITE_PUBLIC_LAUNCH_AT = "2020-01-01T00:00:00+01:00"; diff --git a/server/mess-chat-liste.mjs b/server/mess-chat-liste.mjs index d000c257..20cb3972 100644 --- a/server/mess-chat-liste.mjs +++ b/server/mess-chat-liste.mjs @@ -21,9 +21,11 @@ Diese Datei legt den Bestand an, den er sieht, und macht Bilder. Sie prueft NICHTS und meldet keinen Fehlschlag. - Sie heisst `mess-` und nicht `pruef-`: Die Portvergabe leitet sich - aus den `pruef-`-Namen ab, und eine Messdatei darf die Nummern der - Pruefungen nicht verschieben. + Sie heisst `mess-` und nicht `pruef-`: Beide Sorten leiten ihre + Portnummer aus der Stelle im Alphabet ab, aber jede aus IHRER + eigenen Liste und in ihrem eigenen Bereich (Pruefungen ab 5000, + Messungen ab 5900). So verschiebt eine neue Messdatei die Nummern + der Pruefungen nicht -- und umgekehrt. Aufrufen mit: node server/mess-chat-liste.mjs Bilder: server/mess-chat-liste-breit.png @@ -34,7 +36,8 @@ import { mkdtempSync, rmSync } from "node:fs"; import { tmpdir } from "node:os"; import { join } from "node:path"; -const PORT = 5397; +import { eigenerPort } from "./helfer-port.mjs"; +const PORT = await eigenerPort(import.meta); const ordner = mkdtempSync(join(tmpdir(), "ws-messchat-")); process.env.WORKSPACE_DB = join(ordner, "workspace.db"); process.env.PORT = String(PORT); diff --git a/server/mess-chat-neu-stelle.mjs b/server/mess-chat-neu-stelle.mjs index 3725b579..ce250dcb 100644 --- a/server/mess-chat-neu-stelle.mjs +++ b/server/mess-chat-neu-stelle.mjs @@ -27,7 +27,9 @@ import { execFileSync } from "node:child_process"; import { request as httpAnfrage } from "node:http"; import { createServer as httpsServer } from "node:https"; -const PORT = 5491, HP = 5492; +import { eigenerPort } from "./helfer-port.mjs"; +const PORT = await eigenerPort(import.meta); +const HP = await eigenerPort(import.meta, "mess-chat-neu-stelle (HTTPS)", 1); const CREW = "crew.dogfather-universe.com"; const ordner = mkdtempSync(join(tmpdir(), "ws-neustelle-")); process.env.WORKSPACE_DB = join(ordner, "workspace.db"); diff --git a/server/mess-chat-optik.mjs b/server/mess-chat-optik.mjs index 86346905..de7c51cb 100644 --- a/server/mess-chat-optik.mjs +++ b/server/mess-chat-optik.mjs @@ -26,7 +26,9 @@ import { execFileSync } from "node:child_process"; import { request as httpAnfrage } from "node:http"; import { createServer as httpsServer } from "node:https"; -const PORT = 5403, HP = 5404; +import { eigenerPort } from "./helfer-port.mjs"; +const PORT = await eigenerPort(import.meta); +const HP = await eigenerPort(import.meta, "mess-chat-optik (HTTPS)", 1); const CREW = "crew.dogfather-universe.com"; const ordner = mkdtempSync(join(tmpdir(), "ws-chatoptik-")); process.env.WORKSPACE_DB = join(ordner, "workspace.db"); diff --git a/server/mess-dialog-ausgang.mjs b/server/mess-dialog-ausgang.mjs index a38cb6ae..563cb4b4 100644 --- a/server/mess-dialog-ausgang.mjs +++ b/server/mess-dialog-ausgang.mjs @@ -39,7 +39,9 @@ import { execFileSync } from "node:child_process"; import { request as httpAnfrage } from "node:http"; import { createServer as httpsServer } from "node:https"; -const PORT = 5399, HP = 5400; +import { eigenerPort } from "./helfer-port.mjs"; +const PORT = await eigenerPort(import.meta); +const HP = await eigenerPort(import.meta, "mess-dialog-ausgang (HTTPS)", 1); const CREW = "crew.dogfather-universe.com"; const ordner = mkdtempSync(join(tmpdir(), "ws-dialog-")); process.env.WORKSPACE_DB = join(ordner, "workspace.db"); diff --git a/server/mess-eingang-optik.mjs b/server/mess-eingang-optik.mjs index acd323c1..383fd929 100644 --- a/server/mess-eingang-optik.mjs +++ b/server/mess-eingang-optik.mjs @@ -24,7 +24,9 @@ import { execFileSync } from "node:child_process"; import { request as httpAnfrage } from "node:http"; import { createServer as httpsServer } from "node:https"; -const PORT = 5401, HP = 5402; +import { eigenerPort } from "./helfer-port.mjs"; +const PORT = await eigenerPort(import.meta); +const HP = await eigenerPort(import.meta, "mess-eingang-optik (HTTPS)", 1); const CREW = "crew.dogfather-universe.com"; const ordner = mkdtempSync(join(tmpdir(), "ws-eingang-")); process.env.WORKSPACE_DB = join(ordner, "workspace.db"); diff --git a/server/mess-entwicklung-kacheln.mjs b/server/mess-entwicklung-kacheln.mjs index 9c478b9b..51af6a59 100644 --- a/server/mess-entwicklung-kacheln.mjs +++ b/server/mess-entwicklung-kacheln.mjs @@ -36,7 +36,8 @@ import { mkdtempSync, rmSync } from "node:fs"; import { tmpdir } from "node:os"; import { join } from "node:path"; -const PORT = 5399; +import { eigenerPort } from "./helfer-port.mjs"; +const PORT = await eigenerPort(import.meta); const ordner = mkdtempSync(join(tmpdir(), "ws-messkachel-")); process.env.WORKSPACE_DB = join(ordner, "workspace.db"); process.env.PORT = String(PORT); diff --git a/server/mess-farbe-am-text.mjs b/server/mess-farbe-am-text.mjs index a1646af5..4cc570d9 100644 --- a/server/mess-farbe-am-text.mjs +++ b/server/mess-farbe-am-text.mjs @@ -24,7 +24,8 @@ import { join } from "node:path"; const SEITE = process.argv[2] || "treff-regeln.html"; const SUCHE = process.argv[3] || "Schön, dass du da bist"; -const PORT = 5451; +import { eigenerPort } from "./helfer-port.mjs"; +const PORT = await eigenerPort(import.meta); const ordner = mkdtempSync(join(tmpdir(), "ws-kontrast-")); process.env.WORKSPACE_DB = join(ordner, "workspace.db"); process.env.PORT = String(PORT); diff --git a/server/mess-fokus.mjs b/server/mess-fokus.mjs index 81828c28..c31663c4 100644 --- a/server/mess-fokus.mjs +++ b/server/mess-fokus.mjs @@ -24,27 +24,15 @@ import { join } from "node:path"; const SEITE = process.argv[2] || "wissen.html"; const SUCHE = process.argv[3] || ".kachel"; -const PORT = 5457; - -/* IST DIE NUMMER FREI? Sonst misst dieses Werkzeug an einem fremden - Server -- und liefert ein Ergebnis, das zu einem ganz anderen Stand - gehoert. Die Pruefungen holen sich ihre Nummer ueber helfer-port; - ein Messwerkzeug, das von Hand gestartet wird, braucht wenigstens - diese eine Frage. */ -{ - const netz = await import("node:net"); - const frei = await new Promise((fertig) => { - const s = netz.createServer(); - s.once("error", () => fertig(false)); - s.once("listening", () => s.close(() => fertig(true))); - s.listen(PORT, "127.0.0.1"); - }); - if (!frei) { - console.error(`Port ${PORT} ist belegt -- hier laeuft schon etwas. ` - + "Gemessen wuerde sonst ein fremder Stand. Abgebrochen."); - process.exit(3); - } -} +/* DIE NUMMER KOMMT AUS DEM ALPHABET, WIE BEI DEN PRUEFUNGEN + (01.10.2026). Hier stand eine feste 5457 mit einer eigenen, kurzen + Fassung des Waechters daneben. Die konnte weniger als das Original: + Sie kannte den dritten Ausgang nicht (EACCES -- das System gibt den + Port dauerhaft nicht her) und sagte nicht, wie man nachsieht, wer + ihn haelt. Eine Abschrift eines Waechters ist dieselbe Falle wie +import { eigenerPort } from "./helfer-port.mjs"; + eine Abschrift einer Spaltenliste. */ +const PORT = await eigenerPort(import.meta); const ordner = mkdtempSync(join(tmpdir(), "ws-kontrast-")); process.env.WORKSPACE_DB = join(ordner, "workspace.db"); process.env.PORT = String(PORT); diff --git a/server/mess-gifs-handy.mjs b/server/mess-gifs-handy.mjs index 45cb5840..ac439ab3 100644 --- a/server/mess-gifs-handy.mjs +++ b/server/mess-gifs-handy.mjs @@ -33,7 +33,9 @@ import { execFileSync } from "node:child_process"; import { request as httpAnfrage } from "node:http"; import { createServer as httpsServer } from "node:https"; -const PORT = 5431, HP = 5432; +import { eigenerPort } from "./helfer-port.mjs"; +const PORT = await eigenerPort(import.meta); +const HP = await eigenerPort(import.meta, "mess-gifs-handy (HTTPS)", 1); const CREW = "crew.dogfather-universe.com"; const ordner = mkdtempSync(join(tmpdir(), "ws-gifs-")); process.env.WORKSPACE_DB = join(ordner, "workspace.db"); diff --git a/server/mess-hand-personen.mjs b/server/mess-hand-personen.mjs index a3294b9d..9008b6e9 100644 --- a/server/mess-hand-personen.mjs +++ b/server/mess-hand-personen.mjs @@ -16,10 +16,11 @@ dieselbe Seite, und die Unterschiede werden AUFGEZAEHLT. SIE PRUEFT NICHTS und meldet keinen Fehlschlag. Sie macht eine Liste - und zwei Bilder, auf denen man nachsehen kann. Deshalb `mess-` und - nicht `pruef-`: Die Portvergabe leitet sich aus den `pruef-`-Namen - ab, und eine Messdatei darf die Nummern der Pruefungen nicht - verschieben. + und zwei Bilder, auf denen man nachsehen kann. Sie heisst `mess-` und nicht `pruef-`: Beide Sorten leiten ihre + Portnummer aus der Stelle im Alphabet ab, aber jede aus IHRER + eigenen Liste und in ihrem eigenen Bereich (Pruefungen ab 5000, + Messungen ab 5900). So verschiebt eine neue Messdatei die Nummern + der Pruefungen nicht -- und umgekehrt. EIGENE WEGWERF-DATENBANK, NIE DIE ECHTE. Es entstehen echte Personen und echte Protokollzeilen; in einem laufenden System waeren das @@ -34,7 +35,9 @@ import { execFileSync } from "node:child_process"; import { request as httpAnfrage } from "node:http"; import { createServer as httpsServer } from "node:https"; -const PORT = 5405, HP = 5406; +import { eigenerPort } from "./helfer-port.mjs"; +const PORT = await eigenerPort(import.meta); +const HP = await eigenerPort(import.meta, "mess-hand-personen (HTTPS)", 1); const CREW = "crew.dogfather-universe.com"; const ordner = mkdtempSync(join(tmpdir(), "ws-hand-pers-")); process.env.WORKSPACE_DB = join(ordner, "workspace.db"); diff --git a/server/mess-kachelreihen.mjs b/server/mess-kachelreihen.mjs index d4ebb018..172e8cc1 100644 --- a/server/mess-kachelreihen.mjs +++ b/server/mess-kachelreihen.mjs @@ -29,9 +29,11 @@ Sie prüft NICHTS und meldet keinen Fehlschlag. Sie beantwortet eine Frage, die man vor jeder Umsortierung stellen muss. - Sie heißt `mess-` und nicht `pruef-`: Die Portvergabe leitet sich - aus den `pruef-`-Namen ab, und eine Messdatei darf die Nummern der - Prüfungen nicht verschieben. + Sie heisst `mess-` und nicht `pruef-`: Beide Sorten leiten ihre + Portnummer aus der Stelle im Alphabet ab, aber jede aus IHRER + eigenen Liste und in ihrem eigenen Bereich (Pruefungen ab 5000, + Messungen ab 5900). So verschiebt eine neue Messdatei die Nummern + der Pruefungen nicht -- und umgekehrt. Aufrufen mit: node server/mess-kachelreihen.mjs Nur eine Rolle: ROLLE=modi node server/mess-kachelreihen.mjs @@ -45,7 +47,9 @@ import { execFileSync } from "node:child_process"; import { request as httpAnfrage } from "node:http"; import { createServer as httpsServer } from "node:https"; -const PORT = 5387, HP = 5388; +import { eigenerPort } from "./helfer-port.mjs"; +const PORT = await eigenerPort(import.meta); +const HP = await eigenerPort(import.meta, "mess-kachelreihen (HTTPS)", 1); const CREW = "crew.dogfather-universe.com"; const ordner = mkdtempSync(join(tmpdir(), "ws-kachelreihen-")); process.env.WORKSPACE_DB = join(ordner, "workspace.db"); diff --git a/server/mess-kopfleiste.mjs b/server/mess-kopfleiste.mjs index d4c4f271..5913bef6 100644 --- a/server/mess-kopfleiste.mjs +++ b/server/mess-kopfleiste.mjs @@ -20,7 +20,8 @@ import { mkdtempSync, rmSync } from "node:fs"; import { tmpdir } from "node:os"; import { join } from "node:path"; -const PORT = 5471; +import { eigenerPort } from "./helfer-port.mjs"; +const PORT = await eigenerPort(import.meta); const ordner = mkdtempSync(join(tmpdir(), "ws-kopf-")); process.env.WORKSPACE_DB = join(ordner, "workspace.db"); process.env.PORT = String(PORT); diff --git a/server/mess-notizblock.mjs b/server/mess-notizblock.mjs index bbea436f..19c596fd 100644 --- a/server/mess-notizblock.mjs +++ b/server/mess-notizblock.mjs @@ -56,21 +56,16 @@ process.env.WORKSPACE_DB = join(ordner, "workspace.db"); import { notbremse } from "./helfer-notbremse.mjs"; import { zertifikatBauen } from "./helfer-openssl.mjs"; -/* Eine feste Nummer -- `eigenerPort` leitet seine aus der Stelle im - Alphabet der PRUEFdateien ab, und dieses Werkzeug ist keine. - Geprueft wird trotzdem, ob sie frei ist: Sonst misst man an einem - fremden Server und bekommt ein Bild von einem anderen Stand. */ -const PORT = 5461; -{ - const netz = await import("node:net"); - const frei = await new Promise((fertig) => { - const s = netz.createServer(); - s.once("error", () => fertig(false)); - s.once("listening", () => s.close(() => fertig(true))); - s.listen(PORT, "127.0.0.1"); - }); - if (!frei) { console.error(`Port ${PORT} ist belegt. Abgebrochen.`); process.exit(3); } -} +/* DIE NUMMER KOMMT AUS DEM ALPHABET (01.10.2026). Hier stand: „eine + feste Nummer -- `eigenerPort` leitet seine aus der Stelle im + Alphabet der PRUEFdateien ab, und dieses Werkzeug ist keine." Das + stimmte, war aber die falsche Schlussfolgerung: Statt den Waechter + zu meiden, leiten die Messdateien jetzt aus IHRER eigenen Liste ab, + in einem eigenen Bereich ab 5900. Die abgeschriebene Kurzfassung, + die hier stand, kannte den dritten Ausgang nicht (EACCES) und sagte + auch nicht, wie man nachsieht, wer den Port haelt. */ +import { eigenerPort } from "./helfer-port.mjs"; +const PORT = await eigenerPort(import.meta); process.env.PORT = `${PORT}`; process.env.SITE_ACCESS_SECRET = "lokaler-test"; @@ -185,7 +180,11 @@ const { request: httpAnfrage } = await import("node:http"); const schluesselDatei = join(ordner, "m.key"); const zertDatei = join(ordner, "m.crt"); zertifikatBauen(schluesselDatei, zertDatei, CREW); -const HTTPS_PORT = PORT + 1; +/* NICHT `PORT + 1`: `portNummer` ueberspringt gesperrte Nummern, + deshalb kann die naechste Zahl die NUMMER DER NAECHSTEN DATEI sein, + sobald einmal eine Sperre dazwischenliegt. Heute liegt keine dort -- + das ist Glueck, kein Entwurf. Die zweite Nummer gibt es als nr=1. */ +const HTTPS_PORT = await eigenerPort(import.meta, "mess-notizblock (HTTPS)", 1); const vorbau = httpsServer({ key: readFileSync(schluesselDatei), cert: readFileSync(zertDatei) }, (von, nach) => { const weiter = httpAnfrage({ host: "127.0.0.1", port: PORT, path: von.url, diff --git a/server/mess-quer.mjs b/server/mess-quer.mjs index 6c3a420c..1b3c2ddf 100644 --- a/server/mess-quer.mjs +++ b/server/mess-quer.mjs @@ -29,8 +29,9 @@ const HIER = dirname(fileURLToPath(import.meta.url)); const ordner = mkdtempSync(join(tmpdir(), "mess-reakt-")); process.env.WORKSPACE_DB = join(ordner, "workspace.db"); -const PORT = 5491; -const HTTPS_PORT = PORT + 1; +import { eigenerPort } from "./helfer-port.mjs"; +const PORT = await eigenerPort(import.meta); +const HTTPS_PORT = await eigenerPort(import.meta, "mess-quer (HTTPS)", 1); process.env.PORT = `${PORT}`; process.env.SITE_ACCESS_SECRET = "lokaler-test"; process.env.SITE_PUBLIC_LAUNCH_AT = "2020-01-01T00:00:00+01:00"; diff --git a/server/mess-reaktion.mjs b/server/mess-reaktion.mjs index 97fb1471..72e5a55f 100644 --- a/server/mess-reaktion.mjs +++ b/server/mess-reaktion.mjs @@ -29,8 +29,9 @@ const HIER = dirname(fileURLToPath(import.meta.url)); const ordner = mkdtempSync(join(tmpdir(), "mess-reakt-")); process.env.WORKSPACE_DB = join(ordner, "workspace.db"); -const PORT = 5483; -const HTTPS_PORT = PORT + 1; +import { eigenerPort } from "./helfer-port.mjs"; +const PORT = await eigenerPort(import.meta); +const HTTPS_PORT = await eigenerPort(import.meta, "mess-reaktion (HTTPS)", 1); process.env.PORT = `${PORT}`; process.env.SITE_ACCESS_SECRET = "lokaler-test"; process.env.SITE_PUBLIC_LAUNCH_AT = "2020-01-01T00:00:00+01:00"; diff --git a/server/mess-seiteninhalt.mjs b/server/mess-seiteninhalt.mjs index a54ae415..d50f5824 100644 --- a/server/mess-seiteninhalt.mjs +++ b/server/mess-seiteninhalt.mjs @@ -21,7 +21,8 @@ import { tmpdir } from "node:os"; import { join } from "node:path"; const SEITE = process.argv[2] || "entwicklung.html"; -const PORT = 5461; +import { eigenerPort } from "./helfer-port.mjs"; +const PORT = await eigenerPort(import.meta); const ordner = mkdtempSync(join(tmpdir(), "ws-inhalt-")); process.env.WORKSPACE_DB = join(ordner, "workspace.db"); process.env.PORT = String(PORT); diff --git a/server/mess-sichtbarkeit.mjs b/server/mess-sichtbarkeit.mjs index f0b19fa5..9a43c03b 100644 --- a/server/mess-sichtbarkeit.mjs +++ b/server/mess-sichtbarkeit.mjs @@ -23,9 +23,9 @@ import { mkdtempSync, rmSync } from "node:fs"; import { tmpdir } from "node:os"; import { join } from "node:path"; import { request as httpAnfrage } from "node:http"; -import { portMussFreiSein } from "./helfer-port.mjs"; +import { eigenerPort } from "./helfer-port.mjs"; -const PORT = await portMussFreiSein(4496, "mess-sichtbarkeit"); +const PORT = await eigenerPort(import.meta); const ordner = mkdtempSync(join(tmpdir(), "ws-mess-")); process.env.WORKSPACE_DB = join(ordner, "workspace.db"); process.env.PORT = String(PORT); diff --git a/server/mess-startseite.mjs b/server/mess-startseite.mjs index e94bc41c..3e034f48 100644 --- a/server/mess-startseite.mjs +++ b/server/mess-startseite.mjs @@ -26,9 +26,9 @@ import { mkdtempSync, rmSync } from "node:fs"; import { tmpdir } from "node:os"; import { join } from "node:path"; import { fileURLToPath } from "node:url"; -import { portMussFreiSein } from "./helfer-port.mjs"; +import { eigenerPort } from "./helfer-port.mjs"; -const PORT = await portMussFreiSein(4471, "mess-startseite"); +const PORT = await eigenerPort(import.meta); const ordner = mkdtempSync(join(tmpdir(), "ws-mess-")); process.env.WORKSPACE_DB = join(ordner, "workspace.db"); process.env.PORT = String(PORT); diff --git a/server/mess-support-runde.mjs b/server/mess-support-runde.mjs index b1f84a98..b006a582 100644 --- a/server/mess-support-runde.mjs +++ b/server/mess-support-runde.mjs @@ -39,7 +39,9 @@ import { execFileSync } from "node:child_process"; import { request as httpAnfrage } from "node:http"; import { createServer as httpsServer } from "node:https"; -const PORT = 5411, HP = 5412; +import { eigenerPort } from "./helfer-port.mjs"; +const PORT = await eigenerPort(import.meta); +const HP = await eigenerPort(import.meta, "mess-support-runde (HTTPS)", 1); const CREW = "crew.dogfather-universe.com"; const ordner = mkdtempSync(join(tmpdir(), "ws-supportrunde-")); process.env.WORKSPACE_DB = join(ordner, "workspace.db"); diff --git a/server/mess-support-ueberstand.mjs b/server/mess-support-ueberstand.mjs index a1246af5..88873d03 100644 --- a/server/mess-support-ueberstand.mjs +++ b/server/mess-support-ueberstand.mjs @@ -19,7 +19,8 @@ import { mkdtempSync, rmSync } from "node:fs"; import { tmpdir } from "node:os"; import { join } from "node:path"; -const PORT = 5441; +import { eigenerPort } from "./helfer-port.mjs"; +const PORT = await eigenerPort(import.meta); const ordner = mkdtempSync(join(tmpdir(), "ws-ueber-")); process.env.WORKSPACE_DB = join(ordner, "workspace.db"); process.env.PORT = String(PORT); diff --git a/server/mess-vanvan-karte.mjs b/server/mess-vanvan-karte.mjs index b5401ab6..e00b05ed 100644 --- a/server/mess-vanvan-karte.mjs +++ b/server/mess-vanvan-karte.mjs @@ -40,9 +40,9 @@ import { mkdtempSync, rmSync } from "node:fs"; import { tmpdir } from "node:os"; import { join } from "node:path"; -import { portMussFreiSein } from "./helfer-port.mjs"; +import { eigenerPort } from "./helfer-port.mjs"; -const PORT = await portMussFreiSein(5493, "mess-vanvan-karte"); +const PORT = await eigenerPort(import.meta); const ordner = mkdtempSync(join(tmpdir(), "ws-vanvan-")); process.env.WORKSPACE_DB = join(ordner, "workspace.db"); process.env.PORT = String(PORT); diff --git a/server/pruef-portnummern.mjs b/server/pruef-portnummern.mjs index 409fdb25..bab08c3d 100644 --- a/server/pruef-portnummern.mjs +++ b/server/pruef-portnummern.mjs @@ -20,8 +20,11 @@ sie faellt nur niemandem auf, bis zwei Laeufe kollidieren. ===================================================================== */ -import { readdirSync, readFileSync } from "node:fs"; -import { eigenerPort, portNummer } from "./helfer-port.mjs"; +import { mkdtempSync, readdirSync, readFileSync, rmSync, writeFileSync } from "node:fs"; +import { tmpdir } from "node:os"; +import { join } from "node:path"; +import { pathToFileURL } from "node:url"; +import { eigenerPort, portNummer, MESS_BASIS, GESPERRT } from "./helfer-port.mjs"; let ok_ = 0, fehl = 0; const ok = (b, text) => { if (b) { ok_++; console.log(" ok " + text); } @@ -30,6 +33,11 @@ const ok = (b, text) => { if (b) { ok_++; console.log(" ok " + text); } const ORDNER = new URL(".", import.meta.url).pathname.replace(/^\/([A-Za-z]:)/, "$1"); const dateien = readdirSync(ORDNER) .filter((f) => f.startsWith("pruef-") && f.endsWith(".mjs")).sort(); +/* DIE MESSDATEIEN GEHOEREN DAZU (01.10.2026). Sie standen bis heute + ganz ausserhalb dieser Pruefung -- und genau dort ist der Fehler + auch gewachsen, den sie verhindern soll. */ +const messen = readdirSync(ORDNER) + .filter((f) => f.startsWith("mess-") && f.endsWith(".mjs")).sort(); console.log("\n=== 1. Niemand traegt eine Nummer von Hand ein ==="); const vonHand = []; @@ -186,6 +194,247 @@ try { await eigenerPort(import.meta, "Gegenprobe", 7); } catch (f) { zuHoheNummer = /Nummern je Datei/.test(f?.message || ""); } ok(zuHoheNummer, "und eine dritte Nummer je Datei gibt es nicht"); +console.log("\n=== 5. Die Messdateien leiten ihre Nummer auch ab (01.10.2026) ==="); +/* WAS HIER AM 01.10. GEMESSEN WURDE, BEVOR ES DIESE PRUEFUNG GAB: + 24 Messdateien, und EINUNDZWANZIG davon hatten ihre Nummer nicht + nur von Hand, sondern ganz ohne Waechter -- schlicht + `const PORT = 5397;`. Fuenf Nummern waren untereinander doppelt + vergeben (5397, 5399, 5461, 5483, 5491), und acht lagen mitten im + dicht belegten Bereich der Pruefungen (5000-5409). + + Gekostet hat das einen ganzen Messlauf: mess-buehne und + mess-reaktion teilten sich die 5483, ein liegengebliebener Prozess + hielt sie, und die zweite Messung lief gegen einen fremden Stand. + + Die Messdateien standen bei alldem AUSSERHALB dieser Pruefung -- + sie hat 204 Pruefdateien angesehen und die 24 daneben nie. Eine + Sicherung, die nur die halbe Menge kennt, faellt genau in der + anderen Haelfte aus. */ +{ + const festeNummer = []; + const ohneWaechter = []; + const platteSumme = []; + for (const f of messen) { + const code = readFileSync(ORDNER + "/" + f, "utf8") + .replace(/\/\*[\s\S]*?\*\//g, "").replace(/^\s*\/\/.*$/gm, ""); + if (/const\s+\w*PORT\w*\s*=\s*\d/.test(code) + || /portMussFreiSein\(\s*\d/.test(code)) festeNummer.push(f); + /* `PORT + 1` IST KEINE ABLEITUNG. `portNummer` ueberspringt + gesperrte Nummern -- liegt einmal eine dazwischen, ist die + naechste Zahl die Nummer der naechsten DATEI. Heute liegt dort + keine; das ist Glueck, kein Entwurf. */ + if (/PORT\s*\+\s*1\b/.test(code)) platteSumme.push(f); + const startetServer = /import\(\s*["'`]\.\/index\.js["'`]\s*\)/.test(code) + || /process\.env\.PORT\s*=/.test(code); + if (startetServer && !/eigenerPort\(\s*import\.meta/.test(code)) ohneWaechter.push(f); + } + ok(messen.length > 10, `${messen.length} Messdateien angesehen`); + ok(festeNummer.length === 0, + `keine traegt eine Nummer von Hand (${festeNummer.slice(0, 4).join(", ") || "—"})`); + ok(ohneWaechter.length === 0, + `jede, die einen Server startet, leitet ihre Nummer ab (${ohneWaechter.slice(0, 4).join(", ") || "—"})`); + ok(platteSumme.length === 0, + `keine rechnet ihre zweite Nummer als PORT + 1 (${platteSumme.slice(0, 4).join(", ") || "—"})`); + + /* ---- KANN DIESE ERKENNUNG AUCH NEIN SAGEN? ----------------------- + Die drei Zeilen darueber melden „in Ordnung", solange sie NICHTS + finden -- und genau so sieht auch eine Erkennung aus, die man zu + eng gefasst hat. Am 01.10. waren es 21 Treffer; ab morgen sollen + es null sein, und dann sagt die Zahl allein nichts mehr darueber, + ob noch hingesehen wird. */ + const alsFest = (c) => /const\s+\w*PORT\w*\s*=\s*\d/.test(c) + || /portMussFreiSein\(\s*\d/.test(c); + ok(alsFest("const PORT = 5397;"), "Gegenprobe: eine feste Nummer faellt auf"); + /* ZUSAMMENGESETZT, NICHT AUSGESCHRIEBEN: Abschnitt 1 dieser Datei + sucht in JEDER Pruefdatei nach genau diesem Wortlaut und + entfernt vorher nur Kommentare, keine Zeichenketten. Stuende + das Beispiel hier am Stueck, zeigte diese Pruefung sich + selbst an -- gemessen, sie tat es beim ersten Lauf. */ + ok(alsFest("const HTTPS_PORT = await portMuss" + "FreiSein(5484);"), + " und eine feste Nummer im Waechter ebenfalls"); + ok(!alsFest("const PORT = await eigenerPort(import.meta);"), + " wer ableitet, faellt NICHT auf"); + ok(/PORT\s*\+\s*1/.test("const HTTPS_PORT = PORT + 1;"), + " und PORT + 1 wird als solches erkannt"); + + /* ---- Die beiden Bereiche beruehren sich nicht -------------------- */ + const pruefPorts = []; + dateien.forEach((f, i) => pruefPorts.push(portNummer(i * 2), portNummer(i * 2 + 1))); + const messPorts = []; + messen.forEach((f, i) => messPorts.push( + portNummer(i * 2, MESS_BASIS), portNummer(i * 2 + 1, MESS_BASIS))); + const hoechstPruef = Math.max(...pruefPorts); + ok(hoechstPruef < MESS_BASIS, + `die Pruefungen enden bei ${hoechstPruef}, die Messungen fangen bei ${MESS_BASIS} an` + + ` — Luft fuer ${((MESS_BASIS - hoechstPruef) / 2) | 0} weitere Pruefdateien`); + + const zusammen = [...pruefPorts, ...messPorts]; + ok(new Set(zusammen).size === zusammen.length, + `alle ${zusammen.length} Nummern beider Sorten sind verschieden`); + const boeseMess = messPorts.filter((p) => GESPERRT.has(p)); + ok(boeseMess.length === 0, + `keine Messnummer steht auf der Sperrliste (${boeseMess.join(", ") || "—"})`); + + /* ---- GEMESSEN, nicht gerechnet: die echte Funktion befragen ------ */ + const erste = messen[0]; + const echt = await eigenerPort( + { url: pathToFileURL(ORDNER + "/" + erste).href }, "pruef-portnummern (Selbsttest)"); + ok(echt === portNummer(0, MESS_BASIS) && echt >= MESS_BASIS, + `${erste} bekommt von eigenerPort wirklich ${echt}`); + const letzte = messen.at(-1); + const echt2 = await eigenerPort( + { url: pathToFileURL(ORDNER + "/" + letzte).href }, "pruef-portnummern (Selbsttest)", 1); + ok(echt2 === portNummer((messen.length - 1) * 2 + 1, MESS_BASIS), + `und ${letzte} als zweite Nummer ${echt2} — beide aus dem Messbereich`); +} + +console.log("\n=== 6. Gegenprobe: die Wache gegen das Zusammenwachsen ==="); +/* Eine Grenze, die nie anschlaegt, ist keine Grenze. Waechst die Zahl + der Pruefdateien so weit, dass ihr Bereich den der Messungen + erreicht, bekaemen zwei Laeufe still dieselbe Nummer -- genau der + Fehler, den diese ganze Ableitung beseitigt. + + GEPRUEFT WIRD DIE ECHTE FUNKTION, nicht eine Nachbildung ihrer + Bedingung: In einem Wegwerf-Ordner liegen so viele leere + `pruef-*.mjs`, dass die letzte ueber MESS_BASIS hinauskaeme. Ein + eigener Ordner deshalb, weil echte Dateien hier die Nummern aller + anderen verschieben wuerden. */ +{ + const wegwerf = mkdtempSync(join(tmpdir(), "portwache-")); + const noetig = Math.ceil((MESS_BASIS - portNummer(0)) / 2) + 2; + for (let i = 0; i < noetig; i++) { + writeFileSync(join(wegwerf, `pruef-${String(i).padStart(5, "0")}.mjs`), ""); + } + const letzte = join(wegwerf, `pruef-${String(noetig - 1).padStart(5, "0")}.mjs`); + let sagte = ""; + try { await eigenerPort({ url: pathToFileURL(letzte).href }, "Gegenprobe"); } + catch (f) { sagte = f?.message || ""; } + ok(/stoesst an den der Messdateien/.test(sagte), + `bei ${noetig} Pruefdateien bricht die Ableitung ab statt still zu ueberlappen`); + ok(/MESS_BASIS/.test(sagte) && /hochsetzen/.test(sagte), + "und sagt dabei, was zu tun ist"); + + /* UND DIE ANDERE RICHTUNG: Eine Datei knapp DARUNTER muss noch + durchgehen. Ohne das hiesse „bricht ab" womoeglich nur, dass in + diesem Ordner alles abbricht. */ + const knapp = join(wegwerf, `pruef-${String(noetig - 30).padStart(5, "0")}.mjs`); + let ging = 0; + try { ging = await eigenerPort({ url: pathToFileURL(knapp).href }, "Gegenprobe"); } + catch { ging = 0; } + ok(ging > 0 && ging < MESS_BASIS, + `eine Datei knapp darunter bekommt weiter ihre Nummer (${ging})`); + rmSync(wegwerf, { recursive: true, force: true }); +} + +console.log("\n=== 7. Die uebrigen Werkzeuge, die einen Server starten ==="); +/* BEIM UMBAU AM 01.10. AUFGEFALLEN: Es gibt eine dritte Sorte. Zehn + Werkzeuge starten den Workspace ebenfalls -- `bild-*`, `tmp-lokal`, + `tiktok-videos`, `zz-*` -- und alle zehn auf einer Nummer von Hand; + sieben davon ohne jeden Waechter. + + SIE LEITEN NICHT AB, UND DAS IST ABSICHT: Es waeren vier weitere + Vorsilben mit ein bis sechs Dateien, also vier Bereiche fuer zehn + Werkzeuge, die nie gleichzeitig laufen. Der saubere Weg waere, sie + `mess-` zu nennen -- ein eigener Schritt. + + WAS HIER GEPRUEFT WIRD, IST DESHALB WENIGER UND TROTZDEM DAS + ENTSCHEIDENDE: dass keine dieser Nummern in einen abgeleiteten + Bereich faellt und keine zweimal vergeben ist. Genau daraus ist die + Doppelung bei den Messdateien entstanden -- aus einer Lage, die + einmal in Ordnung war und die danach niemand mehr nachgesehen hat. */ +{ + const uebrige = readdirSync(ORDNER) + .filter((f) => f.endsWith(".mjs") + && !f.startsWith("pruef-") && !f.startsWith("mess-") && !f.startsWith("helfer-")) + .filter((f) => /process\.env\.PORT\s*=/.test(readFileSync(ORDNER + "/" + f, "utf8"))) + .sort(); + ok(uebrige.length > 0, `${uebrige.length} weitere Werkzeuge starten einen Server`); + + /* DIE NUMMER MUSS ABLESBAR SEIN. Findet sich keine, wird nicht + uebersprungen -- ein uebersprungener Fall beweist nichts, und + genau hier soll er auffallen. */ + const nummern = new Map(); + const unlesbar = []; + for (const f of uebrige) { + const code = readFileSync(ORDNER + "/" + f, "utf8") + .replace(/\/\*[\s\S]*?\*\//g, "").replace(/^\s*\/\/.*$/gm, ""); + const t = code.match(/process\.env\.PORT\s*=\s*[`"']?(\d{3,5})/) + || code.match(/const PORT\s*=\s*(\d{3,5})/) + || code.match(/portMussFreiSein\(\s*(\d{3,5})/); + if (!t) { unlesbar.push(f); continue; } + nummern.set(f, Number(t[1])); + } + ok(unlesbar.length === 0, + `bei jedem steht die Nummer im Quelltext (${unlesbar.join(", ") || "—"})`); + + const werte = [...nummern.values()]; + const doppelte = werte.filter((p, i) => werte.indexOf(p) !== i); + ok(werte.length > 0 && doppelte.length === 0, + `keine ihrer ${werte.length} Nummern ist doppelt (${[...new Set(doppelte)].join(", ") || "—"})`); + + const pruefPorts2 = []; + dateien.forEach((f, i) => pruefPorts2.push(portNummer(i * 2), portNummer(i * 2 + 1))); + const messPorts2 = []; + messen.forEach((f, i) => messPorts2.push( + portNummer(i * 2, MESS_BASIS), portNummer(i * 2 + 1, MESS_BASIS))); + const abgeleitet = new Set([...pruefPorts2, ...messPorts2]); + const drin = [...nummern].filter(([, p]) => abgeleitet.has(p)); + ok(werte.length > 0 && drin.length === 0, + "keine liegt in einem abgeleiteten Bereich" + + ` (${drin.map(([f, p]) => `${f}:${p}`).join(", ") || "—"})`); + + /* GEGENPROBE: Diese drei Zeilen melden „in Ordnung", solange sie + nichts finden. Also einmal zeigen, dass sie etwas finden KOENNEN. */ + const probe = [...abgeleitet][0]; + ok(abgeleitet.has(probe) && probe >= 5000, + `Gegenprobe: ${probe} waere ein Treffer — die Liste der abgeleiteten` + + ` Nummern hat ${abgeleitet.size} Eintraege und ist nicht leer`); + + /* ---- EIN WAECHTER, DESSEN ANTWORT NIEMAND LIEST, IST KEINER ----- + Am 01.10. in allen sechs `bild-*.mjs` gefunden: + + await portMussFreiSein(4315, "das Bildwerkzeug"); + process.env.PORT = "4315"; + const BASIS = "http://127.0.0.1:4315"; + + Der Waechter lief, meldete nichts und wirkte nicht. Gibt das + System den Port dauerhaft nicht her, weicht er auf Port + 4000 + aus und GIBT DIE NEUE NUMMER ZURUECK -- diese Werkzeuge hoerten + danach trotzdem auf der alten und stuerzten mit `listen EACCES` + ab, also mit genau dem Fehler, gegen den er gebaut wurde. + + Dazu stand die Zahl dreimal je Datei. Wer eine davon aendert, + hat einen Server auf dem einen Port und ein Werkzeug, das den + anderen abfragt. */ + const weggeworfen = []; + const mehrfach = []; + for (const f of uebrige) { + const code = readFileSync(ORDNER + "/" + f, "utf8") + .replace(/\/\*[\s\S]*?\*\//g, "").replace(/^\s*\/\/.*$/gm, ""); + if (/^\s*await\s+(portMussFreiSein|eigenerPort)\(/m.test(code)) weggeworfen.push(f); + const n = nummern.get(f); + if (n !== undefined) { + const wieOft = (code.match(new RegExp(String(n), "g")) || []).length; + if (wieOft > 1) mehrfach.push(`${f}:${wieOft}x`); + } + } + ok(weggeworfen.length === 0, + `jedes benutzt die Antwort des Waechters (${weggeworfen.join(", ") || "—"})`); + ok(mehrfach.length === 0, + `und schreibt seine Nummer nur einmal hin (${mehrfach.join(", ") || "—"})`); + + /* GEGENPROBE zu beiden: Erkennen sie den Rueckschritt auch? */ + const wirftWeg = (c) => /^\s*await\s+(portMussFreiSein|eigenerPort)\(/m.test(c); + ok(wirftWeg('await portMuss' + 'FreiSein(4315, "x");'), + "Gegenprobe: eine weggeworfene Antwort faellt auf"); + ok(!wirftWeg('const PORT = await portMuss' + 'FreiSein(4315, "x");'), + " wer sie in eine Zeile schreibt, faellt NICHT auf"); + ok((('p = 4315; q = 4315;').match(/4315/g) || []).length === 2, + " und eine zweimal genannte Nummer wird gezaehlt"); + + console.log(` ${[...nummern].map(([f, p]) => `${f.replace(/\.mjs$/, "")} ${p}`).join(", ")}`); +} + console.log(`\n${ok_} Pruefungen, ${fehl} Fehler`); console.log(fehl ? "NICHT IN ORDNUNG\n" : "ALLES IN ORDNUNG\n"); process.exit(fehl ? 1 : 0); diff --git a/server/pruef-ports.mjs b/server/pruef-ports.mjs index cf293f05..2111ae88 100644 --- a/server/pruef-ports.mjs +++ b/server/pruef-ports.mjs @@ -62,9 +62,9 @@ let fehler = 0, geprueft = 0, offen = 0; const ok = (b, t) => { geprueft++; console.log((b ? " ok " : " FEHL ") + t); if (!b) fehler++; }; const unklar = (t) => { offen++; console.log(" -- " + t); }; -const { portNummer, AUSWEICHEN, GESPERRT } = await import("./helfer-port.mjs"); +const { portNummer, AUSWEICHEN, GESPERRT, MESS_BASIS } = await import("./helfer-port.mjs"); -console.log("=== Kann jede Pruefung ihren Port bekommen? ==="); +console.log("=== Kann jede Pruefung und jede Messung ihren Port bekommen? ==="); console.log(""); /* DIE LISTE WIRD GELESEN, NICHT GEPFLEGT -- und zwar mit derselben @@ -76,7 +76,18 @@ const dateien = readdirSync(HIER) .filter((f) => f.startsWith("pruef-") && f.endsWith(".mjs")) .sort(); +/* DIE MESSDATEIEN GEHOEREN SEIT DEM 01.10.2026 DAZU. Sie hatten ihre + Nummern bis dahin von Hand -- einundzwanzig von 24 sogar ohne + jeden Waechter -- und lagen teils mitten im Bereich der + Pruefungen. Jetzt leiten sie ab, aus ihrer eigenen Liste, ab + MESS_BASIS. Dieser Bereich ist neu, und ob der Rechner ihn hergibt, + war eine Annahme, bis er hier durchprobiert wurde. */ +const messen = readdirSync(HIER) + .filter((f) => f.startsWith("mess-") && f.endsWith(".mjs")) + .sort(); + ok(dateien.length > 50, `${dateien.length} Pruefdateien gefunden`); +ok(messen.length > 10, `${messen.length} Messdateien dazu`); ok(dateien.includes("pruef-ports.mjs"), "diese Datei steht selbst in der Liste -- sonst waere die Regel eine andere" + " als die, nach der die Nummern vergeben werden"); @@ -98,8 +109,28 @@ const nummern = []; for (let i = 0; i < dateien.length; i++) { for (const nr of [0, 1]) nummern.push({ datei: dateien[i], nr, port: portNummer(i * 2 + nr) }); } -ok(nummern.length === dateien.length * 2, - `${nummern.length} Nummern fuer ${dateien.length} Dateien (je zwei)`); +/* IN DIESELBE LISTE, nicht in eine zweite: So erben die Messnummern + jeden Abschnitt dieser Datei -- Doppelungen, Sperrliste, die Frage + ans System, den Ausweichport. Eine eigene Liste daneben waere die, + die beim naechsten Abschnitt vergessen wird. */ +for (let i = 0; i < messen.length; i++) { + for (const nr of [0, 1]) { + nummern.push({ datei: messen[i], nr, port: portNummer(i * 2 + nr, MESS_BASIS) }); + } +} +const wieViele = dateien.length + messen.length; +ok(nummern.length === wieViele * 2, + `${nummern.length} Nummern fuer ${wieViele} Dateien (je zwei)`); + +/* DASS SICH DIE BEIDEN BEREICHE NICHT BERUEHREN, steht eine Zeile + weiter unten schon als „keine Nummer doppelt" drin. Hier zusaetzlich + in Klartext, weil die Zahl das Interessante ist: Wie viele + Pruefdateien passen noch dazwischen, bevor es eng wird? */ +const hoechstPruef = Math.max(...nummern + .filter((x) => x.datei.startsWith("pruef-")).map((x) => x.port)); +ok(hoechstPruef < MESS_BASIS, + `die Pruefungen enden bei ${hoechstPruef}, die Messungen fangen bei ${MESS_BASIS} an` + + ` — Luft fuer ${((MESS_BASIS - hoechstPruef) / 2) | 0} weitere Pruefdateien`); const doppelt = nummern .map((x) => x.port) diff --git a/server/tiktok-videos.mjs b/server/tiktok-videos.mjs index 52e5eb1c..d71b5c8f 100644 --- a/server/tiktok-videos.mjs +++ b/server/tiktok-videos.mjs @@ -80,7 +80,6 @@ import { fileURLToPath } from "node:url"; import { request as httpAnfrage } from "node:http"; import { execFileSync, spawnSync } from "node:child_process"; import { createServer as httpsServer } from "node:https"; -import { createServer as netServer } from "node:net"; import { zertifikatBauen } from "./helfer-openssl.mjs"; const HIER = dirname(fileURLToPath(import.meta.url)); @@ -91,19 +90,18 @@ const CREW = "crew.dogfather-universe.com"; const ordner = mkdtempSync(join(tmpdir(), "tk-video-")); process.env.WORKSPACE_DB = join(ordner, "workspace.db"); -/* Eine eigene Nummer. Frei sein muss sie trotzdem -- sonst filmt - dieses Werkzeug einen fremden Server, und man sieht es dem Bild - nicht an. */ -const PORT = 5471; -{ - const frei = await new Promise((fertig) => { - const s = netServer(); - s.once("error", () => fertig(false)); - s.once("listening", () => s.close(() => fertig(true))); - s.listen(PORT, "127.0.0.1"); - }); - if (!frei) { console.error(`Port ${PORT} ist belegt. Abgebrochen.`); process.exit(3); } -} +/* DER ECHTE WAECHTER, NICHT EINE ABSCHRIFT (01.10.2026). Hier stand + eine kurze eigene Fassung -- und die kannte den dritten Ausgang + nicht: Gibt das System den Port dauerhaft nicht her (EACCES), + meldete sie „belegt" und brach ab, statt auszuweichen. Auf diesem + Rechner ist genau das am 23.09. eingetreten (Port 5040, von einem + Windows-Dienst gehalten). Eine abgeschriebene Sicherung ist + dieselbe Falle wie eine abgeschriebene Liste. + + Frei sein muss die Nummer ohnehin: sonst filmt dieses Werkzeug + einen fremden Server, und man sieht es dem Bild nicht an. */ +const { portMussFreiSein } = await import("./helfer-port.mjs"); +const PORT = await portMussFreiSein(5471, "das Videowerkzeug"); process.env.PORT = `${PORT}`; process.env.SITE_ACCESS_SECRET = "lokaler-test"; @@ -495,6 +493,8 @@ console.log(`Chat: ${treffRaum ? `${imChat} von ${CHAT.length} Nachrichten` : "R /* ---------- Der Vorbau mit dem Zertifikat ------------------------------- */ const key = join(ordner, "v.key"), crt = join(ordner, "v.crt"); zertifikatBauen(key, crt, CREW); +/* NICHT AUS EINER FESTEN ZAHL: Weicht der Waechter oben auf + PORT + 4000 aus, muss der Vorbau mitwandern. */ const HTTPS_PORT = PORT + 1; const vorbau = httpsServer({ key: readFileSync(key), cert: readFileSync(crt) }, (von, nach) => { const weiter = httpAnfrage({