Skip to content

Commit

Permalink
Report tcp 0 port properly. Fixes #1679 (#1786)
Browse files Browse the repository at this point in the history
* Report tcp 0 port properly. Fixes #1679

Bonus feature: we now log all localhost addresses that we're bound to,
including ipv6 ones.

* Test: all binders use string events

* Put tests in right place, small refactor
  • Loading branch information
evanphx authored and nateberkopec committed Sep 11, 2019
1 parent 9c9e902 commit d9131ca
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 11 deletions.
11 changes: 10 additions & 1 deletion lib/puma/binder.rb
Expand Up @@ -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
Expand Down
44 changes: 34 additions & 10 deletions test/test_binder.rb
Expand Up @@ -7,14 +7,20 @@

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__
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
Expand All @@ -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
Expand All @@ -52,46 +76,46 @@ 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

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
Expand Down

0 comments on commit d9131ca

Please sign in to comment.