From a0be6bfcac07a256949082e935e1be06753ab872 Mon Sep 17 00:00:00 2001 From: Christophe Besson Date: Thu, 15 Oct 2026 10:17:29 +0200 Subject: feat(cli): stream — a film or a song played in a media player MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `meshbay-cli stream PATH` serves one video or sound file over HTTP on 127.0.0.1 for VLC, mpv or any player that reads HTTP; `--player PROGRAM` starts the player, and closing it stops the stream, as Ctrl+C does. The file goes as the node stores it: no remux, no transcode, no stream slot on the node. Byte ranges are answered from leaseless file_req chunks decrypted in memory, eight ahead and the last 24 kept. Loopback only, a random token in the address, a foreign Host refused (DNS rebinding), an audio or video type with nosniff. The connection is pinged and reopened when it dies; a refusal by the node stops the stream (exit 5). Co-Authored-By: Claude Opus 5.5 --- packages/meshbay-cli/src/meshbay_cli/client/transfers.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'packages/meshbay-cli/src/meshbay_cli/client/transfers.py') diff --git a/packages/meshbay-cli/src/meshbay_cli/client/transfers.py b/packages/meshbay-cli/src/meshbay_cli/client/transfers.py index 3f23c85..2cbf4cd 100644 --- a/packages/meshbay-cli/src/meshbay_cli/client/transfers.py +++ b/packages/meshbay-cli/src/meshbay_cli/client/transfers.py @@ -268,6 +268,20 @@ async def _fetch_chunks(session: GroupSession, lease: Lease, file_id: str, file_ return written +async def read_chunk(session: GroupSession, entry: dict, i: int) -> bytes: + """ + Chunk `i` of a file, decrypted, asked for without a lease: what the + application's players do, and what the node bounds (a dozen files at once + per connection). A refusal raises `NodeRefusal`; a connection that failed, + another `CliError`. + """ + msg = await session.ch.request( + {"type": "file_req", "v": MNP_VERSION, "file_id": entry["id"], "chunk_index": i}, + "file_chunk", timeout=CHUNK_TIMEOUT) + return decrypt_chunk_aes(chunk_key_aes(session.gek, bytes.fromhex(entry["id"]), i), + msg["nonce"], msg["ct"]) + + def mark_of_the_web(path: Path) -> None: """ZoneId 3, as a browser marks a download, so SmartScreen and Protected View apply when it is opened. FAT and exFAT have no alternate streams: nothing to do.""" -- cgit v1.2.3