<turbo-stream action="append" target="posts_list"><template>    <div class="postbit" id="375320" data-post-id="375320">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="jswanner" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/jswanner/120/24585_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  jswanner
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Does this not work?</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">into: fn {:data, data}, {req, resp} -&gt;
  resp = Req.Response.update_private(resp, :length, byte_size(data), &amp;(&amp;1 + byte_size(data)))

  if Req.Response.get_private(resp, :length) &gt; max_size_bytes do
    {:halt, {req, RuntimeError.exception(message: "streamed content length too large")}}
  else
    {:cont, {req, update_in(resp.body, &amp;(&amp;1 &lt;&gt; data))}}
  end
end
</code></pre> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="375320" data-batch-url="/posts/batch_likers">
                        4
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/aborting-req-request-if-max-size-exceeded-while-streaming/72827/12">Post #11</a>
	                </div>
	            </div>
              <div id="likers-container-375320" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="375320"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-solved cat-solved" title="Marked as solution"></div>
  </section>
</div>
    <div class="postbit" id="375321" data-post-id="375321">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="spurgus" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/spurgus/120/39233_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  spurgus
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Hey thanks <a class="mention" href="/u/jswanner" rel="nofollow">@jswanner</a> this does seem to work!</p>
<p>I’ll check more but this looks great. Thanks a lof!</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="375321" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/aborting-req-request-if-max-size-exceeded-while-streaming/72827/13">Post #12</a>
	                </div>
	            </div>
              <div id="likers-container-375321" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="375321"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #12"></div>
  </section>
</div>
    <div class="postbit" id="375324" data-post-id="375324">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="spurgus" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/spurgus/120/39233_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  spurgus
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Thanks, everyone, for your help, you’re awesome!</p>
<p>For the record, here’s the full code:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">defmodule Downloader do
  require Logger

  @default_receive_timeout_ms 10_000
  @default_max_retries 3
  @default_max_size_bytes 20 * 1_024 * 1_024

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

    with {:ok, :valid_url} &lt;- valid_url?(url),
         {:ok, req_client} &lt;- prepare_req_client(opts),
         {:ok, %Req.Response{status: 200, body: body, headers: headers}} &lt;-
           Req.get(req_client, url: url),
         {:ok, content_type} &lt;- get_header(headers, "content-type") do
      Logger.debug("[#{__MODULE__}] finished downloading...")

      {:ok, %{data: body, content_type: content_type}}
    else
      {:error, :invalid_url} -&gt;
        {:error, :invalid_url}

      {:ok, %Req.Response{status: status}} -&gt;
        {:error, :remote_server_error, status}

      {:error, %Req.TransportError{reason: :econnrefused}} -&gt;
        {:error, :remote_server_error, :econnrefused}

      {:error, %Req.TransportError{reason: :timeout}} -&gt;
        {:error, :remote_server_error, :timeout}

      {:error, %RuntimeError{message: "streamed content length too large"}} -&gt;
        {:error, :max_size_exceeded}
    end
  end

  defp valid_url?(url) when is_binary(url) do
    case URI.parse(url) do
      %URI{scheme: scheme, host: host} when scheme in ["http", "https"] and is_binary(host) -&gt;
        {:ok, :valid_url}

      _ -&gt;
        {:error, :invalid_url}
    end
  end

  defp valid_url?(_) do
    {:error, :invalid_url}
  end

  defp get_header(headers, name) do
    headers
    |&gt; Enum.find(fn {key, _} -&gt; String.downcase(key) == name end)
    |&gt; case do
      {_, value} when is_list(value) -&gt; {:ok, hd(value)}
      {_, value} when is_binary(value) -&gt; {:ok, value}
      nil -&gt; {:ok, nil}
    end
  end

  defp prepare_req_client(opts) do
    receive_timeout_ms = opts[:receive_timeout_ms] || @default_receive_timeout_ms
    max_retries = opts[:max_retries] || @default_max_retries
    max_size_bytes = opts[:max_size_bytes] || @default_max_size_bytes

    client =
      Req.new(
        receive_timeout: receive_timeout_ms,
        max_retries: max_retries,
        into: fn {:data, data}, {req, resp} -&gt;
          resp =
            Req.Response.update_private(
              resp,
              :length,
              byte_size(data),
              &amp;(&amp;1 + byte_size(data))
            )

          if Req.Response.get_private(resp, :length) &gt; max_size_bytes do
            {:halt, {req, RuntimeError.exception(message: "streamed content length too large")}}
          else
            {:cont, {req, update_in(resp.body, &amp;(&amp;1 &lt;&gt; data))}}
          end
        end
      )

    {:ok, client}
  end
end

</code></pre> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="375324" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/aborting-req-request-if-max-size-exceeded-while-streaming/72827/14">Post #13</a>
	                </div>
	            </div>
              <div id="likers-container-375324" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="375324"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-last-post cat-last-post" title="Last post!"></div>
  </section>
</div>
</template></turbo-stream><turbo-stream action="replace" target="load-more-container"><template><div id="load-more-container" class="load-more-container">
    <span class="all-loaded">— All posts loaded —</span>
</div></template></turbo-stream>