# 🐞 Не давать отправителю задавать, что уедет в журнал - **Тип:** fix - **Категория:** Очередь — Заведена урожаем ревью и встала в конец машинально: место в плане стройки назначает человек. - **Зачем:** Путь запроса уезжает в журнал целиком: аноним пишет туда до мегабайта своего текста одной строкой, а хвост имени файла приезжает внутри чужого текста ошибки вместо своего поля. - **Теги:** review-2026-08-15 Длину и содержимое строки журнала задаёт тот, кто прислал запрос, а не сервис. Мест два, причина одна. Слой журнала пишет путь запроса полем `http.route` целиком: приведение режет только последний сегмент и только у ссылок на файлы. Отказ подготовки рабочей копии пересказывает отказ библиотеки целиком, а тот несёт полное имя временного файла — вместе с расширением, взятым из имени отправителя. Журнал в этом проекте — место, где наблюдаются инварианты: по нему видно недоставку, остановку конвейера и молчаливый выход из шага. Вытесненный чужим текстом, он перестаёт отвечать на вопрос, ради которого заведён. Класс проект уже назвал недопустимым в приведении отказа провайдера входа ([conventions/logging.md](../../docs/conventions/logging.md)): «без приведения аноним пишет в журнал что угодно и сколько угодно». Здесь тот же канал шире и дешевле — сессия для него не нужна. ## Воспроизведение **Путь запроса.** Поднять сервис и послать запрос, чей путь длиной 900 000 байт: ``` python3 -c 'socket … GET /<900000×"A"> HTTP/1.1' ``` Ответ — `404`, журнал вырастает с 1048 до 901 194 байт одной строкой. Потолок замерен: 1 048 000 байт ещё проходят, 1 100 000 отвергаются кодом `431`. Внедрения строк при этом нет — библиотека журнала квотирует значение. **Хвост имени.** Принять запись, чьё имя несёт 280 байт после последней точки. Отказ подготовки рабочей копии приезжает в журнал уровня `ERROR` строкой вида `error="failed to create work file: open /tmp/transcriber-<число>.<280 байт>: file name too long"`, и поля `file_ext` в ней нет вовсе. ## Затрагивает - слой журнала запроса в `cmd/transcriber` и приведение пути `journalRoute`; - отказ подготовки рабочей копии в `internal/service`, шаг приёма записи; - `docs/conventions/logging.md` — правило о длине поля журнала; - умолчание `MaxHeaderBytes` у сервера: сегодня оно единственное неназванное рядом с названным сроком чтения. ## Критерии приёмки - Путь запроса в журнале не длиннее объявленного предела, и усечение видно в самой строке. Оракул: тот же запрос с путём в 900 000 байт — прирост журнала не превышает предела, а маршрут по первым байтам по-прежнему различим. - Отказ подготовки рабочей копии не пересказывает отказ библиотеки: расширение идёт своим полем. Оракул: проверка приёма с длинным хвостом имени — строки с этим хвостом в журнале нет, поле `file_ext` есть. - Правило записано конвенцией: длину поля журнала не задаёт вызывающий. Оракул: строка в `docs/conventions/logging.md` и ссылка на неё из обеих правок. ## Рамки Приведение пути не должно делать маршрут неразличимым: по журналу отличают приём записи от чтения одной записи — `POST /app/audiorecords` от `GET /app/audiorecords/{id}`. Найдено прогоном ревью задачи `remove-telegram-intake` 2026-08-15, враждебный проход; дефект существовал до той правки, и владелец решил вынести его задачей.