| Crates.io | gosh-dl |
| lib.rs | gosh-dl |
| version | 0.1.6 |
| created_at | 2026-01-09 06:07:55.767032+00 |
| updated_at | 2026-01-25 00:55:34.671636+00 |
| description | A fast, embeddable download engine for Rust. HTTP/HTTPS with multi-connection acceleration and full BitTorrent protocol support. |
| homepage | https://github.com/goshitsarch-eng/gosh-dl |
| repository | https://github.com/goshitsarch-eng/gosh-dl |
| max_upload_size | |
| id | 2031648 |
| size | 918,042 |
A fast, embeddable download engine for Rust applications. Supports HTTP/HTTPS with multi-connection acceleration and full BitTorrent protocol including DHT, PEX, encryption, and WebSeeds.
gosh-dl brings download functionality directly into your Rust application as a native library, eliminating the complexity of managing external processes, parsing JSON-RPC responses, or bundling platform-specific binaries. Modern applications demand seamless integration, and gosh-dl delivers exactly that; async function calls that feel natural in your codebase, compile-time type safety that catches errors before runtime, and shared memory that keeps your application lightweight and responsive.
Whether you're building a media application that needs BitTorrent with streaming support, a package manager requiring resilient HTTP downloads with checksums and mirrors, or any software that moves files across the network, gosh-dl provides the complete feature set you need. Multi-connection acceleration splits large downloads across parallel connections for maximum throughput. Automatic resume with ETag validation ensures interrupted transfers pick up exactly where they left off. Full BitTorrent support includes DHT for trackerless operation, peer exchange for efficient swarm discovery, and protocol encryption for privacy.
The engine handles the complexity of segmented downloads, tracker communication, DHT peer discovery, and connection encryption while exposing a clean, intuitive API that integrates naturally with Tokio-based applications. Priority queues let you control which downloads matter most, bandwidth scheduling adapts to time-of-day constraints, and SQLite persistence ensures nothing is lost across restarts.
A standalone CLI application is coming soon for those who need command-line access to these capabilities.
Add to your Cargo.toml:
[dependencies]
gosh-dl = "0.1"
tokio = { version = "1", features = ["full"] }
Basic usage:
use gosh_dl::{DownloadEngine, EngineConfig, DownloadOptions};
#[tokio::main]
async fn main() -> Result<(), Box<dyn std::error::Error>> {
let engine = DownloadEngine::new(EngineConfig::default()).await?;
// HTTP download
let id = engine.add_http(
"https://example.com/file.zip",
DownloadOptions::default(),
).await?;
// Subscribe to progress events
let mut events = engine.subscribe();
while let Ok(event) = events.recv().await {
println!("Event: {:?}", event);
}
Ok(())
}
All public types are available at the crate root via re-exports. For explicit imports, use gosh_dl::protocol:
use gosh_dl::protocol::{DownloadEvent, DownloadStatus, ProtocolError};
// Add downloads
let http_id = engine.add_http(url, options).await?;
let torrent_id = engine.add_torrent(&torrent_bytes, options).await?;
let magnet_id = engine.add_magnet(magnet_uri, options).await?;
// Control
engine.pause(id).await?;
engine.resume(id).await?;
engine.cancel(id, delete_files).await?;
// Priority
engine.set_priority(id, DownloadPriority::High)?;
// Status
let status = engine.status(id);
let all = engine.list();
let active = engine.active();
let waiting = engine.waiting();
let stopped = engine.stopped();
let stats = engine.global_stats();
use gosh_dl::{DownloadOptions, DownloadPriority, ExpectedChecksum};
let options = DownloadOptions {
priority: DownloadPriority::High,
save_dir: Some(PathBuf::from("/downloads")),
filename: Some("custom_name.zip".to_string()),
user_agent: Some("MyApp/1.0".to_string()),
referer: Some("https://example.com".to_string()),
headers: vec![("Authorization".to_string(), "Bearer token".to_string())],
cookies: Some(vec!["session=abc123".to_string()]),
checksum: ExpectedChecksum::parse("sha256:abcd1234..."),
mirrors: vec!["https://mirror1.example.com/file.zip".to_string()],
max_connections: Some(8),
max_download_speed: Some(5 * 1024 * 1024), // 5 MB/s
// Torrent-specific
selected_files: Some(vec![0, 2, 5]), // Download only specific files
sequential: Some(true), // For streaming playback
..Default::default()
};
use gosh_dl::DownloadEvent;
let mut events = engine.subscribe();
while let Ok(event) = events.recv().await {
match event {
DownloadEvent::Added { id } => println!("Added: {}", id),
DownloadEvent::Started { id } => println!("Started: {}", id),
DownloadEvent::Progress { id, progress } => {
println!("{}: {:.1}% at {} KB/s",
id,
progress.percentage(),
progress.download_speed / 1024
);
}
DownloadEvent::StateChanged { id, old_state, new_state } => {
println!("{}: {:?} -> {:?}", id, old_state, new_state);
}
DownloadEvent::Completed { id } => println!("Done: {}", id),
DownloadEvent::Failed { id, error, retryable } => {
eprintln!("Failed {}: {} (retryable: {})", id, error, retryable);
}
DownloadEvent::Paused { id } => println!("Paused: {}", id),
DownloadEvent::Resumed { id } => println!("Resumed: {}", id),
DownloadEvent::Removed { id } => println!("Removed: {}", id),
}
}
use gosh_dl::{EngineConfig, HttpConfig, DownloadPriority};
use std::path::PathBuf;
let config = EngineConfig {
download_dir: PathBuf::from("/downloads"),
max_concurrent_downloads: 5,
max_connections_per_download: 16,
min_segment_size: 1024 * 1024, // 1 MB
global_download_limit: Some(10 * 1024 * 1024), // 10 MB/s
global_upload_limit: Some(5 * 1024 * 1024), // 5 MB/s
user_agent: "MyApp/1.0".to_string(),
enable_dht: true,
enable_pex: true,
enable_lpd: true,
max_peers: 55,
seed_ratio: 1.0,
database_path: Some(PathBuf::from("/data/gosh-dl.db")),
..Default::default()
};
use gosh_dl::{EngineConfig, ScheduleRule};
// Limit bandwidth during work hours (Mon-Fri, 9am-5pm)
let work_hours = ScheduleRule::weekdays(
9, // start_hour
17, // end_hour
Some(1024 * 1024), // download_limit: 1 MB/s
None, // upload_limit: unlimited
);
let config = EngineConfig::default()
.add_schedule_rule(work_hours);
cargo build --release
cargo test
cargo doc --open
See technical_spec.md for architecture details.
Traditional download managers like aria2 use JSON-RPC for external communication. This works well for standalone tools, but creates friction when embedding download functionality into applications:
With RPC (aria2 approach):
Your App → Serialize JSON → HTTP/WebSocket → aria2 Process → Parse JSON → Execute
← Parse JSON ← HTTP/WebSocket ← ← Serialize JSON ← Result
With native API (gosh-dl approach):
Your App → engine.add_http(url, opts) → Result
? operator, pattern matching on Result, and standard Rust error propagation. No parsing error strings from JSON responses.gosh-dl was designed as a native Rust alternative to aria2, the popular C++ download utility. While aria2 is excellent as a standalone tool, embedding it in applications requires spawning an external process and communicating via JSON-RPC.
| Aspect | aria2 | gosh-dl |
|---|---|---|
| Integration | External process + JSON-RPC | Native library calls |
| Deployment | Bundle platform binaries | Single Rust crate |
| Type Safety | JSON strings | Rust types with compile-time checks |
| Error Handling | Parse JSON responses | Native Result<T, E> |
| Process Management | Handle lifecycle, crashes | None required |
| Memory | Separate process | Shared with your app |
| aria2 RPC | gosh-dl |
|---|---|
aria2.addUri(urls) |
engine.add_http(url, opts) |
aria2.addTorrent(torrent) |
engine.add_torrent(bytes, opts) |
aria2.pause(gid) |
engine.pause(id) |
aria2.unpause(gid) |
engine.resume(id) |
aria2.remove(gid) |
engine.cancel(id, false) |
aria2.tellStatus(gid) |
engine.status(id) |
aria2.tellActive() |
engine.active() |
aria2.tellWaiting() |
engine.waiting() |
aria2.tellStopped() |
engine.stopped() |
aria2.getGlobalStat() |
engine.global_stats() |
aria2.changeOption(gid, {priority}) |
engine.set_priority(id, priority) |
aria2 is a battle-tested download utility and remains an excellent choice for many use cases. Use aria2 if:
Use gosh-dl if:
Both tools support similar feature sets (multi-connection HTTP, BitTorrent, DHT, etc.). The difference is architectural: aria2 is a standalone process you communicate with, gosh-dl is a library you call directly.
A standalone gosh-dl CLI application is now available and can be found here: gosh-dl-cli. It allows command-line access to all engine features for users who prefer terminal workflows or need to script downloads without writing Rust code.
gosh-dl requires Rust 1.75+ for async trait support.
Yes. gosh-dl supports Linux, macOS, and Windows. Platform-specific code handles differences in file handling, network interfaces, and path conventions.
MIT License - see LICENSE for details.