fix(service): trim whitespace from TuneIn path/query params

Guards against whitespace-only stationID/podcastID/encodedName path
segments and tightens the existing empty-string checks on the search
q/cursor query params. Spotted while reviewing stalkerquatre-oss's
fork diff for TuneIn handling improvements; their s0/Radio fallback
defaults were skipped as unprecedented invented values that would
mask malformed requests instead of erroring.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
Tobias Gesellchen
2026-08-09 19:47:49 +02:00
co-authored by Claude Sonnet 5
parent 3cfbd05d99
commit aae1673451
+8 -8
View File
@@ -47,7 +47,7 @@ func (s *Server) HandleTuneInPlayback(w http.ResponseWriter, r *http.Request) {
sanitizeLog(r.URL.Path), sanitizeLog(r.UserAgent()))
}
stationID := chi.URLParam(r, "stationID")
stationID := strings.TrimSpace(chi.URLParam(r, "stationID"))
resp, err := bmx.TuneInPlayback(stationID, s.tuneInStreamFormats())
if err != nil {
@@ -74,8 +74,8 @@ func (s *Server) HandleTuneInPodcastInfo(w http.ResponseWriter, r *http.Request)
sanitizeLog(r.URL.Path), sanitizeLog(r.UserAgent()))
}
podcastID := chi.URLParam(r, "podcastID")
encodedName := r.URL.Query().Get("encoded_name")
podcastID := strings.TrimSpace(chi.URLParam(r, "podcastID"))
encodedName := strings.TrimSpace(r.URL.Query().Get("encoded_name"))
resp, err := bmx.TuneInPodcastInfo(podcastID, encodedName)
if err != nil {
@@ -102,7 +102,7 @@ func (s *Server) HandleTuneInPlaybackPodcast(w http.ResponseWriter, r *http.Requ
sanitizeLog(r.URL.Path), sanitizeLog(r.UserAgent()))
}
podcastID := chi.URLParam(r, "podcastID")
podcastID := strings.TrimSpace(chi.URLParam(r, "podcastID"))
resp, err := bmx.TuneInPlaybackPodcast(podcastID, s.tuneInStreamFormats())
if err != nil {
@@ -271,7 +271,7 @@ func (s *Server) HandleTuneInSearch(w http.ResponseWriter, r *http.Request) {
sanitizeLog(r.URL.Path), sanitizeLog(r.UserAgent()))
}
query := r.URL.Query().Get("q")
query := strings.TrimSpace(r.URL.Query().Get("q"))
if query == "" {
http.Error(w, "query parameter 'q' is required", http.StatusBadRequest)
return
@@ -298,7 +298,7 @@ func (s *Server) HandleTuneInSearchNext(w http.ResponseWriter, r *http.Request)
sanitizeLog(r.URL.Path), sanitizeLog(r.UserAgent()))
}
cursor := r.URL.Query().Get("cursor")
cursor := strings.TrimSpace(r.URL.Query().Get("cursor"))
if cursor == "" {
http.Error(w, "cursor parameter required", http.StatusBadRequest)
return
@@ -319,7 +319,7 @@ func (s *Server) HandleTuneInSearchNext(w http.ResponseWriter, r *http.Request)
// HandleTuneInFavorite handles POST /bmx/tunein/v1/favorite/{stationID}.
func (s *Server) HandleTuneInFavorite(w http.ResponseWriter, r *http.Request) {
stationID := chi.URLParam(r, "stationID")
stationID := strings.TrimSpace(chi.URLParam(r, "stationID"))
if err := s.ds.SaveTuneInFavorite(stationID); err != nil {
log.Printf("Failed to persist TuneIn favorite %s: %s", sanitizeLog(stationID), sanitizeErr(err))
}
@@ -331,7 +331,7 @@ func (s *Server) HandleTuneInFavorite(w http.ResponseWriter, r *http.Request) {
// HandleTuneInDeleteFavorite handles DELETE /bmx/tunein/v1/favorite/{stationID}.
func (s *Server) HandleTuneInDeleteFavorite(w http.ResponseWriter, r *http.Request) {
stationID := chi.URLParam(r, "stationID")
stationID := strings.TrimSpace(chi.URLParam(r, "stationID"))
if err := s.ds.DeleteTuneInFavorite(stationID); err != nil {
log.Printf("Failed to delete TuneIn favorite %s: %s", sanitizeLog(stationID), sanitizeErr(err))
}