From bc661d58ae4e357aa80266694f9d1fab7a102e92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johannes=20M=C3=BCller?= Date: Sat, 30 Jun 2018 13:16:55 +0200 Subject: [PATCH] Refactor `Kemal.run` to allow custom port binding (#463) --- spec/run_spec.cr | 50 +++++++++++++++++++++++++++++++++++++----------- src/kemal.cr | 21 ++++++++++++++++---- 2 files changed, 56 insertions(+), 15 deletions(-) diff --git a/spec/run_spec.cr b/spec/run_spec.cr index 5e6fb08..2553455 100644 --- a/spec/run_spec.cr +++ b/spec/run_spec.cr @@ -1,20 +1,48 @@ require "./spec_helper" +private def run(code) + code = <<-CR + require "./src/kemal" + #{code} + CR + String.build do |stdout| + stderr = String.build do |stderr| + Process.new("crystal", ["eval"], input: IO::Memory.new(code), output: stdout, error: stderr).wait + end + unless stderr.empty? + fail(stderr) + end + end +end + describe "Run" do it "runs a code block after starting" do - Kemal.config.env = "test" - make_me_true = false - Kemal.run do - make_me_true = true - Kemal.stop - end - make_me_true.should eq true + run(<<-CR).should eq "started\nstopped\n" + Kemal.config.env = "test" + Kemal.run do + puts "started" + Kemal.stop + puts "stopped" + end + CR end it "runs without a block being specified" do - Kemal.config.env = "test" - Kemal.run - Kemal.config.running.should eq true - Kemal.stop + run(<<-CR).should eq "[test] Kemal is ready to lead at http://0.0.0.0:3000\ntrue\n" + Kemal.config.env = "test" + Kemal.run + puts Kemal.config.running + CR + end + + it "allows custom HTTP::Server bind" do + run(<<-CR).should eq "[test] Kemal is ready to lead at http://127.0.0.1:3000, http://0.0.0.0:3001\n" + Kemal.config.env = "test" + Kemal.run do |config| + server = config.server.not_nil! + server.bind_tcp "127.0.0.1", 3000, reuse_port: true + server.bind_tcp "0.0.0.0", 3001, reuse_port: true + end + CR end end diff --git a/src/kemal.cr b/src/kemal.cr index 5110a46..6c43e78 100644 --- a/src/kemal.cr +++ b/src/kemal.cr @@ -9,9 +9,7 @@ require "./kemal/helpers/*" module Kemal # Overload of `self.run` with the default startup logging. def self.run(port : Int32?) - self.run port do - log "[#{config.env}] Kemal is ready to lead at #{config.scheme}://#{config.host_binding}:#{config.port}" - end + self.run(port) { } end # Overload of `self.run` without port. @@ -68,7 +66,22 @@ module Kemal config.running = true yield config - server.listen(config.host_binding, config.port) if config.env != "test" + + # Abort if block called `Kemal.stop` + return unless config.running + + unless server.each_address { |_| break true } + server.bind_tcp(config.host_binding, config.port) + end + + display_startup_message(config, server) + + server.listen unless config.env == "test" + end + + def self.display_startup_message(config, server) + addresses = server.addresses.map { |address| "#{config.scheme}://#{address}" }.join ", " + log "[#{config.env}] Kemal is ready to lead at #{addresses}" end def self.stop