Skip to content

Commit

Permalink
Merge pull request rack#166 from josevalim/master
Browse files Browse the repository at this point in the history
Improve content-length middleware
  • Loading branch information
tenderlove committed May 19, 2011
2 parents a4a788e + 2b3abc7 commit f6ff86d
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 6 deletions.
13 changes: 9 additions & 4 deletions lib/rack/content_length.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,9 @@ module Rack
class ContentLength
include Rack::Utils

def initialize(app)
def initialize(app, sendfile=nil)
@app = app
@sendfile = sendfile
end

def call(env)
Expand All @@ -16,10 +17,14 @@ def call(env)
if !STATUS_WITH_NO_ENTITY_BODY.include?(status.to_i) &&
!headers['Content-Length'] &&
!headers['Transfer-Encoding'] &&
body.respond_to?(:to_ary)
!(@sendfile && headers[@sendfile])

length = 0
body.each { |part| length += bytesize(part) }
new_body, length = [], 0
body.each do |part|
new_body << part
length += bytesize(part)
end
body = new_body
headers['Content-Length'] = length.to_s
end

Expand Down
10 changes: 8 additions & 2 deletions test/spec_content_length.rb
Original file line number Diff line number Diff line change
Expand Up @@ -7,13 +7,13 @@
response[1]['Content-Length'].should.equal '13'
end

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

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

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

should "not set Content-Length on sendfile responses" do
app = lambda { |env| [200, {'Content-Type' => 'text/plain', 'X-Sendfile' => 'foo'}, %w(Hello World)] }
response = Rack::ContentLength.new(app, "X-Sendfile").call({})
response[1]['Content-Length'].should.equal nil
end

should "not set Content-Length when Transfer-Encoding is chunked" do
app = lambda { |env| [200, {'Transfer-Encoding' => 'chunked'}, []] }
response = Rack::ContentLength.new(app).call({})
Expand Down

0 comments on commit f6ff86d

Please sign in to comment.