Previous raw TCP approach drained the request body FIRST, then sent the
response. This caused a deadlock:
Server: waiting to READ request body (blocking on conn.Read)
Client: waiting for RESPONSE HEADERS (blocking on conn.Read from server)
Neither can proceed — the client's request-body write is blocked waiting
for response headers, so the server never receives the body, so the drain
never completes, so the server never sends the response.
Fix: send the response FIRST. The client's response-reader unblocks (gets
response), so the client's request-body writer can complete and send the
body. The drain goroutine then reads whatever the client sent. The
server closes the connection while the drain is in progress — fine, the
drain goroutine just gets a connection-closed error and exits.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>