Compression
Rezo’s HTTP adapter automatically decompresses gzip, deflate, brotli, and zstd response bodies. The decompression layer performs magic-byte detection before applying decompression, so a server that incorrectly advertises Content-Encoding: gzip while sending plain text doesn’t break your request.
import rezo from 'rezo';
// Decompression is on by default
const { data } = await rezo.get('https://api.example.com/data'); Supported Algorithms
| Algorithm | Content-Encoding | Magic Bytes | Node.js Decompressor |
|---|---|---|---|
| gzip | gzip, x-gzip | 0x1F 0x8B | zlib.createGunzip() |
| deflate | deflate, x-deflate | 0x78 | zlib.createInflate() |
| brotli | br, brotli | (heuristic) | zlib.createBrotliDecompress() |
| zstd | zstd | 0x28 0xB5 0x2F 0xFD | zlib.createZstdDecompress() |
| raw deflate | gzip-raw | (any) | zlib.createInflate({ windowBits: 15 }) |
Disabling Decompression
Set decompress: false to receive the raw, encoded body unchanged:
// Per-request
const { data } = await rezo.get('https://api.example.com/data', {
decompress: false
});
// Instance-level default
const client = rezo.create({
decompress: false
}); How Magic-Byte Detection Works
The internal smart decompression layer:
- Buffers the first chunk of data (needs at least 4 bytes)
- Checks magic bytes against the declared
Content-Encoding - If magic bytes match, pipes data through the corresponding decompressor
- If magic bytes do not match, passes data through unmodified
- Routes subsequent chunks to either the decompressor or passthrough
Magic Bytes by Algorithm
- gzip: First two bytes must be
0x1F 0x8B. - deflate: First byte must be
0x78(zlib header). Valid second bytes include0x01,0x5E,0x9C,0xDA. - zstd: First four bytes must be
0x28 0xB5 0x2F 0xFD. - brotli: Has no magic bytes, so heuristic detection is used:
- If the data starts with common text characters (
{,[,",<, digits), assume uncompressed. - If the data starts with a UTF-8 BOM (
0xEF 0xBB 0xBF), assume uncompressed. - If 80%+ of the first 16 bytes are printable ASCII, assume uncompressed.
- Otherwise, decompress as brotli.
- If the data starts with common text characters (
Error Recovery
If decompression fails mid-stream (corrupt data), the stream emits an error. For small responses that fit entirely in the initial buffer, a failed decompression falls back to returning the raw bytes.
Why Smart Detection Matters
In practice, many servers and CDNs misconfigure compression:
- A server sends
Content-Encoding: gzipbut the data is actually plain text (common with misconfigured reverse proxies). - A CDN strips compression but leaves the
Content-Encodingheader intact. - An API gateway double-compresses data.
Without smart detection, these scenarios cause cryptic errors like Z_DATA_ERROR or produce garbage output. Rezo’s decompression layer handles all of these gracefully by verifying before decompressing.
What Gets Sent
The HTTP adapter automatically:
- Sends
Accept-Encoding: gzip, deflate, br(or includeszstddepending on the adapter) - Reads the
Content-Encodingheader from the response - Pipes the response through the smart decompression layer
- Returns the decompressed data in
response.data
To send a custom Accept-Encoding, override the header on the request:
const { data } = await rezo.get('https://api.example.com/data', {
headers: {
'Accept-Encoding': 'gzip, deflate' // Skip brotli/zstd offers
}
});