Skip to content

joedborg/stormdrain

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

11 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

stormdrain

A command-line BitTorrent client modelled after curl and wget. Pass it a .torrent file, an HTTP(S) URL to one, or a magnet link and it downloads the content to disk.

Why?

Sometimes, I just want to download a torrent. Existing applications require a daemon running in the background, or have a large GUI with features I don't need. stormdrain is a simple tool that just downloads torrents.

Features

  • .torrent files, HTTP(S) .torrent URLs, and magnet links
  • DHT (BEP-5) for tracker-less and magnet-link operation
  • MSE/PE encryption (BEP-6) with plaintext fallback
  • BEP-9 metadata exchange (fetches the info dict from peers for magnet links)
  • Resume interrupted downloads automatically on the next run
  • Optional seeding after download completes, with ratio and time limits
  • Progress bar showing speed, ETA, and peer count
  • Structured logging via RUST_LOG / --verbose

Installation

cargo install stormdrain

Or from source (requires Rust 1.85 or later, edition 2024):

git clone https://github.com/you/stormdrain
cd stormdrain
cargo install --path .

Or build without installing:

cargo build --release
# binary at target/release/stormdrain

Usage

stormdrain [OPTIONS] <SOURCE>

SOURCE is a path to a .torrent file, an HTTP(S) URL to a .torrent, or a magnet link.

Options

Flag Short Description
--download-dir <DIR> -w Directory to save files (default: current directory)
--port <PORT> -p Peer port advertised to trackers (default: 6881)
--max-download <KBPS> -d Download speed cap in KB/s (0 = unlimited)
--max-upload <KBPS> -u Upload speed cap in KB/s (0 = unlimited)
--sequential Download pieces in order (useful for media streaming)
--seed -s Seed after the download finishes
--seed-ratio <RATIO> Stop seeding when upload/download ratio reaches this value
--seed-time <MINUTES> Stop seeding after this many minutes
--quiet -q Suppress progress bar; print errors only
--verbose -v Enable debug logging (equivalent to RUST_LOG=stormdrain=debug)

Examples

Download a torrent to the current directory:

stormdrain ubuntu-24.04.torrent

Download to a specific directory:

stormdrain -w ~/Downloads ubuntu-24.04.torrent

Download from a URL:

stormdrain https://releases.ubuntu.com/24.04/ubuntu-24.04-desktop-amd64.iso.torrent

Download from a magnet link:

stormdrain "magnet:?xt=urn:btih:..."

Download and seed until ratio 2.0:

stormdrain --seed --seed-ratio 2.0 ubuntu-24.04.torrent

Resume

If a download is interrupted (Ctrl-C, crash, lost connection), the progress is checkpointed to disk after each completed piece. Re-running the same command will verify already-downloaded pieces and continue from where it left off.

Library

The stormdrain crate doubles as a library. Add it as a dependency to embed the engine in your own application:

[dependencies]
stormdrain = "0.1.0"
use std::sync::Arc;
use stormdrain::{download, download::Config, metainfo::Metainfo};

#[tokio::main]
async fn main() {
    let data = std::fs::read("example.torrent").unwrap();
    let meta = Arc::new(Metainfo::from_bytes(&data).unwrap());
    let config = Config::default();
    download::download(meta, config, |stats| {
        println!("{:.1}%", stats.progress * 100.0);
    })
    .await
    .unwrap();
}

Project layout

src/
  lib.rs               library crate root + public re-exports
  bencode.rs           bencode encoder/decoder
  dht.rs               DHT client (BEP-5)
  download.rs          download orchestrator
  error.rs             error types
  file_writer.rs       async multi-file writer
  magnet.rs            magnet link parser
  metainfo.rs          .torrent parser
  piece_manager.rs     piece scheduling and verification
  resume.rs            resume state persistence
  types.rs             shared types (InfoHash, PeerId, PeerAddr)
  peer/
    conn.rs            async peer connection (read/write messages)
    handshake.rs       BEP-3 handshake
    id.rs              peer ID generation
    message.rs         peer wire message codec
    metadata_exchange.rs  BEP-9 info dict fetch
    mse.rs             MSE/PE encryption (BEP-6)
  tracker/
    http.rs            HTTP tracker announce (BEP-3)
    udp.rs             UDP tracker announce (BEP-15)
  bin/
    stormdrain/
      main.rs          entry point + run()
      args.rs          CLI argument definitions (clap)
      display.rs       progress bar + human_size()

License

GPL-3.0-or-later. See LICENSE.

About

A Rust BitTorrent library and CLI

Resources

License

Stars

Watchers

Forks

Contributors

Languages