From 634f38e016542285ead3f8082ba1038016a9df65 Mon Sep 17 00:00:00 2001 From: ChemaVX Date: Sun, 5 Jul 2026 15:56:07 +0000 Subject: [PATCH] =?UTF-8?q?fix(scraper):=20SAFE=5FACCEPT=5FENCODING=20comp?= =?UTF-8?q?artida=20=E2=80=94=20cubre=20la=20sesi=C3=B3n=20SearXNG=20olvid?= =?UTF-8?q?ada?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit La sesión aiohttp de _search_searxng (camino primario de búsqueda) construía sus headers sin Accept-Encoding: heredaba el default de aiohttp, que volvería a anunciar br si algún día se reinstala un backend brotli. El valor vive ahora en src/config.py (SAFE_ACCEPT_ENCODING) en vez de copiado literal por sitio. También corrige el comentario de HEADERS que afirmaba que brotlicffi seguía instalado como fallback — 397546a lo quitó: un br no anunciado hoy falla sin recuperación y la fuente se pierde. Co-Authored-By: Claude Fable 5 --- KNOWN-ISSUES.md | 8 ++++++++ src/config.py | 7 +++++++ src/scraper/exhaustive.py | 17 +++++++++++------ 3 files changed, 26 insertions(+), 6 deletions(-) diff --git a/KNOWN-ISSUES.md b/KNOWN-ISSUES.md index 36f6697..61ba832 100644 --- a/KNOWN-ISSUES.md +++ b/KNOWN-ISSUES.md @@ -27,6 +27,14 @@ Fix applied (commits `397546a` + `76c927f` + `7d07375`, guard relocated triggers it, so a stale same-title draft from a previous run can no longer swallow freshly generated content. +Note: with no backend installed there is NO brotli fallback at all — a server +that responds `Content-Encoding: br` without it being advertised (misbehaving +CDN) fails undecodable and that source is lost. Accepted trade-off. + +The header value lives in one place: `SAFE_ACCEPT_ENCODING` in `src/config.py`. +Every aiohttp session/request must use it explicitly — never rely on aiohttp's +default Accept-Encoding, which silently grows `br` if a backend appears. + Re-test with disclosure.org before ever re-enabling br (e.g. after an aiohttp upgrade). diff --git a/src/config.py b/src/config.py index 4a802b6..24d4484 100644 --- a/src/config.py +++ b/src/config.py @@ -2,6 +2,13 @@ from pydantic_settings import BaseSettings, SettingsConfigDict from pydantic import Field from typing import Optional +# Accept-Encoding para TODA petición aiohttp del proyecto. Nunca anunciar "br": +# el descompresor incremental de aiohttp 3.14 está roto, y con un backend brotli +# instalado aiohttp lo anunciaría POR DEFECTO en cualquier sesión sin +# Accept-Encoding explícito (incidente 2026-07-04, ver KNOWN-ISSUES.md). +# Toda sesión/petición nueva debe usar esta constante, no un literal. +SAFE_ACCEPT_ENCODING = "gzip, deflate" + class Settings(BaseSettings): # Telegram diff --git a/src/scraper/exhaustive.py b/src/scraper/exhaustive.py index 046d641..8cc6179 100644 --- a/src/scraper/exhaustive.py +++ b/src/scraper/exhaustive.py @@ -18,7 +18,7 @@ from duckduckgo_search import DDGS from youtube_transcript_api import YouTubeTranscriptApi, NoTranscriptFound from tenacity import retry, stop_after_attempt, wait_exponential -from src.config import settings +from src.config import settings, SAFE_ACCEPT_ENCODING from src.db.database import ResearchDB logger = structlog.get_logger() @@ -29,10 +29,11 @@ HEADERS = { "Accept-Language": "en-US,en;q=0.9,es;q=0.8", # Sin "br": el descompresor incremental de aiohttp 3.14 falla con streams # brotli válidos según el troceo de chunks (disclosure.org, todaywhy.com; - # los mismos bytes descomprimen bien offline con brotlicffi). Con gzip el - # camino zlib es sólido. brotlicffi queda instalado por si algún servidor - # manda br sin que se anuncie. - "Accept-Encoding": "gzip, deflate", + # los mismos bytes descomprimen bien offline). Con gzip el camino zlib es + # sólido. OJO: ya NO hay ningún backend brotli instalado (397546a quitó + # brotlicffi) — si un servidor responde br sin que se haya anunciado, + # aiohttp falla sin recuperación posible y esa fuente se pierde. + "Accept-Encoding": SAFE_ACCEPT_ENCODING, "DNT": "1", } @@ -41,7 +42,7 @@ REDDIT_HEADERS = { "User-Agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36", "Accept": "application/json, text/javascript, */*; q=0.01", "Accept-Language": "en-US,en;q=0.9", - "Accept-Encoding": "gzip, deflate", # sin "br", ver HEADERS + "Accept-Encoding": SAFE_ACCEPT_ENCODING, # sin "br", ver HEADERS "Referer": "https://www.reddit.com/", "X-Requested-With": "XMLHttpRequest", } @@ -264,6 +265,10 @@ class ExhaustiveScraper: "Accept": "application/json", "X-Forwarded-For": "127.0.0.1", "User-Agent": "ResearchOwl/1.0", + # Sin esto la sesión hereda el default de aiohttp, que anunciaría + # br si algún día se reinstala un backend brotli — y el decode roto + # de 3.14 tumbaría TODAS las búsquedas SearXNG (el camino primario). + "Accept-Encoding": SAFE_ACCEPT_ENCODING, } try: async with aiohttp.ClientSession() as session: