diff --git a/cmd/api-response.go b/cmd/api-response.go index 8d58c6e4254ec..2caf71354644c 100644 --- a/cmd/api-response.go +++ b/cmd/api-response.go @@ -1060,6 +1060,12 @@ func (w *trackingResponseWriter) Write(b []byte) (int, error) { return w.ResponseWriter.Write(b) } +func (w *trackingResponseWriter) Flush() { + if f, ok := w.ResponseWriter.(http.Flusher); ok { + f.Flush() + } +} + func (w *trackingResponseWriter) Unwrap() http.ResponseWriter { return w.ResponseWriter } diff --git a/cmd/api-response_test.go b/cmd/api-response_test.go index 970f62a4c9ffc..c2d91e8a5b1fa 100644 --- a/cmd/api-response_test.go +++ b/cmd/api-response_test.go @@ -24,6 +24,7 @@ import ( "testing" "github.com/klauspost/compress/gzhttp" + xhttp "github.com/minio/minio/internal/http" ) // Tests object location. @@ -159,6 +160,29 @@ func TestTrackingResponseWriter(t *testing.T) { } } +func TestTrackingResponseWriterFlush(t *testing.T) { + rw := httptest.NewRecorder() + trw := &trackingResponseWriter{ResponseWriter: rw} + + trw.Flush() + if trw.headerWritten { + t.Fatal("Flush() should not set headerWritten") + } + + // Simulate the ListenNotificationHandler flow: WriteHeader, Write, Flush + trw.WriteHeader(http.StatusOK) + _, err := trw.Write([]byte("event data")) + if err != nil { + t.Fatalf("Write failed: %v", err) + } + + xhttp.Flush(trw) + + if !rw.Flushed { + t.Fatalf("xhttp.Flush should have flushed the underlying ResponseRecorder via trackingResponseWriter.Flush()") + } +} + func TestHeadersAlreadyWritten(t *testing.T) { rw := httptest.NewRecorder() trw := &trackingResponseWriter{ResponseWriter: rw}