commit f8727360c032cb898c381f0d3e56e7b5229eb518
parent 291ff8fe1a57461580be413f656e1c9a98a81941
Author: Pablo Murad <pblmrd@gmail.com>
Date: Mon, 23 Mar 2026 14:12:48 -0300
fix rss
Diffstat:
3 files changed, 12 insertions(+), 7 deletions(-)
diff --git a/docs/06-site-and-apache.md b/docs/06-site-and-apache.md
@@ -15,7 +15,7 @@
- Opcional: `--certbot` (incompatível com `--dev`).
- Após cópia, por omissão chama `build_directory.py` para gravar `data/members.json` no DocumentRoot (`--no-refresh-members` para omitir).
- **`--sync-public-only`:** só copia `site/public/` → DocumentRoot, `chown www-data` e regenera `members.json`; **não** altera Apache (uso típico após `create_runv_user.py` e disponível para correr à mão).
-- **RSS (`/news/feed.rss`):** o `genlanding` completo (sem `--sync-public-only`) grava `/etc/apache2/conf-available/runv-landing-rss-mime.conf` com **`ForceType text/xml`** e activa com **`a2enconf runv-landing-rss-mime`**. Esse snippet é **global** ao Apache, por isso aplica-se a **:80 e :443** sem editar o VirtualHost SSL que o Certbot gerou. Após mudar o DocumentRoot (ex. `--dev` vs produção), volte a correr o `genlanding` completo para actualizar o snippet.
+- **RSS (`/news/feed.rss`):** o `genlanding` completo (sem `--sync-public-only`) grava `/etc/apache2/conf-available/runv-landing-rss-mime.conf` com **`RemoveType`**, **`ForceType text/xml`** e **`Header set Content-Type`** (sobrepor `mod_mime` / `application/rss+xml`), activa **`a2enmod headers`** e **`a2enconf runv-landing-rss-mime`**. O snippet é **global** ao Apache (**:80 e :443**) sem editar o VirtualHost SSL do Certbot. Após mudar o DocumentRoot, volte a correr o `genlanding` completo para actualizar o snippet.
- Versão actual do script: constante `VERSION` no ficheiro (ex.: `0.07`).
## TLS e DNS
diff --git a/docs/13-troubleshooting.md b/docs/13-troubleshooting.md
@@ -24,8 +24,9 @@
## Feed RSS descarrega em vez de abrir no browser
-- Com `genlanding` ≥ 0.07: confirme que existe **`/etc/apache2/conf-available/runv-landing-rss-mime.conf`**, que o symlink em `conf-enabled` está activo (`a2enconf runv-landing-rss-mime`) e que o `<Directory>` aponta ao **DocumentRoot correcto**; depois `sudo systemctl reload apache2`. O snippet cobre **HTTPS** sem tocar no ficheiro do Certbot (ver [06-site-and-apache.md](06-site-and-apache.md)).
-- Instalações antigas só com `ForceType` no `:80`: acrescente o mesmo bloco `<Directory …/news><Files "feed.rss">ForceType text/xml</Files></Directory>` no VirtualHost **:443** ou migre correr o `genlanding` completo de novo.
+- O `mod_mime` trata `.rss` como `application/rss+xml`; o Chromium costuma **descarregar**. Com `genlanding` ≥ 0.08 o snippet usa **`RemoveType`**, **`Header set Content-Type`** (requer **`mod_headers`**) e **`a2enconf runv-landing-rss-mime`**. Verifique: `curl -sI https://runv.club/news/feed.rss | grep -i content-type` → deve ser **`text/xml`**.
+- Com `genlanding` ≥ 0.07 e < 0.08: confirme **`/etc/apache2/conf-available/runv-landing-rss-mime.conf`**, symlink em `conf-enabled`, DocumentRoot correcto; volte a correr o **`genlanding` completo** (0.08+) para aplicar `Header` + `headers`.
+- Instalações antigas só com `ForceType` no `:80`: corra o `genlanding` completo de novo ou veja [06-site-and-apache.md](06-site-and-apache.md).
## Quotas
diff --git a/site/genlanding.py b/site/genlanding.py
@@ -11,7 +11,7 @@ a :80 e :443 sem editar o vhost SSL do Certbot.
Executar como root (excepto --dry-run). Apenas biblioteca padrão Python 3.
-Versão 0.07 — runv.club
+Versão 0.08 — runv.club
"""
from __future__ import annotations
@@ -28,7 +28,7 @@ import sys
from pathlib import Path
from typing import Final
-VERSION: Final[str] = "0.07"
+VERSION: Final[str] = "0.08"
EXIT_OK: Final[int] = 0
EXIT_USAGE: Final[int] = 1
EXIT_ERROR: Final[int] = 2
@@ -47,7 +47,7 @@ DEV_SITE_CONF: Final[str] = "runv-dev.conf"
APACHE_SITES_AVAILABLE: Final[Path] = Path("/etc/apache2/sites-available")
APACHE_CONF_AVAILABLE: Final[Path] = Path("/etc/apache2/conf-available")
-# Snippet global: aplica ForceType ao feed em todos os vhosts (:80 e :443), sem tocar no SSL do Certbot.
+# Snippet global: MIME do feed em todos os vhosts (:80 e :443), sem tocar no SSL do Certbot.
RSS_MIME_CONF_FILE: Final[str] = "runv-landing-rss-mime.conf"
RSS_MIME_CONF_STEM: Final[str] = "runv-landing-rss-mime"
APACHE_CTL: Final[str] = "/usr/sbin/apache2ctl"
@@ -79,12 +79,15 @@ def render_rss_mime_conf_contents(document_root: Path) -> str:
"""Snippet em conf-available: vale para :80 e :443 (evita editar o vhost SSL do Certbot à mão)."""
root = document_root.as_posix()
return f"""# Gerado por genlanding.py v{VERSION} — runv.club
-# Chromium descarrega feed.rss com application/rss+xml; text/xml mostra o XML na aba.
+# Chromium descarrega com application/rss+xml (mod_mime por extensão .rss).
+# RemoveType + Header forçam text/xml na resposta; requer mod_headers (a2enmod headers).
# Global ao servidor para o caminho actual do DocumentRoot (volte a correr genlanding se mudar).
<Directory {root}/news>
+ RemoveType rss
<Files "feed.rss">
ForceType text/xml
+ Header set Content-Type "text/xml; charset=utf-8"
</Files>
</Directory>
"""
@@ -411,6 +414,7 @@ def main(argv: list[str] | None = None) -> int:
run_cmd(["a2enmod", "userdir"], dry_run=args.dry_run)
run_cmd(["a2enmod", "rewrite"], dry_run=args.dry_run)
+ run_cmd(["a2enmod", "headers"], dry_run=args.dry_run)
rss_conf_path = APACHE_CONF_AVAILABLE / RSS_MIME_CONF_FILE
rss_body = render_rss_mime_conf_contents(document_root)