Aftermarket Hardens Patch, Adapt and Record Against Stalled and Cut Off Uploads
Aftermarket 0.7.2 is about one unglamorous thing: what a proxy does with a request body that doesn’t arrive the normal way. It might come slowly, stop halfway, get cut off, or still be on its way when the upstream has already answered.
That sounds like an edge case. It isn’t, once a proxy sits in front of real clients. Phones lose signal mid-upload. Scripts get killed. Some servers answer 401 before reading a byte of the body. And Go’s HTTP server, which the tools are built on, does some quiet housekeeping with request bodies that a proxy has to stay out of the way of.
What changed
A slow upload is fine, as long as it keeps moving: each part has to arrive within upstream_timeout of the last. One that stops gets 408 and its connection is closed. Before, a stalled client could hold up an answer for good when the upstream was down.
A body that breaks off before its announced length gets 400. The part that did arrive is never treated as the whole thing, so a rule, a template or a recording never works from half a body.
When the upstream answers before the client has finished sending, the answer comes through whole and closes the connection. Whatever the client sends after that can’t be read as a new request.
A client that sends its request and then closes its own side used to get an empty 200. Now it gets the real answer, as long as that arrives within upstream_timeout. A client that’s really gone frees the upstream call by then.
Ordinary traffic keeps its keep-alive connections exactly as before. adapt does better than before: when a mapping replaces or drops a body, adapt reads the old one off, so the connection can be used again.
How it got there
This took four rounds of independent review. The first design fixed the stall and quietly brought back two traps in Go’s server. One of them could answer a client with an empty 200. Each later round found smaller cases: a body exactly one byte over max_body, Expect: 100-continue, a switch of protocols, a client that leaves in the middle of a stream.
Every one of those findings has a test that fails on the version before its fix. The suite now has 474 tests, all passing with Go’s race detector on, on Linux and macOS. Binaries are on the download page.