Skip to content

Commit d06a121

Browse files
committed
feat(httputil): adds ResponseChain.maxBodySize field
Signed-off-by: Dwi Siswanto <git@dw1.io>
1 parent cbe8953 commit d06a121

2 files changed

Lines changed: 22 additions & 11 deletions

File tree

http/normalization.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -76,12 +76,12 @@ func readNNormalizeRespBody(rc *ResponseChain, body *bytes.Buffer) (err error) {
7676
if err != nil {
7777
wrapped = origBody
7878
}
79-
limitReader := io.LimitReader(wrapped, int64(DefaultMaxBodySize))
79+
limitReader := io.LimitReader(wrapped, rc.maxBodySize)
8080

81-
// Read body using ReadFrom for efficiency, but cap growth at DefaultMaxBodySize.
81+
// Read body using ReadFrom for efficiency, but cap growth at maxBodySize.
8282
// We use a custom limitedBuffer wrapper to prevent bytes.Buffer from
8383
// over-allocating (it normally grows to 2x when size is unknown).
84-
limitedBuf := &limitedBuffer{buf: body, maxCap: DefaultMaxBodySize}
84+
limitedBuf := &limitedBuffer{buf: body, maxCap: int(rc.maxBodySize)}
8585
_, err = limitedBuf.ReadFrom(limitReader)
8686
if err != nil {
8787
if strings.Contains(err.Error(), "gzip: invalid header") {

http/respChain.go

Lines changed: 19 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,16 @@ func getBuffer() *bytes.Buffer {
154154
return buff
155155
}
156156

157-
// putBuffer returns a buffer to the pool
157+
// putBuffer returns a buffer to the pool for reuse.
158+
//
159+
// Buffers larger than [DefaultMaxBodySize] are discarded.
160+
// Buffers larger than or equal to largeBufferThreshold are subject to
161+
// maxLargeBuffers limiting.
162+
//
163+
// TODO(dwisiswant0): Current threshold is global. Consider making it
164+
// configurable per instance (via [ResponseChain.maxBodySize]) if needed.
165+
// The current implementation is to prevents memory bloat in typical use-cases.
166+
// And the pool is shared, so per-instance thresholds might cause confusion.
158167
func putBuffer(buf *bytes.Buffer) {
159168
cap := buf.Cap()
160169
if cap > DefaultMaxBodySize {
@@ -205,10 +214,11 @@ func resetBuffer() {
205214
// on every call to previous it returns the previous response
206215
// if it was redirected.
207216
type ResponseChain struct {
208-
headers *bytes.Buffer
209-
body *bytes.Buffer
210-
resp *http.Response
211-
reloaded bool // if response was reloaded to its previous redirect
217+
headers *bytes.Buffer
218+
body *bytes.Buffer
219+
resp *http.Response
220+
reloaded bool // if response was reloaded to its previous redirect
221+
maxBodySize int64
212222
}
213223

214224
// NewResponseChain creates a new response chain for a http request
@@ -225,9 +235,10 @@ func NewResponseChain(resp *http.Response, maxBody int64) *ResponseChain {
225235
}
226236

227237
return &ResponseChain{
228-
headers: getBuffer(),
229-
body: getBuffer(),
230-
resp: resp,
238+
headers: getBuffer(),
239+
body: getBuffer(),
240+
resp: resp,
241+
maxBodySize: maxBody,
231242
}
232243
}
233244

0 commit comments

Comments
 (0)