Merge pull request #76 from werner/feature/middlewares/filters
Basic filter implementation, similar to Sinatra.
This commit is contained in:
commit
e310de4f8a
2 changed files with 77 additions and 0 deletions
25
spec/middleware/filters_spec.cr
Normal file
25
spec/middleware/filters_spec.cr
Normal file
|
@ -0,0 +1,25 @@
|
||||||
|
require "../spec_helper"
|
||||||
|
|
||||||
|
describe "Kemal::Middleware::Filters" do
|
||||||
|
it "executes code before home request" do
|
||||||
|
test_filter = FilterTest.new
|
||||||
|
test_filter.modified = "false"
|
||||||
|
|
||||||
|
filter = Kemal::Middleware::Filter.new
|
||||||
|
filter.add :before, "/greetings", {} of Symbol => String { test_filter.modified = "true" }
|
||||||
|
|
||||||
|
kemal = Kemal::RouteHandler.new
|
||||||
|
kemal.add_route "GET", "/greetings" { test_filter.modified }
|
||||||
|
|
||||||
|
test_filter.modified.should eq("false")
|
||||||
|
request = HTTP::Request.new("GET", "/greetings")
|
||||||
|
create_request_and_return_io(filter, 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
|
||||||
|
|
||||||
|
class FilterTest
|
||||||
|
property modified
|
||||||
|
end
|
52
src/kemal/middleware/filters.cr
Normal file
52
src/kemal/middleware/filters.cr
Normal file
|
@ -0,0 +1,52 @@
|
||||||
|
module Kemal::Middleware
|
||||||
|
# Kemal::Filter handle all code that should be evaluated before and after
|
||||||
|
# every request
|
||||||
|
class Filter < HTTP::Handler
|
||||||
|
def initialize
|
||||||
|
@tree = Radix::Tree.new
|
||||||
|
end
|
||||||
|
|
||||||
|
def add(type, path, options, &block : HTTP::Server::Context -> _)
|
||||||
|
node = radix_path type, path
|
||||||
|
@tree.add node, Block.new &block
|
||||||
|
end
|
||||||
|
|
||||||
|
def call(context)
|
||||||
|
process_filter(context, :before)
|
||||||
|
call_next(context)
|
||||||
|
process_filter(context, :after)
|
||||||
|
end
|
||||||
|
|
||||||
|
private def process_filter(context, type)
|
||||||
|
lookup = @tree.find radix_path(type, context.request.path)
|
||||||
|
if lookup.found? && lookup.payload.is_a? Block
|
||||||
|
block = lookup.payload as Block
|
||||||
|
block.block.call(context)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
private def radix_path(type : Symbol, path)
|
||||||
|
"/#{type}#{path}"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
class Block
|
||||||
|
property block
|
||||||
|
def initialize(&@block : HTTP::Server::Context -> _)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def add_filters
|
||||||
|
Kemal.config.add_handler Kemal::Filters::Filter.new
|
||||||
|
end
|
||||||
|
|
||||||
|
def before(path = "*", options = {} of Symbol => String, &block : HTTP::Server::Context -> _)
|
||||||
|
filter = Kemal.config.handlers.first as Kemal::Filters::Filter
|
||||||
|
filter.add :before, path, options, &block
|
||||||
|
end
|
||||||
|
|
||||||
|
def after(path = "*", options = {} of Symbol => String, &block : HTTP::Server::Context -> _)
|
||||||
|
filter = Kemal.config.handlers.first as Kemal::Filters::Filter
|
||||||
|
filter.add :after, path, options, &block
|
||||||
|
end
|
Loading…
Reference in a new issue