kemal/src/kemal/handler.cr

76 lines
2.6 KiB
Crystal
Raw Normal View History

2017-03-03 20:56:29 +00:00
module Kemal
# `Kemal::Handler` is a subclass of `HTTP::Handler`.
2017-10-06 11:53:53 +00:00
#
2017-03-03 20:56:29 +00:00
# It adds `only`, `only_match?`, `exclude`, `exclude_match?`.
# These methods are useful for custom handlers for conditional execution.
class Handler
include HTTP::Handler
@@only_routes_tree = Radix::Tree(String).new
@@exclude_routes_tree = Radix::Tree(String).new
2017-03-03 20:56:29 +00:00
macro only(paths, method = "GET")
2017-10-06 11:55:37 +00:00
class_name = {{@type.name}}
({{paths}}).each do |path|
@@only_routes_tree.add "#{class_name}/#{{{method}}.downcase}#{path}", "/#{{{method}}.downcase}#{path}"
end
end
2017-03-03 20:56:29 +00:00
macro exclude(paths, method = "GET")
2017-10-06 11:55:37 +00:00
class_name = {{@type.name}}
({{paths}}).each do |path|
@@exclude_routes_tree.add "#{class_name}/#{{{method}}.downcase}#{path}", "/#{{{method}}.downcase}#{path}"
end
end
2017-08-25 13:41:02 +00:00
def call(env : HTTP::Server::Context)
2017-03-03 20:56:29 +00:00
call_next(env)
end
2017-03-03 20:56:29 +00:00
# Processes the path based on `only` paths which is a `Array(String)`.
# If the path is not found on `only` conditions the handler will continue processing.
# If the path is found in `only` conditions it'll stop processing and will pass the request
# to next handler.
#
# However this is not done automatically. All handlers must inherit from `Kemal::Handler`.
#
2017-10-06 11:53:53 +00:00
# ```
# class OnlyHandler < Kemal::Handler
# only ["/"]
2017-03-03 20:56:29 +00:00
#
2017-10-06 11:53:53 +00:00
# def call(env)
# return call_next(env) unless only_match?(env)
# puts "If the path is / i will be doing some processing here."
# end
# end
# ```
2017-08-25 13:41:02 +00:00
def only_match?(env : HTTP::Server::Context)
2017-03-03 20:56:29 +00:00
@@only_routes_tree.find(radix_path(env.request.method, env.request.path)).found?
end
2017-03-03 20:56:29 +00:00
# Processes the path based on `exclude` paths which is a `Array(String)`.
# If the path is not found on `exclude` conditions the handler will continue processing.
# If the path is found in `exclude` conditions it'll stop processing and will pass the request
# to next handler.
#
# However this is not done automatically. All handlers must inherit from `Kemal::Handler`.
#
2017-10-06 11:53:53 +00:00
# ```
# class ExcludeHandler < Kemal::Handler
# exclude ["/"]
2017-03-03 20:56:29 +00:00
#
2017-10-06 11:53:53 +00:00
# def call(env)
# return call_next(env) if exclude_match?(env)
# puts "If the path is not / i will be doing some processing here."
# end
# end
# ```
2017-08-25 13:41:02 +00:00
def exclude_match?(env : HTTP::Server::Context)
2017-03-03 20:56:29 +00:00
@@exclude_routes_tree.find(radix_path(env.request.method, env.request.path)).found?
end
2017-08-24 20:32:43 +00:00
private def radix_path(method : String, path : String)
2017-03-03 20:56:29 +00:00
"#{self.class}/#{method.downcase}#{path}"
end
end
end