-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Closed
Description
Problem
After upgrading to Rack 3, I found that Rack::Response
generates an incorrect content-length header when:
- it is constructed with an empty array for the body, and
write
is called multiple times
Here is a simple reproduction script:
require "rack"
status = 200
headers = {}
response = Rack::Response.new([], status, headers)
# Write 11 total bytes
response.write "hello"
response.write "world"
response.write "!"
# Resulting content-length should be 11, but is 26
response.headers
# => {"content-length"=>"26"}
Underlying cause
When Rack::Response
is constructed with an empty array, it sets this internal state:
Line 82 in 0cd4d40
@buffered = nil # undetermined as of yet. |
This causes the value of @length
to accumulate on every call to Rack::Response#write
:
Lines 317 to 323 in 0cd4d40
if @buffered.nil? | |
if @body.is_a?(Array) | |
# The user supplied body was an array: | |
@body = @body.compact | |
@body.each do |part| | |
@length += part.to_s.bytesize | |
end |
When chunked?
is false
, @length
is incremented yet again, and then emitted as a content-length header:
Lines 348 to 350 in 0cd4d40
unless chunked? | |
@length += chunk.bytesize | |
set_header(CONTENT_LENGTH, @length.to_s) |
The result is that the content-length value is too large, and the error gets larger on every call to write
.
Metadata
Metadata
Assignees
Labels
No labels