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


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>The library is great.<br>
Probably the only thing I’m very skeptical about is enabled retries by default.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="323212" 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/req-a-batteries-included-http-client-for-elixir/48494/42">Post #41</a>
	                </div>
	            </div>
              <div id="likers-container-323212" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="323212"
                     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 #41"></div>
  </section>
</div>
    <div class="postbit" id="323217" data-post-id="323217">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="wojtekmach" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/wojtekmach/120/999_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  wojtekmach
                    <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 class="user-title">
									<span>Hex Core Team</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>The default is :safe_transient, safe meaning only GET or HEAD, transient meaning network errors, 408/500/503/etc. Trivial to turn off though!</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="323217" 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/req-a-batteries-included-http-client-for-elixir/48494/43">Post #42</a>
	                </div>
	            </div>
              <div id="likers-container-323217" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="323217"
                     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 #42"></div>
  </section>
</div>
    <div class="postbit" id="329573" data-post-id="329573">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="wojtekmach" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/wojtekmach/120/999_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  wojtekmach
                    <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 class="user-title">
									<span>Hex Core Team</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Hey everyone, Req v0.5 is out! I’ve written a <a href="https://dashbit.co/blog/req-v0.5" rel="noopener nofollow ugc">release blog post</a> for the occasion. Happy hacking!</p>
<hr>
<p>Req v0.5.0 brings testing enhancements, errors standardization, <code>%Req.Response.Async{}</code>, and more improvements and bug fixes.</p>
<h3><a name="p-329573-testing-enhancements-1" class="anchor" href="#p-329573-testing-enhancements-1" aria-label="Heading link" rel="nofollow"></a>Testing Enhancements</h3>
<p>In previous releases, we could only create test <em>stubs</em> (using <a href="https://hexdocs.pm/req/Req.Test.html#stub/2" rel="noopener nofollow ugc"><code>Req.Test.stub/2</code></a>), that is, fake<br>
HTTP servers which had predefined behaviour. Let’s say we’re integrating with a third-party<br>
weather service and we might create a stub for it like below:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">Req.Test.stub(MyApp.Weather, fn conn -&gt;
  Req.Test.json(conn, %{"celsius" =&gt; 25.0})
end)
</code></pre>
<p>Anytime we hit this fake we’ll get the same result. This works extremely well for simple<br>
integrations however it’s not quite enough for more complicated ones. Imagine we’re using<br>
something like AWS S3 and we test uploading some data and reading it back again. While we could do<br>
this:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">Req.Test.stub(MyApp.S3, fn
  conn when conn.method == "PUT" -&gt;
    # ...

  conn when conn.method == "GET" -&gt;
    # ...
end)
</code></pre>
<p>making the test just a little bit more thorough will make it MUCH more complicated, for example:<br>
the first GET request should return a 404, we then make a PUT, and now GET should return a 200.<br>
We could solve it by adding some state to our test (e.g. an agent) but there is a simpler way and<br>
that is to set request expectations using the new <a href="https://hexdocs.pm/req/Req.Test.html#expect/3" rel="noopener nofollow ugc"><code>Req.Test.expect/3</code></a> function:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">Req.Test.expect(MyApp.S3, fn conn when conn.method == "GET" -&gt;
  Plug.Conn.send_resp(conn, 404, "not found")
end)

Req.Test.expect(MyApp.S3, fn conn when conn.method == "PUT" -&gt;
  {:ok, body, conn} = Plug.Conn.read_body(conn)
  assert body == "foo"
  Plug.Conn.send_resp(conn, 200, "")
end)

Req.Test.expect(MyApp.S3, fn conn when conn.method == "GET" -&gt;
  Plug.Conn.send_resp(conn, 200, "foo")
end)
</code></pre>
<p>The important part is the request expectations are meant to run in order (and fail if they don’t).</p>
<p>In this release we’re also adding <a href="https://hexdocs.pm/req/Req.Test.html#transport_error/2" rel="noopener nofollow ugc"><code>Req.Test.transport_error/2</code></a>, a way to simulate network<br>
errors.</p>
<p>Here is another example using both of the new features, let’s simulate a server that is<br>
having issues: on the first request it is not responding and on the following two requests it<br>
returns an HTTP 500. Only on the third request it returns an HTTP 200. Req by default<br>
automatically retries transient errors (using <a href="https://hexdocs.pm/req/Req.Steps.html#retry/1" rel="noopener nofollow ugc"><code>retry</code></a> step) so it will make multiple<br>
requests exercising all of our request expectations:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">iex&gt; Req.Test.expect(MyApp.S3, &amp;Req.Test.transport_error(&amp;1, :econnrefused))
iex&gt; Req.Test.expect(MyApp.S3, 2, &amp;Plug.Conn.send_resp(&amp;1, 500, "internal server error"))
iex&gt; Req.Test.expect(MyApp.S3, &amp;Plug.Conn.send_resp(&amp;1, 200, "ok"))
iex&gt; Req.get!(plug: {Req.Test, MyApp.S3}).body
# 15:57:06.309 [error] retry: got exception, will retry in 1000ms, 3 attempts left
# 15:57:06.309 [error] ** (Req.TransportError) connection refused
# 15:57:07.310 [error] retry: got response with status 500, will retry in 2000ms, 2 attempts left
# 15:57:09.311 [error] retry: got response with status 500, will retry in 4000ms, 1 attempt left
"ok"
</code></pre>
<p>Finally, for parity with <a href="https://hexdocs.pm/mox" rel="noopener nofollow ugc">Mox</a>, we add functions for setting ownership<br>
mode:</p>
<ul>
<li><a href="https://hexdocs.pm/req/Req.Test.html#set_req_test_from_context/1" rel="noopener nofollow ugc"><code>Req.Test.set_req_test_from_context/1</code></a></li>
<li><a href="https://hexdocs.pm/req/Req.Test.html#set_req_test_to_private/1" rel="noopener nofollow ugc"><code>Req.Test.set_req_test_to_private/1</code></a></li>
<li><a href="https://hexdocs.pm/req/Req.Test.html#set_req_test_to_shared/1" rel="noopener nofollow ugc"><code>Req.Test.set_req_test_to_shared/1</code></a></li>
</ul>
<p>And for verifying expectations:</p>
<ul>
<li><a href="https://hexdocs.pm/req/Req.Test.html#verify!/0" rel="noopener nofollow ugc"><code>Req.Test.verify!/0</code></a></li>
<li><a href="https://hexdocs.pm/req/Req.Test.html#verify!/1" rel="noopener nofollow ugc"><code>Req.Test.verify!/1</code></a></li>
<li><a href="https://hexdocs.pm/req/Req.Test.html#verify_on_exit!/1" rel="noopener nofollow ugc"><code>Req.Test.verify_on_exit!/1</code></a></li>
</ul>
<p>Thanks to Andrea Leopardi for driving the testing improvements.</p>
<h3><a name="p-329573-standardized-errors-2" class="anchor" href="#p-329573-standardized-errors-2" aria-label="Heading link" rel="nofollow"></a>Standardized Errors</h3>
<p>In previous releases, when using the default adapter, Finch, Req could return these exceptions on<br>
network/protocol errors: <code>Mint.TransportError</code>, <code>Mint.HTTPError</code>, and <code>Finch.Error</code>. They have<br>
now been standardized into: <a href="https://hexdocs.pm/req/Req.TransportError.html" rel="noopener nofollow ugc"><code>Req.TransportError</code></a> and <a href="https://hexdocs.pm/req/Req.HTTPError.html" rel="noopener nofollow ugc"><code>Req.HTTPError</code></a> for more consistent<br>
experience. In fact, this standardization was the pre-requisite of adding<br>
<a href="https://hexdocs.pm/req/Req.Test.html#transport_error/2" rel="noopener nofollow ugc"><code>Req.Test.transport_error/2</code></a>!</p>
<p>Two additional exception structs have been added: <a href="https://hexdocs.pm/req/Req.ArchiveError.html" rel="noopener nofollow ugc"><code>Req.ArchiveError</code></a> and <a href="https://hexdocs.pm/req/Req.DecompressError.html" rel="noopener nofollow ugc"><code>Req.DecompressError</code></a><br>
for zip/tar/etc errors in <a href="https://hexdocs.pm/req/Req.Steps.html#decode_body/1" rel="noopener nofollow ugc"><code>decode_body</code></a> and gzip/br/zstd/etc errors in <a href="https://hexdocs.pm/req/Req.Steps.html#decompress_body/1" rel="noopener nofollow ugc"><code>decompress_body</code></a><br>
respectively. Additionally, <a href="https://hexdocs.pm/req/Req.Steps.html#decode_body/1" rel="noopener nofollow ugc"><code>decode_body</code></a> now returns <code>Jason.DecodeError</code> instead of raising it.</p>
<h3><a name="p-329573-reqresponseasync-3" class="anchor" href="#p-329573-reqresponseasync-3" aria-label="Heading link" rel="nofollow"></a><code>%Req.Response.Async{}</code></h3>
<p>In previous releases we added ability to stream response body chunks into the current process<br>
mailbox using the <code>into: :self</code> option. When such is used, the <code>response.body</code> is now set to<br>
<a href="https://hexdocs.pm/req/Req.Response.Async.html" rel="noopener nofollow ugc"><code>Req.Response.Async</code></a> struct which implements the <a href="https://hexdocs.pm/elixir/Enumerable.html" rel="noopener nofollow ugc"><code>Enumerable</code></a> protocol.</p>
<p>Here’s a quick example:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">resp = Req.get!("http://httpbin.org/stream/2", into: :self)
resp.body
#=&gt; #Req.Response.Async&lt;...&gt;
Enum.each(resp.body, &amp;IO.puts/1)
# {"url": "http://httpbin.org/stream/2", ..., "id": 0}
# {"url": "http://httpbin.org/stream/2", ..., "id": 1}
</code></pre>
<p>Here is another example where we use Req to talk to two different servers. The first server<br>
produces some test data, strings <code>"foo"</code>, <code>"bar"</code> and <code>"baz"</code>. The second one is an “echo” server, it simply<br>
responds with the request body it returned. We then stream data from one server, transform it, and<br>
stream it to the other one:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">Mix.install([
  {:req, "~&gt; 0.5"},
  {:bandit, "~&gt; 1.0"}
])

{:ok, _} =
  Bandit.start_link(
    scheme: :http,
    port: 4000,
    plug: fn conn, _ -&gt;
      conn = Plug.Conn.send_chunked(conn, 200)
      {:ok, conn} = Plug.Conn.chunk(conn, "foo")
      {:ok, conn} = Plug.Conn.chunk(conn, "bar")
      {:ok, conn} = Plug.Conn.chunk(conn, "baz")
      conn
    end
  )

{:ok, _} =
  Bandit.start_link(
    scheme: :http,
    port: 4001,
    plug: fn conn, _ -&gt;
      {:ok, body, conn} = Plug.Conn.read_body(conn)
      Plug.Conn.send_resp(conn, 200, body)
    end
  )

resp = Req.get!("http://localhost:4000", into: :self)
stream = resp.body |&gt; Stream.with_index() |&gt; Stream.map(fn {data, idx} -&gt; "[#{idx}]#{data}" end)
Req.put!("http://localhost:4001", body: stream).body
#=&gt; "[0]foo[1]bar[2]baz"
</code></pre>
<p><code>Req.Response.Async</code> is an experimental feature which may change in the future.</p>
<p>The existing caveats to <code>into: :self</code> still apply, that is:</p>
<ul>
<li>
<p>If the request is sent using HTTP/1, an extra process is spawned to consume messages from the<br>
underlying socket.</p>
</li>
<li>
<p>On both HTTP/1 and HTTP/2 the messages are sent to the current process as soon as they arrive,<br>
as a firehose with no back-pressure.</p>
</li>
</ul>
<p>If you wish to maximize request rate or have more control over how messages are streamed, use<br>
<code>into: fun</code> or <code>into: collectable</code> instead.</p>
<h3><a name="p-329573-full-v050-changelog-4" class="anchor" href="#p-329573-full-v050-changelog-4" aria-label="Heading link" rel="nofollow"></a>Full v0.5.0 CHANGELOG</h3>
<ul>
<li>
<p><a href="https://hexdocs.pm/req/Req.html" rel="noopener nofollow ugc"><code>Req</code></a>: Deprecate setting <code>:headers</code> to values other than string/integer/<code>DateTime</code>.<br>
This is to potentially allow special handling of atom values in the future.</p>
</li>
<li>
<p><a href="https://hexdocs.pm/req/Req.html" rel="noopener nofollow ugc"><code>Req</code></a>: Add <code>Req.run/2</code> and <code>Req.run!/2</code>.</p>
</li>
<li>
<p><a href="https://hexdocs.pm/req/Req.html" rel="noopener nofollow ugc"><code>Req</code></a>: <code>into: :self</code> now sets <code>response.body</code> as <code>Req.Response.Async</code> which implements<br>
enumerable.</p>
</li>
<li>
<p><a href="https://hexdocs.pm/req/Req.Request.html" rel="noopener nofollow ugc"><code>Req.Request</code></a>: Deprecate setting <code>:redact_auth</code>. It now has no effect. Instead of allowing<br>
to opt out of, we give an idea what the secret was without revealing it fully:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">iex&gt; Req.new(auth: {:basic, "foobar:baz"})
%Req.Request{
  options: %{auth: {:basic, "foo*******"}},
  ...
}

iex&gt; Req.new(headers: [authorization: "bearer foobarbaz"])
%Req.Request{
  headers: %{"authorization" =&gt; ["bearer foo******"]},
  ...
}
</code></pre>
</li>
<li>
<p><a href="https://hexdocs.pm/req/Req.Request.html" rel="noopener nofollow ugc"><code>Req.Request</code></a>: Deprecate <code>halt/1</code> in favour of <code>Req.Request.halt/2</code>.</p>
</li>
<li>
<p><a href="https://hexdocs.pm/req/Req.Test.html" rel="noopener nofollow ugc"><code>Req.Test</code></a>: Add <a href="https://hexdocs.pm/req/Req.Test.html#transport_error/2" rel="noopener nofollow ugc"><code>Req.Test.transport_error/2</code></a> to simulate transport errors.</p>
</li>
<li>
<p><a href="https://hexdocs.pm/req/Req.Test.html" rel="noopener nofollow ugc"><code>Req.Test</code></a>: Add <a href="https://hexdocs.pm/req/Req.Test.html#expect/3" rel="noopener nofollow ugc"><code>Req.Test.expect/3</code></a>.</p>
</li>
<li>
<p><a href="https://hexdocs.pm/req/Req.Test.html" rel="noopener nofollow ugc"><code>Req.Test</code></a>: Add functions for setting ownership mode: <a href="https://hexdocs.pm/req/Req.Test.html#set_req_test_from_context/1" rel="noopener nofollow ugc"><code>Req.Test.set_req_test_from_context/1</code></a>, <a href="https://hexdocs.pm/req/Req.Test.html#set_req_test_to_private/1" rel="noopener nofollow ugc"><code>Req.Test.set_req_test_to_private/1</code></a>,<br>
<a href="https://hexdocs.pm/req/Req.Test.html#set_req_test_to_shared/1" rel="noopener nofollow ugc"><code>Req.Test.set_req_test_to_shared/1</code></a> and for verifying expectations: <a href="https://hexdocs.pm/req/Req.Test.html#verify!/0" rel="noopener nofollow ugc"><code>Req.Test.verify!/0</code></a>, <a href="https://hexdocs.pm/req/Req.Test.html#verify!/1" rel="noopener nofollow ugc"><code>Req.Test.verify!/1</code></a>, and <a href="https://hexdocs.pm/req/Req.Test.html#verify_on_exit!/1" rel="noopener nofollow ugc"><code>Req.Test.verify_on_exit!/1</code></a>.</p>
</li>
<li>
<p><a href="https://hexdocs.pm/req/Req.Test.html" rel="noopener nofollow ugc"><code>Req.Test</code></a>: Add <a href="https://hexdocs.pm/req/Req.Test.html#html/2" rel="noopener nofollow ugc"><code>Req.Test.html/2</code></a>.</p>
</li>
<li>
<p><a href="https://hexdocs.pm/req/Req.Test.html" rel="noopener nofollow ugc"><code>Req.Test</code></a>: Add <a href="https://hexdocs.pm/req/Req.Test.html#text/2" rel="noopener nofollow ugc"><code>Req.Test.text/2</code></a>.</p>
</li>
<li>
<p><a href="https://hexdocs.pm/req/Req.Test.html" rel="noopener nofollow ugc"><code>Req.Test</code></a>: Drop <code>:nimble_ownership</code> dependency.</p>
</li>
<li>
<p><a href="https://hexdocs.pm/req/Req.Test.html" rel="noopener nofollow ugc"><code>Req.Test</code></a>: Deprecate <code>Req.Test.stub/1</code>, i.e. the intended use case is to only work<br>
with <em>plug</em> stubs/mocks.</p>
</li>
<li>
<p><a href="https://hexdocs.pm/req/Req.Steps.html#decode_body/1" rel="noopener nofollow ugc"><code>decode_body</code></a>: Return <code>Jason.DecodeError</code> on JSON errors instead of raising it.</p>
</li>
<li>
<p><a href="https://hexdocs.pm/req/Req.Steps.html#decode_body/1" rel="noopener nofollow ugc"><code>decode_body</code></a>: Return <a href="https://hexdocs.pm/req/Req.ArchiveError.html" rel="noopener nofollow ugc"><code>Req.ArchiveError</code></a> on tar/zip errors.</p>
</li>
<li>
<p><a href="https://hexdocs.pm/req/Req.Steps.html#decompress_body/1" rel="noopener nofollow ugc"><code>decompress_body</code></a>: Return <a href="https://hexdocs.pm/req/Req.DecompressError.html" rel="noopener nofollow ugc"><code>Req.DecompressError</code></a>.</p>
</li>
<li>
<p><a href="https://hexdocs.pm/req/Req.Steps.html#put_aws_sigv4/1" rel="noopener nofollow ugc"><code>put_aws_sigv4</code></a>: Drop <code>:aws_signature</code> dependency.</p>
</li>
<li>
<p><a href="https://hexdocs.pm/req/Req.Steps.html#retry/1" rel="noopener nofollow ugc"><code>retry</code></a>: <strong>(BREAKING CHANGE)</strong> Consider<br>
<code>%Req.TransportError{reason: :closed | :econnrefused | :timeout}</code> as transient. Previously<br>
<em>any</em> exceptions with those reason values were consider as such.</p>
</li>
<li>
<p><a href="https://hexdocs.pm/req/Req.Steps.html#retry/1" rel="noopener nofollow ugc"><code>retry</code></a>: <strong>(BREAKING CHANGE)</strong> Consider<br>
<code>%Req.HTTPError{protocol: :http2, reason: :unprocessed}</code> as transient.</p>
</li>
<li>
<p><a href="https://hexdocs.pm/req/Req.Steps.html#run_finch/1" rel="noopener nofollow ugc"><code>run_finch</code></a>: <strong>(BREAKING CHANGE)</strong> Return <a href="https://hexdocs.pm/req/Req.HTTPError.html" rel="noopener nofollow ugc"><code>Req.HTTPError</code></a> instead of <code>Mint.HTTPError</code>.</p>
</li>
<li>
<p><a href="https://hexdocs.pm/req/Req.Steps.html#run_finch/1" rel="noopener nofollow ugc"><code>run_finch</code></a>: <strong>(BREAKING CHANGE)</strong> Return <a href="https://hexdocs.pm/req/Req.TransportError.html" rel="noopener nofollow ugc"><code>Req.TransportError</code></a> instead of <code>Mint.TransportError</code>.</p>
</li>
<li>
<p><a href="https://hexdocs.pm/req/Req.Steps.html#run_finch/1" rel="noopener nofollow ugc"><code>run_finch</code></a>: Set <code>inet6: true</code> if URL looks like IPv6 address.</p>
</li>
<li>
<p><a href="https://hexdocs.pm/req/Req.Steps.html#put_plug/1" rel="noopener nofollow ugc"><code>put_plug</code></a>: Move most documentation to <a href="https://hexdocs.pm/req/Req.Steps.html#run_plug/1" rel="noopener nofollow ugc"><code>run_plug</code></a>.</p>
</li>
<li>
<p><a href="https://hexdocs.pm/req/Req.Steps.html#run_plug/1" rel="noopener nofollow ugc"><code>run_plug</code></a>: Make public.</p>
</li>
<li>
<p><a href="https://hexdocs.pm/req/Req.Steps.html#run_plug/1" rel="noopener nofollow ugc"><code>run_plug</code></a>: Add support for simulating network issues using <a href="https://hexdocs.pm/req/Req.Test.html#transport_error/2" rel="noopener nofollow ugc"><code>Req.Test.transport_error/2</code></a>.</p>
</li>
<li>
<p><a href="https://hexdocs.pm/req/Req.Steps.html#run_plug/1" rel="noopener nofollow ugc"><code>run_plug</code></a>: Support passing 2-arity functions as plugs.</p>
</li>
<li>
<p><a href="https://hexdocs.pm/req/Req.Steps.html#run_plug/1" rel="noopener nofollow ugc"><code>run_plug</code></a>: Automatically fetch query params.</p>
</li>
<li>
<p><a href="https://hexdocs.pm/req/Req.Steps.html#verify_checksum/1" rel="noopener nofollow ugc"><code>verify_checksum</code></a>: Fix handling compressed responses.</p>
</li>
</ul> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="329573" data-batch-url="/posts/batch_likers">
                        19
                      </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/req-a-batteries-included-http-client-for-elixir/48494/44">Post #43</a>
	                </div>
	            </div>
              <div id="likers-container-329573" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="329573"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-most-liked cat-most-liked" title="One of the top 3 liked posts in this thread!"></div>
  </section>
</div>
    <div class="postbit" id="330826" data-post-id="330826">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Hello,</p>
<p>Do Req supports  the encryption/decryption of the payload according to JWE standard?<br>
I am trying to test using it to connect to highly secured service in sandbox and they mandates OAUTH 1.0 using RSA keys besides full encryption of the payload. I did look at documents and the forum and it seems it is still not supported "I am new to elixir so I could be wrong <img src="https://forum.elixirforum.com/images/emoji/apple/slight_smile.png?v=15" title=":slight_smile:" class="emoji" alt=":slight_smile:" loading="lazy" width="20" height="20">  "<br>
</p><div class="lightbox-wrapper"><a class="lightbox" href="https://forum.elixirforum.com/uploads/default/original/3X/a/6/a61e9ee2c3980d0be39cdfd43a77f0070736959d.png" data-download-href="https://forum.elixirforum.com/uploads/default/a61e9ee2c3980d0be39cdfd43a77f0070736959d" title="image" rel="nofollow"><img src="https://forum.elixirforum.com/uploads/default/optimized/3X/a/6/a61e9ee2c3980d0be39cdfd43a77f0070736959d_2_690x356.png" alt="image" data-base62-sha1="nHyRBfBdoWaPA50AXAfmolj2BLD" width="690" height="356" srcset="https://forum.elixirforum.com/uploads/default/optimized/3X/a/6/a61e9ee2c3980d0be39cdfd43a77f0070736959d_2_690x356.png, https://forum.elixirforum.com/uploads/default/optimized/3X/a/6/a61e9ee2c3980d0be39cdfd43a77f0070736959d_2_1035x534.png 1.5x, https://forum.elixirforum.com/uploads/default/original/3X/a/6/a61e9ee2c3980d0be39cdfd43a77f0070736959d.png 2x" data-dominant-color="F8F8F8"><div class="meta"><svg class="fa d-icon d-icon-far-image svg-icon" aria-hidden="true"><use href="#far-image"></use></svg><span class="filename">image</span><span class="informations">1208×625 42.8 KB</span><svg class="fa d-icon d-icon-discourse-expand svg-icon" aria-hidden="true"><use href="#discourse-expand"></use></svg></div></a></div><p></p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="330826" 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/req-a-batteries-included-http-client-for-elixir/48494/45">Post #44</a>
	                </div>
	            </div>
              <div id="likers-container-330826" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="330826"
                     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 #44"></div>
  </section>
</div>
    <div class="postbit" id="330830" data-post-id="330830">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="wojtekmach" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/wojtekmach/120/999_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  wojtekmach
                    <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 class="user-title">
									<span>Hex Core Team</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Nope, not supported.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="330830" 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/req-a-batteries-included-http-client-for-elixir/48494/46">Post #45</a>
	                </div>
	            </div>
              <div id="likers-container-330830" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="330830"
                     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 #45"></div>
  </section>
</div>
    <div class="postbit" id="337395" data-post-id="337395">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="wojtekmach" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/wojtekmach/120/999_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  wojtekmach
                    <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 class="user-title">
									<span>Hex Core Team</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Hey folks, just a quick update on Req. Recently I published an article, <a href="https://dashbit.co/blog/sdks-with-req-s3" class="inline-onebox" rel="noopener nofollow ugc">SDKs with Req: S3 - Dashbit Blog</a>, and the recent Req focus was on all things S3. The biggest change in Req is adding <code>:form_multipart</code> option:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">iex&gt; Mix.install([{:req, "~&gt; 0.5.6"}])
iex&gt; File.write!("c.txt", "ccc")
iex&gt;
iex&gt; resp =
...&gt;   Req.post!(
...&gt;     "https://httpbin.org/anything",
...&gt;     form_multipart: [
...&gt;       a: "aaa",
...&gt;       b: {"bbb", filename: "b.txt"},
...&gt;       c: File.stream!("c.txt", 2048)
...&gt;     ]
...&gt;   )
iex&gt;
iex&gt; resp.body |&gt; Map.take(["form", "files"])
%{"files" =&gt; %{"b" =&gt; "bbb", "c" =&gt; "ccc"}, "form" =&gt; %{"a" =&gt; "aaa"}}```
</code></pre>
<p><a href="https://github.com/wojtekmach/req_s3" rel="noopener nofollow ugc">ReqS3</a> also got updated, it now automatically decodes all XML responses, reads common <code>AWS_*</code> system env variables out of the box, and has improved support for S3-compatible services. Here’s an example using <a href="https://min.io" rel="noopener nofollow ugc">MinIO</a>:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">$ docker run -p 9000:9000 minio/minio server /data
</code></pre>
<pre data-code-wrap="elixir"><code class="lang-elixir">Mix.install([
  {:req_s3, "~&gt; 0.2.3"}
])

req =
  Req.new()
  |&gt; ReqS3.attach()
  |&gt; Req.merge(
    aws_sigv4: [
      access_key_id: "minioadmin",
      secret_access_key: "minioadmin"
    ],
    aws_endpoint_url_s3: "http://localhost:9000"
  )

# create bucket
%{status: status} = Req.put!(req, url: "s3://bucket1")
true = status in [200, 409]

# create object
%{status: 200} = Req.put!(req, url: "s3://bucket1/object1", body: "value1")

# list objects
%{status: 200, body: body} = Req.get!(req, url: "s3://bucket1")
dbg(body)
</code></pre>
<p>See changelogs for more information:</p>
<ul>
<li><a href="https://hexdocs.pm/req/changelog.html" class="inline-onebox" rel="noopener nofollow ugc">CHANGELOG — req v0.6.2</a></li>
<li><a href="https://hexdocs.pm/req_s3/changelog.html" class="inline-onebox" rel="noopener nofollow ugc">CHANGELOG — req_s3 v0.2.3</a></li>
</ul>
<p>Happy hacking!</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="337395" data-batch-url="/posts/batch_likers">
                        8
                      </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/req-a-batteries-included-http-client-for-elixir/48494/47">Post #46</a>
	                </div>
	            </div>
              <div id="likers-container-337395" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="337395"
                     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 #46"></div>
  </section>
</div>
    <div class="postbit" id="339319" data-post-id="339319">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p><s>I’ve noticed that Req returns iodata when the response is streamed/chunked from the server. The <a href="https://hexdocs.pm/req/Req.Steps.html#decode_body/1" rel="noopener nofollow ugc">automatic decoding step</a> doesn’t happen, although the content type (csv in my case <code>txt/csv</code>) is set appropriately. Is this expected behavior, or could this be improved?</s></p>
<p><s>In this particular case I’m not using Req’s body response streaming feature. Getting the full response body in one go would be ideal. I see there is an <code>:into</code> option for the response body, but I don’t know how to set its value to collect the response in a binary (and it still wouldn’t decode automatically).</s></p>
<p>Never mind, I totally misinterpreted something I was seeing. What I saw was not iodata, but was the decoded csv after all! Even chunked responses get decoded perfectly. Sorry for the confusion!</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="339319" 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/req-a-batteries-included-http-client-for-elixir/48494/48">Post #47</a>
	                </div>
	            </div>
              <div id="likers-container-339319" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="339319"
                     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 #47"></div>
  </section>
</div>
    <div class="postbit" id="361899" data-post-id="361899">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>When setting <code>plug: {Req.Test, ApiMock}</code> via global test config, is there a way to swap the original API module back for some tests when we need to test actual network instead of a plug mock? E.g. in Mox we can use <code>Mox.stub_with</code> to stub the mock with original API module. Is the only current way is to somehow reset <code>plug</code> option for <code>Req</code> in these specific tests, or avoid using global configuration for <code>plug</code> in the first place and set it granularly/separately for each test?</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="361899" 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/req-a-batteries-included-http-client-for-elixir/48494/49">Post #48</a>
	                </div>
	            </div>
              <div id="likers-container-361899" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="361899"
                     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 #48"></div>
  </section>
</div>
    <div class="postbit" id="361915" data-post-id="361915">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="wojtekmach" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/wojtekmach/120/999_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  wojtekmach
                    <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 class="user-title">
									<span>Hex Core Team</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>There isn’t a built-in way to do that. I plan to add a <code>Req.Test.passthrough(mock_name)</code> in the next version of Req. In the meantime, you can use some private internals to achieve that, though they are not guaranteed not to break but they probably will not, see:</p>
<p><a href="https://github.com/livebook-dev/livebook/blob/v0.15.5/lib/livebook/fly_api.ex#L309:L330" class="onebox" target="_blank" rel="noopener nofollow ugc">https://github.com/livebook-dev/livebook/blob/v0.15.5/lib/livebook/fly_api.ex#L309:L330</a></p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="361915" data-batch-url="/posts/batch_likers">
                        2
                      </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/req-a-batteries-included-http-client-for-elixir/48494/50">Post #49</a>
	                </div>
	            </div>
              <div id="likers-container-361915" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="361915"
                     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 #49"></div>
  </section>
</div>
    <div class="postbit" id="361992" data-post-id="361992">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>There’s one problem here, <code>__fetch_plug__ </code> fetches first expectation removing it from expectations list: <a href="https://github.com/wojtekmach/req/blob/15717c6ba78a675dee1d3442526b5120265ce073/lib/req/test.ex#L371" class="inline-onebox" rel="noopener nofollow ugc">req/lib/req/test.ex at 15717c6ba78a675dee1d3442526b5120265ce073 · wojtekmach/req · GitHub</a></p>
<p>This causes the first expectation in the test to be ignored. Am I missing something, or this expectation could somehow be put back after the check done by <code>test_options</code>?</p>
<p>My current solution is to prepend dumb expectation:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">    def fix_expectations do
      Req.Test.expect(__MODULE__, fn _conn -&gt; :ignored_expectation 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="361992" 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/req-a-batteries-included-http-client-for-elixir/48494/51">Post #50</a>
	                </div>
	            </div>
              <div id="likers-container-361992" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="361992"
                     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 #50"></div>
  </section>
</div>
</template></turbo-stream><turbo-stream action="replace" target="load-more-container"><template><div id="load-more-container" class="load-more-container">
    <a class="load-more-button" data-turbo-stream="true" href="/topics/48494/load_more?page=6">Load more posts (13 remaining)</a>
</div></template></turbo-stream>