diff --git a/History.md b/History.md index 8e2f1e4e37..70442df3b6 100644 --- a/History.md +++ b/History.md @@ -3,7 +3,7 @@ * Features * Strip whitespace at end of HTTP headers (#2010) * Optimize HTTP parser for JRuby (#2012) - * Add SSL support for the control app (#2046) + * Add SSL support for the control app and cli (#2046, #2052) * Bugfixes * Fix Errno::EINVAL when SSL is enabled and browser rejects cert (#1564) diff --git a/lib/puma/control_cli.rb b/lib/puma/control_cli.rb index 6bad828b88..6d4118f062 100644 --- a/lib/puma/control_cli.rb +++ b/lib/puma/control_cli.rb @@ -141,6 +141,12 @@ def send_request # create server object by scheme server = case uri.scheme + when "ssl" + require 'openssl' + OpenSSL::SSL::SSLSocket.new( + TCPSocket.new(uri.host, uri.port), + OpenSSL::SSL::SSLContext.new + ).tap(&:connect) when "tcp" TCPSocket.new uri.host, uri.port when "unix" diff --git a/test/test_pumactl.rb b/test/test_pumactl.rb index bb4c00b0a0..515c2dec9f 100644 --- a/test/test_pumactl.rb +++ b/test/test_pumactl.rb @@ -1,16 +1,19 @@ require_relative "helper" require_relative "helpers/config_file" +require_relative "helpers/ssl" require 'puma/control_cli' class TestPumaControlCli < TestConfigFileBase + include SSLHelper + def setup # use a pipe to get info across thread boundary @wait, @ready = IO.pipe end def wait_booted - line = @wait.gets until line =~ /Listening on/ + line = @wait.gets until line =~ /Use Ctrl-C to stop/ end def teardown @@ -138,18 +141,43 @@ def test_control_url_and_status assert_match "200 OK", body assert_match "embedded app", body - status_cmd = Puma::ControlCLI.new(opts + ["status"]) - out, _ = capture_subprocess_io do - status_cmd.run - end - assert_match "Puma is started\n", out + assert_command_cli_output opts + ["status"], "Puma is started" + assert_command_cli_output opts + ["stop"], "Command stop sent success" - shutdown_cmd = Puma::ControlCLI.new(opts + ["halt"]) - out, _ = capture_subprocess_io do - shutdown_cmd.run + assert_kind_of Thread, t.join, "server didn't stop" + end + + def test_control_ssl + host = "127.0.0.1" + port = find_open_port + url = "ssl://#{host}:#{port}?#{ssl_query}" + + opts = [ + "--control-url", url, + "--control-token", "ctrl", + "--config-file", "test/config/app.rb", + ] + + control_cli = Puma::ControlCLI.new (opts + ["start"]), @ready, @ready + t = Thread.new do + control_cli.run end - assert_match "Command halt sent success\n", out + + wait_booted + + assert_command_cli_output opts + ["status"], "Puma is started" + assert_command_cli_output opts + ["stop"], "Command stop sent success" assert_kind_of Thread, t.join, "server didn't stop" end + + private + + def assert_command_cli_output(options, expected_out) + cmd = Puma::ControlCLI.new(options) + out, _ = capture_subprocess_io do + cmd.run + end + assert_match expected_out, out + end end