| … | … | @@ -26,7 +26,19 @@ export function generateVhosts (registry) { |
| 26 | 26 | const nodeMap = new Map() |
| 27 | 27 | for (const node of registry.nodes) nodeMap.set(node.petname, node) |
| 28 | 28 | |
| 29 | | for (const h of registry.hosts || []) { |
| 29 | // ★ Wildcard vhosts MUST be emitted last. Apache matches name-based vhosts in configuration |
| 30 | // order, so a `ServerAlias *.7rnx.net` block shadows every specific vhost defined after it. |
| 31 | // Registry order is insertion order, so before this sort any host registered AFTER the |
| 32 | // wildcard silently resolved to the wildcard's backend — pds/p2p only ever worked because |
| 33 | // they predate it. Found when ap.7rnx.net (added later) was answered by the atproto membrane |
| 34 | // on :3399 instead of ap-bridge on :3400, with no error anywhere to indicate why. |
| 35 | const orderedHosts = [...(registry.hosts || [])].sort((a, b) => { |
| 36 | const aw = a.serverName.startsWith('*.') ? 1 : 0 |
| 37 | const bw = b.serverName.startsWith('*.') ? 1 : 0 |
| 38 | return aw - bw |
| 39 | }) |
| 40 | |
| 41 | for (const h of orderedHosts) { |
| 30 | 42 | const node = nodeMap.get(h.node) |
| 31 | 43 | if (!node) continue |
| 32 | 44 | assertSafe(node.ip, 'node ip') |