-
-
Notifications
You must be signed in to change notification settings - Fork 1.1k
httpFancyWriter.ReadFrom double-counts BytesWritten when Tee is set #1067
Copy link
Copy link
Open
Description
Description
httpFancyWriter.ReadFrom in middleware/wrap_writer.go double-counts the bytes written when a Tee writer is set.
When tee != nil, ReadFrom uses io.Copy(&f.basicWriter, r) which routes writes through basicWriter.Write(). The Write method already increments basicWriter.bytes on line 112. However, after io.Copy returns, ReadFrom also adds n to basicWriter.bytes again on line 212:
func (f *httpFancyWriter) ReadFrom(r io.Reader) (int64, error) {
if f.basicWriter.tee != nil {
n, err := io.Copy(&f.basicWriter, r)
f.basicWriter.bytes += int(n) // BUG: double-counts, basicWriter.Write already incremented bytes
return n, err
}
// ...non-tee path correctly counts since rf.ReadFrom bypasses basicWriter.Write
}This causes BytesWritten() to return double the actual number of bytes when using ReadFrom with a Tee writer.
Reproduction
func TestHttpFancyWriterReadFromWithTee(t *testing.T) {
original := &httptest.ResponseRecorder{
HeaderMap: make(http.Header),
Body: new(bytes.Buffer),
}
f := &httpFancyWriter{basicWriter: basicWriter{ResponseWriter: original}}
var teeBuf bytes.Buffer
f.Tee(&teeBuf)
input := "hello world"
n, err := f.ReadFrom(strings.NewReader(input))
// n == 11, err == nil
// f.BytesWritten() == 22 -- BUG: should be 11
}Fix
Remove the redundant f.basicWriter.bytes += int(n) line in the tee branch, since io.Copy through basicWriter.Write already handles byte counting.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
No labels