From 7a9101a99dd5e662f69fa8980285cb795dceb41c Mon Sep 17 00:00:00 2001 From: Konstantin Haase Date: Wed, 3 Nov 2010 13:51:52 +0100 Subject: [PATCH] Like routes, filters now also take conditions: before :agent => /Songbird/ do # ... end after '/blog/*', :host_name => 'example.com' do # ... end Test and documentation (English and German) included. --- README.de.rdoc | 10 +++++ README.rdoc | 10 +++++ lib/sinatra/base.rb | 19 ++++---- test/filter_test.rb | 106 +++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 135 insertions(+), 10 deletions(-) diff --git a/README.de.rdoc b/README.de.rdoc index 75c1a907..e2a66d4a 100644 --- a/README.de.rdoc +++ b/README.de.rdoc @@ -571,6 +571,16 @@ Filter können optional auch mit einem Pattern ausgestattet werden, welche auf d session[:last_slug] = slug end +Ähnlich wie Routen können Filter auch mit weiteren Bedingungen eingeschränkt werden: + + before :agent => /Songbird/ do + # ... + end + + after '/blog/*', :host_name => 'example.com' do + # ... + end + == Anhalten Zum sofortigen stoppen eines Request in einem Filter oder einer Route: diff --git a/README.rdoc b/README.rdoc index 08314699..6466ee3e 100644 --- a/README.rdoc +++ b/README.rdoc @@ -558,6 +558,16 @@ request path matches that pattern: session[:last_slug] = slug end +Like routes, filters also take conditions: + + before :agent => /Songbird/ do + # ... + end + + after '/blog/*', :host_name => 'example.com' do + # ... + end + == Halting To immediately stop a request within a filter or route use: diff --git a/lib/sinatra/base.rb b/lib/sinatra/base.rb index 22e91155..d91cfff6 100644 --- a/lib/sinatra/base.rb +++ b/lib/sinatra/base.rb @@ -933,21 +933,22 @@ module Sinatra # Define a before filter; runs before all requests within the same # context as route handlers and may access/modify the request and # response. - def before(path = nil, &block) - add_filter(:before, path, &block) + def before(path = nil, options = {}, &block) + add_filter(:before, path, options, &block) end # Define an after filter; runs after all requests within the same # context as route handlers and may access/modify the request and # response. - def after(path = nil, &block) - add_filter(:after, path, &block) + def after(path = nil, options = {}, &block) + add_filter(:after, path, options, &block) end # add a filter - def add_filter(type, path = nil, &block) + def add_filter(type, path = nil, options = {}, &block) return filters[type] << block unless path - block, *arguments = compile!(type, path, block) + path, options = //, path if path.respond_to?(:each_pair) + block, *arguments = compile!(type, path, block, options) add_filter(type) do process_route(*arguments) { instance_eval(&block) } end @@ -1014,9 +1015,8 @@ module Sinatra def route(verb, path, options={}, &block) # Because of self.options.host host_name(options.delete(:host)) if options.key?(:host) - options.each { |option, args| send(option, *args) } - block, pattern, keys, conditions = compile! verb, path, block + block, pattern, keys, conditions = compile! verb, path, block, options invoke_hook(:route_added, verb, path, block) (@routes[verb] ||= []). @@ -1027,7 +1027,8 @@ module Sinatra extensions.each { |e| e.send(name, *args) if e.respond_to?(name) } end - def compile!(verb, path, block) + def compile!(verb, path, block, options = {}) + options.each_pair { |option, args| send(option, *args) } method_name = "#{verb} #{path}" define_method(method_name, &block) diff --git a/test/filter_test.rb b/test/filter_test.rb index d9adb10e..e27ff612 100644 --- a/test/filter_test.rb +++ b/test/filter_test.rb @@ -264,7 +264,7 @@ class AfterFilterTest < Test::Unit::TestCase get '/foo/bar' assert_equal subpath, 'bar' end - + it 'is possible to access url params from the route param' do ran = false mock_app do @@ -277,4 +277,108 @@ class AfterFilterTest < Test::Unit::TestCase get '/foo/bar' assert ran end + + it 'is possible to apply host_name conditions to before filters with no path' do + ran = false + mock_app do + before(:host_name => 'example.com') { ran = true } + get('/') { 'welcome' } + end + get '/', {}, { 'HTTP_HOST' => 'example.org' } + assert !ran + get '/', {}, { 'HTTP_HOST' => 'example.com' } + assert ran + end + + it 'is possible to apply host_name conditions to before filters with a path' do + ran = false + mock_app do + before('/foo', :host_name => 'example.com') { ran = true } + get('/') { 'welcome' } + end + get '/', {}, { 'HTTP_HOST' => 'example.com' } + assert !ran + get '/foo', {}, { 'HTTP_HOST' => 'example.org' } + assert !ran + get '/foo', {}, { 'HTTP_HOST' => 'example.com' } + assert ran + end + + it 'is possible to apply host_name conditions to after filters with no path' do + ran = false + mock_app do + after(:host_name => 'example.com') { ran = true } + get('/') { 'welcome' } + end + get '/', {}, { 'HTTP_HOST' => 'example.org' } + assert !ran + get '/', {}, { 'HTTP_HOST' => 'example.com' } + assert ran + end + + it 'is possible to apply host_name conditions to after filters with a path' do + ran = false + mock_app do + after('/foo', :host_name => 'example.com') { ran = true } + get('/') { 'welcome' } + end + get '/', {}, { 'HTTP_HOST' => 'example.com' } + assert !ran + get '/foo', {}, { 'HTTP_HOST' => 'example.org' } + assert !ran + get '/foo', {}, { 'HTTP_HOST' => 'example.com' } + assert ran + end + + it 'is possible to apply user_agent conditions to before filters with no path' do + ran = false + mock_app do + before(:user_agent => /foo/) { ran = true } + get('/') { 'welcome' } + end + get '/', {}, { 'HTTP_USER_AGENT' => 'bar' } + assert !ran + get '/', {}, { 'HTTP_USER_AGENT' => 'foo' } + assert ran + end + + it 'is possible to apply user_agent conditions to before filters with a path' do + ran = false + mock_app do + before('/foo', :user_agent => /foo/) { ran = true } + get('/') { 'welcome' } + end + get '/', {}, { 'HTTP_USER_AGENT' => 'foo' } + assert !ran + get '/foo', {}, { 'HTTP_USER_AGENT' => 'bar' } + assert !ran + get '/foo', {}, { 'HTTP_USER_AGENT' => 'foo' } + assert ran + end + + it 'is possible to apply user_agent conditions to after filters with no path' do + ran = false + mock_app do + after(:user_agent => /foo/) { ran = true } + get('/') { 'welcome' } + end + get '/', {}, { 'HTTP_USER_AGENT' => 'bar' } + assert !ran + get '/', {}, { 'HTTP_USER_AGENT' => 'foo' } + assert ran + end + + it 'is possible to apply user_agent conditions to before filters with a path' do + ran = false + mock_app do + after('/foo', :user_agent => /foo/) { ran = true } + get('/') { 'welcome' } + end + get '/', {}, { 'HTTP_USER_AGENT' => 'foo' } + assert !ran + get '/foo', {}, { 'HTTP_USER_AGENT' => 'bar' } + assert !ran + get '/foo', {}, { 'HTTP_USER_AGENT' => 'foo' } + assert ran + end end