Skip to content

Show the request body in the failure dump - #82

Merged
korya merged 1 commit into
masterfrom
korya-fix-request-body-dump
Aug 8, 2026
Merged

Show the request body in the failure dump#82
korya merged 1 commit into
masterfrom
korya-fix-request-body-dump

Conversation

@korya

@korya korya commented Aug 8, 2026

Copy link
Copy Markdown
Owner

Problem

After a failed POST the dump left out the one thing you need: what was sent.

FAILED: POST http://…/echo (HTTP/1.1)

POST /echo HTTP/1.1
Host: 127.0.0.1:8791
User-Agent: Go-http-client/1.1
Content-Length: 24          ← claims 24 bytes
                            ← ships zero

Two problems in one. The payload is missing when it is the first question anyone asks, and what is printed is not a valid HTTP message — it cannot be replayed, pasted into a bug report, or fed to anything that parses HTTP.

The cause is ordering: the request is rendered after it has been sent, and sending consumes req.Body.

Solution

Clone the request through GetBody before rendering it, and stop using http.Request.Write as a pretty-printer.

POST /echo HTTP/1.1
Host: 127.0.0.1:59095
User-Agent: Go-http-client/1.1
Content-Length: 24

THIS-IS-THE-REQUEST-BODY

The replay machinery already existed — --retry needed a fresh request per attempt, so cloneForAttempt was already there and already tested. This is a second caller for it.

Why not just re-attach the body and let Write do it

That fixes the missing payload and reintroduces #18. http.Request.Write is a wire-format serializer: a 5MB -d would land in the report whole, and a binary one would go to the terminal raw. writeTo stopped using http.Response.Write for exactly that reason, and the request half never got the same treatment.

So the split is: headers from Write, which knows what actually goes on the wire — Host, User-Agent and Content-Length are none of them in req.Header, so hand-rendering would silently lose the very header this issue is about — and the body through the same renderer as the response.

Content-Length: 300

01234567890123456789…                          ← 256 bytes

  << Payload is cropped: 44 bytes are hidden >>
Content-Length: 4

00000000  ff fe 07 08                    |....|

A request with no body renders exactly as before. A body that cannot be replayed — no GetBody — falls back to headers alone rather than failing, because a broken dump must not replace the failure being reported.

Other Changes

TestKnownIssue19RequestBodyMissing is deleted, replaced by TestE2EDumpShowsTheRequestBody: the payload appears, it survives a --retry (the dump records one exchange, so it must outlast however many attempts it took), long payloads crop, binary payloads hex-dump, and a body-less GET is untouched.

Test_writeRequest covers the same five at the unit level against a request drained the way http.Client drains it, so the state under test is the state the dump actually receives rather than a fresh request that would pass trivially.

Note on binary payloads: a NUL byte cannot reach -d at all, since exec rejects it in an argument. The tests use \xff\xfe\x07\x08, which is reachable and equally non-printable.

There are no screenshots because there is no rendered UI; this tool's user-visible surface is terminal output, shown inline above.

Closes #19

Related:

🤖 Generated with Claude Code

https://claude.ai/code/session_019EMMhgmTkbzAsmeNy97PrP

@korya
korya force-pushed the korya-fix-bare-header branch from f058f11 to 8d2bc4a Compare August 8, 2026 13:15
@korya
korya force-pushed the korya-fix-request-body-dump branch from 0601193 to 790f7fa Compare August 8, 2026 13:15
@korya
korya force-pushed the korya-fix-bare-header branch from 8d2bc4a to 77c0cc5 Compare August 8, 2026 13:20
@korya
korya force-pushed the korya-fix-request-body-dump branch from 790f7fa to 43bdce4 Compare August 8, 2026 13:20
Base automatically changed from korya-fix-bare-header to master August 8, 2026 13:22
The dump advertised a Content-Length and shipped nothing behind it:

    FAILED: POST http://…/echo (HTTP/1.1)

    POST /echo HTTP/1.1
    Host: 127.0.0.1:8791
    User-Agent: Go-http-client/1.1
    Content-Length: 24          <- claims 24 bytes
                                <- ships zero

After a failed POST the first question is what was actually sent, and
that was the one thing the report left out. It was also not a valid HTTP
message, so it could not be replayed or pasted anywhere useful.

The cause is that the request is rendered after the send, and the send
consumes req.Body. Cloning it through GetBody replays the payload; the
machinery arrived with --retry, which already needed a fresh request per
attempt.

Rendering no longer goes through http.Request.Write alone, for the same
reason writeTo stopped going through http.Response.Write in #18: it is a
wire-format serializer, so a 5MB -d would have landed in the report
whole and a binary one would have gone to the terminal raw. The headers
still come from Write, which knows what actually goes on the wire --
Host, User-Agent and Content-Length are none of them in req.Header --
and the body now goes through the same renderer as the response, so it
crops at 256 bytes and hex-dumps when it is not text.

A request with no body renders as it did. A body that cannot be replayed
falls back to headers alone rather than failing the dump, because a
failed dump must not replace the failure being reported.

Closes #19

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019EMMhgmTkbzAsmeNy97PrP
@korya
korya force-pushed the korya-fix-request-body-dump branch from 43bdce4 to 09f4f91 Compare August 8, 2026 13:23
@korya
korya marked this pull request as ready for review August 8, 2026 13:24
@korya
korya merged commit 06d99d3 into master Aug 8, 2026
8 checks passed
@korya
korya deleted the korya-fix-request-body-dump branch August 8, 2026 13:26
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.

Request body is never shown in the failure dump (and Content-Length contradicts it)

1 participant