Чек-лист Jambotron v0.2.3, 75.2 — IMAP (и IMAP-часть 75.1: TLS).
Старый IMAP (выключен, ~20 .block() на сетевом потоке) удалён и написан заново по той же схеме, что SMTP.
Сервер
ImapServer (Reactor Netty): декодер собирает целые команды с литералами: {n} после + Ready, {n+} (LITERAL+) сразу, ограничение 50 МБ. Команды выполняются по одной на рабочем потоке, ответы уходят по порядку.
TLS: STARTTLS на IMAP_PORT (3143) и неявный TLS на IMAPS_PORT (993); сертификат тот же, что у SMTP. Вход только внутри TLS (LOGINDISABLED до него). Команды открытым текстом, присланные вместе со STARTTLS, не выполняются, соединение закрывается.
IDLE: проверка папки раз в 5 с, клиенту уходят EXISTS, EXPUNGE и FETCH FLAGS, пока не придёт DONE. Входящие команды читаются сразу, независимо от выполнения, поэтому DONE виден во время IDLE.
Также SEARCH (все ключи RFC 3501), STORE, COPY/MOVE с COPYUID, APPEND с APPENDUID, EXPUNGE и UID EXPUNGE, LIST/LSUB/STATUS. CREATE, RENAME и DELETE работают с папками, имена в modified UTF-7.
MimeTree делит письмо на части по байтам, поэтому размеры в BODYSTRUCTURE совпадают с BODY[].
Данные (V4)
UID в папке выдаёт триггер в базе. Письмо, перенесённое из веба, по IMAP или через SMTP, получает новый, больший UID, и клиент его не пропустит. Сохранение строки без переноса UID не меняет.
Новые флаги \Answered и \Deleted.
message_sources хранит письмо ровно как пришло (SMTP, APPEND). Для писем из веб-почты MIME собирается один раз (MimeSource, граница и Message-ID зависят от id письма). Правка черновика или его вложений этот исходник сбрасывает.
Проверка
:backend:test 47/47. Новые тесты: настоящий клиент Angus IMAP (папки, письма, вложения через BODYSTRUCTURE и BODY[1]/[2], поиск, UID, APPEND/COPY/MOVE/EXPUNGE, папки с кириллицей); сырые литералы и LITERAL+; IDLE; подмешивание после STARTTLS; секции вложенного письма; пример mUTF-7 из RFC 3501.
Вживую на PostgreSQL со старой версией (V3) и письмами, затем обновление до V4: UID пронумерованы, uid_next выставлен верно. Python imaplib через STARTTLS и порт 993 проверил по 23 пунктам, ошибок 0: папки special-use, UTF-8 тема, BODYSTRUCTURE и вложение, поиск, \Seen после BODY[], черновик из веба (один размер дважды), APPEND, COPY, MOVE, EXPUNGE, STATUS, папка «Проекты», IDLE с письмом по SMTP во время ожидания. Триггер UID проверен напрямую.
После мержа на staging: загрузить ZIP и передеплоить (миграция V4 пройдёт сама), затем в Jambotron открыть внутренний TCP-порт mail:3143. Thunderbird на компьютере не в сети WireGuard, поэтому подключается через SSH-туннель к Contabo: ssh -L 3143:10.30.1.77:<порт> root@<contabo>, в Thunderbird — localhost:3143, STARTTLS, принять самоподписанный сертификат.
Чек-лист Jambotron v0.2.3, **75.2 — IMAP** (и IMAP-часть 75.1: TLS).
Старый IMAP (выключен, ~20 `.block()` на сетевом потоке) удалён и написан заново по той же схеме, что SMTP.
**Сервер**
- `ImapServer` (Reactor Netty): декодер собирает целые команды с литералами: `{n}` после `+ Ready`, `{n+}` (LITERAL+) сразу, ограничение 50 МБ. Команды выполняются по одной на рабочем потоке, ответы уходят по порядку.
- **TLS:** STARTTLS на `IMAP_PORT` (3143) и неявный TLS на `IMAPS_PORT` (993); сертификат тот же, что у SMTP. Вход только внутри TLS (`LOGINDISABLED` до него). Команды открытым текстом, присланные вместе со STARTTLS, не выполняются, соединение закрывается.
- **IDLE:** проверка папки раз в 5 с, клиенту уходят `EXISTS`, `EXPUNGE` и `FETCH FLAGS`, пока не придёт `DONE`. Входящие команды читаются сразу, независимо от выполнения, поэтому `DONE` виден во время IDLE.
**Протокол** (`ImapSession`): IMAP4rev1, LITERAL+, SASL-IR, IDLE, UIDPLUS, MOVE, UNSELECT, NAMESPACE, SPECIAL-USE, ID.
- FETCH: `ENVELOPE`, `BODYSTRUCTURE`, `BODY[section]<partial>` (HEADER, HEADER.FIELDS[.NOT], TEXT, MIME, вложенные `message/rfc822`).
- Также SEARCH (все ключи RFC 3501), STORE, COPY/MOVE с `COPYUID`, APPEND с `APPENDUID`, EXPUNGE и UID EXPUNGE, LIST/LSUB/STATUS. CREATE, RENAME и DELETE работают с папками, имена в modified UTF-7.
- `MimeTree` делит письмо на части по байтам, поэтому размеры в `BODYSTRUCTURE` совпадают с `BODY[]`.
**Данные (V4)**
- **UID в папке выдаёт триггер в базе.** Письмо, перенесённое из веба, по IMAP или через SMTP, получает новый, больший UID, и клиент его не пропустит. Сохранение строки без переноса UID не меняет.
- Новые флаги `\Answered` и `\Deleted`.
- `message_sources` хранит письмо ровно как пришло (SMTP, APPEND). Для писем из веб-почты MIME собирается один раз (`MimeSource`, граница и Message-ID зависят от id письма). Правка черновика или его вложений этот исходник сбрасывает.
**Проверка**
- `:backend:test` 47/47. Новые тесты: настоящий клиент Angus IMAP (папки, письма, вложения через BODYSTRUCTURE и BODY[1]/[2], поиск, UID, APPEND/COPY/MOVE/EXPUNGE, папки с кириллицей); сырые литералы и LITERAL+; IDLE; подмешивание после STARTTLS; секции вложенного письма; пример mUTF-7 из RFC 3501.
- **Вживую на PostgreSQL** со старой версией (V3) и письмами, затем обновление до V4: UID пронумерованы, `uid_next` выставлен верно. Python `imaplib` через STARTTLS и порт 993 проверил по 23 пунктам, ошибок 0: папки special-use, UTF-8 тема, BODYSTRUCTURE и вложение, поиск, `\Seen` после BODY[], черновик из веба (один размер дважды), APPEND, COPY, MOVE, EXPUNGE, STATUS, папка «Проекты», IDLE с письмом по SMTP во время ожидания. Триггер UID проверен напрямую.
**После мержа на staging:** загрузить ZIP и передеплоить (миграция V4 пройдёт сама), затем в Jambotron открыть внутренний TCP-порт `mail:3143`. Thunderbird на компьютере не в сети WireGuard, поэтому подключается через SSH-туннель к Contabo: `ssh -L 3143:10.30.1.77:<порт> root@<contabo>`, в Thunderbird — `localhost:3143`, STARTTLS, принять самоподписанный сертификат.
— α
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Старый IMAP (выключен, .block() на сетевом потоке) удалён, написан заново:
- ImapServer: декодер целых команд с литералами ({n} после "+ Ready", {n+}),
команды по одной на рабочем потоке; STARTTLS (без выполнения открытого текста
после него) и неявный TLS; IDLE с опросом раз в 5 с до DONE
- ImapSession: IMAP4rev1 + LITERAL+, SASL-IR, IDLE, UIDPLUS, MOVE, UNSELECT,
NAMESPACE, SPECIAL-USE, ID; FETCH (ENVELOPE, BODYSTRUCTURE, BODY[section]<partial>),
SEARCH, STORE, COPY/MOVE с COPYUID, APPEND с APPENDUID, EXPUNGE/UID EXPUNGE
- MimeTree: части письма по байтам — размеры BODYSTRUCTURE совпадают с BODY[]
- V4: UID на папку выдаёт триггер (перенос из веба тоже получает новый UID),
флаги \Answered/\Deleted, message_sources — письмо как пришло (SMTP, APPEND)
или собранное один раз (MimeSource); правка черновика сбрасывает его
- тесты: настоящий клиент Angus IMAP, сырые литералы/IDLE/подмешивание (47 всего)
- живая проверка: обновление V3 -> V4 на PostgreSQL с письмами, Python imaplib:
STARTTLS, 993, папки, вложения, поиск, APPEND/COPY/MOVE/EXPUNGE, IDLE — 0 ошибок
α
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Чек-лист Jambotron v0.2.3, 75.2 — IMAP (и IMAP-часть 75.1: TLS).
Старый IMAP (выключен, ~20
.block()на сетевом потоке) удалён и написан заново по той же схеме, что SMTP.Сервер
ImapServer(Reactor Netty): декодер собирает целые команды с литералами:{n}после+ Ready,{n+}(LITERAL+) сразу, ограничение 50 МБ. Команды выполняются по одной на рабочем потоке, ответы уходят по порядку.IMAP_PORT(3143) и неявный TLS наIMAPS_PORT(993); сертификат тот же, что у SMTP. Вход только внутри TLS (LOGINDISABLEDдо него). Команды открытым текстом, присланные вместе со STARTTLS, не выполняются, соединение закрывается.EXISTS,EXPUNGEиFETCH FLAGS, пока не придётDONE. Входящие команды читаются сразу, независимо от выполнения, поэтомуDONEвиден во время IDLE.Протокол (
ImapSession): IMAP4rev1, LITERAL+, SASL-IR, IDLE, UIDPLUS, MOVE, UNSELECT, NAMESPACE, SPECIAL-USE, ID.ENVELOPE,BODYSTRUCTURE,BODY[section]<partial>(HEADER, HEADER.FIELDS[.NOT], TEXT, MIME, вложенныеmessage/rfc822).COPYUID, APPEND сAPPENDUID, EXPUNGE и UID EXPUNGE, LIST/LSUB/STATUS. CREATE, RENAME и DELETE работают с папками, имена в modified UTF-7.MimeTreeделит письмо на части по байтам, поэтому размеры вBODYSTRUCTUREсовпадают сBODY[].Данные (V4)
\Answeredи\Deleted.message_sourcesхранит письмо ровно как пришло (SMTP, APPEND). Для писем из веб-почты MIME собирается один раз (MimeSource, граница и Message-ID зависят от id письма). Правка черновика или его вложений этот исходник сбрасывает.Проверка
:backend:test47/47. Новые тесты: настоящий клиент Angus IMAP (папки, письма, вложения через BODYSTRUCTURE и BODY[1]/[2], поиск, UID, APPEND/COPY/MOVE/EXPUNGE, папки с кириллицей); сырые литералы и LITERAL+; IDLE; подмешивание после STARTTLS; секции вложенного письма; пример mUTF-7 из RFC 3501.uid_nextвыставлен верно. Pythonimaplibчерез STARTTLS и порт 993 проверил по 23 пунктам, ошибок 0: папки special-use, UTF-8 тема, BODYSTRUCTURE и вложение, поиск,\Seenпосле BODY[], черновик из веба (один размер дважды), APPEND, COPY, MOVE, EXPUNGE, STATUS, папка «Проекты», IDLE с письмом по SMTP во время ожидания. Триггер UID проверен напрямую.После мержа на staging: загрузить ZIP и передеплоить (миграция V4 пройдёт сама), затем в Jambotron открыть внутренний TCP-порт
mail:3143. Thunderbird на компьютере не в сети WireGuard, поэтому подключается через SSH-туннель к Contabo:ssh -L 3143:10.30.1.77:<порт> root@<contabo>, в Thunderbird —localhost:3143, STARTTLS, принять самоподписанный сертификат.— α
🤖 Generated with Claude Code
Старый IMAP (выключен, .block() на сетевом потоке) удалён, написан заново: - ImapServer: декодер целых команд с литералами ({n} после "+ Ready", {n+}), команды по одной на рабочем потоке; STARTTLS (без выполнения открытого текста после него) и неявный TLS; IDLE с опросом раз в 5 с до DONE - ImapSession: IMAP4rev1 + LITERAL+, SASL-IR, IDLE, UIDPLUS, MOVE, UNSELECT, NAMESPACE, SPECIAL-USE, ID; FETCH (ENVELOPE, BODYSTRUCTURE, BODY[section]<partial>), SEARCH, STORE, COPY/MOVE с COPYUID, APPEND с APPENDUID, EXPUNGE/UID EXPUNGE - MimeTree: части письма по байтам — размеры BODYSTRUCTURE совпадают с BODY[] - V4: UID на папку выдаёт триггер (перенос из веба тоже получает новый UID), флаги \Answered/\Deleted, message_sources — письмо как пришло (SMTP, APPEND) или собранное один раз (MimeSource); правка черновика сбрасывает его - тесты: настоящий клиент Angus IMAP, сырые литералы/IDLE/подмешивание (47 всего) - живая проверка: обновление V3 -> V4 на PostgreSQL с письмами, Python imaplib: STARTTLS, 993, папки, вложения, поиск, APPEND/COPY/MOVE/EXPUNGE, IDLE — 0 ошибок α Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>