From c3acff57542b78a2054e2fa8ffe1ecf23fe229fe Mon Sep 17 00:00:00 2001 From: Jean Boussier Date: Fri, 11 Feb 2022 15:58:08 +0100 Subject: [PATCH] Ensure `close` is called on the response body no matter what Another fallout from https://github.com/puma/puma/pull/2809 is that in some cases the `res_body.close` wasn't called because some previous code raised. For Rails apps it means CurrentAttributes and a few other important states aren't reset properly. This is being improved on the Rails side too, but I believe it would be good to harden this on the puma side as well. --- lib/puma/request.rb | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/lib/puma/request.rb b/lib/puma/request.rb index 948992895f..698cea68de 100644 --- a/lib/puma/request.rb +++ b/lib/puma/request.rb @@ -167,11 +167,16 @@ def handle_request(client, lines, requests) end ensure - uncork_socket io - - body.close - client.tempfile.unlink if client.tempfile - res_body.close if res_body.respond_to? :close + begin + uncork_socket io + + body.close + client.tempfile.unlink if client.tempfile + ensure + # Whatever happens, we MUST call `close` on the response body. + # Otherwise Rack::BodyProxy callbacks may not fire and lead to various state leaks + res_body.close if res_body.respond_to? :close + end after_reply.each { |o| o.call } end