@@ -278,6 +278,43 @@ func (pt *PerfTest) loadTargets(filepath string) ([]vegeta.Target, error) {
278278 return targets , nil
279279}
280280
281+ // limitBodyTransport wraps an http.RoundTripper and pre-limits response bodies.
282+ //
283+ // Vegeta v12 library reads maxBody bytes then drains the remainder with
284+ // io.Copy(io.Discard, r.Body). If the server resets the connection during
285+ // that drain, Vegeta records the result as failed (Code=0) even though a 200
286+ // OK was already received. The Python/vegeta-CLI binary (older) skips the
287+ // drain step and counts 200 as success immediately.
288+ //
289+ // By capping resp.Body at maxBytes here, the subsequent drain reads 0 bytes
290+ // and succeeds, so res.Code is set to the actual HTTP status, matching the
291+ // Python/CLI behavior: success = received 2xx status.
292+ type limitBodyTransport struct {
293+ base http.RoundTripper
294+ maxBytes int64
295+ }
296+
297+ func (t * limitBodyTransport ) RoundTrip (req * http.Request ) (* http.Response , error ) {
298+ resp , err := t .base .RoundTrip (req )
299+ if err != nil || resp == nil {
300+ return resp , err
301+ }
302+ if resp .Body != nil {
303+ resp .Body = & limitedReadCloser {
304+ Reader : io .LimitReader (resp .Body , t .maxBytes ),
305+ Closer : resp .Body ,
306+ }
307+ }
308+ return resp , nil
309+ }
310+
311+ // limitedReadCloser combines a limited Reader with the original Closer so
312+ // resp.Body.Close() still reaches the underlying TCP connection.
313+ type limitedReadCloser struct {
314+ io.Reader
315+ io.Closer
316+ }
317+
281318// runVegetaAttack executes a Vegeta attack using the library.
282319func (pt * PerfTest ) runVegetaAttack (ctx context.Context , targets []vegeta.Target , qps int , duration time.Duration , outputFile string ) (* vegeta.Metrics , error ) {
283320 rate := vegeta.Rate {Freq : qps , Per : time .Second }
@@ -296,7 +333,7 @@ func (pt *PerfTest) runVegetaAttack(ctx context.Context, targets []vegeta.Target
296333 }
297334
298335 customClient := & http.Client {
299- Transport : tr ,
336+ Transport : & limitBodyTransport { base : tr , maxBytes : int64 ( maxBodyInt )} ,
300337 }
301338
302339 //
0 commit comments