Skip to content

Bound response-body memory during assertion evaluation #106

Description

@korya

Problem

The reusable client buffers the complete response with io.ReadAll, then buffers the complete decoded payload again for gzip, deflate, brotli, or zstd. The 20-second HTTP timeout bounds elapsed time but not allocation: a fast response can deliver a very large body, and a small compressed response can expand far beyond its wire size.

This matters more now that github.com/korya/http-assert is a library. A long-lived process using it against an unhealthy or untrusted endpoint should not risk exhausting its own memory while checking that endpoint.

This is distinct from #91 and #92, which concern how an already-buffered body is rendered in CLI output.

Proposed contract

Add a configurable response-body bound to httpassert.Client while keeping its zero value safe and useful.

  • Zero-value clients use a documented finite default.
  • Callers can select another limit and deliberately opt out when their use case requires it.
  • Enforce the bound on both bytes received from the transport and bytes produced by decompression; limiting only the wire body does not contain compression expansion.
  • Return an error recognizable with errors.Is or errors.As, including which limit was exceeded.
  • Close the response body on every limit/error path and document whether a partial Result.Response is returned.
  • Keep status/header-only outcomes semantically honest when the response body cannot be read completely; do not report a fully passed result for an incomplete response.

Acceptance criteria

  • Oversized identity, gzip, deflate, brotli, and zstd responses terminate at the configured bound.
  • Exactly-at-limit bodies remain valid.
  • The default and override behavior are documented and covered through the public API.
  • CLI subprocess coverage proves an oversized response cannot exhaust the process and produces a bounded diagnostic.
  • Existing small-response assertion behavior remains unchanged.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions