diff --git a/.github/workflows/test-external.yaml b/.github/workflows/test-external.yaml index d55882cea..bcf7a6c72 100644 --- a/.github/workflows/test-external.yaml +++ b/.github/workflows/test-external.yaml @@ -11,7 +11,7 @@ jobs: fail-fast: false matrix: os: [ubuntu-latest] - ruby: ['2.7', '3.0', '3.1'] + ruby: ['3.0', '3.1', '3.2', '3.3'] runs-on: ${{matrix.os}} diff --git a/CHANGELOG.md b/CHANGELOG.md index 09a7aa440..c1f38daf6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,16 @@ All notable changes to this project will be documented in this file. For info on how to format all future additions to this file please reference [Keep A Changelog](https://keepachangelog.com/en/1.0.0/). +## Unreleased + +## [3.0.9] - 2024-01-31 + +- Fix incorrect content-length header that was emitted when `Rack::Response#write` was used in some situations. ([#2150](https://github.com/rack/rack/pull/2150), [@mattbrictson]) + +## [3.0.8] - 2023-06-14 + +- Fix some unused variable verbose warnings. ([#2084](https://github.com/rack/rack/pull/2084), [@jeremyevans], [@skipkayhil](https://github.com/skipkayhil)) + ## [3.0.7] - 2023-03-16 - Make query parameters without `=` have `nil` values. ([#2059](https://github.com/rack/rack/pull/2059), [@jeremyevans]) diff --git a/lib/rack/response.rb b/lib/rack/response.rb index f24683bcb..b9b02c272 100644 --- a/lib/rack/response.rb +++ b/lib/rack/response.rb @@ -328,6 +328,8 @@ def buffered_body! @body.each do |part| @length += part.to_s.bytesize end + + @buffered = true elsif @body.respond_to?(:each) # Turn the user supplied body into a buffered array: body = @body diff --git a/lib/rack/version.rb b/lib/rack/version.rb index e634f23ae..e2deadab2 100644 --- a/lib/rack/version.rb +++ b/lib/rack/version.rb @@ -25,7 +25,7 @@ def self.version VERSION end - RELEASE = "3.0.8" + RELEASE = "3.0.9" # Return the Rack release as a dotted string. def self.release diff --git a/test/spec_response.rb b/test/spec_response.rb index ef8aa481c..11e64d61f 100644 --- a/test/spec_response.rb +++ b/test/spec_response.rb @@ -412,7 +412,7 @@ def object_with_each.each status.must_equal 404 end - it "correctly updates content-type when writing when not initialized with body" do + it "correctly updates content-length when writing when initialized without body" do r = Rack::Response.new r.write('foo') r.write('bar') @@ -423,20 +423,39 @@ def object_with_each.each header['content-length'].must_equal '9' end - it "correctly updates content-type when writing when initialized with body" do + it "correctly updates content-length when writing when initialized with Array body" do + r = Rack::Response.new(["foo"]) + r.write('bar') + r.write('baz') + _, header, body = r.finish + str = "".dup; body.each { |part| str << part } + str.must_equal "foobarbaz" + header['content-length'].must_equal '9' + end + + it "correctly updates content-length when writing when initialized with String body" do + r = Rack::Response.new("foo") + r.write('bar') + r.write('baz') + _, header, body = r.finish + str = "".dup; body.each { |part| str << part } + str.must_equal "foobarbaz" + header['content-length'].must_equal '9' + end + + it "correctly updates content-length when writing when initialized with object body that responds to #each" do obj = Object.new def obj.each yield 'foo' yield 'bar' end - ["foobar", ["foo", "bar"], obj].each do - r = Rack::Response.new(["foo", "bar"]) - r.write('baz') - _, header, body = r.finish - str = "".dup; body.each { |part| str << part } - str.must_equal "foobarbaz" - header['content-length'].must_equal '9' - end + r = Rack::Response.new(obj) + r.write('baz') + r.write('baz') + _, header, body = r.finish + str = "".dup; body.each { |part| str << part } + str.must_equal "foobarbazbaz" + header['content-length'].must_equal '12' end it "doesn't return invalid responses" do