Skip to content

Commit a696e0d

Browse files
authored
fix(response_writer): only mark hijacked on successful hijack (#80)
1 parent 53de839 commit a696e0d

2 files changed

Lines changed: 46 additions & 2 deletions

File tree

response_writer.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ package fox
66

77
import (
88
"bufio"
9+
"errors"
910
"fmt"
1011
"io"
1112
"log"
@@ -235,8 +236,11 @@ func (r *recorder) Push(target string, opts *http.PushOptions) error {
235236
// an error matching [http.ErrNotSupported]. See [http.Hijacker] for more details.
236237
func (r *recorder) Hijack() (net.Conn, *bufio.ReadWriter, error) {
237238
if hijacker, ok := r.ResponseWriter.(http.Hijacker); ok {
238-
r.hijacked = true
239-
return hijacker.Hijack()
239+
c, rw, err := hijacker.Hijack()
240+
if !errors.Is(err, http.ErrNotSupported) && !errors.Is(err, http.ErrHijacked) {
241+
r.hijacked = true
242+
}
243+
return c, rw, err
240244
}
241245
return nil, nil, ErrNotSupported()
242246
}

response_writer_test.go

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -142,6 +142,7 @@ func TestRecorder_Hijack(t *testing.T) {
142142
assert: func(t *testing.T, w ResponseWriter) {
143143
_, _, err := w.Hijack()
144144
assert.NoError(t, err)
145+
assert.True(t, w.(*recorder).hijacked)
145146
},
146147
},
147148
{
@@ -152,6 +153,45 @@ func TestRecorder_Hijack(t *testing.T) {
152153
assert: func(t *testing.T, w ResponseWriter) {
153154
_, _, err := w.Hijack()
154155
assert.ErrorIs(t, err, http.ErrNotSupported)
156+
assert.False(t, w.(*recorder).hijacked)
157+
},
158+
},
159+
{
160+
name: "underlying hijacker returns http.ErrNotSupported does not mark hijacked",
161+
rec: &recorder{
162+
ResponseWriter: struct {
163+
http.ResponseWriter
164+
http.Hijacker
165+
}{
166+
ResponseWriter: httptest.NewRecorder(),
167+
Hijacker: hijackWriterFunc(func() (net.Conn, *bufio.ReadWriter, error) {
168+
return nil, nil, http.ErrNotSupported
169+
}),
170+
},
171+
},
172+
assert: func(t *testing.T, w ResponseWriter) {
173+
_, _, err := w.Hijack()
174+
assert.ErrorIs(t, err, http.ErrNotSupported)
175+
assert.False(t, w.(*recorder).hijacked)
176+
},
177+
},
178+
{
179+
name: "underlying hijacker returns http.ErrHijacked does not mark hijacked",
180+
rec: &recorder{
181+
ResponseWriter: struct {
182+
http.ResponseWriter
183+
http.Hijacker
184+
}{
185+
ResponseWriter: httptest.NewRecorder(),
186+
Hijacker: hijackWriterFunc(func() (net.Conn, *bufio.ReadWriter, error) {
187+
return nil, nil, http.ErrHijacked
188+
}),
189+
},
190+
},
191+
assert: func(t *testing.T, w ResponseWriter) {
192+
_, _, err := w.Hijack()
193+
assert.ErrorIs(t, err, http.ErrHijacked)
194+
assert.False(t, w.(*recorder).hijacked)
155195
},
156196
},
157197
}

0 commit comments

Comments
 (0)