Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Report tcp 0 port properly. Fixes #1679 #1786

Merged
merged 3 commits into from Sep 11, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
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