core.http
Read-probe HTTP-эндпоинта: health-check, API-readiness, чтение версии.
core.http.probe делает один GET или HEAD к url и возвращает факты об ответе (status / body / elapsed_ms / ключи заголовков) в register. Это verb-форма, а не declarative-state: changed=false всегда и ненастраиваемо — probe ничего не меняет на хосте. Работает secure-by-default: https-only, SSRF-guard по резолвнутому IP, проверка TLS-цепочки; не пишет на ФС и не выполняет подпроцессов, поэтому root не нужен.
Требования
- Rootне требуется
- Сторона
soul-side - Коллекция
soulstack.network - Категория
network
network_outboundСостояния
core.http.probe — Один GET/HEAD-запрос к url; ответ (status / body / elapsed_ms / ключи заголовков) возвращается в register.
Никогда: read-only probe конструктивно не мутирует state.
Всегда — probe только читает, шаг остаётся no-op.
Параметры
| Параметр | Тип | Обяз. / дефолт | Описание |
|---|---|---|---|
url | string | required | Целевой URL (только https://; SSRF-guard на резолвнутый IP). |
method | stringGET | HEAD | optional · GET | HTTP-метод GET|HEAD (default GET); мутирующие методы запрещены. |
headers | map<string> | optional | HTTP-заголовки (значения секретны, в output не попадают). |
status_codes | list<int> | optional | Ожидаемые коды ответа (список int); по умолчанию 2xx. |
allow_private | bool | optional | Снять SSRF-guard для internal health-check (default false). |
allow_http | bool | optional | Разрешить http:// (снять https-only); file:// остаётся запрещён. Не открывает SSRF (default false). |
insecure_skip_verify | bool | optional | Отключить TLS-верификацию (self-signed / internal CA); MITM-риск (default false). |
timeout | stringformat: duration | optional | Таймаут probe (Soul Stack duration, напр. "30s"). |
Пример — Дождаться, пока сервис ответит HTTP 200 (с retry)
- name: Wait until the service answers HTTP 200 module: core.http.probe register: health retry: { count: 5, delay: 3s } params: url: https://service.internal:8443/healthz method: GET status_codes: [200] allow_private: trueOutput
| Поле | Тип | Описание |
|---|---|---|
status | int | |
body | string (semi-trusted, cap 64 KiB) | |
truncated | bool | |
elapsed_ms | int | |
changed | false | |
headers_keys | [string] | только если заданы headers (отсортированные ключи без значений) |
warnings | [string] | только если взведён opt-out-флаг (по строке на снятый контур, с host) |
Заметки
- changed=false всегда, конструктивно и ненастраиваемо — read-probe не меняет состояние хоста. Интерпретировать факт (up/down, версия из body) можно через changed_when: на уровне scenario (прецедент — core.exec.run).
- verb-форма, не declarative-state: возвращает факты об эндпоинте в register, ничего не приводя к состоянию. Мутирующие HTTP (POST/PUT/PATCH/DELETE) сознательно отложены post-MVP отдельным ADR-расширением (вероятно core.http.request) — тогда же решится changed-контракт для мутаций.
- Не выполняет подпроцессов и ничего не пишет на ФС: чистый HTTP-клиент в памяти. Манифест объявляет только network_outbound (без exec_subprocess и fs_write_root).
- Cap тела — 64 KiB (защита от OOM): сверх лимита тело отбрасывается, в output ставится truncated: true (граница режется по полной UTF-8-руне). Бинарные / битые байты тела приводятся к валидному UTF-8 (замена на U+FFFD).
- Статус вне status_codes → шаг failed, но с приложенным output (status/body для диагностики). Транспортная ошибка (DNS/TLS/timeout/заблокированный downgrade-редирект) → failed без output.
Безопасность и умолчания
- https-only по умолчанию — http:// и file:// отвергаются (util.ValidateFetchURL). Снять до http(s) — allow_http; file:// остаётся запрещён даже с allow_http.
- SSRF-guard: probe в metadata (169.254.169.254) / loopback / RFC1918 / link-local заблокирован по фактически резолвнутому IP — закрывает прямой SSRF на cloud-metadata IAM и DNS-rebind. Снять для легитимного internal health-check — allow_private. allow_http SSRF не открывает: dial-guard живёт отдельно.
- TLS — системный trust store по умолчанию; отключить верификацию для self-signed / internal CA — insecure_skip_verify (MITM-риск, взводить только для доверенного internal-эндпоинта). Downgrade-защита редиректов: редирект на не-https блокируется; при allow_http допускается hop https→http, но редирект на не-http(s) схему блокируется всегда.
- Три opt-out-флага ортогональны (HTTP-клиент строится per-call): снятие одного не ослабляет другие. При взведении любого probe кладёт в output warnings — по строке на снятый контур, только с host (без полного URL и headers).
- Тело semi-trusted: маскируются только vault-ref-подстроки (vault:… → ***MASKED***, включая ref внутри JSON); произвольный plaintext-секрет в теле не маскируется — не кладите в probe-эндпоинт то, что не должно светиться. headers sensitive-by-construction: значения не логируются, в output отдаётся только список ключей.