From 1f8511698883c10dcd96993fb4c94c77490dd710 Mon Sep 17 00:00:00 2001 From: Fritz Zaucker Date: Fri, 29 May 2026 19:53:22 +0200 Subject: [PATCH] Fix unbounded memory growth in Conditional middleware The Conditional middleware's Response transform taps the per-connection `early-responses` Supplier but never completes it. The RequestResponse middleware completes the same Supplier via `LAST ... .done` when its response pipeline ends; Conditional omitted this, so the Supplier (and the connection-scoped state reachable from its subscription) was retained, leaking memory on every request that passes through any Conditional middleware (e.g. Cro::APIToken-based auth, Cro's own auth middleware). Reproduction: a server with a no-op Conditional middleware grows RSS linearly and unboundedly under repeated requests (~80 KB/request), while an equivalent RequestResponse middleware plateaus. Adding the matching `.done` brings Conditional in line with RequestResponse and the growth stops. All existing tests pass (t/http-middleware, t/http-router, t/router-auth, t/http-auth-*, t/http-session-*). --- lib/Cro/HTTP/Middleware.rakumod | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/Cro/HTTP/Middleware.rakumod b/lib/Cro/HTTP/Middleware.rakumod index 4124835b..a1a88419 100644 --- a/lib/Cro/HTTP/Middleware.rakumod +++ b/lib/Cro/HTTP/Middleware.rakumod @@ -132,6 +132,7 @@ role Cro::HTTP::Middleware::Conditional does Cro::HTTP::Middleware::Pair { } whenever $pipeline -> $response { emit $response; + LAST $connection-state.early-responses.done; } } }