From 147fb46cdc6ede60dbdcde6025433303c490fe8a Mon Sep 17 00:00:00 2001 From: atlas Date: Wed, 17 Jun 2026 18:22:35 +0200 Subject: [PATCH] nix(forge): derive ROOT_URL scheme from gateway TLS, not always http MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Fixes #1724. The forgejo ROOT_URL was hardcoded `http://` even when the gateway terminates TLS, producing broken clone links and mixed-content redirects for a TLS deployment. Derive the scheme + port from gateway state: `https` (on httpsPort) when the gateway terminates TLS (`gateway.selfSignedTls` or `gateway.tls.certDir` set), `http` (on gateway.port) otherwise — dropping the port suffix on the canonical port for the scheme (80 / 443). The per-agent in-cluster HIVE_FORGE_URL is unaffected (it stays http on the gateway's :80 path); this only changes the public ROOT_URL forgejo advertises. Refreshes the `rootUrl` option description (the TLS scheme is auto-derived now, so the manual-override-for-TLS note is gone). Eval-proven: gateway.selfSignedTls = true → ROOT_URL = https://forge./; false → http://forge./. --- nix/modules/hive-forge.nix | 41 ++++++++++++++++++++++++-------------- 1 file changed, 26 insertions(+), 15 deletions(-) diff --git a/nix/modules/hive-forge.nix b/nix/modules/hive-forge.nix index d81921a8..022dda29 100644 --- a/nix/modules/hive-forge.nix +++ b/nix/modules/hive-forge.nix @@ -12,18 +12,26 @@ let # ROOT_URL forgejo advertises in clone links + outbound URLs. When # served behind the gateway, `cfg.domain` doubles as both the # forgejo `DOMAIN` setting AND the gateway vhost server-name, so - # ROOT_URL just uses it directly (drops the port suffix when the - # gateway is on the canonical port 80). When direct (gateway off - # or `behindGateway = false`), keep the host:port shape so direct - # browser access on `:httpPort` still produces correct links. - # Operators can override via `cfg.rootUrl` for TLS / non-default - # gateway ports / bespoke shapes. + # ROOT_URL just uses it directly (dropping the port suffix on the + # canonical port for the scheme — 80 for http, 443 for https). The + # scheme + port follow what the gateway actually serves: `https` when + # the gateway terminates TLS (a self-signed cert or an external + # `tls.certDir`), `http` otherwise (#1724) — advertising `http://` for + # a TLS gateway produces broken clone links + mixed-content redirects. + # When direct (gateway off or `behindGateway = false`), keep the + # host:httpPort shape so direct browser access still produces correct + # links. Operators can still override via `cfg.rootUrl` for bespoke + # shapes. + gatewayTls = gatewayCfg.selfSignedTls || gatewayCfg.tls.certDir != null; defaultRootUrl = if cfg.behindGateway then let - portSuffix = if gatewayCfg.port == 80 then "" else ":${toString gatewayCfg.port}"; + scheme = if gatewayTls then "https" else "http"; + port = if gatewayTls then gatewayCfg.httpsPort else gatewayCfg.port; + canonicalPort = if gatewayTls then 443 else 80; + portSuffix = if port == canonicalPort then "" else ":${toString port}"; in - "http://${cfg.domain}${portSuffix}/" + "${scheme}://${cfg.domain}${portSuffix}/" else "http://${cfg.domain}:${toString cfg.httpPort}/"; effectiveRootUrl = if cfg.rootUrl != null then cfg.rootUrl else defaultRootUrl; @@ -147,16 +155,19 @@ in description = '' Override the auto-derived forgejo `ROOT_URL`. When `null` (default), `ROOT_URL` is derived from `cfg.domain` + gateway - state: + state, including the scheme: - - `behindGateway = true` → `http://''${cfg.domain}/` (uses - `services.hyperhive.gateway.port` when non-80) + - `behindGateway = true` → `https://''${cfg.domain}/` when the + gateway terminates TLS (`gateway.selfSignedTls = true` or + `gateway.tls.certDir` set), otherwise `http://''${cfg.domain}/`. + A non-canonical gateway port (`gateway.port` for http, + `gateway.httpsPort` for https) is appended as `:`. - `behindGateway = false` → `http://''${cfg.domain}:''${cfg.httpPort}/` - Set this to a fully-qualified URL when running behind TLS - termination (`https://...`), a non-default gateway port, or - a bespoke shape. Must end with `/` per forgejo's `ROOT_URL` - contract. + The TLS scheme is derived automatically now, so you only need to + set this for a genuinely bespoke shape (e.g. an external reverse + proxy on a different host/path). Must end with `/` per forgejo's + `ROOT_URL` contract. ''; };