@@ -2,12 +2,26 @@ package middleware
22
33import (
44 "bytes"
5+ "io"
56 "net/http"
67 "net/http/httptest"
78 "strings"
89 "testing"
910)
1011
12+ // readerFromRecorder is a ResponseRecorder that also satisfies io.ReaderFrom,
13+ // mirroring the real net/http response writer (which implements ReadFrom and
14+ // is what httpFancyWriter.ReadFrom fast-paths to). Bytes copied via ReadFrom
15+ // are recorded to the body so a test can observe whether they reached the
16+ // original writer.
17+ type readerFromRecorder struct {
18+ * httptest.ResponseRecorder
19+ }
20+
21+ func (r * readerFromRecorder ) ReadFrom (src io.Reader ) (int64 , error ) {
22+ return io .Copy (r .ResponseRecorder .Body , src )
23+ }
24+
1125func TestHttpFancyWriterRemembersWroteHeaderWhenFlushed (t * testing.T ) {
1226 f := & httpFancyWriter {basicWriter : basicWriter {ResponseWriter : httptest .NewRecorder ()}}
1327 f .Flush ()
@@ -109,3 +123,25 @@ func TestHttpFancyWriterReadFromByteCountWithTee(t *testing.T) {
109123 assertEqual (t , len (input ), f .BytesWritten ())
110124 assertEqual (t , []byte (input ), teeBuf .Bytes ())
111125}
126+
127+ // TestHttpFancyWriterReadFromHonorsDiscard verifies that Discard() suppresses
128+ // the body even when it is written via ReadFrom/io.Copy. Before the fix, the
129+ // non-tee ReadFrom path streamed straight to the original ResponseWriter's
130+ // ReaderFrom, bypassing the discard flag entirely.
131+ func TestHttpFancyWriterReadFromHonorsDiscard (t * testing.T ) {
132+ original := & readerFromRecorder {& httptest.ResponseRecorder {
133+ HeaderMap : make (http.Header ),
134+ Body : new (bytes.Buffer ),
135+ }}
136+ f := & httpFancyWriter {basicWriter : basicWriter {ResponseWriter : original }}
137+ f .Discard ()
138+
139+ const input = "hello world"
140+ n , err := f .ReadFrom (strings .NewReader (input ))
141+ assertNoError (t , err )
142+ assertEqual (t , int64 (len (input )), n )
143+ // The data must NOT reach the original writer once Discard() is set.
144+ assertEqual (t , 0 , original .Body .Len ())
145+ // BytesWritten still reflects the bytes consumed.
146+ assertEqual (t , len (input ), f .BytesWritten ())
147+ }
0 commit comments