caddyhttp: drop defensive checks in UnwrapResponseWriterAs

Per review, the nil-pointer guard and the next == w self-reference
guard defended against shapes that no in-tree ResponseWriter wrapper
produces. Drop both, simplifying the loop. Also remove the
self-reference test that exercised the now-removed guard.
This commit is contained in:
tomholford 2026-05-05 18:25:24 -07:00
parent 15d20011de
commit a4c99d7aeb
2 changed files with 2 additions and 26 deletions

View file

@ -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

View file

@ -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")
}
}