diff --git a/shard.yml b/shard.yml index 94cfad5..fec84ba 100644 --- a/shard.yml +++ b/shard.yml @@ -4,7 +4,7 @@ version: 0.11.1 dependencies: radix: github: luislavena/radix - version: 0.1.1 + version: 0.3.0 kilt: github: jeromegn/kilt version: 0.3.3 diff --git a/spec/middleware/filters_spec.cr b/spec/middleware/filters_spec.cr index 599e7fe..b603868 100644 --- a/spec/middleware/filters_spec.cr +++ b/spec/middleware/filters_spec.cr @@ -186,5 +186,5 @@ describe "Kemal::Middleware::Filters" do end class FilterTest - property modified + property modified : String? end diff --git a/spec/route_handler_spec.cr b/spec/route_handler_spec.cr index 2b89bb3..a3a108f 100644 --- a/spec/route_handler_spec.cr +++ b/spec/route_handler_spec.cr @@ -20,7 +20,7 @@ describe "Kemal::RouteHandler" do end it "routes request with multiple query strings" do - get "/" do |env| + get "/" do |env| "hello #{env.params.query["message"]} time #{env.params.query["time"]}" end request = HTTP::Request.new("GET", "/?message=world&time=now") @@ -155,5 +155,4 @@ describe "Kemal::RouteHandler" do client_response.status_code.should eq(302) client_response.headers.has_key?("Location").should eq(true) end - end diff --git a/spec/spec_helper.cr b/spec/spec_helper.cr index 4f829b1..3b04ff8 100644 --- a/spec/spec_helper.cr +++ b/spec/spec_helper.cr @@ -53,5 +53,5 @@ end Spec.after_each do Kemal.config.handlers.clear - Kemal::RouteHandler::INSTANCE.tree = Radix::Tree.new + Kemal::RouteHandler::INSTANCE.tree = Radix::Tree(Route).new end diff --git a/src/kemal.cr b/src/kemal.cr index a071609..84155f6 100644 --- a/src/kemal.cr +++ b/src/kemal.cr @@ -9,12 +9,12 @@ module Kemal config.add_handler Kemal::RouteHandler::INSTANCE config.server = HTTP::Server.new(config.host_binding.not_nil!, config.port, config.handlers) - config.server.ssl = config.ssl + config.server.not_nil!.ssl = config.ssl unless config.env == "test" Signal::INT.trap { config.logger.write "Kemal is going to take a rest!\n" - config.server.close + config.server.not_nil!.close exit } @@ -32,7 +32,7 @@ module Kemal end config.logger.write "[#{config.env}] Kemal is ready to lead at #{config.scheme}://#{config.host_binding}:#{config.port}\n" - config.server.listen + config.server.not_nil!.listen end end end diff --git a/src/kemal/base_log_handler.cr b/src/kemal/base_log_handler.cr index 3495e40..040bab2 100644 --- a/src/kemal/base_log_handler.cr +++ b/src/kemal/base_log_handler.cr @@ -1,7 +1,7 @@ require "http" class Kemal::BaseLogHandler < HTTP::Handler - def initialize(@env) + def initialize(@env : String) end def call(context) diff --git a/src/kemal/cli.cr b/src/kemal/cli.cr index d074f09..c74a9b2 100644 --- a/src/kemal/cli.cr +++ b/src/kemal/cli.cr @@ -2,10 +2,13 @@ require "option_parser" module Kemal class CLI + @config : Kemal::Config + @key_file : String + def initialize @ssl_enabled = false - @key_file = nil - @cert_file = nil + @key_file = "" + @cert_file = "" @config = Kemal.config parse configure_ssl diff --git a/src/kemal/common_log_handler.cr b/src/kemal/common_log_handler.cr index ab03eb3..9074c15 100644 --- a/src/kemal/common_log_handler.cr +++ b/src/kemal/common_log_handler.cr @@ -2,6 +2,7 @@ require "colorize" require "http" class Kemal::CommonLogHandler < Kemal::BaseLogHandler + @handler : IO::FileDescriptor getter handler def initialize(@env) diff --git a/src/kemal/config.cr b/src/kemal/config.cr index 1c151c3..52ab926 100644 --- a/src/kemal/config.cr +++ b/src/kemal/config.cr @@ -2,9 +2,11 @@ module Kemal class Config INSTANCE = Config.new HANDLERS = [] of HTTP::Handler + @ssl : OpenSSL::SSL::Context? + @server : HTTP::Server? property host_binding, ssl, port, env, public_folder, logging, - always_rescue, error_handler, serve_static, server + always_rescue, serve_static, server def initialize @host_binding = "0.0.0.0" @@ -14,9 +16,11 @@ module Kemal @public_folder = "./public" @logging = true @logger = nil - @always_rescue = true @error_handler = nil - @server = uninitialized HTTP::Server + @always_rescue = true + @run = false + @ssl = nil + @server = nil end def logger @@ -51,16 +55,16 @@ module Kemal def setup_logging @logger ||= if @logging - Kemal::CommonLogHandler.new(@env) - else - Kemal::NullLogHandler.new(@env) - end + Kemal::CommonLogHandler.new(@env) + else + Kemal::NullLogHandler.new(@env) + end HANDLERS.insert(0, @logger.not_nil!) end private def setup_error_handler if @always_rescue - @error_handler ||= Kemal::CommonExceptionHandler::INSTANCE + @error_handler ||= Kemal::CommonExceptionHandler.new HANDLERS.insert(1, @error_handler.not_nil!) end end diff --git a/src/kemal/context.cr b/src/kemal/context.cr index 333e752..a198ea4 100644 --- a/src/kemal/context.cr +++ b/src/kemal/context.cr @@ -13,7 +13,7 @@ class HTTP::Server end def route_lookup - @route_lookup ||= Kemal::RouteHandler::INSTANCE.lookup_route(@request.override_method as String, @request.path) + Kemal::RouteHandler::INSTANCE.lookup_route(@request.override_method as String, @request.path) end def route_defined? diff --git a/src/kemal/helpers.cr b/src/kemal/helpers.cr index e0309dd..9c1a411 100644 --- a/src/kemal/helpers.cr +++ b/src/kemal/helpers.cr @@ -52,7 +52,6 @@ def logger(logger) Kemal.config.add_handler logger end - def serve_static(status) Kemal.config.serve_static = status end diff --git a/src/kemal/middleware/filters.cr b/src/kemal/middleware/filters.cr index 0402087..b265ac0 100644 --- a/src/kemal/middleware/filters.cr +++ b/src/kemal/middleware/filters.cr @@ -6,7 +6,7 @@ module Kemal::Middleware # This middleware is lazily instantiated and added to the handlers as soon as a call to `after_X` or `before_X` is made. def initialize - @tree = Radix::Tree.new + @tree = Radix::Tree(Array(Kemal::Middleware::Block)).new Kemal.config.add_handler(self) end @@ -23,7 +23,7 @@ module Kemal::Middleware # :nodoc: This shouldn't be called directly, it's not private because I need to call it for testing purpose since I can't call the macros in the spec. # It adds the block for the corresponding verb/path/type combination to the tree. - def _add_route_filter(verb, path, type, &block : HTTP::Server::Context -> _) + def _add_route_filter(verb, path, type, &block : HTTP::Server::Context -> String) lookup = lookup_filters_for_path_type(verb, path, type) if lookup.found? && lookup.payload.is_a?(Array(Block)) (lookup.payload as Array(Block)) << Block.new(&block) @@ -33,12 +33,12 @@ module Kemal::Middleware end # This can be called directly but it's simpler to just use the macros, it will check if another filter is not already defined for this verb/path/type and proceed to call `add_route_filter` - def before(verb, path = "*", &block : HTTP::Server::Context -> _) + def before(verb, path = "*", &block : HTTP::Server::Context -> String) _add_route_filter verb, path, :before, &block end # This can be called directly but it's simpler to just use the macros, it will check if another filter is not already defined for this verb/path/type and proceed to call `add_route_filter` - def after(verb, path = "*", &block : HTTP::Server::Context -> _) + def after(verb, path = "*", &block : HTTP::Server::Context -> String) _add_route_filter verb, path, :after, &block end @@ -68,9 +68,9 @@ module Kemal::Middleware end class Block - property block + property block : (HTTP::Server::Context -> String) - def initialize(&@block : HTTP::Server::Context -> _) + def initialize(&@block : HTTP::Server::Context -> String) end def call(context) @@ -86,7 +86,7 @@ end ALL_METHODS = %w(get post put patch delete all) {% for type in ["before", "after"] %} {% for method in ALL_METHODS %} - def {{type.id}}_{{method.id}}(path = "*", &block : HTTP::Server::Context -> _) + def {{type.id}}_{{method.id}}(path = "*", &block : HTTP::Server::Context -> String) Kemal::Middleware::Filter::INSTANCE.{{type.id}}({{method}}.upcase, path, &block) end {% end %} diff --git a/src/kemal/middleware/http_basic_auth.cr b/src/kemal/middleware/http_basic_auth.cr index 2b490d5..92ec849 100644 --- a/src/kemal/middleware/http_basic_auth.cr +++ b/src/kemal/middleware/http_basic_auth.cr @@ -13,7 +13,7 @@ module Kemal::Middleware AUTH_MESSAGE = "Could not verify your access level for that URL.\nYou have to login with proper credentials" HEADER_LOGIN_REQUIRED = "Basic realm=\"Login Required\"" - def initialize(@username, @password) + def initialize(@username : String?, @password : String?) end def call(context) diff --git a/src/kemal/param_parser.cr b/src/kemal/param_parser.cr index e7ef0f5..96ceced 100644 --- a/src/kemal/param_parser.cr +++ b/src/kemal/param_parser.cr @@ -9,11 +9,15 @@ class Kemal::ParamParser URL_ENCODED_FORM = "application/x-www-form-urlencoded" APPLICATION_JSON = "application/json" - def initialize(@request) + def initialize(@request : HTTP::Request) @url = {} of String => String @query = {} of String => String @body = {} of String => String @json = {} of String => AllParamTypes + @url_parsed = false + @query_parsed = false + @body_parsed = false + @json_parsed = false end {% for method in %w(url query body json) %} diff --git a/src/kemal/request.cr b/src/kemal/request.cr index 60dc1cd..946dfed 100644 --- a/src/kemal/request.cr +++ b/src/kemal/request.cr @@ -1,7 +1,7 @@ # Opening HTTP::Request to add override_method property class HTTP::Request property override_method - property url_params + property url_params : Hash(String, String)? def override_method @override_method ||= check_for_method_override! diff --git a/src/kemal/route.cr b/src/kemal/route.cr index de65c3b..78395d9 100644 --- a/src/kemal/route.cr +++ b/src/kemal/route.cr @@ -3,8 +3,10 @@ # what action to be done if the route is matched. class Kemal::Route getter handler - getter method + @handler : HTTP::Server::Context -> String + @method : String - def initialize(@method, @path, &@handler : HTTP::Server::Context -> _) + def initialize(@method, @path : String, &handler : HTTP::Server::Context -> _) + @handler = ->(context : HTTP::Server::Context) { handler.call(context).to_s } end end diff --git a/src/kemal/route_handler.cr b/src/kemal/route_handler.cr index 44f5ff0..a3278d5 100644 --- a/src/kemal/route_handler.cr +++ b/src/kemal/route_handler.cr @@ -9,7 +9,7 @@ class Kemal::RouteHandler < HTTP::Handler property tree def initialize - @tree = Radix::Tree.new + @tree = Radix::Tree(Route).new end def call(context) @@ -33,7 +33,7 @@ class Kemal::RouteHandler < HTTP::Handler def process_request(context) raise Kemal::Exceptions::RouteNotFound.new(context) unless context.route_defined? route = context.route_lookup.payload as Route - context.response.print(route.handler.call(context).to_s) + context.response.print(route.handler.call(context)) context end diff --git a/src/kemal/websocket_handler.cr b/src/kemal/websocket_handler.cr index cf13f91..28e39ae 100644 --- a/src/kemal/websocket_handler.cr +++ b/src/kemal/websocket_handler.cr @@ -1,7 +1,7 @@ # Kemal::WebSocketHandler is used for each define WebSocket route. # For each WebSocket route a new handler is created and registered to global handlers. class Kemal::WebSocketHandler < HTTP::WebSocketHandler - def initialize(@path, &@proc : HTTP::WebSocket, HTTP::Server::Context -> Void) + def initialize(@path : String, &@proc : HTTP::WebSocket, HTTP::Server::Context -> Void) Kemal.config.add_ws_handler self end