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 = Kemal::Application.new
|
||||||
application.add_handler CustomTestHandler.new
|
application.add_handler CustomTestHandler.new
|
||||||
application.setup
|
application.setup
|
||||||
application.handlers.size.should eq 9
|
application.handlers.size.should eq 8
|
||||||
end
|
end
|
||||||
|
|
||||||
it "toggles the shutdown message" do
|
it "toggles the shutdown message" do
|
||||||
|
|
|
@ -12,7 +12,7 @@ describe "Macros" do
|
||||||
it "adds a custom handler" do
|
it "adds a custom handler" do
|
||||||
add_handler CustomTestHandler.new
|
add_handler CustomTestHandler.new
|
||||||
Kemal.application.setup
|
Kemal.application.setup
|
||||||
Kemal.application.handlers.size.should eq 7
|
Kemal.application.handlers.size.should eq 8
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
class Kemal::Application < Kemal::Base
|
class Kemal::Application < Kemal::Base
|
||||||
def initialize(config = Config.default)
|
def initialize(config = Config.default)
|
||||||
super config
|
super(config)
|
||||||
add_filter_handler(filter_handler)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Overload of self.run with the default startup logging
|
# Overload of self.run with the default startup logging
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
require "./helpers/*"
|
require "./helpers/*"
|
||||||
|
require "./base/*"
|
||||||
|
|
||||||
# Kemal Base
|
# Kemal Base
|
||||||
# The DSL currently consists of
|
# The DSL currently consists of
|
||||||
|
@ -10,19 +11,18 @@ class Kemal::Base
|
||||||
include FileHelpers
|
include FileHelpers
|
||||||
include Templates
|
include Templates
|
||||||
include Macros
|
include Macros
|
||||||
|
include Base::DSL
|
||||||
|
include Base::Builder
|
||||||
|
|
||||||
HTTP_METHODS = %w(get post put patch delete options)
|
# :nodoc:
|
||||||
FILTER_METHODS = %w(get post put patch delete options all)
|
|
||||||
|
|
||||||
getter route_handler = Kemal::RouteHandler.new
|
getter route_handler = Kemal::RouteHandler.new
|
||||||
|
# :nodoc:
|
||||||
getter filter_handler = Kemal::FilterHandler.new
|
getter filter_handler = Kemal::FilterHandler.new
|
||||||
|
# :nodoc:
|
||||||
getter websocket_handler = Kemal::WebSocketHandler.new
|
getter websocket_handler = Kemal::WebSocketHandler.new
|
||||||
|
|
||||||
getter handlers = [] of HTTP::Handler
|
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
|
getter error_handlers = {} of Int32 => HTTP::Server::Context, Exception -> String
|
||||||
@handler_position = 0
|
|
||||||
|
|
||||||
getter config : Config
|
getter config : Config
|
||||||
|
|
||||||
|
@ -31,133 +31,11 @@ class Kemal::Base
|
||||||
property? running = false
|
property? running = false
|
||||||
|
|
||||||
def initialize(@config = Config.base)
|
def initialize(@config = Config.base)
|
||||||
@logger = if @config.logging?
|
@filter_handler = FilterHandler.new(self)
|
||||||
Kemal::LogHandler.new
|
@route_handler = RouteHandler.new(self)
|
||||||
else
|
@websocket_handler = WebSocketHandler.new(self)
|
||||||
Kemal::NullLogHandler.new
|
|
||||||
end
|
|
||||||
add_filter_handler(filter_handler)
|
|
||||||
end
|
|
||||||
|
|
||||||
{% for method in HTTP_METHODS %}
|
initialize_defaults
|
||||||
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
|
|
||||||
end
|
end
|
||||||
|
|
||||||
# Overload of self.run with the default startup logging
|
# Overload of self.run with the default startup logging
|
||||||
|
@ -180,6 +58,11 @@ class Kemal::Base
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
# DEPRECATED: This method should be replaced with `#running?`
|
||||||
|
def running
|
||||||
|
running?
|
||||||
|
end
|
||||||
|
|
||||||
private def prepare_for_server_start
|
private def prepare_for_server_start
|
||||||
unless @config.env == "test"
|
unless @config.env == "test"
|
||||||
Signal::INT.trap do
|
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
|
(config.is_a?(Hash) && config[key]?) || false
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
def extra_options(&@extra_options : OptionParser ->)
|
def extra_options(&@extra_options : OptionParser ->)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -65,12 +64,12 @@ module Kemal
|
||||||
|
|
||||||
# Creates a config with basic value (disabled logging, disabled serve_static, disabled shutdown_message)
|
# Creates a config with basic value (disabled logging, disabled serve_static, disabled shutdown_message)
|
||||||
def self.base
|
def self.base
|
||||||
new.tap do |config|
|
new(
|
||||||
config.logging = false
|
logging: false,
|
||||||
config.serve_static = false
|
serve_static: false,
|
||||||
config.shutdown_message = false
|
shutdown_message: false,
|
||||||
config.always_rescue = false
|
always_rescue: false,
|
||||||
end
|
)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue