refactor(transcoding): replace strings.EqualFold with direct comparison for protocol and limitation checks

Signed-off-by: Deluan <deluan@navidrome.org>
This commit is contained in:
Deluan 2026-02-05 20:39:06 -05:00
parent c60fb2e419
commit 0d727444ea
2 changed files with 44 additions and 13 deletions

View File

@ -5,7 +5,6 @@ import (
"fmt"
"net/http"
"strconv"
"strings"
"github.com/navidrome/navidrome/core"
"github.com/navidrome/navidrome/log"
@ -98,7 +97,7 @@ func (r *clientInfoRequest) toCore() *core.ClientInfo {
Required: lim.Required,
}
// Convert audioBitrate limitation values from bps to kbps
if strings.EqualFold(lim.Name, core.LimitationAudioBitrate) {
if lim.Name == core.LimitationAudioBitrate {
coreLim.Values = convertBitrateValues(lim.Values)
}
coreCP.Limitations = append(coreCP.Limitations, coreLim)
@ -164,26 +163,26 @@ func (r *clientInfoRequest) validate() error {
}
func isValidProtocol(p string) bool {
return strings.EqualFold(p, core.ProtocolHTTP) || strings.EqualFold(p, core.ProtocolHLS)
return p == core.ProtocolHTTP || p == core.ProtocolHLS
}
func isValidCodecProfileType(t string) bool {
return strings.EqualFold(t, core.CodecProfileTypeAudio)
return t == core.CodecProfileTypeAudio
}
func isValidLimitationName(n string) bool {
return strings.EqualFold(n, core.LimitationAudioChannels) ||
strings.EqualFold(n, core.LimitationAudioBitrate) ||
strings.EqualFold(n, core.LimitationAudioProfile) ||
strings.EqualFold(n, core.LimitationAudioSamplerate) ||
strings.EqualFold(n, core.LimitationAudioBitdepth)
return n == core.LimitationAudioChannels ||
n == core.LimitationAudioBitrate ||
n == core.LimitationAudioProfile ||
n == core.LimitationAudioSamplerate ||
n == core.LimitationAudioBitdepth
}
func isValidComparison(c string) bool {
return strings.EqualFold(c, core.ComparisonEquals) ||
strings.EqualFold(c, core.ComparisonNotEquals) ||
strings.EqualFold(c, core.ComparisonLessThanEqual) ||
strings.EqualFold(c, core.ComparisonGreaterThanEqual)
return c == core.ComparisonEquals ||
c == core.ComparisonNotEquals ||
c == core.ComparisonLessThanEqual ||
c == core.ComparisonGreaterThanEqual
}
// GetTranscodeDecision handles the OpenSubsonic getTranscodeDecision endpoint.

View File

@ -110,6 +110,38 @@ var _ = Describe("Transcode endpoints", func() {
Expect(err.Error()).To(ContainSubstring("invalid codec profile type"))
})
It("rejects wrong-case protocol", func() {
body := `{"directPlayProfiles":[{"containers":["mp3"],"audioCodecs":["mp3"],"protocols":["HTTP"]}]}`
r := newJSONPostRequest("mediaId=song-1&mediaType=song", body)
_, err := router.GetTranscodeDecision(w, r)
Expect(err).To(HaveOccurred())
Expect(err.Error()).To(ContainSubstring("invalid protocol"))
})
It("rejects wrong-case codec profile type", func() {
body := `{"codecProfiles":[{"type":"audiocodec","name":"mp3"}]}`
r := newJSONPostRequest("mediaId=song-1&mediaType=song", body)
_, err := router.GetTranscodeDecision(w, r)
Expect(err).To(HaveOccurred())
Expect(err.Error()).To(ContainSubstring("invalid codec profile type"))
})
It("rejects wrong-case comparison operator", func() {
body := `{"codecProfiles":[{"type":"AudioCodec","name":"mp3","limitations":[{"name":"audioBitrate","comparison":"lessthanequal","values":["320"]}]}]}`
r := newJSONPostRequest("mediaId=song-1&mediaType=song", body)
_, err := router.GetTranscodeDecision(w, r)
Expect(err).To(HaveOccurred())
Expect(err.Error()).To(ContainSubstring("invalid comparison"))
})
It("rejects wrong-case limitation name", func() {
body := `{"codecProfiles":[{"type":"AudioCodec","name":"mp3","limitations":[{"name":"AudioBitrate","comparison":"Equals","values":["320"]}]}]}`
r := newJSONPostRequest("mediaId=song-1&mediaType=song", body)
_, err := router.GetTranscodeDecision(w, r)
Expect(err).To(HaveOccurred())
Expect(err.Error()).To(ContainSubstring("invalid limitation name"))
})
It("returns a valid decision response", func() {
mockMFRepo.SetData(model.MediaFiles{
{ID: "song-1", Suffix: "mp3", Codec: "MP3", BitRate: 320, Channels: 2, SampleRate: 44100},