diff --git a/lib/sinatra/base.rb b/lib/sinatra/base.rb index 4b057809..0475312e 100644 --- a/lib/sinatra/base.rb +++ b/lib/sinatra/base.rb @@ -328,7 +328,11 @@ module Sinatra private def dispatch! - self.class.filters.each { |block| invoke(block) } + self.class.filters.each do |block| + res = catch(:halt) { instance_eval(&block) ; :continue } + return unless res == :continue + end + if routes = self.class.routes[@request.request_method] path = @request.path_info original_params = nested_params(@request.params) @@ -408,6 +412,7 @@ module Sinatra when (100...599) === res @response.status = res end + res end @@ -522,7 +527,7 @@ module Sinatra end def before(&block) - @filters << lambda { instance_eval(&block) ; nil } + @filters << block end def condition(&block) diff --git a/test/filter_test.rb b/test/filter_test.rb index 5b0c3dda..1f7a58e4 100644 --- a/test/filter_test.rb +++ b/test/filter_test.rb @@ -33,15 +33,30 @@ describe "Filters" do assert_equal 'bar', body end + it "can modify instance variables available to routes" do + mock_app { + before { @foo = 'bar' } + get('/foo') { @foo } + } + + get '/foo' + assert ok? + assert_equal 'bar', body + end + it "allows redirects in filters" do mock_app { before { redirect '/bar' } - get('/foo') { 'ORLY?!' } + get('/foo') do + fail 'before block should have halted processing' + 'ORLY?!' + end } get '/foo' assert redirect? assert_equal '/bar', response['Location'] + assert_equal '', body end it "does not modify the response with its return value" do