diff options
| author | Cosmin Dumitru <cosu@cosu.ro> | 2026-02-18 21:08:35 +0100 |
|---|---|---|
| committer | Cosmin Dumitru <cosu@cosu.ro> | 2026-02-18 21:08:35 +0100 |
| commit | 37b50fe13c689e8fb89288da12f79bf7164e1194 (patch) | |
| tree | 6700515145dc62c913dc7524b3392f396747dc1b /MediaBrowser.Model | |
| parent | 06a6c6e16b274e99e00402a21818d4dbb760eca7 (diff) | |
Fix malformed query string in StreamInfo.ToUrl() causing 500 error via proxies
StreamInfo.ToUrl() generated URLs like `/master.m3u8?&DeviceId=...` (note `?&`)
because `?` was appended to the path and all parameters started with `&`. When
the first optional parameter (DeviceProfileId) was null, the result was a
malformed query string.
This is harmless when clients hit Jellyfin directly (ASP.NET Core tolerates `?&`),
but when accessed through a reverse proxy that parses and re-serializes the URL
(e.g. Home Assistant ingress via aiohttp/yarl), `?&` becomes `?=&` — introducing
an empty-key query parameter. ParseStreamOptions then crashes on `param.Key[0]`
with IndexOutOfRangeException.
Changes:
- StreamInfo.ToUrl(): Track query start position and replace the first `&` with
`?` after all parameters are appended, producing valid query strings
- ParseStreamOptions: Guard against empty query parameter keys
- Tests: Remove .Replace("?&", "?") workaround that masked the bug
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Diffstat (limited to 'MediaBrowser.Model')
| -rw-r--r-- | MediaBrowser.Model/Dlna/StreamInfo.cs | 12 |
1 files changed, 9 insertions, 3 deletions
diff --git a/MediaBrowser.Model/Dlna/StreamInfo.cs b/MediaBrowser.Model/Dlna/StreamInfo.cs index 551bee89e..7aad97ce0 100644 --- a/MediaBrowser.Model/Dlna/StreamInfo.cs +++ b/MediaBrowser.Model/Dlna/StreamInfo.cs @@ -895,7 +895,7 @@ public class StreamInfo if (SubProtocol == MediaStreamProtocol.hls) { - sb.Append("/master.m3u8?"); + sb.Append("/master.m3u8"); } else { @@ -906,10 +906,10 @@ public class StreamInfo sb.Append('.'); sb.Append(Container); } - - sb.Append('?'); } + var queryStart = sb.Length; + if (!string.IsNullOrEmpty(DeviceProfileId)) { sb.Append("&DeviceProfileId="); @@ -1133,6 +1133,12 @@ public class StreamInfo sb.Append(query); } + // Replace the first '&' with '?' to form a valid query string. + if (sb.Length > queryStart) + { + sb[queryStart] = '?'; + } + return sb.ToString(); } |
