Skip to content

Send the Jellyfin download token in the Authorization header - #1603

Open
pablofontanilla wants to merge 1 commit into
TortugaPower:developfrom
pablofontanilla:fix/jellyfin-download-auth
Open

pablofontanilla wants to merge 1 commit into
TortugaPower:developfrom
pablofontanilla:fix/jellyfin-download-auth

Conversation

@pablofontanilla

@pablofontanilla pablofontanilla commented Sep 24, 2026 •

Copy link
Copy Markdown

Summary

Refs #1598. Jellyfin audiobook downloads fail with HTTP 401.

createItemDownloadRequest sent the access token only as an ?api_key= query item. Our Jellyfin 12.1.0 server rejects that with a 401. This PR:

  • sets Authorization: MediaBrowser Token="…" on the download request. It is set after wrapWithCustomHeaders, so a custom header cannot replace it (same rule as JellyfinHeaderInjector).
  • removes the ?api_key= query item. This also keeps the token out of the download task's persisted taskDescription (SingleFileDownload-<url>).

No new files and no project.pbxproj changes. The tests are in the existing JellyfinQuickConnectTests.swift.

Header test on our 12.1.0 server

curl, same item, same API key:

Auth method /Items/{id}/Download (range) /Users/{uid}/Items/{id}
?api_key= 401 –
X-Emby-Token: <key> 401 401
X-MediaBrowser-Token: <key> – 401
X-Emby-Authorization: MediaBrowser Token="<key>" – 401
Authorization: MediaBrowser Token="<key>" 206 200

We did not check whether this is a 12.x default or a server setting.

Overlap with #1586

#1586 also fixes this download path, with X-Emby-Token and no ?api_key=. On our server, X-Emby-Token also gets a 401 (see the table), so #1586 may need the Authorization header too.

@GianniCarlo, you can pick the merge order. If this PR merges first, keep your version of createItemDownloadRequest when you rebase and change the header. If you prefer, I can rebase this PR onto #1586.

Out of scope

#1598 also says that Quick Connect does not work. This PR does not change Quick Connect.

Tests

  • New JellyfinDownloadRequestTests (2 tests): the token is in the Authorization header, and the URL has no token and no api_key.
  • Unit Tests plan (BookPlayerTests), iPhone 17 simulator: 535/535 pass.
  • Manual test on the 12.1.0 server (iPhone 17 simulator): an 807 MB audiobook downloaded and imported. There was no 401. (Before the fix, the same request with ?api_key= returned 401 with curl.)

🤖 Generated with Claude Code

The download request put the access token only in an `?api_key=` query
item. A Jellyfin 12.1.0 server rejects that with a 401, so downloads
failed. The request now sets `Authorization: MediaBrowser Token="…"`
after the custom headers, so a custom header cannot replace it.

The `?api_key=` query item is removed, so the token does not go into the
download task's persisted `taskDescription`.

Refs TortugaPower#1598

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@pablofontanilla
pablofontanilla marked this pull request as ready for review September 24, 2026 14:34

This branch has not been deployed

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant