# `Req.Decompress`
[🔗](https://github.com/wojtekmach/req/blob/v0.8.0-rc.0/lib/req/decompress.ex#L1)

Asks the server to return compressed response.

The response body is decompressed based on the `content-encoding` response header. This step
is off by default; set `compressed: true` to opt in.

Supported formats:

| Format        | Decoder                                         |
| ------------- | ----------------------------------------------- |
| gzip, x-gzip  | [`:zlib`]                                       |
| br            | [`:brotli`] (if [`:brotli`] is installed)       |
| zstd          | [`:zstd`] (requires Erlang/OTP 28+)             |
| _other_       | Returns data as is                              |

This step updates the following headers to reflect the changes:

  * `content-encoding` is removed
  * `content-length` is removed

> #### Only enable compression for trusted servers {: .info}
>
> This step decompresses the whole response body into memory with no size limit, so a small
> response can expand into many gigabytes. A malicious or compromised server can exploit this
> to exhaust memory and crash the client (a decompression bomb / denial of service). For this
> reason compression is off by default; only set `compressed: true` for endpoints you trust.

## Request Options

  * `:compressed` - if set to `true`, sets the `accept-encoding` header with compression
    algorithms that Req supports and decompresses the response body. Defaults to `false`.

  * `:raw` - if set to `true`, disables response body decompression. Defaults to `false`.

    Note: setting `raw: true` also disables response body decoding.

## Examples

By default, Req does not ask for a compressed response. Pass `compressed: true` to request one
and have Req decompress the body, so we get back the decompressed content:

    iex> response = Req.get!("https://elixir-lang.org", compressed: true)
    iex> response.body |> binary_part(0, 15)
    "<!DOCTYPE html>"

To inspect the raw compressed bytes the server sent, additionally pass `raw: true`, which
disables decompression. Notice the body now starts with `<<31, 139>>`, the "magic bytes"
for gzip:

    iex> response = Req.get!("https://elixir-lang.org", compressed: true, raw: true)
    iex> Req.Response.get_header(response, "content-encoding")
    ["gzip"]
    iex> response.body |> binary_part(0, 2)
    <<31, 139>>

Zstandard is supported out of the box on Erlang/OTP 28+ (via the built-in [`:zstd`] module).
Brotli is supported if the optional [`:brotli`] package is installed:

    Mix.install([
      :req,
      {:brotli, "~> 0.3.0"}
    ])

    response = Req.get!("https://httpbingo.org/anything", compressed: true)
    response.body["headers"]["Accept-Encoding"]
    #=> ["zstd, br, gzip"]

[`:zlib`]:   https://www.erlang.org/doc/apps/erts/zlib.html
[`:brotli`]: https://brotli.hexdocs.pm
[`:zstd`]:   https://www.erlang.org/doc/apps/stdlib/zstd.html

---

*Consult [api-reference.md](api-reference.md) for complete listing*
