ODL

Flexible download library and CLI intended to be fast, reliable, and easy to use.
Quick Start
Install
Linux / macOS (installs to ~/.local/bin by default):
curl -fsSL https://raw.githubusercontent.com/jd1378/odl/main/tools/install.sh | sh
Custom directory:
curl -fsSL https://raw.githubusercontent.com/jd1378/odl/main/tools/install.sh | sh -s -- --dir /usr/local/bin
Windows (PowerShell, installs to %LOCALAPPDATA%\Programs\odl and adds it to user PATH):
irm https://raw.githubusercontent.com/jd1378/odl/main/tools/install.ps1 | iex
From source (any platform with Rust toolchain):
cargo install odl
Uninstall
Linux / macOS:
curl -fsSL https://raw.githubusercontent.com/jd1378/odl/main/tools/uninstall.sh | sh
# also drop user config
curl -fsSL https://raw.githubusercontent.com/jd1378/odl/main/tools/uninstall.sh | sh -s -- --purge
Windows (PowerShell):
irm https://raw.githubusercontent.com/jd1378/odl/main/tools/uninstall.ps1 | iex
Use
odl https://example.com/file.zip
Features
| Feature | Description |
|---|
| ⚡ Multi-part downloads | Configurable parallel connections for faster downloads |
| 🔄 Automatic resume support | Seamlessly continue interrupted downloads (if server supports range requests) |
| 📝 Conflict resolution | Handles file changes and existing files intelligently (configurable) |
| 🛡️ Crash resilient | Minimizes data loss during unexpected interruptions |
| 🌐 Custom HTTP headers & proxy support | Flexible networking options for advanced use cases |
| 🔁 Retry logic | Automatic retries with configurable backoff on failures |
| 🕒 Preserve modification times (optional) | Optionally keeps server file modification timestamps |
| 🏷️ Server-sent file names | Uses server-provided file names when available; otherwise falls back to the URL's last segment. |
This project provides both a command-line program (odl) and a Rust library (odl crate). Use the CLI for quick downloads and scripting; use the library when you need programmatic control inside an application.
CLI Usage
- Download a single remote file (URL)
# Download a single URL and use the server-provided filename
odl https://example.com/file.zip
# Specify output file path
odl https://example.com/file.zip -o /path/to/save/file.zip
- Download from a remote list (URL pointing to a newline-separated list of URLs)
# Treat the input as a remote list of URLs and save downloaded files into a directory
odl --remote-list https://example.com/list.txt -o /downloads
- Download from a local file containing URLs
# Input file contains one URL per line; output is a directory
odl /path/to/urls.txt -o /downloads
- Temporary (one-off) configuration via CLI flags
# Limit max connections for this single run
odl --max-connections 4 https://example.com/file.zip
# Temporary speed limit (per run). Accepts either a raw byte count or a human‑readable value with units; input is case‑insensitive.
# All different representations work the same: KiB, K, KB
odl --speed-limit 100K https://example.com/file.zip
- Persistent configuration (save changes to config file)
The CLI provides a config subcommand that updates the persistent configuration (default config path is odl/config.toml inside the user's appdata directory). Changes made with odl config are saved and used by subsequent runs.
# Show current configuration and its location
odl config --show
# Set persistent max connections
odl config --max-connections 8
# Use a specific config file and change a value there
odl config --config-file ~/.config/odl/config.toml --max-connections 6
# Then you can use it for a new download:
odl --config-file ~/.config/odl/config.toml https://example.com/file.zip
Note: Flags passed directly to odl (for example --max-connections, --speed-limit, --user-agent, etc.) apply only to that invocation and override persistent configuration for that run.
Machine interface (--format json)