rqbit is a bittorrent client written in Rust. Has HTTP API and Web UI, and can be used as a library.
Also has a desktop app built with Tauri.
Assuming you are downloading to ~/Downloads.
rqbit server start ~/Downloads
Assuming you are downloading to ~/Downloads. If the server is already started, -o ~/Downloads
can be omitted.
rqbit download -o ~/Downloads 'magnet:?....' [https?:https://url/to/.torrent] [/path/to/local/file.torrent]
Access with https://localhost:3030/web/. It looks similar to Desktop app, see screenshot below.
The desktop app is a thin wrapper on top of the Web UI frontend.
Download it in Releases for OSX and Windows. For Linux, build manually with
cargo tauri build
![Rqbit desktop](https://private-user-images.githubusercontent.com/221386/308307296-51f56542-667f-4f5e-a1e0-942b1df4cd5a.png?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJnaXRodWIuY29tIiwiYXVkIjoicmF3LmdpdGh1YnVzZXJjb250ZW50LmNvbSIsImtleSI6ImtleTUiLCJleHAiOjE3MjU2NTk4OTYsIm5iZiI6MTcyNTY1OTU5NiwicGF0aCI6Ii8yMjEzODYvMzA4MzA3Mjk2LTUxZjU2NTQyLTY2N2YtNGY1ZS1hMWUwLTk0MmIxZGY0Y2Q1YS5wbmc_WC1BbXotQWxnb3JpdGhtPUFXUzQtSE1BQy1TSEEyNTYmWC1BbXotQ3JlZGVudGlhbD1BS0lBVkNPRFlMU0E1M1BRSzRaQSUyRjIwMjQwOTA2JTJGdXMtZWFzdC0xJTJGczMlMkZhd3M0X3JlcXVlc3QmWC1BbXotRGF0ZT0yMDI0MDkwNlQyMTUzMTZaJlgtQW16LUV4cGlyZXM9MzAwJlgtQW16LVNpZ25hdHVyZT03ZmU2MDk1ZjE3MDdlY2RiZTAxOTNkZmZhZjkwMTUzMjdiOTY2NDBkNWI0YzRhZTEwNjU0ZmE5YzQ4MmFjMjdiJlgtQW16LVNpZ25lZEhlYWRlcnM9aG9zdCZhY3Rvcl9pZD0wJmtleV9pZD0wJnJlcG9faWQ9MCJ9.Z-szCspd9H06wVcmzRqcrODRgffATk5YcJh8QDjCWN0)
rqbit can stream torrent files and smartly block the stream until the pieces are available. The pieces getting streamed are prioritized. All of this allows you to seek and live stream videos for example.
You can also stream to e.g. VLC or other players with HTTP URLs. Supports seeking too (through various range headers). The streaming URLs look like https://IP:3030/torrents/<torrent_id>/stream/<file_id>
rqbit can advertise managed torrents to LAN, e.g. your TVs and stream torrents there (without transcoding). Seeking to arbitrary points in the videos is supported too.
Usage from CLI
rqbit --upnp-server-hostname <YOUR_IP_VISIBLE_FROM_LAN> server start ...
Anecdotally from a few reports, rqbit is faster than other clients they've tried, at least with their default settings.
Memory usage for the server is usually within a few tens of megabytes, which makes it great for e.g. RaspberryPI.
CPU is spent mostly on SHA1 checksumming.
There are pre-built binaries in Releases. If someone wants to put rqbit into e.g. homebrew, PRs welcome :)
If you have rust toolchain installed, this should work:
cargo install rqbit
Docker images are published at ikatson/rqbit
Just a regular Rust binary build process.
cargo build --release
The "webui" feature requires npm and python3 installed.
Increase verbosity. Possible values: trace, debug, info, warn, error.
Will print the contents of the torrent file or the magnet link.
If you want to resume downloading a file that already exists, you'll need to add this option.
This will increase the default peer connect timeout. The default one is 2 seconds, and it's sometimes not enough.
Use a regex here to select files by their names.
- Sequential downloading (the default and only option)
- Resume downloading file(s) if they already exist on disk
- Selective downloading using a regular expression for filename
- DHT support. Allows magnet links to work, and makes more peers available.
- HTTP API
- Pausing / unpausing / deleting (with files or not) APIs
- Stateful server
- Web UI
- Streaming, with seeking
- UPNP port forwarding to your router
- UPNP Media Server
- Fastresume (no rehashing)
By default it listens on https://127.0.0.1:3030.
curl -s 'https://127.0.0.1:3030/'
{
"apis": {
"GET /": "list all available APIs",
"GET /dht/stats": "DHT stats",
"GET /dht/table": "DHT routing table",
"GET /torrents": "List torrents (default torrent is 0)",
"GET /torrents/{id_or_infohash}": "Torrent details",
"GET /torrents/{id_or_infohash}/haves": "The bitfield of have pieces",
"GET /torrents/{id_or_infohash}/peer_stats": "Per peer stats",
"GET /torrents/{id_or_infohash}/stats/v1": "Torrent stats",
"GET /web/": "Web UI",
"POST /rust_log": "Set RUST_LOG to this post launch (for debugging)",
"POST /torrents": "Add a torrent here. magnet: or https:// or a local file.",
"POST /torrents/{id_or_infohash}/delete": "Forget about the torrent, remove the files",
"POST /torrents/{id_or_infohash}/forget": "Forget about the torrent, keep the files",
"POST /torrents/{id_or_infohash}/pause": "Pause torrent",
"POST /torrents/{id_or_infohash}/start": "Resume torrent",
"POST /torrents/{id_or_infohash}/update_only_files": "Change the selection of files to download. You need to POST json of the following form {"only_files": [0, 1, 2]}"
},
"server": "rqbit"
}
curl -d 'magnet:?...' https://127.0.0.1:3030/torrents
OR
curl -d 'https://.../file.torrent' https://127.0.0.1:3030/torrents
OR
curl --data-binary @/tmp/xubuntu-23.04-minimal-amd64.iso.torrent https://127.0.0.1:3030/torrents
Supported query parameters, all optional:
- overwrite=true|false
- only_files_regex - the regular expression string to match filenames
- output_folder - the folder to download to. If not specified, defaults to the one that rqbit server started with
- list_only=true|false - if you want to just list the files in the torrent instead of downloading
- crates/rqbit - main binary
- crates/librqbit - main library
- crates/librqbit-core - torrent utils
- crates/bencode - bencode serializing/deserializing
- crates/buffers - wrappers around binary buffers
- crates/clone_to_owned - a trait to make something owned
- crates/sha1w - wrappers around sha1 libraries
- crates/peer_binary_protocol - the protocol to talk to peers
- crates/dht - Distributed Hash Table implementation
- crates/upnp - upnp port forwarding
- crates/upnp_serve - upnp MediaServer
- desktop - desktop app built with Tauri
First of all, I love Rust. The project was created purely for the fun of the process of writing code in Rust.
I was not satisfied with my regular bittorrent client, and was wondering how much work would it be to create a new one from scratch, and it got where it is, starting from bencode protocol implemenation, then peer protocol, etc, etc.