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