From 5b3ca4df66afa2516a028ca9f909e2c73b82839e Mon Sep 17 00:00:00 2001 From: Evan Phoenix Date: Thu, 25 Apr 2019 16:27:27 -0700 Subject: [PATCH 1/3] Report tcp 0 port properly. Fixes #1679 Bonus feature: we now log all localhost addresses that we're bound to, including ipv6 ones. --- lib/puma/binder.rb | 11 ++++++++++- test/test_binder.rb | 22 ++++++++++++++++++++++ 2 files changed, 32 insertions(+), 1 deletion(-) diff --git a/lib/puma/binder.rb b/lib/puma/binder.rb index 1c498dbf21..6880242044 100644 --- a/lib/puma/binder.rb +++ b/lib/puma/binder.rb @@ -111,7 +111,16 @@ def parse(binds, logger) bak = params.fetch('backlog', 1024).to_i io = add_tcp_listener uri.host, uri.port, opt, bak - logger.log "* Listening on #{str}" + + @ios.each do |i| + addr = if i.local_address.ipv6? + "[#{i.local_address.ip_unpack[0]}]:#{i.local_address.ip_unpack[1]}" + else + i.local_address.ip_unpack.join(':') + end + + logger.log "* Listening on tcp://#{addr}" + end end @listeners << [str, io] if io diff --git a/test/test_binder.rb b/test/test_binder.rb index 89a7e58416..3f55c6cb10 100644 --- a/test/test_binder.rb +++ b/test/test_binder.rb @@ -95,4 +95,26 @@ def test_binder_parses_tlsv1_1_enabled refute ssl_context_for_binder(@binder).no_tlsv1_1 end + + def test_correct_zero_port + @events = Puma::Events.strings + @binder = Puma::Binder.new(@events) + @binder.parse(["tcp://localhost:0"], @events) + + m = %r!tcp://127.0.0.1:(\d+)!.match(@events.stdout.string) + port = m[1].to_i + + refute_equal 0, port + end + + def test_logs_all_localhost_bindings + @events = Puma::Events.strings + @binder = Puma::Binder.new(@events) + @binder.parse(["tcp://localhost:0"], @events) + + assert_match %r!tcp://127.0.0.1:(\d+)!, @events.stdout.string + if @binder.loopback_addresses.include?("::1") + assert_match %r!tcp://\[::1\]:(\d+)!, @events.stdout.string + end + end end From d24669858ce28b6ad58b668e8e7caaf1339772cb Mon Sep 17 00:00:00 2001 From: Nate Berkopec Date: Wed, 11 Sep 2019 11:52:43 +0000 Subject: [PATCH 2/3] Test: all binders use string events --- test/test_binder.rb | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/test/test_binder.rb b/test/test_binder.rb index 3f55c6cb10..9dacd58d72 100644 --- a/test/test_binder.rb +++ b/test/test_binder.rb @@ -7,7 +7,7 @@ class TestBinderBase < Minitest::Test def setup - @events = Puma::Events.null + @events = Puma::Events.strings @binder = Puma::Binder.new(@events) @key = File.expand_path "../../examples/puma/puma_keypair.pem", __FILE__ @cert = File.expand_path "../../examples/puma/cert_puma.pem", __FILE__ @@ -97,8 +97,6 @@ def test_binder_parses_tlsv1_1_enabled end def test_correct_zero_port - @events = Puma::Events.strings - @binder = Puma::Binder.new(@events) @binder.parse(["tcp://localhost:0"], @events) m = %r!tcp://127.0.0.1:(\d+)!.match(@events.stdout.string) @@ -108,8 +106,6 @@ def test_correct_zero_port end def test_logs_all_localhost_bindings - @events = Puma::Events.strings - @binder = Puma::Binder.new(@events) @binder.parse(["tcp://localhost:0"], @events) assert_match %r!tcp://127.0.0.1:(\d+)!, @events.stdout.string From 41eebf446ebd79e72e44f48682dc9237c0bdc3fa Mon Sep 17 00:00:00 2001 From: Nate Berkopec Date: Wed, 11 Sep 2019 11:59:08 +0000 Subject: [PATCH 3/3] Put tests in right place, small refactor --- test/test_binder.rb | 60 +++++++++++++++++++++++++-------------------- 1 file changed, 33 insertions(+), 27 deletions(-) diff --git a/test/test_binder.rb b/test/test_binder.rb index 9dacd58d72..b5ab9aa575 100644 --- a/test/test_binder.rb +++ b/test/test_binder.rb @@ -9,12 +9,18 @@ class TestBinderBase < Minitest::Test def setup @events = Puma::Events.strings @binder = Puma::Binder.new(@events) - @key = File.expand_path "../../examples/puma/puma_keypair.pem", __FILE__ - @cert = File.expand_path "../../examples/puma/cert_puma.pem", __FILE__ end private + def key + @key ||= File.expand_path "../../examples/puma/puma_keypair.pem", __FILE__ + end + + def cert + @cert ||= File.expand_path "../../examples/puma/cert_puma.pem", __FILE__ + end + def ssl_context_for_binder(binder) binder.instance_variable_get(:@ios)[0].instance_variable_get(:@ctx) end @@ -26,6 +32,24 @@ def test_localhost_addresses_dont_alter_listeners_for_tcp_addresses assert_equal [], @binder.instance_variable_get(:@listeners) end + + def test_correct_zero_port + @binder.parse(["tcp://localhost:0"], @events) + + m = %r!tcp://127.0.0.1:(\d+)!.match(@events.stdout.string) + port = m[1].to_i + + refute_equal 0, port + end + + def test_logs_all_localhost_bindings + @binder.parse(["tcp://localhost:0"], @events) + + assert_match %r!tcp://127.0.0.1:(\d+)!, @events.stdout.string + if @binder.loopback_addresses.include?("::1") + assert_match %r!tcp://\[::1\]:(\d+)!, @events.stdout.string + end + end end class TestBinderJRuby < TestBinderBase @@ -52,7 +76,7 @@ def setup end def test_localhost_addresses_dont_alter_listeners_for_ssl_addresses - @binder.parse(["ssl://localhost:10002?key=#{@key}&cert=#{@cert}"], @events) + @binder.parse(["ssl://localhost:10002?key=#{key}&cert=#{cert}"], @events) assert_equal [], @binder.instance_variable_get(:@listeners) end @@ -60,57 +84,39 @@ def test_localhost_addresses_dont_alter_listeners_for_ssl_addresses def test_binder_parses_ssl_cipher_filter ssl_cipher_filter = "AES@STRENGTH" - @binder.parse(["ssl://0.0.0.0?key=#{@key}&cert=#{@cert}&ssl_cipher_filter=#{ssl_cipher_filter}"], @events) + @binder.parse(["ssl://0.0.0.0?key=#{key}&cert=#{cert}&ssl_cipher_filter=#{ssl_cipher_filter}"], @events) assert_equal ssl_cipher_filter, ssl_context_for_binder(@binder).ssl_cipher_filter end def test_binder_parses_tlsv1_disabled - @binder.parse(["ssl://0.0.0.0?key=#{@key}&cert=#{@cert}&no_tlsv1=true"], @events) + @binder.parse(["ssl://0.0.0.0?key=#{key}&cert=#{cert}&no_tlsv1=true"], @events) assert ssl_context_for_binder(@binder).no_tlsv1 end def test_binder_parses_tlsv1_enabled - @binder.parse(["ssl://0.0.0.0?key=#{@key}&cert=#{@cert}&no_tlsv1=false"], @events) + @binder.parse(["ssl://0.0.0.0?key=#{key}&cert=#{cert}&no_tlsv1=false"], @events) refute ssl_context_for_binder(@binder).no_tlsv1 end def test_binder_parses_tlsv1_tlsv1_1_unspecified_defaults_to_enabled - @binder.parse(["ssl://0.0.0.0?key=#{@key}&cert=#{@cert}"], @events) + @binder.parse(["ssl://0.0.0.0?key=#{key}&cert=#{cert}"], @events) refute ssl_context_for_binder(@binder).no_tlsv1 refute ssl_context_for_binder(@binder).no_tlsv1_1 end def test_binder_parses_tlsv1_1_disabled - @binder.parse(["ssl://0.0.0.0?key=#{@key}&cert=#{@cert}&no_tlsv1_1=true"], @events) + @binder.parse(["ssl://0.0.0.0?key=#{key}&cert=#{cert}&no_tlsv1_1=true"], @events) assert ssl_context_for_binder(@binder).no_tlsv1_1 end def test_binder_parses_tlsv1_1_enabled - @binder.parse(["ssl://0.0.0.0?key=#{@key}&cert=#{@cert}&no_tlsv1_1=false"], @events) + @binder.parse(["ssl://0.0.0.0?key=#{key}&cert=#{cert}&no_tlsv1_1=false"], @events) refute ssl_context_for_binder(@binder).no_tlsv1_1 end - - def test_correct_zero_port - @binder.parse(["tcp://localhost:0"], @events) - - m = %r!tcp://127.0.0.1:(\d+)!.match(@events.stdout.string) - port = m[1].to_i - - refute_equal 0, port - end - - def test_logs_all_localhost_bindings - @binder.parse(["tcp://localhost:0"], @events) - - assert_match %r!tcp://127.0.0.1:(\d+)!, @events.stdout.string - if @binder.loopback_addresses.include?("::1") - assert_match %r!tcp://\[::1\]:(\d+)!, @events.stdout.string - end - end end