所以我的理解是halt命令应该在当前过滤器中停止请求,但它似乎继续。接下来是一个非常简单的Sinatra应用程序来证明这一点。
server.rb
require 'sinatra'
before do
puts "before halt"
halt 401
puts "after halt"
end
before '/partners*' do
puts "i am in before /partners"
end
after '/partners*' do
puts "i am in after /partners"
end
get '/partners/v1/:public_id' do
puts "i am in the actual route"
end
我在以下位置打电话给'get':localhost:4567/partners/v1/111
我希望输出的内容:
before halt
实际输出的是什么:
before halt
i am in after /partners
所以我的问题正是如此:
1.为什么停止继续(显示达到after '/partners*'
)
2.为什么它会点击after '/partners*'
而不是before '/partners*'
答案 0 :(得分:1)
Here is the code for halt
和here is the code for invoke
,invoke
下面是the method declaration for dispatch!
如您所见,dispatch!
调用invoke
,它运行路径块并支持halt
。它还会在:before
块中运行invoke
过滤器。
invoke do
static! if settings.static? && (request.get? || request.head?)
filter! :before
route!
所以你可以在halt
过滤器中before
并且它不会到达路线,这就是为什么你看不到路线块的任何输出。
但是,dispatch!
方法也有ensure
:
ensure
begin
filter! :after unless env['sinatra.static_file']
ensure
执行它所说的内容,将始终对其进行评估。这就是处理after '/partners*'
块的原因。这是预期的行为(因为它的编码非常清楚)。基本上,如果你输入一个after
块,无论halt
过滤器或路由块中的before
是什么,它都会得到处理。
来自文档:
路由按照定义的顺序进行匹配。调用与请求匹配的第一个路由。
...在与路径相同的上下文中的每个请求之前评估过滤器
现在,文档并没有明确说明这一点,但如果你将这两个引号加在一起,我会认为“过滤器按照它们的定义顺序匹配”。基本上,因为它符合实际行为。
所有before
过滤器都应该运行,但是您在第一个过滤器中放置了halt
,因此第二个过滤器(before '/partners*'
)不会运行。