github.com/OrelSokolov/active_torrent.cr
0.1.0 / published Nov 5, 2026 / repository
ActiveTorrent — an MVP of a p2p large-file distribution engine for CRails: bencode/metainfo (BEP 3), a Torrent model over ActiveStorage blobs, signed metainfo/announce tokens, webseed serving (BEP 19), a private HTTP tracker (BEP 3/23) with swarm stats, and SSE seedbox sync. The BitTorrent wire protocol and the seedbox binary are not implemented yet (phases 2-3, see PLAN.md).
active_torrent.cr
An MVP of a p2p large-file distribution engine for
CRails — the BitTorrent piece
Rails never had. Not a port of a gem: the protocol references are the
BEPs, and the design docs live in the monorepo
(plans/ActiveTorrentDescription.md).
Status as of this MVP (2026-11-04, phases 0–1):
- bencode codec (BEP 3) — no external deps, dict keys sorted,
invalid-UTF-8 strings decode to bytes; stricter than the ruby gem
(
i42/3:abraise instead of being silently forgiven); - metainfo: streaming piece hashing (SHA-1),
.torrentbuild/parse, magnet URIs —info_hashis invariant to announce/ url-list, so metadata is assembled from DB rows; - Torrent model (
active_torrent_torrents):publish_blob!/publish_metainfo!(seedbox origin without the file on the server), ahas_torrent :filemacro, signed metainfo tokens (MessageVerifier, purposetorrent_metainfo); - webseed serving (BEP 19): the server is the last-resort seed —
url-listis embedded only while the swarm is degraded (seeders < K), drops out once the swarm is healthy; - private HTTP tracker (BEP 3/23): announce by signed token
(purpose
torrent_announce), compact peer lists, started/stopped/ completed events, peer TTL (3×interval, lazy sweep), swarm stats (active_torrent_seed_stats); - seedbox sync: snapshot
GET /torrents/public?since=(cursor onupdated_at, Bearer token) + SSEGET /torrents/events(torrent.created/updated/retired/health, Last-Event-ID replay from a ring buffer); - retired torrents answer
410 Goneeverywhere (metainfo, announce).
Not implemented yet (phases 2–4): the BitTorrent wire protocol,
super-seed, the seedbox binary, seedbox_origin publish flow,
WebTorrent/WebRTC. The event bus is in-process — multi-worker pubsub
is deferred. See PLAN.md.
Oracle-first (per the monorepo's AGENTS.md rule): 39 cases recorded
against the ruby bencode gem 0.8.0, a real uTorrent fixture
(leaves.torrent), and ruby Digest::SHA1 (byte-exact .torrent
round-trip); announce responses are covered by BEP 3/23 fixtures. The
mirror spec runs the same cases without edits.
Install
dependencies:
active_torrent_cr:
github: OrelSokolov/active_torrent.cr
version: ~> 0.1.0
controllers.cr is opt-in (it pulls action_pack_cr): apps require
require "active_torrent_cr/controllers" and mount the routes —
exactly like ActiveStorage.
Specs
crystal spec # oracle mirror + model/tracker/events units (sqlite)
The demo app (examples/torrent_demo in the monorepo) exercises the
full pipeline: release → .torrent/magnet → webseed → tracker → SSE
→ retire.