Skip to content

Commit 2b3abc7

Browse files
committed
Improve Rack::ContentLength middleware.
1) It makes Rack::ContentLength middleware conform with the rack specification by removing the to_ary check; 2) Make Rack::ContentLength accept an extra header argument that checks for sendfile headers
1 parent a4a788e commit 2b3abc7

2 files changed

Lines changed: 17 additions & 6 deletions

File tree

lib/rack/content_length.rb

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,9 @@ module Rack
55
class ContentLength
66
include Rack::Utils
77

8-
def initialize(app)
8+
def initialize(app, sendfile=nil)
99
@app = app
10+
@sendfile = sendfile
1011
end
1112

1213
def call(env)
@@ -16,10 +17,14 @@ def call(env)
1617
if !STATUS_WITH_NO_ENTITY_BODY.include?(status.to_i) &&
1718
!headers['Content-Length'] &&
1819
!headers['Transfer-Encoding'] &&
19-
body.respond_to?(:to_ary)
20+
!(@sendfile && headers[@sendfile])
2021

21-
length = 0
22-
body.each { |part| length += bytesize(part) }
22+
new_body, length = [], 0
23+
body.each do |part|
24+
new_body << part
25+
length += bytesize(part)
26+
end
27+
body = new_body
2328
headers['Content-Length'] = length.to_s
2429
end
2530

test/spec_content_length.rb

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,13 @@
77
response[1]['Content-Length'].should.equal '13'
88
end
99

10-
should "not set Content-Length on variable length bodies" do
10+
should "set Content-Length even on variable length bodies" do
1111
body = lambda { "Hello World!" }
1212
def body.each ; yield call ; end
1313

1414
app = lambda { |env| [200, {'Content-Type' => 'text/plain'}, body] }
1515
response = Rack::ContentLength.new(app).call({})
16-
response[1]['Content-Length'].should.be.nil
16+
response[1]['Content-Length'].should.equal '12'
1717
end
1818

1919
should "not change Content-Length if it is already set" do
@@ -28,6 +28,12 @@ def body.each ; yield call ; end
2828
response[1]['Content-Length'].should.equal nil
2929
end
3030

31+
should "not set Content-Length on sendfile responses" do
32+
app = lambda { |env| [200, {'Content-Type' => 'text/plain', 'X-Sendfile' => 'foo'}, %w(Hello World)] }
33+
response = Rack::ContentLength.new(app, "X-Sendfile").call({})
34+
response[1]['Content-Length'].should.equal nil
35+
end
36+
3137
should "not set Content-Length when Transfer-Encoding is chunked" do
3238
app = lambda { |env| [200, {'Transfer-Encoding' => 'chunked'}, []] }
3339
response = Rack::ContentLength.new(app).call({})

0 commit comments

Comments
 (0)