mirror of
https://github.com/navidrome/navidrome.git
synced 2026-05-03 06:51:16 +00:00
fix(subsonic): strip OpenSubsonic extensions from playlists for legacy clients
buildOSPlaylist was the only OpenSubsonic builder function missing the LegacyClients guard, causing attributes like `validUntil` and `readonly` to appear in playlist XML responses for legacy clients like DSub2000. This caused a crash when DSub2000 tried to parse evaluated smart playlists containing the `validUntil` attribute.
This commit is contained in:
parent
c60637de24
commit
23f3556371
@ -159,6 +159,10 @@ func (api *Router) buildPlaylist(ctx context.Context, p model.Playlist) response
|
|||||||
}
|
}
|
||||||
|
|
||||||
func buildOSPlaylist(ctx context.Context, p model.Playlist) *responses.OpenSubsonicPlaylist {
|
func buildOSPlaylist(ctx context.Context, p model.Playlist) *responses.OpenSubsonicPlaylist {
|
||||||
|
player, ok := request.PlayerFrom(ctx)
|
||||||
|
if ok && isClientInList(conf.Server.Subsonic.LegacyClients, player.Client) {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
pls := responses.OpenSubsonicPlaylist{}
|
pls := responses.OpenSubsonicPlaylist{}
|
||||||
|
|
||||||
if p.IsSmartPlaylist() {
|
if p.IsSmartPlaylist() {
|
||||||
|
|||||||
@ -128,6 +128,23 @@ var _ = Describe("buildPlaylist", func() {
|
|||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
Context("with legacy client", func() {
|
||||||
|
BeforeEach(func() {
|
||||||
|
conf.Server.Subsonic.LegacyClients = "legacy-client"
|
||||||
|
player := model.Player{Client: "legacy-client"}
|
||||||
|
ctx = request.WithPlayer(ctx, player)
|
||||||
|
})
|
||||||
|
|
||||||
|
It("returns all standard fields but no OpenSubsonic extensions", func() {
|
||||||
|
result := router.buildPlaylist(ctx, playlist)
|
||||||
|
|
||||||
|
Expect(result.Comment).To(Equal("Test comment"))
|
||||||
|
Expect(result.Owner).To(Equal("admin"))
|
||||||
|
Expect(result.Public).To(BeTrue())
|
||||||
|
Expect(result.OpenSubsonicPlaylist).To(BeNil())
|
||||||
|
})
|
||||||
|
})
|
||||||
|
|
||||||
Context("when no player in context", func() {
|
Context("when no player in context", func() {
|
||||||
It("returns all fields", func() {
|
It("returns all fields", func() {
|
||||||
result := router.buildPlaylist(ctx, playlist)
|
result := router.buildPlaylist(ctx, playlist)
|
||||||
@ -213,6 +230,23 @@ var _ = Describe("buildPlaylist", func() {
|
|||||||
Expect(result.ValidUntil).To(Equal(&validUntil))
|
Expect(result.ValidUntil).To(Equal(&validUntil))
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
Context("with legacy client", func() {
|
||||||
|
BeforeEach(func() {
|
||||||
|
conf.Server.Subsonic.LegacyClients = "legacy-client"
|
||||||
|
player := model.Player{Client: "legacy-client"}
|
||||||
|
ctx = request.WithPlayer(ctx, player)
|
||||||
|
})
|
||||||
|
|
||||||
|
It("returns standard fields but no OpenSubsonic extensions", func() {
|
||||||
|
result := router.buildPlaylist(ctx, playlist)
|
||||||
|
|
||||||
|
Expect(result.Comment).To(Equal("Test comment"))
|
||||||
|
Expect(result.Owner).To(Equal("admin"))
|
||||||
|
Expect(result.Public).To(BeTrue())
|
||||||
|
Expect(result.OpenSubsonicPlaylist).To(BeNil())
|
||||||
|
})
|
||||||
|
})
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user