diff --git a/packages/cultnet-ts/src/cultmesh-authority.ts b/packages/cultnet-ts/src/cultmesh-authority.ts index d61f6072..31cbcb61 100644 --- a/packages/cultnet-ts/src/cultmesh-authority.ts +++ b/packages/cultnet-ts/src/cultmesh-authority.ts @@ -366,14 +366,16 @@ export function isLoopbackEndpoint(value: string): boolean { * scheme containing "quic", over a string `System.Uri` parses at all. * * `refusedByCSharpUriShape` runs first here for the same reason it runs first in - * `isLoopbackEndpoint`, and it matters more: `URL` repairs eleven spellings + * `isLoopbackEndpoint`, and it matters more: `URL` accepts eleven spellings * `System.Uri` refuses outright, and every one of them would be *protected* here - * and unprotected in C#. `wss:x`, `wss:host`, `wss:host:8443`, `wss:/host` and - * `wss:///host` have no authority for `System.Uri` to accept; `wss://host\path` - * and `wss://host:8443\` carry a backslash; `wss://ho\tst/m`, `wss://host\t/m`, - * `quic://ho\tst` carry a tab and `wss://host\r\n/m` a CR/LF, which `URL` - * deletes. Letting any of them answer true would clear the channel-protection - * gate on a route C# refuses. + * and unprotected in C#. Only four of the eleven are repairs in the sense of + * `URL` rewriting the host: `wss://ho\tst/m`, `wss://host\t/m` and + * `quic://ho\tst` carry a tab and `wss://host\r\n/m` a CR/LF, all of which `URL` + * deletes. The other seven `URL` simply admits as written: `wss:x`, `wss:host`, + * `wss:host:8443`, `wss:/host` and `wss:///host` have no authority for + * `System.Uri` to accept, and `wss://host\path` and `wss://host:8443\` carry a + * backslash. Letting any of the eleven answer true would clear the + * channel-protection gate on a route C# refuses. * * Two spellings of Soul's 71 still disagree, both the safe way round: C# calls * them protected and this answers false, so a route is refused rather than diff --git a/packages/cultnet-ts/test/cultmesh-authority.test.ts b/packages/cultnet-ts/test/cultmesh-authority.test.ts index dbf5a8d7..e0c47234 100644 --- a/packages/cultnet-ts/test/cultmesh-authority.test.ts +++ b/packages/cultnet-ts/test/cultmesh-authority.test.ts @@ -390,12 +390,18 @@ const CSHARP_PROTECTED_ANSWERS: readonly (readonly [string, boolean])[] = [ // The eleven of the 71 where the two sides still differ, every one of them the // safe way round: C# calls the endpoint protected and TypeScript does not, so a -// route is refused rather than admitted. `refusedByCSharpUriShape` is stricter -// than `System.Uri.TryCreate` on purpose — it also refuses the host repairs that -// would make `isLoopbackEndpoint` lie — and a zone id and a non-breaking-space -// host throw in `URL` before any rule of ours runs. None of them is dialable as -// a browser CultMesh route. Pinned exactly, not merely excluded: if one of these -// starts answering true, or a twelfth spelling joins them, this fails. +// route is refused rather than admitted. They are not one shape. Three carry a +// backslash (`wss:\\host/m`, `wss://host:8443/\`, `QUIC:\\host`) and two have no +// authority for `System.Uri` to accept (`quic:host`, `quic:`); those five +// `refusedByCSharpUriShape` refuses on the raw string, before any host exists to +// repair. Four are host repairs `URL` would make and C# would not — a trailing +// dot on `wss://host./m` and `wss://127.0.0.1./m`, a fullwidth host on the other +// two — which is the same reason that pre-check runs first in +// `isLoopbackEndpoint`. The last two throw in `URL` before any rule of ours +// runs: an IPv6 zone id and a non-breaking space in the host. None of the eleven +// is dialable as a browser CultMesh route. Pinned exactly, not merely excluded: +// if one of these starts answering true, or a twelfth spelling joins them, this +// fails. const STRICTER_THAN_CSHARP: readonly string[] = [ "wss:\\\\host/m", "wss://host./m",