fix: as_curl form-encodes a dict data= body with doseq=True

urlencode(data) without doseq rendered a list-valued form field as its urlencoded python
repr (x=%5B%271%27...) instead of aiohttp FormData's repeated-pair wire form (x=1&x=2), so
a debug curl for a list-valued body replayed a different request than request() sent. add
doseq=True to match the wire. preview/debug-only; scalar values and non-dict bodies are
byte-unchanged.

Signed-off-by: disqualifier <dev@disqualifier.me>
This commit is contained in:
2026-07-06 21:16:08 -04:00
parent eed607b08c
commit 45d8830833
+3 -2
View File
@@ -36,8 +36,9 @@ class RequestPreview:
if self.details["data"] is not None: if self.details["data"] is not None:
data = self.details["data"] data = self.details["data"]
# aiohttp form-encodes a dict data= body (application/x-www-form-urlencoded); # aiohttp form-encodes a dict data= body (application/x-www-form-urlencoded);
# render that wire form, not the python repr, so the curl replays identically # render that wire form, not the python repr, so the curl replays identically.
rendered = urlencode(data) if isinstance(data, dict) else str(data) # doseq=True mirrors aiohttp's FormData: a list value becomes repeated k=v pairs
rendered = urlencode(data, doseq=True) if isinstance(data, dict) else str(data)
parts.append(f"--data {shlex.quote(rendered)}") parts.append(f"--data {shlex.quote(rendered)}")
elif self.details["json"] is not None: elif self.details["json"] is not None:
# is-not-None: an empty-but-valid body ({} / []) must still render # is-not-None: an empty-but-valid body ({} / []) must still render