From f5c80c7b67fa990e8b8651649b7c8c25f53b291b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20M=C3=BCller?= Date: Mon, 17 Jul 2017 18:14:26 +0200 Subject: [PATCH] Extract default app behavior from Kemal::Base to Kemal::Application --- spec/config_spec.cr | 11 +++++-- src/kemal/application.cr | 37 +++++++++++++++++++++++ src/kemal/base.cr | 64 ++++++++++++++++------------------------ src/kemal/config.cr | 15 ++++++++++ src/kemal/dsl.cr | 1 + 5 files changed, 87 insertions(+), 41 deletions(-) create mode 100644 src/kemal/application.cr diff --git a/spec/config_spec.cr b/spec/config_spec.cr index 48fc31d..9ead52f 100644 --- a/spec/config_spec.cr +++ b/spec/config_spec.cr @@ -27,11 +27,18 @@ describe "Config" do config.host_binding.should eq "127.0.0.1" end - it "adds a custom handler" do + it "adds a custom handler to Base" do application = Kemal::Base.new application.add_handler CustomTestHandler.new application.setup - application.handlers.size.should eq(8) + application.handlers.size.should eq 6 + end + + it "adds a custom handler to Application" do + application = Kemal::Application.new + application.add_handler CustomTestHandler.new + application.setup + application.handlers.size.should eq 9 end it "toggles the shutdown message" do diff --git a/src/kemal/application.cr b/src/kemal/application.cr new file mode 100644 index 0000000..e7fa19c --- /dev/null +++ b/src/kemal/application.cr @@ -0,0 +1,37 @@ +class Kemal::Application < Kemal::Base + def initialize(config = Config.default) + super config + add_filter_handler(filter_handler) + end + + # Overload of self.run with the default startup logging + def run(port = nil) + run port do + log "[#{config.env}] Kemal is ready to lead at #{config.scheme}://#{config.host_binding}:#{port || config.port}" + end + end + + private def prepare_for_server_start + super + + unless error_handlers.has_key?(404) + error 404 do |env| + render_404 + end + end + + # Test environment doesn't need to have signal trap, built-in images, and logging. + unless @config.env == "test" + # This route serves the built-in images for not_found and exceptions. + get "/__kemal__/:image" do |env| + image = env.params.url["image"] + file_path = File.expand_path("lib/kemal/images/#{image}", Dir.current) + if File.exists? file_path + send_file env, file_path + else + halt env, 404 + end + end + end + end +end diff --git a/src/kemal/base.cr b/src/kemal/base.cr index cf118ae..09af652 100644 --- a/src/kemal/base.cr +++ b/src/kemal/base.cr @@ -30,7 +30,7 @@ class Kemal::Base property! server : HTTP::Server property? running = false - def initialize(@config = Config.new) + def initialize(@config = Config.base) @logger = if @config.logging? Kemal::LogHandler.new else @@ -161,61 +161,47 @@ class Kemal::Base end # Overload of self.run with the default startup logging - def run(port = nil) + def run(port : Int32? = nil) run port do log "[#{config.env}] Kemal is ready to lead at #{config.scheme}://#{config.host_binding}:#{config.port}" end end - # Overload of self.run to allow just a block - def run(&block) - run nil, &block - end - # The command to run a `Kemal` application. # The port can be given to `#run` but is optional. # If not given Kemal will use `Kemal::Config#port` - def run(port = nil, &block) - @config.port = port if port - + def run(port : Int32? = nil) setup - @server = server = HTTP::Server.new(@config.host_binding, @config.port, @handlers) + prepare_for_server_start + + start_server(port) do + yield self + end + end + + private def prepare_for_server_start + unless @config.env == "test" + Signal::INT.trap do + log "Kemal is going to take a rest!" if @config.shutdown_message? + stop if running? + exit + end + end + end + + private def start_server(port) + @server = server = HTTP::Server.new(@config.host_binding, port || @config.port, @handlers) {% if !flag?(:without_openssl) %} server.tls = config.ssl {% end %} - unless error_handlers.has_key?(404) - error 404 do |env| - render_404 - end - end - - # Test environment doesn't need to have signal trap, built-in images, and logging. - unless config.env == "test" - Signal::INT.trap do - log "Kemal is going to take a rest!" if config.shutdown_message? - Kemal.stop if running? - exit - end - - # This route serves the built-in images for not_found and exceptions. - get "/__kemal__/:image" do |env| - image = env.params.url["image"] - file_path = File.expand_path("lib/kemal/images/#{image}", Dir.current) - if File.exists? file_path - send_file env, file_path - else - halt env, 404 - end - end - end - + server.bind @running = true - yield self + yield - server.listen if @config.env != "test" + server.listen unless @config.env == "test" end def stop diff --git a/src/kemal/config.cr b/src/kemal/config.cr index b129c65..e4db16a 100644 --- a/src/kemal/config.cr +++ b/src/kemal/config.cr @@ -57,5 +57,20 @@ module Kemal def extra_options(&@extra_options : OptionParser ->) end + + # Create a config with default values + def self.default + new + end + + # 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 + end end end diff --git a/src/kemal/dsl.cr b/src/kemal/dsl.cr index 0d94283..4c8575a 100644 --- a/src/kemal/dsl.cr +++ b/src/kemal/dsl.cr @@ -6,6 +6,7 @@ # - WebSocket(ws) # - before_* # - error +require "../kemal" require "./dsl/*" {% for method in Kemal::Base::HTTP_METHODS %}