Skip to content

Fix/ws fragmented recv#538

Open
Sceef wants to merge 2 commits intoFlowseal:mainfrom
Sceef:fix/ws-fragmented-recv
Open

Fix/ws fragmented recv#538
Sceef wants to merge 2 commits intoFlowseal:mainfrom
Sceef:fix/ws-fragmented-recv

Conversation

@Sceef
Copy link
Copy Markdown

@Sceef Sceef commented Apr 2, 2026

Русский

  1. Прокси: фрагментированные WebSocket-сообщения (proxy/tg_ws_proxy.py)
    _read_frame теперь возвращает флаг FIN вместе с opcode и payload.
    recv() собирает одно целое BINARY/TEXT-сообщение по RFC 6455: если первый фрейм с FIN=0, следующие кадры с opcode continuation (0) склеиваются до фрейма с FIN=1.
    PING/PONG по-прежнему обрабатываются между фрагментами и не ломают сборку.
    При нарушении порядка фреймов (continuation без начала или новый data-фрейм до конца предыдущего сообщения) соединение закрывается и возвращается None.
    Зачем: раньше отдавался только первый фрейм, остальные отбрасывались — ломался MTProto-поток и часть медиа (крупные файлы, превью и т.д.) могла не загружаться, если сервер шлёт фрагментированные WS-кадры.

  2. Сборка: PyInstaller и pkg_resources / jaraco (packaging/.spec)
    В datas добавлена рекурсивная упаковка каталога setuptools/_vendor в setuptools/_vendor внутри бандла.
    В hiddenimports добавлен platformdirs.
    Зачем: в setuptools 80+ pkg_resources дописывает setuptools/_vendor в sys.path и импортирует jaraco.
    и platformdirs. В onefile без этого каталога на диске при старте падало: ModuleNotFoundError: No module named 'jaraco' (runtime hook pyi_rth_pkgres).

Изменения внесены в windows, linux и macos spec-файлы.

English

  1. Proxy: fragmented WebSocket messages (proxy/tg_ws_proxy.py)
    _read_frame now returns a FIN flag along with opcode and payload.
    recv() reassembles one logical BINARY/TEXT message per RFC 6455: if the first frame has FIN=0, subsequent continuation (opcode 0) frames are concatenated until a frame with FIN=1.
    PING/PONG are still handled between fragments without breaking reassembly.
    On protocol violations (continuation without a start, or a new data frame before the previous message ends), the connection is closed and None is returned.
    Why: Previously only the first frame was returned and the rest were dropped, which corrupted the MTProto byte stream and could break some media downloads when the server sends fragmented WebSocket frames.

  2. Packaging: PyInstaller vs pkg_resources / jaraco (packaging/.spec)
    datas: recursively bundle setuptools/_vendor into setuptools/_vendor inside the frozen app.
    hiddenimports: add platformdirs.
    Why: Setuptools 80+ pkg_resources prepends setuptools/_vendor to sys.path and imports jaraco.
    and platformdirs. One-file builds did not ship that tree on disk, so startup failed with ModuleNotFoundError: No module named 'jaraco' (via pyi_rth_pkgres).

Applied to Windows, Linux, and macOS spec files.

Sceef added 2 commits April 2, 2026 14:49
RFC 6455 allows large BINARY payloads to be split across multiple
frames with FIN=0 and CONTINUATION opcodes. The previous recv() only
returned the first fragment, corrupting the MTProto stream and breaking
some media downloads. Control frames between fragments are still
handled as before.

Made-with: Cursor
Setuptools 80+ pkg_resources imports jaraco.* and platformdirs after
adding setuptools/_vendor to sys.path. PyInstaller onefile did not ship
that tree, causing ModuleNotFoundError: jaraco at pyi_rth_pkgres.
Include the full _vendor directory as datas; add platformdirs to
hiddenimports. Applied to windows, linux, and macos specs.

Made-with: Cursor
@Flowseal
Copy link
Copy Markdown
Owner

Flowseal commented Apr 2, 2026

Зачем: раньше отдавался только первый фрейм, остальные отбрасывались — ломался MTProto-поток и часть медиа (крупные файлы, превью и т.д.) могла не загружаться, если сервер шлёт фрагментированные WS-кадры.

class _MsgSplitter:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants