Skip to content

v0.26.1

Choose a tag to compare

@rustyconover rustyconover released this 21 Jul 21:40
· 276 commits to main since this release

Decode compressed requests even when response compression is off

make_wsgi_app(compression_level=None) dropped _CompressionMiddleware entirely — but that middleware does two independent jobs: decompressing request bodies and compressing response bodies. Removing it removed both.

So a compression-disabled server fed a zstd request body handed compressed bytes straight to the Arrow reader and returned a 500 (Invalid IPC stream: negative continuation token) instead of decoding it.

That path is reachable in practice: the DuckDB engine client defaults to zstd request bodies and only re-picks a codec on a 415, so it never learns to stop.

The fix

The two capabilities are now separately expressible:

  • encode_levels — governs response compression; empty means never compress a response.
  • decode_encodings — governs which request Content-Encoding values are accepted.

A boolean flag was deliberately not used: it would have left the encode and decode sets fused, which is precisely the bug.

VGI-Supported-Encodings still tracks the encode set and is still emitted present-but-empty when compression is off. Being lenient about what we accept is not a capability worth announcing — the header is the contract a client negotiates against. Unknown request codecs still return 415.

Conformance

Two new cross-language cases:

  • an advertised codec must round-trip as a request body;
  • a compression-disabled server must answer a compressed request with a negotiated result and never a 5xx.

The second is gated at "negotiated failure, never 5xx" rather than "must decode", because every SDK shares this latent split and other repos consume this suite from PyPI — a hard requirement would red their CI for behaviour they haven't shipped yet.