Risuko
Architecture

Protocol Handlers

How Risuko handles different download protocols.

Risuko's engine includes specialized handlers for each supported protocol. Each handler is a separate module within risuko-engine.

HTTP/HTTPS

Module: engine/http.rs

The HTTP handler supports multi-threaded range-based downloads:

  • Sends a GET request with Range: bytes=0-0 to probe file size and range support
  • Divides the file into 1 MiB pieces when at least min-split-size bytes; spawns N worker tasks (configurable via split, like aria2's -s/-x) that pull pieces from a shared lock-free queue
  • Work-stealing is inherent: any idle worker claims the next free piece, so a slow connection never holds back the rest of the download
  • Resume granularity is per-piece (≤1 MiB lost on SIGKILL): each piece tracks an AtomicU32 byte counter that the writer increments per flushed Bytes, and a sidecar JSON snapshot is persisted every 2 s
  • Downloads use HTTP Range headers; workers are pinned to HTTP/1.1 to keep each piece on its own TCP connection
  • Each piece streams bytes::Bytes directly into a dedicated writer task that issues positioned writes (pwrite on Unix, seek_write on Windows) against a shared file handle, so workers never contend on a seek lock
  • Calls fsync once on completion before renaming the .part file into place
  • Validates the Content-Range header on every 206 response and aborts on mismatch; sends If-Match when an ETag was recorded for resume
  • Falls back to a single-connection download when the file is below min-split-size or the server doesn't support ranges
  • Handles redirects, cookies, and custom headers
  • Supports proxy connections via the all-proxy option

Key Options

OptionDefaultDescription
split16Number of parallel worker tasks (one TCP connection each)
min-split-size1MSkip splitting for files smaller than this
user-agentChrome UA stringCustom user agent
headerCustom HTTP headers
all-proxyProxy URL
refererHTTP referer
max-download-limit0Per-task speed limit (bytes/s, 0 = unlimited)
remote-timefalseSet the local file mtime from the server's Last-Modified header

BitTorrent

Module: engine/torrent.rs

Built on risuko-bt:

  • Magnet link resolution (session fast-path for already-managed torrents, then tracker + DHT)
  • .torrent file parsing via the bundled bencode decoder
  • BEP-5 DHT for peer discovery, dual-stack (IPv4 + IPv6 via BEP-32) when an IPv6 socket can be bound
  • BEP-14 Local Service Discovery (LSD) for peers on the same LAN
  • BEP-10 extension protocol with ut_metadata (BEP-9); the ut_pex extension id is advertised but BEP-11 peer ingest is not yet wired
  • BEP-8 Message Stream Encryption (MSE/PE) with selectable plaintext / prefer / require policy
  • UPnP IGD port forwarding for the listener (TCP + UDP)
  • Rarest-first piece selection with endgame mode and SHA-1 verification off the async runtime
  • HTTP/HTTPS (BEP-23 compact) and UDP (BEP-15) trackers
  • Configurable seeding (ratio, time, or keep-seeding), upload speed limiting
  • Tunable per-peer request pipeline and per-torrent peer cap

Key Options

OptionDescription
seed-ratioStop seeding after this upload/download ratio
seed-timeStop seeding after this many minutes
keep-seedingSeed until manually stopped (overrides seed-time / seed-ratio)
max-upload-limitUpload speed limit (bytes/s)
bt-trackerAdditional tracker URLs
bt-max-peers-per-torrentMax concurrent peer connections per torrent (default 100)
bt-max-outstanding-per-peerMax pipelined chunk requests per peer (default 128)
bt-enable-upnpUPnP IGD port forwarding (default true)
bt-upnp-leaseUPnP mapping lease in seconds (default 300)
bt-enable-lsdBEP-14 Local Service Discovery (default true)
bt-encryption-policyMSE/PE policy: plaintext, prefer, require (default prefer)
bt-listen-v6Also bind an IPv6 TCP listener (default false)

Seeding Behavior

After a torrent download completes, seeding behavior depends on the seed options:

  1. onBtDownloadComplete fires when the download finishes
  2. If keep-seeding is true, or seed-time > 0, or seed-ratio > 0, the task stays active and seeding continues
  3. When keep-seeding is true, seed-time / seed-ratio limits are ignored; seeding runs until the task is stopped manually
  4. Otherwise seeding stops when seed-time elapses or seed-ratio is reached (whichever comes first)
  5. onDownloadComplete fires when seeding is done (or immediately if no seeding was requested)

ED2K

Module: engine/ed2k/

Supports the eDonkey2000 protocol for downloading files using ed2k:// links.

M3U8/HLS

Module: engine/m3u8/

Downloads HTTP Live Streaming content:

  • Parses M3U8 playlist files
  • Downloads all segments in parallel
  • Concatenates segments into the final file
  • Supports both live and VOD playlists

FTP/SFTP

Module: engine/ftp/

File Transfer Protocol handler:

  • FTP with optional TLS encryption
  • SFTP (SSH File Transfer Protocol)
  • Passive mode support
  • Directory listing and file download

RSS

Module: engine/rss/

Automatic feed subscription and download:

  • Add RSS/Atom feed URLs
  • Periodic polling for new items (configurable interval)
  • Automatic download of new items matching configured rules
  • Persistent feed state via StorageBackend

The RSS manager uses tokio::spawn for async polling and requires a tokio runtime context.

Protocol Routing

The engine does not auto-detect protocols from URLs. Each protocol has a dedicated RPC method or API function:

ProtocolRPC MethodNode.js FunctionCLI
HTTP/HTTPSrisuko.addUriaddUririsuko download <url>
BitTorrent (.torrent)risuko.addTorrentaddTorrentrisuko download <file.torrent> (auto-detected)
BitTorrent (magnet)addMagnetPassed to addUri
ED2Krisuko.addEd2kaddEd2k
M3U8/HLSaddM3u8
FTP/SFTPaddFtp

The CLI's download command only distinguishes .torrent files (by checking if the path ends with .torrent and exists on disk). All other inputs are passed to addUri. The Node.js API provides protocol-specific functions (addTorrent, addMagnet, addEd2k, addM3u8, addFtp) that call the engine directly.

On this page