@@ -162,10 +162,25 @@ func (p *protocolSniffer) sniff() {
162162 reader : io .MultiReader (bytes .NewReader (buf ), c ),
163163 }
164164
165- if buf [0 ] == 0x16 { // TLS Handshake record type
166- p .tlsChan <- wrapped
167- } else {
168- p .httpChan <- wrapped
165+ target := p .httpChan
166+ if buf [0 ] == 0x16 {
167+ target = p .tlsChan
168+ }
169+
170+ select {
171+ case target <- wrapped :
172+ default :
173+ // Channel full, drop the oldest to make room for new (likely asset) requests
174+ select {
175+ case old := <- target :
176+ old .Close ()
177+ default :
178+ }
179+ select {
180+ case target <- wrapped :
181+ default :
182+ c .Close () // Really full
183+ }
169184 }
170185 }(conn )
171186 }
@@ -341,7 +356,7 @@ func (s *Server) listenWithReuse(network, address string) (net.Listener, error)
341356 if err != nil {
342357 return nil , err
343358 }
344- return & BannedListener { ln , s } , nil
359+ return ln , nil
345360}
346361
347362func (s * Server ) Shutdown (ctx context.Context ) error {
@@ -416,9 +431,11 @@ func (s *Server) Start() error {
416431 s .TranscoderM .StartTranscoder (tc )
417432 }
418433 }
434+ // Start configured AutoDJs
419435 for _ , adj := range s .Config .AutoDJs {
420436 if adj .Enabled {
421- streamer , err := s .StreamerM .StartStreamer (adj .Name , adj .Mount , adj .MusicDir , adj .Loop , adj .Format , adj .Bitrate , adj .InjectMetadata , adj .Playlist , adj .MPDEnabled , adj .MPDPort , adj .MPDPassword , adj .Visible )
437+ absMusicDir , _ := filepath .Abs (adj .MusicDir )
438+ streamer , err := s .StreamerM .StartStreamer (adj .Name , adj .Mount , absMusicDir , adj .Loop , adj .Format , adj .Bitrate , adj .InjectMetadata , adj .Playlist , adj .MPDEnabled , adj .MPDPort , adj .MPDPassword , adj .Visible )
422439 if err != nil {
423440 logrus .WithError (err ).Errorf ("Failed to start AutoDJ %s" , adj .Name )
424441 } else {
@@ -659,8 +676,8 @@ func (s *Server) startHTTPS(mux *http.ServeMux, addr string) error {
659676
660677 sniffer := & protocolSniffer {
661678 Listener : rawLn ,
662- tlsChan : make (chan net.Conn , 1024 ),
663- httpChan : make (chan net.Conn , 1024 ),
679+ tlsChan : make (chan net.Conn , 4096 ),
680+ httpChan : make (chan net.Conn , 4096 ),
664681 }
665682 go sniffer .sniff ()
666683
@@ -2354,14 +2371,16 @@ func (s *Server) handleAddAutoDJ(w http.ResponseWriter, r *http.Request) {
23542371 format = "mp3"
23552372 }
23562373
2374+ absMusicDir , _ := filepath .Abs (musicDir )
2375+
23572376 if mount [0 ] != '/' {
23582377 mount = "/" + mount
23592378 }
23602379
23612380 adj := & config.AutoDJConfig {
23622381 Name : name ,
23632382 Mount : mount ,
2364- MusicDir : musicDir ,
2383+ MusicDir : absMusicDir ,
23652384 Format : format ,
23662385 Bitrate : bitrate ,
23672386 Enabled : true ,
@@ -2440,7 +2459,8 @@ func (s *Server) handleToggleAutoDJ(w http.ResponseWriter, r *http.Request) {
24402459
24412460 if adj .Enabled {
24422461 if existing == nil {
2443- streamer , err := s .StreamerM .StartStreamer (adj .Name , adj .Mount , adj .MusicDir , adj .Loop , adj .Format , adj .Bitrate , adj .InjectMetadata , adj .Playlist , adj .MPDEnabled , adj .MPDPort , adj .MPDPassword , adj .Visible )
2462+ absMusicDir , _ := filepath .Abs (adj .MusicDir )
2463+ streamer , err := s .StreamerM .StartStreamer (adj .Name , adj .Mount , absMusicDir , adj .Loop , adj .Format , adj .Bitrate , adj .InjectMetadata , adj .Playlist , adj .MPDEnabled , adj .MPDPort , adj .MPDPassword , adj .Visible )
24442464 if err == nil {
24452465 if adj .InjectMetadata {
24462466 if st , ok := s .Relay .GetStream (adj .Mount ); ok {
@@ -2531,14 +2551,25 @@ func (s *Server) handlePlayerQueue(w http.ResponseWriter, r *http.Request) {
25312551 }
25322552
25332553 if action == "add" {
2534- streamer .PushToQueue (path )
2554+ musicDir := streamer .GetMusicDir ()
2555+ fullPath := path
2556+ if ! filepath .IsAbs (path ) {
2557+ fullPath = filepath .Join (musicDir , path )
2558+ }
2559+ // Security: Ensure fullPath is still within musicDir
2560+ if ! strings .HasPrefix (fullPath , musicDir ) {
2561+ http .Error (w , "Forbidden" , http .StatusForbidden )
2562+ return
2563+ }
2564+ abs , _ := filepath .Abs (fullPath )
2565+ streamer .PushToQueue (abs )
25352566 } else if action == "remove" {
25362567 var index int
25372568 fmt .Sscanf (r .FormValue ("index" ), "%d" , & index )
25382569 streamer .RemoveFromQueue (index )
25392570 }
25402571
2541- http . Redirect ( w , r , "/admin#tab-streamer" , http .StatusSeeOther )
2572+ w . WriteHeader ( http .StatusOK )
25422573}
25432574
25442575func (s * Server ) handlePlayerShuffle (w http.ResponseWriter , r * http.Request ) {
@@ -2598,8 +2629,22 @@ func (s *Server) handlePlayerFiles(w http.ResponseWriter, r *http.Request) {
25982629 musicDir := streamer .GetMusicDir ()
25992630 fullPath := filepath .Join (musicDir , subDir )
26002631
2632+ // Security: Ensure fullPath is still within musicDir
2633+ if ! strings .HasPrefix (fullPath , musicDir ) {
2634+ http .Error (w , "Forbidden" , http .StatusForbidden )
2635+ return
2636+ }
2637+
2638+ logrus .WithFields (logrus.Fields {
2639+ "mount" : mount ,
2640+ "musicDir" : musicDir ,
2641+ "subDir" : subDir ,
2642+ "fullPath" : fullPath ,
2643+ }).Debug ("AutoDJ File Browser: Reading directory" )
2644+
26012645 entries , err := os .ReadDir (fullPath )
26022646 if err != nil {
2647+ logrus .WithError (err ).Errorf ("AutoDJ File Browser: Failed to read directory: %s" , fullPath )
26032648 http .Error (w , err .Error (), http .StatusInternalServerError )
26042649 return
26052650 }
@@ -2651,7 +2696,15 @@ func (s *Server) handlePlayerPlaylistAction(w http.ResponseWriter, r *http.Reque
26512696 }
26522697
26532698 if action == "add" {
2654- fullPath := filepath .Join (streamer .GetMusicDir (), relPath )
2699+ musicDir := streamer .GetMusicDir ()
2700+ fullPath := filepath .Join (musicDir , relPath )
2701+
2702+ // Security: Ensure fullPath is still within musicDir
2703+ if ! strings .HasPrefix (fullPath , musicDir ) {
2704+ http .Error (w , "Forbidden" , http .StatusForbidden )
2705+ return
2706+ }
2707+
26552708 info , err := os .Stat (fullPath )
26562709 if err == nil {
26572710 if info .IsDir () {
@@ -2721,11 +2774,13 @@ func (s *Server) handleUpdateAutoDJ(w http.ResponseWriter, r *http.Request) {
27212774 bitrate := 128
27222775 fmt .Sscanf (bitrateStr , "%d" , & bitrate )
27232776
2777+ absMusicDir , _ := filepath .Abs (musicDir )
2778+
27242779 for _ , adj := range s .Config .AutoDJs {
27252780 if adj .Mount == oldMount {
27262781 adj .Name = name
27272782 adj .Mount = newMount
2728- adj .MusicDir = musicDir
2783+ adj .MusicDir = absMusicDir
27292784 adj .Format = format
27302785 adj .Bitrate = bitrate
27312786 adj .Loop = loop
0 commit comments