[Bug]: iOS Safari incorrectly interprets file download content-type headers and adds incorrect file extensions #2194

Closed
opened 2026-04-25 00:04:51 +02:00 by adam · 3 comments
Owner

Originally created by @chancez on GitHub (Aug 20, 2024).

What happened?

This isnt' a bug with audiobookshelf, but I'm filing this issue because I'd like to implement a workaround for bad iOS Safari behavior.

Basically, when downloading a book such as my-favorite-book.m4b from the "audio tracks" section of audiobookshelf, Safari on iOS will prompt if you wish to view/download my-favorite-book.m4b.mp4, adding the .mp4 extension. Based on some testing, Safari on iOS (and apparently Chrome too) will interpret the Content-Type header and add an "appropriate" file extension to the existing file name being downloaded if needed.

Audiobookshelf is correctly returning Content-Type: audio/mp4 however, Safari interprets this to mean it should be an "mp4" file, causing it to add the .mp4 extension (even though "mp4" and "m4b" are technically the same, and m4b itself is a convention that Apple itself created... 🙃).

Now, this isn't the end of the world, but it means for certain audiobook readers, it will not open the file unless it's renamed, as these apps interpret the file as a video file based on the file extension. This means you must rename the file in the iOS files app before it can be imported into the audiobook reader app.

Now, this is something I can manage, but it's a lot to ask for my wife and my mom. What I'd like, is to see if you would be willing to accept a PR to add a work-around for this behavior. I've tested, and if you use Content-Type: audio/m4b (yes: which isn't standard) it doesn't add the file extension.

So I'd like to ask:

Would you accept a PR that:

  • Unconditionally returns Content-Type: audio/m4b for m4b files
    OR:
  • Checks the user-agent to see if the browser is Safari and returns Content-Type: audio/m4b for m4b files. This is probably more complex/complicated then simply using audio/m4b though.

References:

There's a ton of references if you search "Safari unwanted file extension" in Google.

What did you expect to happen?

The file is downloaded without the .mp4 extension.

Steps to reproduce the issue

On an iPad/iPhone:

  1. Open Safari
  2. Browse to audiobookshelf
  3. Open an audiobook with an m4b file in audiobookshelf
  4. Open the "Audio Tracks" section
  5. Click on the ⋮
  6. Click download
  7. Notice the prompt to download the file adds an extra extension

Audiobookshelf version

v2.12.3

How are you running audiobookshelf?

Docker

What OS is your Audiobookshelf server hosted from?

Linux

If the issue is being seen in the UI, what browsers are you seeing the problem on?

Safari on iOS

Logs

No response

Additional Notes

I've temporarily made a work-around in my reverse proxy to simply hardcode the content-type header to audio/m4b but that will cause issues for any other file types I try to download.

Originally created by @chancez on GitHub (Aug 20, 2024). ### What happened? This isnt' a bug with audiobookshelf, but I'm filing this issue because I'd like to implement a workaround for bad iOS Safari behavior. Basically, when downloading a book such as `my-favorite-book.m4b` from the "audio tracks" section of audiobookshelf, Safari on iOS will prompt if you wish to view/download `my-favorite-book.m4b.mp4`, adding the `.mp4` extension. Based on some testing, Safari on iOS (and apparently Chrome too) will interpret the `Content-Type` header and add an "appropriate" file extension to the existing file name being downloaded if needed. Audiobookshelf is correctly returning `Content-Type: audio/mp4` however, Safari interprets this to mean it should be an "mp4" file, causing it to add the `.mp4` extension (even though "mp4" and "m4b" are _technically_ the same, and m4b itself is a convention that Apple itself created... 🙃). Now, this isn't the end of the world, but it means for certain audiobook readers, it will not open the file unless it's renamed, as these apps interpret the file as a video file based on the file extension. This means you must rename the file in the iOS files app before it can be imported into the audiobook reader app. Now, this is something I can manage, but it's a lot to ask for my wife and my mom. What I'd like, is to see if you would be willing to accept a PR to add a work-around for this behavior. I've tested, and if you use `Content-Type: audio/m4b` (yes: which isn't standard) it doesn't add the file extension. So I'd like to ask: Would you accept a PR that: - Unconditionally returns `Content-Type: audio/m4b` for m4b files OR: - Checks the user-agent to see if the browser is Safari and returns `Content-Type: audio/m4b` for m4b files. This is probably more complex/complicated then simply using `audio/m4b` though. References: - https://discussions.apple.com/thread/250904310?sortBy=rank - https://github.com/epoupon/fileshelter/issues/30 - https://www.redmine.org/issues/31275 - https://discussions.apple.com/thread/6493440 There's a ton of references if you search "Safari unwanted file extension" in Google. ### What did you expect to happen? The file is downloaded without the `.mp4` extension. ### Steps to reproduce the issue On an iPad/iPhone: 1. Open Safari 2. Browse to audiobookshelf 4. Open an audiobook with an m4b file in audiobookshelf 5. Open the "Audio Tracks" section 6. Click on the ⋮ 7. Click download 8. Notice the prompt to download the file adds an extra extension ### Audiobookshelf version v2.12.3 ### How are you running audiobookshelf? Docker ### What OS is your Audiobookshelf server hosted from? Linux ### If the issue is being seen in the UI, what browsers are you seeing the problem on? Safari on iOS ### Logs _No response_ ### Additional Notes I've temporarily made a work-around in my reverse proxy to simply hardcode the content-type header to `audio/m4b` but that will cause issues for any other file types I try to download.
adam added the bug label 2026-04-25 00:04:51 +02:00
adam closed this issue 2026-04-25 00:04:51 +02:00
Author
Owner

@advplyr commented on GitHub (Aug 20, 2024):

Yeah we can add this. We should check the user agent before setting the audio/m4b mime type.

Mime type is being set here for download library file.
https://github.com/advplyr/audiobookshelf/blob/26d2c5a8f07d43c107a694f7f2fd90ceae978c5c/server/controllers/LibraryItemController.js#L816-L820

uaParserJS library is added also that can be used to check the user agent string. Currently that is only being used for device objects.
https://github.com/advplyr/audiobookshelf/blob/26d2c5a8f07d43c107a694f7f2fd90ceae978c5c/server/managers/PlaybackSessionManager.js#L46-L47

@advplyr commented on GitHub (Aug 20, 2024): Yeah we can add this. We should check the user agent before setting the audio/m4b mime type. Mime type is being set here for download library file. https://github.com/advplyr/audiobookshelf/blob/26d2c5a8f07d43c107a694f7f2fd90ceae978c5c/server/controllers/LibraryItemController.js#L816-L820 uaParserJS library is added also that can be used to check the user agent string. Currently that is only being used for device objects. https://github.com/advplyr/audiobookshelf/blob/26d2c5a8f07d43c107a694f7f2fd90ceae978c5c/server/managers/PlaybackSessionManager.js#L46-L47
Author
Owner

@chancez commented on GitHub (Aug 20, 2024):

Great, thanks. I'll take a look at implementing this today or tomorrow hopefully.

@chancez commented on GitHub (Aug 20, 2024): Great, thanks. I'll take a look at implementing this today or tomorrow hopefully.
Author
Owner

@github-actions[bot] commented on GitHub (Aug 31, 2024):

Fixed in v2.13.0.

@github-actions[bot] commented on GitHub (Aug 31, 2024): Fixed in [v2.13.0](https://github.com/advplyr/audiobookshelf/releases/tag/v2.13.0).
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/audiobookshelf#2194