|
|
|
@@ -340,7 +340,7 @@ func (s *Server) handleRuntimeFaultReset(w http.ResponseWriter, r *http.Request) |
|
|
|
http.Error(w, "method not allowed", http.StatusMethodNotAllowed) |
|
|
|
return |
|
|
|
} |
|
|
|
if !s.rejectBody(w, r) { |
|
|
|
if s.rejectBody(w, r) { // BUG-01 fix: rejectBody returns true when rejected |
|
|
|
return |
|
|
|
} |
|
|
|
s.mu.RLock() |
|
|
|
@@ -383,6 +383,14 @@ func (s *Server) handleAudioStream(w http.ResponseWriter, r *http.Request) { |
|
|
|
return |
|
|
|
} |
|
|
|
|
|
|
|
// BUG-10 fix: /audio/stream is a long-lived streaming endpoint. |
|
|
|
// The global HTTP server ReadTimeout (5s) and WriteTimeout (10s) would |
|
|
|
// kill connections mid-stream. Disable them per-request via ResponseController |
|
|
|
// (requires Go 1.20+, confirmed Go 1.22). |
|
|
|
rc := http.NewResponseController(w) |
|
|
|
_ = rc.SetReadDeadline(time.Time{}) |
|
|
|
_ = rc.SetWriteDeadline(time.Time{}) |
|
|
|
|
|
|
|
r.Body = http.MaxBytesReader(w, r.Body, audioStreamBodyLimit) |
|
|
|
|
|
|
|
// Read body in chunks and push to ring buffer |
|
|
|
@@ -426,7 +434,7 @@ func (s *Server) handleTXStart(w http.ResponseWriter, r *http.Request) { |
|
|
|
http.Error(w, "method not allowed", http.StatusMethodNotAllowed) |
|
|
|
return |
|
|
|
} |
|
|
|
if !s.rejectBody(w, r) { |
|
|
|
if s.rejectBody(w, r) { // BUG-01 fix: rejectBody returns true when rejected |
|
|
|
return |
|
|
|
} |
|
|
|
s.mu.RLock() |
|
|
|
@@ -450,7 +458,7 @@ func (s *Server) handleTXStop(w http.ResponseWriter, r *http.Request) { |
|
|
|
http.Error(w, "method not allowed", http.StatusMethodNotAllowed) |
|
|
|
return |
|
|
|
} |
|
|
|
if !s.rejectBody(w, r) { |
|
|
|
if s.rejectBody(w, r) { // BUG-01 fix: rejectBody returns true when rejected |
|
|
|
return |
|
|
|
} |
|
|
|
s.mu.RLock() |
|
|
|
|