Skip to content

Allow qBittorrent to determine hash ahead of time to avoid association errors#610

Open
T4g1 wants to merge 3 commits into
Listenarrs:canaryfrom
T4g1:fix/609-qbittorrent-hash
Open

Allow qBittorrent to determine hash ahead of time to avoid association errors#610
T4g1 wants to merge 3 commits into
Listenarrs:canaryfrom
T4g1:fix/609-qbittorrent-hash

Conversation

@T4g1
Copy link
Copy Markdown
Contributor

@T4g1 T4g1 commented May 21, 2026

Summary

Changes

Changed

  • Algorithm to match download in QBittorrent and Listennarr now use a more deterministic approach

Testing

  • Added a proper mock for qBittorrent API
  • Added test data framework
  • Added test on a real torrent file (public domain)

Notes

As i was not able to reproduce the issue discussed on Discord (association errors when adding torrents to qBittorrent), this might not solve the real issue but it should be an improvement nonetheless

@T4g1 T4g1 requested a review from therobbiedavis May 21, 2026 12:13
@T4g1 T4g1 self-assigned this May 21, 2026
@T4g1 T4g1 requested a review from a team May 21, 2026 12:13
@T4g1 T4g1 added the patch patch version bump - backward compatible bug fixes label May 21, 2026
Copy link
Copy Markdown
Collaborator

@therobbiedavis therobbiedavis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good for the most part. We need to clean up dead code, and I had a question about BencodeNET

Comment thread listenarr.api/Program.cs Outdated
if (!loginResponse.IsSuccessStatusCode)
{
var body = await loginResponse.Content.ReadAsStringAsync(cancellationToken);
var redacted = LogRedaction.RedactText(body, LogRedaction.GetSensitiveValuesFromEnvironment().Concat([client.Password ?? string.Empty]));
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doesn't look be used

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there might be some more dead code in the adapter like TryPredownloadTorrentFileAsync(), but it's not a blocker. If you get a chance, we should probably also try to clean up the files as we touch them.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I agree but as I already have a whole PR dedicated to cleaning the adapters (#599) i'd rather not change too much here

Comment thread listenarr.infrastructure/Adapters/QbittorrentAdapter.cs
Comment thread listenarr.infrastructure/Adapters/QbittorrentAdapter.cs Outdated
Comment thread Directory.Packages.props
@T4g1 T4g1 requested a review from therobbiedavis May 24, 2026 23:15
Copy link
Copy Markdown
Collaborator

@therobbiedavis therobbiedavis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great job, I still have some hesitation around the cookies and url only torrent adds but I think this is looking better.

Sidenote: Let's make sure we don't commit an impermissible torrent to the repo 😆

Comment thread listenarr.api/Program.cs

// Register named HttpClients for each adapter type so adapter implementations can request the appropriately-configured client.
// qbittorrent
builder.Services.AddSingleton<CookieContainer>();
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

My suspicion is that this could cause errors for those running multiple instances under the same host, like a docker user would. What about moving this into a qBittorrent session manager keyed client.Id + normalized baseUrl + username?

}
}
else
byte[]? torrentFileData = result.TorrentFileContent;
Copy link
Copy Markdown
Collaborator

@therobbiedavis therobbiedavis May 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this regresses URL-only torrent adds. If pre-download returns Empty, we still have a valid httpTorrentUrl, but hash remains empty and AddAsync returns null before reaching the URL add branch. qBittorrent supports adding http/https torrent URLs directly, and canary handled this by adding the URL and then detecting the new hash from torrents/info afterward. I am not sure the best way to handle this with the new direction here though. wdyt?

Copy link
Copy Markdown
Contributor Author

@T4g1 T4g1 May 26, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Indeed, if we can't get the torrent file, we assume qBittorrent will not be able to get it either, hence the branch to add with Magnet/URL will only perform the magnet add
Do you think we should handle the URL case even though we are unable to get the torrent ourselves ? In that case, we re-introduce the issue where we cannot garantee that the hash can be found afterwards

if (!loginResponse.IsSuccessStatusCode)
{
var body = await loginResponse.Content.ReadAsStringAsync(cancellationToken);
var redacted = LogRedaction.RedactText(body, LogRedaction.GetSensitiveValuesFromEnvironment().Concat([client.Password ?? string.Empty]));
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there might be some more dead code in the adapter like TryPredownloadTorrentFileAsync(), but it's not a blocker. If you get a chance, we should probably also try to clean up the files as we touch them.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

patch patch version bump - backward compatible bug fixes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

qBittorrent: Trouble to link ongoing downloads with qBittorrent

2 participants