From 16ac6806a663d49c1084be1b6f17ad9b698934ac Mon Sep 17 00:00:00 2001 From: Samuel Williams Date: Thu, 10 Sep 2026 18:55:36 +1200 Subject: [PATCH 1/2] Avoid enumerating closed response bodies Assisted-By: devx/b8194217-b20a-4799-b266-4910beb3ee2b --- lib/protocol/rack/body/enumerable.rb | 4 +++- releases.md | 1 + test/protocol/rack/body/enumerable.rb | 10 ++++++++++ 3 files changed, 14 insertions(+), 1 deletion(-) diff --git a/lib/protocol/rack/body/enumerable.rb b/lib/protocol/rack/body/enumerable.rb index eaf43cb..4b71272 100644 --- a/lib/protocol/rack/body/enumerable.rb +++ b/lib/protocol/rack/body/enumerable.rb @@ -103,7 +103,9 @@ def close(error = nil) # @yields {|chunk| ...} # @parameter chunk [String] A chunk of the response body. def each(&block) - @body.each(&block) + if body = @body + body.each(&block) + end rescue => error raise ensure diff --git a/releases.md b/releases.md index c903c8e..1ab6cc0 100644 --- a/releases.md +++ b/releases.md @@ -3,6 +3,7 @@ ## Unreleased - Respect the result of rewinding the underlying request body. + - Avoid enumerating a response body after it has been closed. ## v0.22.1 diff --git a/test/protocol/rack/body/enumerable.rb b/test/protocol/rack/body/enumerable.rb index a564b52..9c851c9 100644 --- a/test/protocol/rack/body/enumerable.rb +++ b/test/protocol/rack/body/enumerable.rb @@ -58,6 +58,16 @@ end end.to raise_exception(RuntimeError, message: be =~ /Bad Enumerable/) end + + it "does not enumerate after being closed" do + body = subject.new(["Hello World"], 11) + body.close + + chunks = [] + body.each{|chunk| chunks << chunk} + + expect(chunks).to be(:empty?) + end end with "#call" do From 1c20444c978a4fd40ea761b2c7ff1d23fe2d46db Mon Sep 17 00:00:00 2001 From: Samuel Williams Date: Thu, 10 Sep 2026 19:04:32 +1200 Subject: [PATCH 2/2] Simplify closed body enumeration Assisted-By: devx/b8194217-b20a-4799-b266-4910beb3ee2b --- lib/protocol/rack/body/enumerable.rb | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/protocol/rack/body/enumerable.rb b/lib/protocol/rack/body/enumerable.rb index 4b71272..0a33c18 100644 --- a/lib/protocol/rack/body/enumerable.rb +++ b/lib/protocol/rack/body/enumerable.rb @@ -103,9 +103,7 @@ def close(error = nil) # @yields {|chunk| ...} # @parameter chunk [String] A chunk of the response body. def each(&block) - if body = @body - body.each(&block) - end + @body&.each(&block) rescue => error raise ensure