Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Follow Rack protocol, closes #325 #326

Closed
wants to merge 1 commit into from

2 participants

@jnicklas

With this commit, Sinatra only ever calls #each
on the response body, this makes Sinatra work as
middleware under Rails 3.1

Anders Törnqvist and Jonas Nicklas Follow Rack protocol, closes #325
With this commit, Sinatra only ever calls #each
on the response body, this makes Sinatra work as
middleware under Rails 3.1
02399ab
@rkh rkh closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Jul 11, 2011
  1. Follow Rack protocol, closes #325

    Anders Törnqvist and Jonas Nicklas authored
    With this commit, Sinatra only ever calls #each
    on the response body, this makes Sinatra work as
    middleware under Rails 3.1
This page is out of date. Refresh to see the latest.
Showing with 31 additions and 9 deletions.
  1. +15 −7 lib/sinatra/base.rb
  2. +16 −2 test/base_test.rb
View
22 lib/sinatra/base.rb
@@ -75,8 +75,10 @@ def finish
if status.to_i / 100 == 1
headers.delete "Content-Length"
headers.delete "Content-Type"
- elsif body.respond_to? :to_ary and not [204, 304].include?(status.to_i)
- headers["Content-Length"] = body.inject(0) { |l, p| l + Rack::Utils.bytesize(p) }.to_s
+ elsif not [204, 304].include?(status.to_i)
+ length = 0
+ body.each { |part| length += Rack::Utils.bytesize(part) }
+ headers["Content-Length"] = length.to_s
end
super
end
@@ -613,15 +615,21 @@ def call!(env) # :nodoc:
invoke { dispatch! }
invoke { error_block!(response.status) }
- unless @response['Content-Type']
- if body.respond_to? :to_ary and body[0].respond_to? :content_type
- content_type body[0].content_type
+ set_content_type! unless @response['Content-Type']
+
+ @response.finish
+ end
+
+ def set_content_type!
+ body.each do |part|
+ if part.respond_to? :content_type
+ content_type part.content_type
else
content_type :html
end
+ return
end
-
- @response.finish
+ content_type :html
end
# Access settings defined with Base.set.
View
18 test/base_test.rb
@@ -57,10 +57,22 @@ class TestApp < Sinatra::Base
end
describe "Sinatra::Base as Rack middleware" do
+ class StrictRackReponse
+ def initialize(array)
+ @array = array
+ end
+ def each(&block)
+ @array.each(&block)
+ end
+ def to_ary
+ raise "calling me is evil, please don't!"
+ end
+ end
+
app = lambda { |env|
headers = {'X-Downstream' => 'true'}
headers['X-Route-Missing'] = env['sinatra.route-missing'] || ''
- [210, headers, ['Hello from downstream']] }
+ [210, headers, StrictRackReponse.new(['Hello from downstream'])] }
class TestMiddleware < Sinatra::Base
end
@@ -126,7 +138,9 @@ class TestMiddleware < Sinatra::Base
assert_nil res
assert_equal 210, response.status
assert_equal 'true', response['X-Downstream']
- assert_equal ['Hello from downstream'], response.body
+ parts = []
+ response.body.each { |part| parts << part }
+ assert_equal ['Hello from downstream'], parts
'Hello after explicit forward'
end
end
Something went wrong with that request. Please try again.