Skip to content

streams: support reverse-proxy published base URL#3976

Open
vanackere wants to merge 1 commit into
music-assistant:devfrom
vanackere:feat/streamer-published-url
Open

streams: support reverse-proxy published base URL#3976
vanackere wants to merge 1 commit into
music-assistant:devfrom
vanackere:feat/streamer-published-url

Conversation

@vanackere
Copy link
Copy Markdown

@vanackere vanackere commented May 25, 2026

The streamserver hardcoded http:// in the published base_url. That makes it impossible to run the streamserver behind a TLS-terminating reverse proxy, which is required for some clients — the Sonos S2 controller app for instance silently ignores artwork URLs served over http:// (App Transport Security on iOS, cleartext-traffic policy on Android) and falls back to its built-in placeholder image.

Add a single optional CONF_PUBLISH_BASE_URL advanced setting that lets the user override the URL advertised to stream clients with a full URL of the form scheme://host[:port][/path] (e.g. https://music.example.com/streamer). When empty, falls back to the previous http://<publish_ip>:<bind_port> behavior so existing setups are unaffected.

publish_ip deliberately stays a literal IP — many local-discovery providers (AirPlay, Sendspin, Chromecast, ...) call inet_pton / ipaddress.ip_address on it. Only the advertised URL for stream clients can now diverge.

What does this implement/fix?

Types of changes

  • Bugfix (non-breaking change which fixes an issue) — bugfix
  • New feature (non-breaking change which adds functionality) — new-feature
  • Enhancement to an existing feature — enhancement
  • New music/player/metadata/plugin provider — new-provider
  • Breaking change (fix or feature that would cause existing functionality to not work as expected) — breaking-change
  • Refactor (no behaviour change) — refactor
  • Documentation only — documentation
  • Maintenance / chore — maintenance
  • CI / workflow change — ci
  • Dependencies bump — dependencies

Checklist

  • The code change is tested and works locally.
  • pre-commit run --all-files passes.
  • pytest passes, and tests have been added/updated under tests/ where applicable.
  • For changes to shared models, the companion PR in music-assistant/models is linked.
  • For changes affecting the UI, the companion PR in music-assistant/frontend is linked.
  • I have read and complied with the project's AI Policy for any AI-assisted contributions.

The streamserver hardcoded `http://` in the published `base_url`. That makes
it impossible to run the streamserver behind a TLS-terminating reverse proxy,
which is required for some clients — the Sonos S2 controller app for instance
silently ignores artwork URLs served over `http://` (App Transport Security
on iOS, cleartext-traffic policy on Android) and falls back to its built-in
placeholder image.

Add a single optional `CONF_PUBLISH_BASE_URL` advanced setting that lets the
user override the URL advertised to stream clients with a full URL of the form
`scheme://host[:port][/path]` (e.g. `https://music.example.com/streamer`).
When empty, falls back to the previous `http://<publish_ip>:<bind_port>`
behavior so existing setups are unaffected.

`publish_ip` deliberately stays a literal IP — many local-discovery providers
(AirPlay, Sendspin, Chromecast, ...) call `inet_pton` / `ipaddress.ip_address`
on it. Only the *advertised* URL for stream clients can now diverge.
@vanackere
Copy link
Copy Markdown
Author

This change is tested and allows me to have proper artwork in my sonos app when playing from music assistant

@OzGav
Copy link
Copy Markdown
Contributor

OzGav commented May 25, 2026

The problem this solves is cosmetic. Audio plays fine over plain HTTP, the only thing that doesn't work is the album art showing in the Sonos app. If you controlled your music through Music Assistant you would never see a problem. So this only affects people who use the native Sonos app with MA as a background source, and even then it's just a missing thumbnail.

To fix that, the change asks the user to run a reverse proxy with HTTPS in front of the stream server, and then it swaps the address MA gives to every player, not just Sonos. That's a potential problem. A lot of local players like Squeezebox and older DLNA speakers can't do HTTPS, so anyone who turns this on to fix the Sonos art could end up breaking audio on their other speakers without realising why.

My question is whether this is worth a permanent setting in core. It's a narrow case, it's cosmetic, and MA on its own isn't affected. One alternative is to document a reverse proxy setup for the people who really want it. If we do decide it's worth having, I suggest it should be limited to the Sonos player so it can't affect everyone's other speakers.

@marcelveldt
Copy link
Copy Markdown
Member

This PR goes a bit against our whole recommendation that players should be on the same vLAN (or flat network) as players and the streams server provides a simple, painless way to stream the audio to players. There is a reason that the streamserver does not add HTTPS by default as it adds unneeded overhead and a lot of players even struggle with HTTPS, especially the older ones.

Maybe this works for Sonos players but it will fail for others.

The whole idea of this streams server being detached from the normal webserver is that we can provide the players on the network this direct connection, without the overhead.

Putting the streams server behind a reverse proxy is just a bad idea.
You may be knowing what you are doing but also a lot of people don't and then end up filing support requests that stuff is not working properly. It may even set the wrong expectation that the streams server can be exposed on the internet. It is NOT, its meant to be served only locally on your network. Imagine what will happen if somebody (accidentally) opens it up on the internet.

So I'm inclined to say that this PR should not be accepted in this form.
In normal situations your players should just be on the same L2 network as the MA server and there is no reason to not do that unless complicating your setup. So maybe start with your reasoning why you want it setup this way.

@vanackere
Copy link
Copy Markdown
Author

In my particular case, my Sonos devices are indeed on a dedicated network distinct from Music Assistant (for security reasons) and it was not too much work to set up an https reverse proxy (not exposed to the internet, of course).

Well yes, this is of course cosmetic, but at least for me, it's quite nice to have proper icons in the Sonos app when playing from Music Assistant, and the code change is both really minor, hidden under advanced options, and a quality-of-life improvement... why not?

I'm willing to change this into another form that would make this acceptable if you think this may either introduce confusion or issues for existing users (personally I think the stream configuration is already quite confusing / reserved for advanced users anyway).
Adding a Sonos-specific option would be an alternative but I didn't want to make too much changes to the existing code and this one looked quite reasonable / low risk.

@marcelveldt
Copy link
Copy Markdown
Member

But the streams server shouldn't be behind a reverse proxy at all.
Streams server = local network only, direct connection to the players. You can even decide to have your setup multi-homed so the streams server sits on your IoT interface.

I'm afraid if we add this, we will run into situations where people have issues with audio because of the reverse proxy in between (which we cant control).

@vanackere
Copy link
Copy Markdown
Author

vanackere commented May 27, 2026 via email

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

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants