diff --git a/modules/caddyhttp/responsewriter.go b/modules/caddyhttp/responsewriter.go index f3b731ba9..9727e7be4 100644 --- a/modules/caddyhttp/responsewriter.go +++ b/modules/caddyhttp/responsewriter.go @@ -68,7 +68,7 @@ func (rww *ResponseWriterWrapper) Unwrap() http.ResponseWriter { // own type assertions and cannot see past a wrapper. func UnwrapResponseWriterAs[T any](w http.ResponseWriter) (T, bool) { var zero T - for w != nil { + for { if t, ok := any(w).(T); ok { return t, true } @@ -76,13 +76,8 @@ func UnwrapResponseWriterAs[T any](w http.ResponseWriter) (T, bool) { if !ok { return zero, false } - next := u.Unwrap() - if next == w { - return zero, false - } - w = next + w = u.Unwrap() } - return zero, false } // ErrNotImplemented is returned when an underlying diff --git a/modules/caddyhttp/responsewriter_test.go b/modules/caddyhttp/responsewriter_test.go index 5b11758a7..f11af9b63 100644 --- a/modules/caddyhttp/responsewriter_test.go +++ b/modules/caddyhttp/responsewriter_test.go @@ -6,7 +6,6 @@ import ( "net/http" "strings" "testing" - "time" ) type responseWriterSpy interface { @@ -243,21 +242,3 @@ func TestUnwrapResponseWriterAs_NotFound(t *testing.T) { } } -type selfUnwrapWriter struct{ baseRespWriter } - -func (s *selfUnwrapWriter) Unwrap() http.ResponseWriter { return s } - -func TestUnwrapResponseWriterAs_StopsOnSelfReference(t *testing.T) { - // Defensive: a wrapper whose Unwrap returns itself must not loop forever. - loop := &selfUnwrapWriter{} - done := make(chan struct{}) - go func() { - defer close(done) - _, _ = UnwrapResponseWriterAs[targetIface](loop) - }() - select { - case <-done: - case <-time.After(time.Second): - t.Fatal("UnwrapResponseWriterAs hung on self-referential Unwrap") - } -}