- Login success = HTTP 200 "Ok." or 204 (5.2+); session cookie taken from
Set-Cookie by name (SID / QBT_SID_<port> / custom) and sent back as-is.
- Failure classes: "Fails." / 401 -> auth; 403 IP ban / 429 -> rate;
wrong API Key (403) -> auth with hint; 5xx -> protocol.
- Downloader instance auth kind: password / api_key (qB 5.2+ Bearer, no
/auth/login) / none (whitelisted subnet); stored in settings.authKind,
credential write-only in secret_ref, cleared when switching to none.
One qbAuthConfig() shared by sync, agent capability and connection test.
- Settings form: auth kind select, password / API Key fields (no echo).
- testkit: mock qB 5.2 login behaviour, IP ban, bypassAuth;
makeTorrent({ realPieces }) builds real piece hashes for real qB checks.
- Real-container matrix (QB_REAL, skipped by default): 5.1.2 and 5.2.4,
login / add / query / tags / pause-resume / delete keeping data.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
qbittorrent
qBittorrent WebUI API v2 适配(QbClient 实现 DownloaderClient,按实例创建,DownloaderRegistry 管多实例):Cookie 登录与会话过期自动重登、API Key(Bearer)、torrents/add(磁力/URL/.torrent,savepath/category/tags/paused+stopped/rename/contentLayout,autoTMM 固定关闭)、torrents/info(hashes/tag/category/filter,多标签子集过滤)、files、filePrio、pause/resume(5.x 自动切到 stop/start)、标签增删与定义删除、delete(deleteFiles 必须显式;deleteFiles:true 必须给每个 hash 附 SafeDeleteCheck,未通过 assertSafeToDeleteData——路径在任何库根内/是库根上级、未验证入库、库根为空——即抛 unsafe_delete 且不发请求)、setForceStart/recheck/setLocation/setCategory/限速与分享限制、只读偏好、sync/maindata、app/version。错误统一为 DownloaderError(auth/network/timeout/notfound/rate/rejected/protocol/unsafe_delete),读请求按配置重试,写请求不自动重试。submit() 本地算 infohash(bencode 自写)→ 预查已存在 → 提交 → 按 hash 或探针标签确认;收单超时/断连时先回查再给结论(added/already_exists/accepted_unconfirmed/rejected/unreachable)。状态映射与完成判定对照 MoviePilot,未知状态不兜底为完成。
仅对 mock 与官方 API 文档验证,未连接真实实例。