Skip to content

Fix ExAws.Request.Req: don't rewrite bodyless GETs to POST - #1251

Open
gernotkogler wants to merge 2 commits into
ex-aws:mainfrom
gernotkogler:fix-req-adapter-bodyless-get
Open

Fix ExAws.Request.Req: don't rewrite bodyless GETs to POST#1251
gernotkogler wants to merge 2 commits into
ex-aws:mainfrom
gernotkogler:fix-req-adapter-bodyless-get

Conversation

@gernotkogler

@gernotkogler gernotkogler commented Aug 2, 2026

Copy link
Copy Markdown

Closes #1246.

Req 0.7 automatically converts a GET into a POST when a non-nil request body is set. ExAws calls its HTTP client with "" for bodyless requests (every S3 GET is built with body: data[:body] || ""), and "" != nil, so every GET made through ExAws.Request.Req goes out as a POST. Because SigV4 is signed over the original GET, the server rejects it with SignatureDoesNotMatch (or, for non-signed backends, 405).

In Req's model "no body" is nil, not "", so the adapter just needs to translate ExAws's convention:

body = if body in [nil, ""], do: nil, else: body

Changes:

  • fix the shipped ExAws.Request.Req adapter (normalise ""nil)
  • add a regression test: a bodyless GET must reach the server as a GET (verified failing as POST under req 0.7.2 without the fix, passing with it)
  • apply the same fix to the Req adapter example in the ExAws.Request.HttpClient moduledoc

Only :get is affected by Req's rewrite, so HEAD/PUT/POST/DELETE are unchanged.

Req rewrites a GET into a POST when a non-nil request body is set. ExAws
represents a bodyless request with "" (e.g. an S3 GET), so the documented
Req adapter turned every such GET into a POST and servers replied 405.
Normalise an empty body to nil so the method is preserved.
@sjmadsen

sjmadsen commented Aug 3, 2026

Copy link
Copy Markdown

This kind of addresses #1246, but it would be even better if it fixed the existing Req adapter already in ExAws:

def request(method, url, body \\ "", headers \\ [], http_opts \\ []) do

Req 0.7 rewrites a GET into a POST when a non-nil request body is set.
ExAws calls the adapter with "" for bodyless requests, so every GET made
through ExAws.Request.Req went out as a POST; SigV4 is signed over the GET,
so the server rejects it with SignatureDoesNotMatch (issue ex-aws#1246).

Normalise an empty body to nil so the method is preserved, and add a
regression test asserting a bodyless GET reaches the server as a GET.
@gernotkogler gernotkogler changed the title Fix Req adapter example: send bodyless requests as nil Fix ExAws.Request.Req: don't rewrite bodyless GETs to POST Aug 4, 2026
@gernotkogler

Copy link
Copy Markdown
Author

Good call — I hadn't spotted the shipped ExAws.Request.Req module (it postdates the version I was on). I've now fixed it there as the primary change, added a regression test (verified it fails as POST under req 0.7.2 without the fix), and kept the matching fix to the moduledoc example. Updated the PR to close #1246.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

ExAws.Request.Req sends signed GET requests as POST with req 0.7 (SignatureDoesNotMatch)

2 participants