Security, Reliability & Web-UI Hardening
Security & Concurrency
- WebSocket hub races fixed — slow-client eviction now runs under the write lock (was a concurrent map write under a read lock that could panic the hub); the send channel is closed exactly once.
- WebSocket origin checks —
CheckOriginvalidatesOriginagainst the allow-list (same-origin allowed, cross-origin denied by default), preventing cross-site WebSocket hijacking. - Race-free settings updates —
POST /api/settingslocks and publishes the proxy config copy-on-write, so it no longer races in-flight downloads. - Constant-time basic-auth comparison; checked
crypto/rand; coalescer stopped on shutdown.
Reliability
- Stronger verification — files are SHA256-verified whenever a content hash is known (covers multipart);
--verify etagnow actually verifies instead of doing nothing. - Path-traversal guard on entries from the (operator-configurable) repo tree before any write.
- Mirror push/pull streams blobs with
io.Copy(no whole-file-into-RAM) and--verifydoes a real SHA256 check. - Typed errors (
*APIError/*DownloadError/*VerificationError) soerrors.Is/Asworks.
Web UI
- One model at a time (#85) — adding several models via Analyze used to start them all at once. Downloads now run serially (like the CLI); extra models stay
queued. The setting "Concurrent downloads" is relabeled "Parallel files per model".
Internal / Docs
- Version sourced from the build (health, WebSocket, UI footer); removed dead blob-coordination code; documented dismiss/mirror/cache endpoints and
analyze -i/download --exact.
Full Changelog: v3.1.1...v3.2.0