Now if you use json’s Decoder you can read a body and still might end up without reused connection - if a response contains a newline.
Decoder only reads X bytes (512? I don’t remember) and if the structure fits into these bytes exactly (and the multiplications of it) the newline leaves hanging there.
I always check for Decoder.More (this drains whitespace) after decoding.
It drains up to 256K unread bytes period, it doesn't just optimize the case of the body not being read at all.
https://cs.opensource.google/go/go/+/refs/tags/go1.27.2:src/...
What it won't do looking at the code is handle streamed responses over transfer-encoding:chunked which means that if the other end is doing
json.NewEncoder(responseWriter).Encode(&someStruct)
this optimization won't do anything.Oof, that is an edge case I wasn't aware of at all. Hard to know where it's documented since it's an integration of both those packages
While it’s convenient, the Decoder isn’t recommended for those use cases precisely because of the edge cases around readers that don’t contain at most one JSON document with no suffixes.
The standard library maintainers recognized this as a problem that there was no “better,” more convenient way to do it and in encoding/json/v2 they have UnmarshalRead for that use case: https://pkg.go.dev/encoding/json/v2#UnmarshalRead