Skip compression of partial responses in `GZipMiddleware`

Merged
KL
3mo ago
+28-3

Bypass compression when a response is partial content (status 206). Compressing a byte range corrupts the Content-Range/Content-Length semantics (the range refers to the identity representation) and breaks media playback and resumable downloads in browsers; it's the root cause of the range-request breakage that pushed Streamlit to subclass the middleware (see #3414 discussion).

  • FileResponse range responses now pass through untouched.
  • Status-only detection also covers multipart/byteranges responses, which carry Content-Range inside each body part rather than in the top-level headers.
  • No Vary: Accept-Encoding on the bypass path - the partial response never varies by encoding, consistent with the existing excluded/pre-encoded handling.
  • Precedent: actix-web and Caddy skip status 206 in their encoders; nginx only ever compresses 200/403/404. RFC 9110 defines ranges over the selected representation.

Stacked on #3419.

AI Disclaimer

This PR was developed with the assistance of either Claude or Codex. I've reviewed and verified the changes.