diff --git a/lib/sinatra/base.rb b/lib/sinatra/base.rb index cd7a70ab..e2d4bdc0 100644 --- a/lib/sinatra/base.rb +++ b/lib/sinatra/base.rb @@ -328,7 +328,7 @@ module Sinatra private def dispatch! - self.class.filters.each {|block| instance_eval(&block)} + self.class.filters.each { |block| invoke(block) } if routes = self.class.routes[@request.request_method] path = @request.path_info original_params = nested_params(@request.params) @@ -382,6 +382,8 @@ module Sinatra def invoke(block) res = catch(:halt) { instance_eval(&block) } + return if res.nil? + case when res.respond_to?(:to_str) @response.body = [res] @@ -405,8 +407,6 @@ module Sinatra @response.body = res when (100...599) === res @response.status = res - when res.nil? - @response.body = [] end res end @@ -522,7 +522,7 @@ module Sinatra end def before(&block) - @filters << block + @filters << lambda { instance_eval(&block) ; nil } end def condition(&block) diff --git a/test/filter_test.rb b/test/filter_test.rb index 91d033c4..5b0c3dda 100644 --- a/test/filter_test.rb +++ b/test/filter_test.rb @@ -32,4 +32,29 @@ describe "Filters" do assert ok? assert_equal 'bar', body end + + it "allows redirects in filters" do + mock_app { + before { redirect '/bar' } + get('/foo') { 'ORLY?!' } + } + + get '/foo' + assert redirect? + assert_equal '/bar', response['Location'] + end + + it "does not modify the response with its return value" do + mock_app { + before { 'Hello World!' } + get '/foo' do + assert_equal [], response.body + 'cool' + end + } + + get '/foo' + assert ok? + assert_equal 'cool', body + end end