| … | … | @@ -23,6 +23,23 @@ export function generateVhosts (registry) { |
| 23 | 23 | lines.push('# TLS is supplied by mod_md for any *.7rnx.net ServerName.') |
| 24 | 24 | lines.push('') |
| 25 | 25 | |
| 26 | // ── Connection reuse (server context, applies to every site on this box) ── | |
| 27 | // | |
| 28 | // Every client here is remote: ~95ms RTT to the VPS, and a home backend adds | |
| 29 | // ~110ms more over the VPN. A fresh TCP+TLS handshake therefore costs ~210ms — | |
| 30 | // measured as HALF of a cold page load (fresh 427ms vs reused 210ms on | |
| 31 | // /git/repos). Debian's default KeepAliveTimeout 5 closes the connection | |
| 32 | // between one page view and the next click, so ordinary browsing re-pays that | |
| 33 | // handshake constantly and reads to users as "it randomly needs to warm up". | |
| 34 | // | |
| 35 | // Emitted at TOP LEVEL (not inside a <VirtualHost>) so it covers the apex | |
| 36 | // path-routed site — which serves /git — and not just the host-routed vhosts | |
| 37 | // below. apache2.conf sets this at line ~124 and includes sites-enabled/ at | |
| 38 | // ~238, so this later definition wins. | |
| 39 | lines.push('# Override apache2.conf\'s default of 5 (see git history for the latency measurements).') | |
| 40 | lines.push('KeepAliveTimeout 65') | |
| 41 | lines.push('') | |
| 42 | ||
| 26 | 43 | const nodeMap = new Map() |
| 27 | 44 | for (const node of registry.nodes) nodeMap.set(node.petname, node) |
| 28 | 45 |
| … | … | @@ -1,6 +1,6 @@ |
| 1 | 1 | { |
| 2 | 2 | "name": "7rnx-proxy", |
| 3 | "version": "1.1.0", | |
| 3 | "version": "1.2.0", | |
| 4 | 4 | "description": "Reverse proxy management CLI for 7rnx.net Apache2 server", |
| 5 | 5 | "type": "module", |
| 6 | 6 | "bin": { |
| … | … | @@ -40,6 +40,29 @@ describe('generateVhosts (host mode)', () => { |
| 40 | 40 | hosts: [{ name: 'bad', node: 'x', port: 80, serverName: 'evil.com\n<script>' }] |
| 41 | 41 | }), /unsafe serverName/) |
| 42 | 42 | }) |
| 43 | ||
| 44 | // Every client of this proxy is remote (~95ms RTT to the VPS, ~110ms more over | |
| 45 | // the VPN to a home backend), so a TCP+TLS handshake costs ~210ms — measured half | |
| 46 | // of a cold page load. Debian ships KeepAliveTimeout 5, which drops the connection | |
| 47 | // between one page view and the next click, making the user re-pay that handshake | |
| 48 | // and read as "it randomly needs to warm up again". | |
| 49 | it('emits a KeepAliveTimeout override at SERVER context', () => { | |
| 50 | const out = generateVhosts(registry) | |
| 51 | assert.match(out, /^KeepAliveTimeout 65$/m, 'KeepAliveTimeout emitted') | |
| 52 | ||
| 53 | // Must sit ABOVE the first <VirtualHost>: nested inside one it would apply to | |
| 54 | // that vhost alone, leaving the apex site (which serves /git) on the default 5. | |
| 55 | const ka = out.search(/^KeepAliveTimeout 65$/m) | |
| 56 | const firstVhost = out.indexOf('<VirtualHost') | |
| 57 | assert.ok(ka !== -1 && firstVhost !== -1, 'both directives present') | |
| 58 | assert.ok(ka < firstVhost, 'KeepAliveTimeout precedes the first VirtualHost block') | |
| 59 | }) | |
| 60 | ||
| 61 | // It is global tuning, not per-host, so it must not depend on registry contents. | |
| 62 | it('emits the KeepAliveTimeout override even with no hosts registered', () => { | |
| 63 | const out = generateVhosts({ nodes: [], hosts: [] }) | |
| 64 | assert.match(out, /^KeepAliveTimeout 65$/m) | |
| 65 | }) | |
| 43 | 66 | }) |
| 44 | 67 | |
| 45 | 68 | describe('Registry host methods', () => { |