mirror of
https://gitea.invidious.io/iv-org/shard-kemal.git
synced 2024-08-15 00:53:36 +00:00
Extract Base::Builder and Base::DSL from Kemal::Base
This commit is contained in:
parent
f5c80c7b67
commit
29b18c927c
7 changed files with 223 additions and 143 deletions
|
@ -38,7 +38,7 @@ describe "Config" do
|
|||
application = Kemal::Application.new
|
||||
application.add_handler CustomTestHandler.new
|
||||
application.setup
|
||||
application.handlers.size.should eq 9
|
||||
application.handlers.size.should eq 8
|
||||
end
|
||||
|
||||
it "toggles the shutdown message" do
|
||||
|
|
|
@ -12,7 +12,7 @@ describe "Macros" do
|
|||
it "adds a custom handler" do
|
||||
add_handler CustomTestHandler.new
|
||||
Kemal.application.setup
|
||||
Kemal.application.handlers.size.should eq 7
|
||||
Kemal.application.handlers.size.should eq 8
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
class Kemal::Application < Kemal::Base
|
||||
def initialize(config = Config.default)
|
||||
super config
|
||||
add_filter_handler(filter_handler)
|
||||
super(config)
|
||||
end
|
||||
|
||||
# Overload of self.run with the default startup logging
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
require "./helpers/*"
|
||||
require "./base/*"
|
||||
|
||||
# Kemal Base
|
||||
# The DSL currently consists of
|
||||
|
@ -10,19 +11,18 @@ class Kemal::Base
|
|||
include FileHelpers
|
||||
include Templates
|
||||
include Macros
|
||||
include Base::DSL
|
||||
include Base::Builder
|
||||
|
||||
HTTP_METHODS = %w(get post put patch delete options)
|
||||
FILTER_METHODS = %w(get post put patch delete options all)
|
||||
|
||||
# :nodoc:
|
||||
getter route_handler = Kemal::RouteHandler.new
|
||||
# :nodoc:
|
||||
getter filter_handler = Kemal::FilterHandler.new
|
||||
# :nodoc:
|
||||
getter websocket_handler = Kemal::WebSocketHandler.new
|
||||
|
||||
getter handlers = [] of HTTP::Handler
|
||||
getter custom_handlers = [] of Tuple(Nil | Int32, HTTP::Handler)
|
||||
getter filter_handlers = [] of HTTP::Handler
|
||||
getter error_handlers = {} of Int32 => HTTP::Server::Context, Exception -> String
|
||||
@handler_position = 0
|
||||
|
||||
getter config : Config
|
||||
|
||||
|
@ -31,133 +31,11 @@ class Kemal::Base
|
|||
property? running = false
|
||||
|
||||
def initialize(@config = Config.base)
|
||||
@logger = if @config.logging?
|
||||
Kemal::LogHandler.new
|
||||
else
|
||||
Kemal::NullLogHandler.new
|
||||
end
|
||||
add_filter_handler(filter_handler)
|
||||
end
|
||||
@filter_handler = FilterHandler.new(self)
|
||||
@route_handler = RouteHandler.new(self)
|
||||
@websocket_handler = WebSocketHandler.new(self)
|
||||
|
||||
{% for method in HTTP_METHODS %}
|
||||
def {{method.id}}(path, &block : HTTP::Server::Context -> _)
|
||||
raise Kemal::Exceptions::InvalidPathStartException.new({{method}}, path) unless Kemal::Utils.path_starts_with_slash?(path)
|
||||
route_handler.add_route({{method}}.upcase, path, &block)
|
||||
end
|
||||
{% end %}
|
||||
|
||||
def ws(path, &block : HTTP::WebSocket, HTTP::Server::Context -> Void)
|
||||
raise Kemal::Exceptions::InvalidPathStartException.new("ws", path) unless Kemal::Utils.path_starts_with_slash?(path)
|
||||
websocket_handler.add_route path, &block
|
||||
end
|
||||
|
||||
def error(status_code, &block : HTTP::Server::Context, Exception -> _)
|
||||
add_error_handler status_code, &block
|
||||
end
|
||||
|
||||
# All the helper methods available are:
|
||||
# - before_all, before_get, before_post, before_put, before_patch, before_delete, before_options
|
||||
# - after_all, after_get, after_post, after_put, after_patch, after_delete, after_options
|
||||
{% for type in ["before", "after"] %}
|
||||
{% for method in FILTER_METHODS %}
|
||||
def {{type.id}}_{{method.id}}(path = "*", &block : HTTP::Server::Context -> _)
|
||||
filter_handler.{{type.id}}({{method}}.upcase, path, &block)
|
||||
end
|
||||
{% end %}
|
||||
{% end %}
|
||||
|
||||
def clear
|
||||
@router_included = false
|
||||
@handler_position = 0
|
||||
@default_handlers_setup = false
|
||||
|
||||
handlers.clear
|
||||
custom_handlers.clear
|
||||
filter_handlers.clear
|
||||
error_handlers.clear
|
||||
|
||||
route_handler.clear
|
||||
websocket_handler.clear
|
||||
end
|
||||
|
||||
def handlers=(handlers : Array(HTTP::Handler))
|
||||
clear
|
||||
@handlers.replace(handlers)
|
||||
end
|
||||
|
||||
def add_handler(handler : HTTP::Handler)
|
||||
@custom_handlers << {nil, handler}
|
||||
end
|
||||
|
||||
def add_handler(handler : HTTP::Handler, position : Int32)
|
||||
@custom_handlers << {position, handler}
|
||||
end
|
||||
|
||||
def add_filter_handler(handler : HTTP::Handler)
|
||||
@filter_handlers << handler
|
||||
end
|
||||
|
||||
def add_error_handler(status_code, &handler : HTTP::Server::Context, Exception -> _)
|
||||
@error_handlers[status_code] = ->(context : HTTP::Server::Context, error : Exception) { handler.call(context, error).to_s }
|
||||
end
|
||||
|
||||
def setup
|
||||
unless @default_handlers_setup && @router_included
|
||||
setup_init_handler
|
||||
setup_log_handler
|
||||
setup_error_handler
|
||||
setup_static_file_handler
|
||||
setup_custom_handlers
|
||||
setup_filter_handlers
|
||||
@default_handlers_setup = true
|
||||
@router_included = true
|
||||
handlers.insert(handlers.size, websocket_handler)
|
||||
handlers.insert(handlers.size, route_handler)
|
||||
end
|
||||
end
|
||||
|
||||
private def setup_init_handler
|
||||
@handlers.insert(@handler_position, Kemal::InitHandler.new(self))
|
||||
@handler_position += 1
|
||||
end
|
||||
|
||||
private def setup_log_handler
|
||||
@handlers.insert(@handler_position, logger)
|
||||
@handler_position += 1
|
||||
end
|
||||
|
||||
private def setup_error_handler
|
||||
if @config.always_rescue?
|
||||
@error_handler ||= Kemal::ExceptionHandler.new
|
||||
@handlers.insert(@handler_position, @error_handler.not_nil!)
|
||||
@handler_position += 1
|
||||
end
|
||||
end
|
||||
|
||||
private def setup_static_file_handler
|
||||
if @config.serve_static.is_a?(Hash)
|
||||
@handlers.insert(@handler_position, Kemal::StaticFileHandler.new(@config.public_folder))
|
||||
@handler_position += 1
|
||||
end
|
||||
end
|
||||
|
||||
private def setup_custom_handlers
|
||||
@custom_handlers.each do |ch|
|
||||
position = ch[0]
|
||||
if !position
|
||||
@handlers.insert(@handler_position, ch[1])
|
||||
@handler_position += 1
|
||||
else
|
||||
@handlers.insert(position, ch[1])
|
||||
@handler_position += 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private def setup_filter_handlers
|
||||
@filter_handlers.each do |h|
|
||||
@handlers.insert(@handler_position, h)
|
||||
end
|
||||
initialize_defaults
|
||||
end
|
||||
|
||||
# Overload of self.run with the default startup logging
|
||||
|
@ -180,6 +58,11 @@ class Kemal::Base
|
|||
end
|
||||
end
|
||||
|
||||
# DEPRECATED: This method should be replaced with `#running?`
|
||||
def running
|
||||
running?
|
||||
end
|
||||
|
||||
private def prepare_for_server_start
|
||||
unless @config.env == "test"
|
||||
Signal::INT.trap do
|
||||
|
|
108
src/kemal/base/builder.cr
Normal file
108
src/kemal/base/builder.cr
Normal file
|
@ -0,0 +1,108 @@
|
|||
class Kemal::Base
|
||||
module Builder
|
||||
getter custom_handlers = [] of Tuple(Nil | Int32, HTTP::Handler)
|
||||
getter filter_handlers = [] of HTTP::Handler
|
||||
@handler_position = 0
|
||||
|
||||
def clear
|
||||
@router_included = false
|
||||
@handler_position = 0
|
||||
@default_handlers_setup = false
|
||||
|
||||
handlers.clear
|
||||
custom_handlers.clear
|
||||
filter_handlers.clear
|
||||
error_handlers.clear
|
||||
|
||||
route_handler.clear
|
||||
websocket_handler.clear
|
||||
end
|
||||
|
||||
def handlers=(handlers : Array(HTTP::Handler))
|
||||
clear
|
||||
@handlers.replace(handlers)
|
||||
end
|
||||
|
||||
def add_handler(handler : HTTP::Handler)
|
||||
@custom_handlers << {nil, handler}
|
||||
end
|
||||
|
||||
def add_handler(handler : HTTP::Handler, position : Int32)
|
||||
@custom_handlers << {position, handler}
|
||||
end
|
||||
|
||||
def add_filter_handler(handler : HTTP::Handler)
|
||||
@filter_handlers << handler
|
||||
end
|
||||
|
||||
def add_error_handler(status_code, &handler : HTTP::Server::Context, Exception -> _)
|
||||
@error_handlers[status_code] = ->(context : HTTP::Server::Context, error : Exception) { handler.call(context, error).to_s }
|
||||
end
|
||||
|
||||
def setup
|
||||
@logger = if @config.logging?
|
||||
LogHandler.new
|
||||
else
|
||||
NullLogHandler.new
|
||||
end
|
||||
unless @default_handlers_setup && @router_included
|
||||
setup_init_handler
|
||||
setup_log_handler
|
||||
setup_error_handler
|
||||
setup_static_file_handler
|
||||
setup_custom_handlers
|
||||
setup_filter_handlers
|
||||
@default_handlers_setup = true
|
||||
@router_included = true
|
||||
handlers.insert(handlers.size, websocket_handler)
|
||||
handlers.insert(handlers.size, route_handler)
|
||||
end
|
||||
end
|
||||
|
||||
private def setup_init_handler
|
||||
@handlers.insert(@handler_position, Kemal::InitHandler.new(self))
|
||||
@handler_position += 1
|
||||
end
|
||||
|
||||
private def setup_log_handler
|
||||
@handlers.insert(@handler_position, logger)
|
||||
@handler_position += 1
|
||||
end
|
||||
|
||||
private def setup_error_handler
|
||||
if @config.always_rescue?
|
||||
error_handler = @error_handler ||= Kemal::ExceptionHandler.new
|
||||
@handlers.insert(@handler_position, error_handler)
|
||||
@handler_position += 1
|
||||
end
|
||||
end
|
||||
|
||||
private def setup_static_file_handler
|
||||
if @config.serve_static.is_a?(Hash)
|
||||
@handlers.insert(@handler_position, Kemal::StaticFileHandler.new(@config.public_folder))
|
||||
@handler_position += 1
|
||||
end
|
||||
end
|
||||
|
||||
# Handle WebSocketHandler
|
||||
private def setup_custom_handlers
|
||||
@custom_handlers.each do |ch|
|
||||
position = ch[0]
|
||||
if !position
|
||||
@handlers.insert(@handler_position, ch[1])
|
||||
@handler_position += 1
|
||||
else
|
||||
@handlers.insert(position, ch[1])
|
||||
@handler_position += 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
private def setup_filter_handlers
|
||||
@handlers.insert(@handler_position, filter_handler)
|
||||
@filter_handlers.each do |h|
|
||||
@handlers.insert(@handler_position, h)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
91
src/kemal/base/dsl.cr
Normal file
91
src/kemal/base/dsl.cr
Normal file
|
@ -0,0 +1,91 @@
|
|||
class Kemal::Base
|
||||
module DSL
|
||||
HTTP_METHODS = %w(get post put patch delete options)
|
||||
FILTER_METHODS = %w(get post put patch delete options all)
|
||||
|
||||
macro included
|
||||
# :nodoc:
|
||||
DEFAULT_HANDLERS = [] of {String, String, (HTTP::Server::Context -> Nil)}
|
||||
# :nodoc:
|
||||
WEBSOCKET_HANDLERS = [] of {String, (HTTP::WebSocket, HTTP::Server::Context -> Void)}
|
||||
# :nodoc:
|
||||
DEFAULT_ERROR_HANDLERS = [] of {Int32, (HTTP::Server::Context, Exception -> Nil)}
|
||||
# :nodoc:
|
||||
DEFAULT_FILTERS = [] of {Symbol, String, String, (HTTP::Server::Context -> Nil)}
|
||||
end
|
||||
|
||||
{% for method in HTTP_METHODS %}
|
||||
def {{method.id}}(path, &block : HTTP::Server::Context -> _)
|
||||
raise Kemal::Exceptions::InvalidPathStartException.new({{method}}, path) unless Kemal::Utils.path_starts_with_slash?(path)
|
||||
route_handler.add_route({{method}}.upcase, path, &block)
|
||||
end
|
||||
{% end %}
|
||||
|
||||
def ws(path, &block : HTTP::WebSocket, HTTP::Server::Context -> Void)
|
||||
raise Kemal::Exceptions::InvalidPathStartException.new("ws", path) unless Kemal::Utils.path_starts_with_slash?(path)
|
||||
websocket_handler.add_route path, &block
|
||||
end
|
||||
|
||||
def error(status_code, &block : HTTP::Server::Context, Exception -> _)
|
||||
add_error_handler status_code, &block
|
||||
end
|
||||
|
||||
# All the helper methods available are:
|
||||
# - before_all, before_get, before_post, before_put, before_patch, before_delete, before_options
|
||||
# - after_all, after_get, after_post, after_put, after_patch, after_delete, after_options
|
||||
{% for type in ["before", "after"] %}
|
||||
{% for method in FILTER_METHODS %}
|
||||
def {{type.id}}_{{method.id}}(path = "*", &block : HTTP::Server::Context -> _)
|
||||
filter_handler.{{type.id}}({{method}}.upcase, path, &block)
|
||||
end
|
||||
{% end %}
|
||||
{% end %}
|
||||
|
||||
private def initialize_defaults
|
||||
DEFAULT_HANDLERS.each do |method, path, block|
|
||||
route_handler.add_route(method.upcase, path, &block)
|
||||
end
|
||||
|
||||
WEBSOCKET_HANDLERS.each do |path, block|
|
||||
ws(path, &block)
|
||||
end
|
||||
|
||||
DEFAULT_ERROR_HANDLERS.each do |status_code, block|
|
||||
add_error_handler status_code, &block
|
||||
end
|
||||
|
||||
DEFAULT_FILTERS.each do |type, method, path, block|
|
||||
if type == :before
|
||||
filter_handler.before(method, path, &block)
|
||||
else
|
||||
filter_handler.after(method, path, &block)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
{% for method in HTTP_METHODS %}
|
||||
def self.{{method.id}}(path, &block : HTTP::Server::Context -> _)
|
||||
DEFAULT_HANDLERS << { {{method}}, path, block }
|
||||
end
|
||||
{% end %}
|
||||
|
||||
def self.ws(path, &block : HTTP::WebSocket, HTTP::Server::Context -> Void)
|
||||
WEBSOCKET_HANDLERS << {path, block}
|
||||
end
|
||||
|
||||
def self.error(status_code, &block : HTTP::Server::Context, Exception -> _)
|
||||
DEFAULT_ERROR_HANDLERS << {status_code, block}
|
||||
end
|
||||
|
||||
# All the helper methods available are:
|
||||
# - before_all, before_get, before_post, before_put, before_patch, before_delete, before_options
|
||||
# - after_all, after_get, after_post, after_put, after_patch, after_delete, after_options
|
||||
{% for type in [:before, :after] %}
|
||||
{% for method in FILTER_METHODS %}
|
||||
def self.{{type.id}}_{{method.id}}(path = "*", &block : HTTP::Server::Context -> _)
|
||||
DEFAULT_FILTERS << { {{type}}, {{method}}, path, block }
|
||||
end
|
||||
{% end %}
|
||||
{% end %}
|
||||
end
|
||||
end
|
|
@ -54,7 +54,6 @@ module Kemal
|
|||
(config.is_a?(Hash) && config[key]?) || false
|
||||
end
|
||||
|
||||
|
||||
def extra_options(&@extra_options : OptionParser ->)
|
||||
end
|
||||
|
||||
|
@ -65,12 +64,12 @@ module Kemal
|
|||
|
||||
# Creates a config with basic value (disabled logging, disabled serve_static, disabled shutdown_message)
|
||||
def self.base
|
||||
new.tap do |config|
|
||||
config.logging = false
|
||||
config.serve_static = false
|
||||
config.shutdown_message = false
|
||||
config.always_rescue = false
|
||||
end
|
||||
new(
|
||||
logging: false,
|
||||
serve_static: false,
|
||||
shutdown_message: false,
|
||||
always_rescue: false,
|
||||
)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue