fix(coalesce): copy the primary response body for waiters

Waiters read the primary response buffer while fasthttp could reuse it for another request. A waiter could then send the wrong body. The primary now gives waiters their own copy.
This commit is contained in:
2026-11-03 00:02:15 +00:00
parent 10d3946f1e
commit e2af5b079f
2 changed files with 39 additions and 5 deletions
+12 -5
View File
@@ -740,11 +740,7 @@ func performProxyRequest(c fiber.Ctx, proxyURL string) error {
}, proxyErr
}
return &CoalescedResponse{
Body: c.Response().Body(),
StatusCode: c.Response().StatusCode(),
// Headers intentionally left nil; not populated or read anywhere.
}, nil
return snapshotCoalescedResponse(c), nil
})
// Check for error from rc.Do (though it typically returns nil)
@@ -773,6 +769,17 @@ func performProxyRequest(c fiber.Ctx, proxyURL string) error {
return performProxyRequestCore(c, proxyURL, cacheKey)
}
// snapshotCoalescedResponse captures the primary's response for waiters. It
// copies the body because fasthttp reuses the buffer once the primary handler
// returns, while waiters can still be reading.
func snapshotCoalescedResponse(c fiber.Ctx) *CoalescedResponse {
return &CoalescedResponse{
Body: bytes.Clone(c.Response().Body()),
StatusCode: c.Response().StatusCode(),
// Headers intentionally left nil; not populated or read anywhere.
}
}
// performProxyRequestCore executes the proxy request with retries and circuit breaker
// This is the core implementation used by both direct calls and coalesced requests
func performProxyRequestCore(c fiber.Ctx, proxyURL string, cacheKey string) error {