Aborting Req request if max size exceeded while streaming

Hi!

I have a Downloader module that GETs files given a URL, using Req. It has a timeout option but I would like to abort the download when it exceeds a given maximum size, so I don’t have to wait until the file has been completely downloaded to check the final size.

I think that can be done using Req’s streaming capabilities but I’m not being able to get it working. Can anyone help with this? This is my module so far:

defmodule Utils.Downloader do
  require Logger

  @default_receive_timeout_ms 20_000

  def download(url, opts \\ []) do
    Logger.debug("[#{__MODULE__}] downloading...")

    with {:ok, req_client} <- prepare_req_client(opts),
         {:ok, %Req.Response{status: 200, body: body, headers: headers}} <-
           Req.get(req_client, url: url),
         {:ok, content_type} <- get_content_type(headers) do
      Logger.debug("[#{__MODULE__}] finished downloading...")

      {:ok, %{content_type: content_type, data: body}}
    else
      {:error, :cant_get_content_type} ->
        {:error, :cant_get_content_type}

      %Req.Response{status: status} when status != 200 ->
        {:erorr, :cant_download_image}
    end
  end

  defp get_content_type(headers) do
    headers
    |> Enum.find(fn {key, _} -> String.downcase(key) == "content-type" end)
    |> case do
      {_, value} when is_list(value) -> {:ok, hd(value)}
      {_, value} when is_binary(value) -> {:ok, value}
      nil -> {:error, :cant_get_content_type}
    end
  end

  defp prepare_req_client(opts \\ []) do
    receive_timeout_ms = opts[:receive_timeout_ms] || @default_receive_timeout_ms

    client = Req.new(receive_timeout: receive_timeout_ms)

    {:ok, client}
  end
end