Usenet virtual filesystem with WebDAV serving. Stream files directly from Usenet without downloading — no local storage required.
Written entirely in Rust — pure async I/O, zero-copy streaming, and a single statically-linked binary.
nzbdav-rs accepts NZB files, processes them to discover contained files (RAR archives, plain files), and serves the content as a virtual WebDAV filesystem. Every file read streams directly from Usenet on demand.
NZB → Pipeline → Virtual Filesystem → WebDAV → Browser/VLC/rclone
- Pure Rust RAR4/RAR5 parser — header-only, no decompression, no external libraries
- Native async NNTP client — TLS via rustls, connection pooling, pipelining
- Single binary — ~17MB statically linked, no runtime dependencies
- Memory safe — no buffer overflows, no null pointer dereferences, no data races
- Fast — async I/O throughout, zero-copy where possible, SIMD yEnc decoding
- SABnzbd-compatible API — drop-in download client for Sonarr, Radarr, Lidarr, AIOStreams
- On-demand streaming — no local storage; articles fetched from Usenet in real time
- RAR5 encrypted archives — PBKDF2-HMAC-SHA256 key derivation, AES-256-CBC header decryption
- Multi-server failover — priority-ordered connection pools with automatic failover
- WebDAV server — PROPFIND, GET (with Range), PUT, DELETE, MOVE, COPY, MKCOL, OPTIONS
- Browser playback — stream video directly in Chrome/VLC via WebDAV
- Web UI — queue, history, file browser, upload, server management, settings, real-time logs
- Concurrent processing — configurable parallel NZB pipeline
- Password support — extracts from NZB filename
{{password}}or XML metadata - WebSocket — real-time status updates
# Build
cargo build --release -p nzbdav-app
# Run
./target/release/nzbdav-app --port 8080
# Open the web UI
open http://localhost:8080/ui- Add a Usenet server in the Servers tab
- Upload an NZB in the Upload tab (or configure Sonarr)
- Watch processing in the Logs tab
- Browse and stream files in the Files tab
Rust workspace with 7 crates:
nzbdav-core Models, DB, config, blob store
nzbdav-rar RAR4/RAR5 header parser (pure Rust, no decompression)
nzbdav-stream On-demand Usenet streaming (MultiSegmentStream, SeekableSegmentStream)
nzbdav-pipeline NZB processing (deobfuscation, RAR/plain processors, aggregators)
nzbdav-dav WebDAV server (custom axum handlers)
nzbdav-arr Sonarr/Radarr client, health check, monitoring
nzbdav-app Binary: CLI, SABnzbd API, server management, WebSocket, frontend
| Crate | Version | Description |
|---|---|---|
| nzb-nntp | 0.2.3 | Async NNTP client with TLS, pipelining, connection pooling |
| nzb-core | 0.2.2 | NZB parser, models, SQLite database |
| nzb-decode | 0.1.1 | yEnc decoding and file assembly |
| rust-par2 | 0.1.2 | PAR2 verify and repair |
All settings configurable via CLI flags, environment variables, or the web UI:
--port HTTP listen port (default: 8080, env: NZBDAV_PORT)
--host Listen address (default: 0.0.0.0, env: NZBDAV_HOST)
--db-path SQLite database path (default: nzbdav.db, env: NZBDAV_DB)
--log-level Log level (default: info, env: NZBDAV_LOG)
--api-key API key for SABnzbd API (env: NZBDAV_API_KEY)
--webdav-user WebDAV basic auth username (env: NZBDAV_WEBDAV_USER)
--webdav-pass WebDAV basic auth password (env: NZBDAV_WEBDAV_PASS)
Add nzbdav-rs as a SABnzbd download client:
- Settings → Download Clients → Add → SABnzbd
- Host: your nzbdav host, Port: 8080, API Key: your key
- Category:
tv(Sonarr) ormovies(Radarr)
nzbdav-rs speaks the SABnzbd API protocol — Sonarr/Radarr don't know the difference.
For file access, mount the WebDAV with rclone and configure a remote path mapping. See TEST_STACK.md for details.
AIOStreams is a Stremio addon that uses Usenet as a streaming source via the NzbDAV service type. nzbdav-rs is fully compatible with AIOStreams from v0.5.2 onwards.
Configuration in AIOStreams:
| Field | Value |
|---|---|
| URL | http://your-host:8080/dav |
| Public URL | http://your-public-host:8080/dav |
| API Key | your NZBDAV_API_KEY |
| Username | your NZBDAV_WEBDAV_USER |
| Password | your NZBDAV_WEBDAV_PASS |
The SABnzbd API is served at both /api and /dav/api so the single URL field satisfies both the WebDAV (/dav) and API (/dav/api) requirements.
How it works:
Stremio → AIOStreams → (NZBHydra2/Newznab) → addurl to nzbdav-rs
↓
poll history until Completed
↓
WebDAV PROPFIND to discover files
↓
307 redirect to /dav/content/{category}/{name}/{file}
↓
Stremio streams the video
See TEST_STACK.md for a ready-made Docker Compose stack that wires up nzbdav-rs, NZBHydra2, AIOStreams, and Stremio for local testing.
- SABnzbd API:
/api?mode=addfile|addurl|queue|history|version|status|get_cats(also at/dav/api) - Server management:
GET/POST /api/servers,PUT/DELETE /api/servers/{id} - Settings:
GET/PUT /api/settings - Database backup:
GET /api/backup - WebSocket:
ws://host:port/ws(real-time queue/history/log events)
MIT