Security hardening for request/response framing, resource limits, and Rack compatibility. This major release includes changes to non-streaming retries and response-hook types.
Breaking changes
- Non-streaming requests no longer automatically retry transport failures.
This prevents replay with consumed request input; applications that require
retries must implement them with a fresh body and an explicit retry policy. - Rack 3 response hooks receive arrays for repeated header values, including
Set-Cookie, and non-streaming statuses are integers. Update hooks that
assumed newline-separated headers or string statuses. Rack 2 retains its
newline-separated header representation. - Invalid or ambiguous HTTP framing is now rejected, incomplete responses fail,
and uploads without a known length use fresh chunked framing. Backends must
accept properly framed HTTP/1.1 requests and send valid, complete responses.
Security
- Reframe decoded request bodies without a
CONTENT_LENGTHusing chunked
encoding instead of sending body bytes afterContent-Length: 0. Bound
known-length input streams so excess bytes cannot become another backend
request; malformed lengths and prematurely ended uploads return400. - Reject ambiguous backend framing (
Transfer-EncodingwithContent-Length,
conflicting or invalid lengths, and unsupported transfer codings) with502. - Strip response headers named by the backend's
Connectionfields as well as
the standard hop-by-hop headers. - Enforce
max_response_lengthbefore buffering each chunk in non-streaming
mode, including rejecting declared oversized responses before reading them. - Detect premature EOF in fixed-length responses: return
502before sending
headers, or raise while streaming so the server aborts the incomplete transfer. - Disable Net::HTTP transport retries in non-streaming mode as well as streaming
mode, preventing replay with an already-consumed request body.
Fixed
- Return integer statuses in non-streaming mode and preserve multiple response
header values as arrays on Rack 3 (includingSet-Cookie). Rack 2 keeps its
newline-separated representation. - Remove entity headers forbidden by Rack on 1xx/204/304 responses. HEAD and
304 representation sizes no longer incorrectly trigger the response body cap. - Replace a remaining live-host test with a local fixture and simulate failed
DNS resolution without sending external DNS queries. Add offline adversarial
framing, size-limit, retry, andRack::Lintregression checks.
See the upgrade guide before upgrading.
Install with gem "rack-proxy", "~> 2.0".
Full changelog: v1.0.2...v2.0.0