Add WithMaxResponseBody option to prevent client-side OOM

Wraps response body with io.LimitedReader when configured, preventing
unbounded reads from io.ReadAll in Response.Bytes(). Protects against
upstream services returning unexpectedly large responses.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-03-22 21:48:05 +03:00
parent 49be6f8a7e
commit 21274c178a
3 changed files with 112 additions and 12 deletions

View File

@@ -12,18 +12,19 @@ import (
)
type clientOptions struct {
baseURL string
timeout time.Duration
transport http.RoundTripper
logger *slog.Logger
errorMapper ErrorMapper
middlewares []middleware.Middleware
retryOpts []retry.Option
enableRetry bool
cbOpts []circuitbreaker.Option
enableCB bool
endpoints []balancer.Endpoint
balancerOpts []balancer.Option
baseURL string
timeout time.Duration
transport http.RoundTripper
logger *slog.Logger
errorMapper ErrorMapper
middlewares []middleware.Middleware
retryOpts []retry.Option
enableRetry bool
cbOpts []circuitbreaker.Option
enableCB bool
endpoints []balancer.Endpoint
balancerOpts []balancer.Option
maxResponseBody int64
}
// Option configures a Client.
@@ -85,3 +86,11 @@ func WithEndpoints(eps ...balancer.Endpoint) Option {
func WithBalancer(opts ...balancer.Option) Option {
return func(o *clientOptions) { o.balancerOpts = opts }
}
// WithMaxResponseBody limits the number of bytes read from response bodies
// by Response.Bytes (and by extension String, JSON, XML). If the response
// body exceeds n bytes, reading stops and returns an error.
// A value of 0 means no limit (the default).
func WithMaxResponseBody(n int64) Option {
return func(o *clientOptions) { o.maxResponseBody = n }
}