Add support for the `hashes` query parameter (pipe-separated, case-insensitive)
to match real qBittorrent API behavior. This fixes compatibility with cleanuparr
and *arr apps that rely on hash-based filtering.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Applied to TorBox, can be extended easily to other providers
- Reads response headers commonplace for pre-emptive rate limit throttling and retry-after
- When a rate limit is reached, displays a warning in the UI
- Fix socket leak from direct allocation of HttpClient, replaced with factory which handles pooling and re-use of sockets.
While HttpClient is Disposable, it doesn't gaurantee (and does not) directly release underlying sockets for queries at the time the client is disposed. These sockets will go into a TCP WAIT state often for a very long time. The expected pattern in C# is to always use the HttClientFactory which will correctly handle re-use of the OS sockets in suqsequent queries reducing resource and memory leaks.
This fix allows Cleanuparr to successfully connect to RDT Client by making the
health check endpoints accessible without authentication, matching real qBittorrent
behavior. The three endpoints affected are:
- /api/v2/app/version
- /api/v2/app/webapiVersion
- /api/v2/app/buildInfo
Fixes#867
- ### Problem
When using multiple *arr instances (sonarr, radarr ...), the queue
on each instance displays *all* torrents being processed by RDT.
The normal behaviour is to display torrents that have the same
category as the one set in the DownloadClient config on
radarr/sonarr.
### Solution
*arr uses the `/api/v2/torrents/info` QBittorrent endpoint which
accepts a `category` query string.
This is how the Qbittorent API behaves when that query string
exists:
```text
See https://github.com/qbittorrent/qBittorrent/wiki/WebUI-API-(qBittorrent-4.1)#get-torrent-list
Get torrents with the given category.
empty string means "without category";
no "category" parameter means "any category"
```
See [here](3125b038d5/src/NzbDrone.Core/Download/Clients/QBittorrent/QBittorrentProxyV2.cs (L96)) how radarr sets the categories when making the query.
Thanks for your indulgence, first time writing dotnet :)