mirror of
https://gitea.invidious.io/iv-org/shard-kemal.git
synced 2024-08-15 00:53:36 +00:00
Merge pull request #106 from jmoriau/added-feature-to-filters
Ability to add many blocks per route filter
This commit is contained in:
commit
43d34886c4
2 changed files with 65 additions and 26 deletions
|
@ -143,6 +143,46 @@ describe "Kemal::Middleware::Filters" do
|
||||||
client_response = HTTP::Client::Response.from_io(io_with_context, decompress: false)
|
client_response = HTTP::Client::Response.from_io(io_with_context, decompress: false)
|
||||||
client_response.body.should eq("false")
|
client_response.body.should eq("false")
|
||||||
end
|
end
|
||||||
|
|
||||||
|
it "executes 3 differents blocks after all request" do
|
||||||
|
test_filter = FilterTest.new
|
||||||
|
test_filter.modified = "false"
|
||||||
|
test_filter_second = FilterTest.new
|
||||||
|
test_filter_second.modified = "false"
|
||||||
|
test_filter_third = FilterTest.new
|
||||||
|
test_filter_third.modified = "false"
|
||||||
|
|
||||||
|
filter_middleware = Kemal::Middleware::Filter.new
|
||||||
|
filter_middleware._add_route_filter("ALL", "/greetings", :before) { test_filter.modified = test_filter.modified == "true" ? "false" : "true" }
|
||||||
|
filter_middleware._add_route_filter("ALL", "/greetings", :before) { test_filter_second.modified = test_filter_second.modified == "true" ? "false" : "true" }
|
||||||
|
filter_middleware._add_route_filter("ALL", "/greetings", :before) { test_filter_third.modified = test_filter_third.modified == "true" ? "false" : "true" }
|
||||||
|
|
||||||
|
kemal = Kemal::RouteHandler::INSTANCE
|
||||||
|
kemal.add_route "GET", "/greetings" { test_filter.modified }
|
||||||
|
kemal.add_route "POST", "/greetings" { test_filter_second.modified }
|
||||||
|
kemal.add_route "PUT", "/greetings" { test_filter_third.modified }
|
||||||
|
|
||||||
|
test_filter.modified.should eq("false")
|
||||||
|
test_filter_second.modified.should eq("false")
|
||||||
|
test_filter_third.modified.should eq("false")
|
||||||
|
request = HTTP::Request.new("GET", "/greetings")
|
||||||
|
create_request_and_return_io(filter_middleware, request)
|
||||||
|
io_with_context = create_request_and_return_io(kemal, request)
|
||||||
|
client_response = HTTP::Client::Response.from_io(io_with_context, decompress: false)
|
||||||
|
client_response.body.should eq("true")
|
||||||
|
|
||||||
|
request = HTTP::Request.new("POST", "/greetings")
|
||||||
|
create_request_and_return_io(filter_middleware, request)
|
||||||
|
io_with_context = create_request_and_return_io(kemal, request)
|
||||||
|
client_response = HTTP::Client::Response.from_io(io_with_context, decompress: false)
|
||||||
|
client_response.body.should eq("false")
|
||||||
|
|
||||||
|
request = HTTP::Request.new("PUT", "/greetings")
|
||||||
|
create_request_and_return_io(filter_middleware, request)
|
||||||
|
io_with_context = create_request_and_return_io(kemal, request)
|
||||||
|
client_response = HTTP::Client::Response.from_io(io_with_context, decompress: false)
|
||||||
|
client_response.body.should eq("true")
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
class FilterTest
|
class FilterTest
|
||||||
|
|
|
@ -21,55 +21,50 @@ module Kemal::Middleware
|
||||||
context
|
context
|
||||||
end
|
end
|
||||||
|
|
||||||
# This checks is filter is already defined for the verb/path/type combination
|
|
||||||
def filter_for_path_type_defined?(verb, path, type)
|
|
||||||
lookup = @tree.find radix_path(verb, path, type)
|
|
||||||
lookup.found? && lookup.payload.is_a? Block
|
|
||||||
end
|
|
||||||
|
|
||||||
# :nodoc: This shouldn't be called directly, it's not private because I need to call it for testing purpose since I can't call the macros in the spec.
|
# :nodoc: This shouldn't be called directly, it's not private because I need to call it for testing purpose since I can't call the macros in the spec.
|
||||||
# It adds the block for the corresponding verb/path/type combination to the tree.
|
# It adds the block for the corresponding verb/path/type combination to the tree.
|
||||||
def _add_route_filter(verb, path, type, &block : HTTP::Server::Context -> _)
|
def _add_route_filter(verb, path, type, &block : HTTP::Server::Context -> _)
|
||||||
node = radix_path(verb, path, type)
|
lookup = lookup_filters_for_path_type(verb, path, type)
|
||||||
@tree.add node, Block.new &block
|
if lookup.found? && lookup.payload.is_a?(Array(Block))
|
||||||
|
(lookup.payload as Array(Block)) << Block.new(&block)
|
||||||
|
else
|
||||||
|
@tree.add radix_path(verb, path, type), [Block.new(&block)]
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
# This can be called directly but it's simpler to just use the macros, it will check if another filter is not already defined for this verb/path/type and proceed to call `add_route_filter`
|
# This can be called directly but it's simpler to just use the macros, it will check if another filter is not already defined for this verb/path/type and proceed to call `add_route_filter`
|
||||||
def before(verb, path = "*", &block : HTTP::Server::Context -> _)
|
def before(verb, path = "*", &block : HTTP::Server::Context -> _)
|
||||||
raise Kemal::Middleware::Filter::BeforeFilterAlreadyDefinedException.new(verb, path) if filter_for_path_type_defined?(verb, path, :before)
|
|
||||||
_add_route_filter verb, path, :before, &block
|
_add_route_filter verb, path, :before, &block
|
||||||
end
|
end
|
||||||
|
|
||||||
# This can be called directly but it's simpler to just use the macros, it will check if another filter is not already defined for this verb/path/type and proceed to call `add_route_filter`
|
# This can be called directly but it's simpler to just use the macros, it will check if another filter is not already defined for this verb/path/type and proceed to call `add_route_filter`
|
||||||
def after(verb, path = "*", &block : HTTP::Server::Context -> _)
|
def after(verb, path = "*", &block : HTTP::Server::Context -> _)
|
||||||
raise Kemal::Middleware::Filter::AfterFilterAlreadyDefinedException.new(verb, path) if filter_for_path_type_defined?(verb, path, :after)
|
|
||||||
_add_route_filter verb, path, :after, &block
|
_add_route_filter verb, path, :after, &block
|
||||||
end
|
end
|
||||||
|
|
||||||
# This will fetch the block for the verb/path/type from the tree and call it.
|
# This will fetch the block for the verb/path/type from the tree and call it.
|
||||||
private def call_block_for_path_type(verb, path, type, context)
|
private def call_block_for_path_type(verb, path, type, context)
|
||||||
lookup = @tree.find radix_path(verb, path, type)
|
lookup = lookup_filters_for_path_type(verb, path, type)
|
||||||
if lookup.found? && lookup.payload.is_a? Block
|
if lookup.found? && lookup.payload.is_a? Array(Block)
|
||||||
block = lookup.payload as Block
|
blocks = lookup.payload as Array(Block)
|
||||||
block.block.call(context)
|
blocks.each { |block| block.call(context) }
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# This checks is filter is already defined for the verb/path/type combination
|
||||||
|
private def filter_for_path_type_defined?(verb, path, type)
|
||||||
|
lookup = @tree.find radix_path(verb, path, type)
|
||||||
|
lookup.found? && lookup.payload.is_a? Block
|
||||||
|
end
|
||||||
|
|
||||||
|
# This returns a lookup for verb/path/type
|
||||||
|
private def lookup_filters_for_path_type(verb, path, type)
|
||||||
|
@tree.find radix_path(verb, path, type)
|
||||||
|
end
|
||||||
|
|
||||||
private def radix_path(verb, path, type : Symbol)
|
private def radix_path(verb, path, type : Symbol)
|
||||||
"#{type}/#{verb}/#{path}"
|
"#{type}/#{verb}/#{path}"
|
||||||
end
|
end
|
||||||
|
|
||||||
class BeforeFilterAlreadyDefinedException < Exception
|
|
||||||
def initialize(verb, path)
|
|
||||||
super "A before-filter is already defined for path: '#{verb}:#{path}'."
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
class AfterFilterAlreadyDefinedException < Exception
|
|
||||||
def initialize(verb, path)
|
|
||||||
super "An after-filter is already defined for path: '#{verb}:#{path}'."
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
end
|
||||||
|
|
||||||
class Block
|
class Block
|
||||||
|
@ -77,6 +72,10 @@ module Kemal::Middleware
|
||||||
|
|
||||||
def initialize(&@block : HTTP::Server::Context -> _)
|
def initialize(&@block : HTTP::Server::Context -> _)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def call(context)
|
||||||
|
@block.call(context)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue