-
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
writeis 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