diff --git a/README.md b/README.md index 2990f20..874aedf 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,117 @@ -# gekata +**Gekata** — это легковесный сервис на Node.js для извлечения «связных доменов» с веб-страниц, запускаемый в контейнере Debian с Chromium; он сначала делает предзапросы с ручным следованием редиректам, затем при необходимости поднимает безголовый браузер, ограничивает глубину редиректов и кэширует результаты в SQLite через better-sqlite3. Сервис предоставляет HTTP API /domains, возвращающее финальный URL, цепочку редиректов и список связанных доменов, а также /health для проверки готовности. -Extract all domains from site \ No newline at end of file +### Назначение + +Gekata сканирует заданный домен, разрешает маркетинговые и другие редиректы до целевой HTML-страницы, загружает её в безголовом Chromium и собирает множество доменных имён из всех сетевых запросов страницы, формируя список «связных доменов» для анализа интеграций, трекинга и CDN. Такой подход работает и для динамических сайтов с клиентским рендерингом. + +### Архитектура + +- Веб-сервер на Express предоставляет REST‑маршруты, принимает домен, валидирует его и инициирует сканирование, обрабатывая таймауты и коды ошибок. +- Предпроверка делает GET с ручным управлением редиректами, классифицируя сценарии: форс‑редиректы «маркетинга», запреты 403, скачивания и не‑HTML контент, чтобы экономить запуск браузера. +- Эскалация в безголовый Chromium (через Playwright) выполняет навигацию, применяя ограничение глубины редиректов только для документных переходов и ожидая «тихое окно» сети для стабильного сбора доменов. +- Кэширование результатов в SQLite с TTL ускоряет повторные запросы; используется лучшее для продакшна подключение better-sqlite3 и WAL‑журналирование для устойчивости. + + +### Потоки данных + +- Вход: GET /domains?domain= — принимает хост или URL, нормализует до ASCII/Punycode и формирует стартовый https:// URL. +- Предобработка: ручной обход 3xx с ограничением шагов; детекция «похожих на файл» ссылок и контента non‑HTML; маркетинговый редирект помечается и может быть целевой. +- Сканирование браузером: навигация на целевой URL, слежение за запросами/ответами страницы, сбор доменов из всех сетевых событий, исключая шум (google/doubleclick по эвристике), построение цепочки редиректов для документной навигации. +- Выход: JSON с finalUrl, relatedDomains[], redirectChain[], статусами ok/skipped/blocked и служебными пометками (cached, ttl). + + +### API + +- GET /domains +Параметры: domain — доменное имя или URL. +Ответ 200 ok: + - domain: нормализованный запрошенный домен. + - finalUrl: конечный URL после редиректов/навигации. + - relatedDomains: уникальные домены, замеченные при загрузке страницы. + - redirectChain: массив { from, to, status } для документных 3xx. + - cached: true/false, cachedAt, ttlAt. + - status: ok | skipped | blocked; дополнительные note/reason при skip/blocked. +- GET /health — простой JSON { ok: true } для readiness/liveness. + + +### Обработка редиректов + +- На этапе предпроверки ограничение PRECHECK_MAX_REDIRECTS предотвращает бесконечные цепочки до запуска браузера; 403 заставляет эскалировать в браузер, non‑HTML/attachment возвращают немедленный ответ. +- В браузере включён маршрут‑ограничитель только для документной навигации: запросы навигации обрабатываются с maxRedirects, ассеты идут без ограничений, чтобы не ломать рендеринг. +- Если лимит превышен, навигация завершается контролируемо и возвращается ошибка «Too many redirects», переводимая в понятный статус ответа API. + + +### Кэш и TTL + +- SQLite таблица domain_cache хранит: домен, JSON списка доменов, финальный URL, цепочку редиректов, время обновления и ttl_at. +- Повторные обращения до истечения TTL возвращают сохранённый результат без запуска браузера, снижая задержки и нагрузку. + + +### Контейнеризация + +- Образ состоит из двух стадий: builder и runtime, обе на debian:bookworm-slim. +- Стадия builder устанавливает Node.js, компилятор и заголовки SQLite для сборки native‑модуля better‑sqlite3, затем выполняет npm ci с пропуском dev‑зависимостей и копирует исходники. +- Стадия runtime устанавливает tini как корректный PID 1, Node.js runtime, системный Chromium и минимальный набор X/GTK/NSS/GBM/шрифтов, необходимых для безголового режима; копируются node_modules и исходники из builder. +- Создаётся непривилегированный пользователь nodeuser; директория приложения принадлежит ему; сервис запускается не от root. + + +### Переменные окружения + +- PORT — порт HTTP сервера (по умолчанию 3000). +- CHROMIUM_PATH — путь к системному Chromium (/usr/bin/chromium в контейнере). +- CACHE_TTL_SECONDS — срок жизни кэша (по умолчанию 6 часов). +- HARD_TIMEOUT_MS — жёсткий таймаут обработки HTTP‑запроса (по умолчанию 70 секунд). +- MAX_REDIRECT_STEPS — максимальная глубина редиректов для документной навигации (по умолчанию 20). +- NAV_TIMEOUT_MS, QUIET_WINDOW_MS — таймауты навигации и «тихого окна» сети. +- DEBUG — включает подробные логи страницы/сетевых событий при значении 1. + + +### Безопасность и устойчивость + +- tini как init обрабатывает сигналы и «зомби» процессы; контейнер корректно завершает Chromium по SIGTERM/SIGINT, предотвращая утечки. +- Запуск под непривилегированным пользователем снижает риск компрометации; Chromium стартует с флагами no‑sandbox/disable‑setuid-sandbox, что совместимо с безпривилегированным окружением контейнеров. +- Ограничение редиректов для документных переходов устраняет зацикливание «маркетинговых» и неверных конфигураций, не влияя на загрузку ассетов. + + +### Производительность + +- npm ci в builder‑стадии плюс копирование package*.json до исходников задействуют кэш слоёв Docker, ускоряя сборки. +- better‑sqlite3 с синхронными подготовленными выражениями обеспечивает быстрый локальный кэш без отдельного сервиса БД. +- Предпроверка HTTP избавляет от лишних подъёмов браузера для не‑HTML или «прикреплённых» ответов. + + +### Сборка и запуск + +- Сборка образа: + - docker build -t gekata:latest . +- Запуск контейнера: + - docker run --rm -p 3000:3000 -e CACHE_TTL_SECONDS=21600 -e MAX_REDIRECT_STEPS=20 gekata:latest +- Примеры запросов: + - curl -s "http://localhost:3000/health" + - curl -s "http://localhost:3000/domains?domain=forum.xda-developers.com" + + +### Журналирование и диагностика + +- Лог‑метки [BOOT], [HTTP], [SCAN], [BROWSER], [CACHE], [SIGNAL] позволяют быстро локализовать этап и тип события. +- При включённом DEBUG=1 логируются консоль страницы, ошибки, неудавшиеся запросы и сетевые эвенты, что помогает анализировать блокировки, CORS, антибот‑защиту и таймауты. + + +### Ограничения + +- Сайты с жёсткими антибот‑мерами (403/JS‑челленджи) могут быть помечены как blocked или потребовать дополнительной эмуляции (например, иные user‑agent/locale/timezone/proxy). +- Сбор связанных доменов базируется на фактически выполненных сетевых запросах и может меняться при A/B тестах, гео‑таргетинге или различиях по user‑agent. + + +### Расширения и доработки + +- Добавить белый/чёрный список доменов, тонкую фильтрацию трекеров и интеграций. +- Вынести кэш в внешний SQLite‑файл через volume для сохранения между рестартами, настроить резервное копирование. +- Параметризовать user‑agent/locale/timezone и добавить поддержку прокси для региональных сценариев. +- Экспортировать полный сетевой журнал и тайминги (HAR‑подобный формат) как опциональную выгрузку. + + +### Файлы проекта + +- server.js — основной сервис, логика API, предобработка, сканирование браузером, кэш, ограничения редиректов, завершение по сигналам. +- Dockerfile — двухстадийная сборка, системный Chromium в рантайме, tini, непривилегированный пользователь, переменные окружения и запуск службы.