diff --git a/lib/proxy/launcher.rb b/lib/proxy/launcher.rb index f7b8a6a03..2568d3588 100644 --- a/lib/proxy/launcher.rb +++ b/lib/proxy/launcher.rb @@ -79,8 +79,16 @@ def launch ::Proxy::PluginInitializer.new(plugins).initialize_plugins - require 'proxy/launcher/webrick' - launcher = ::Launcher::Webrick.new(self) + case settings.http_server_type + when 'webrick' + require 'proxy/launcher/webrick' + launcher = ::Launcher::Webrick.new(self) + when 'puma' + require 'proxy/launcher/puma' + launcher = ::Launcher::Puma.new(self) + else + fail "Unknown http_server_type: #{settings.http_server_type}" + end launcher.launch rescue SignalException => e diff --git a/lib/proxy/launcher/puma.rb b/lib/proxy/launcher/puma.rb new file mode 100644 index 000000000..ebe4de403 --- /dev/null +++ b/lib/proxy/launcher/puma.rb @@ -0,0 +1,87 @@ +require 'puma' +require 'puma/configuration' +require 'proxy/app' + +module Launcher + class Puma + attr_reader :launcher + + def initialize(launcher) + @launcher = launcher + end + + def launch + ::Puma::Launcher.new(conf).run + end + + private + + def conf + ::Puma::Configuration.new do |user_config| + user_config.environment('production') + user_config.app(app) + + if launcher.http_enabled? + bind_hosts do |host| + user_config.bind "tcp://#{host}:#{settings.http_port}" + end + end + + if launcher.https_enabled? + ssl_options = { + key: settings.ssl_private_key, + cert: settings.ssl_certificate, + ca: settings.ssl_ca_file, + ssl_cipher_filter: launcher.ciphers.join(':'), + verify_mode: 'peer', + no_tlsv1: true, + no_tlsv1_1: true, + } + + bind_hosts do |host| + user_config.ssl_bind(host, settings.https_port, ssl_options) + end + end + + user_config.on_restart do + ::Proxy::LogBuffer::Decorator.instance.roll_log = true + end + + begin + user_config.plugin('systemd') + rescue ::Puma::UnknownPlugin + end + end + end + + def app + ::Proxy::App.new(launcher.plugins) + end + + def binds + end + + def bind_hosts + settings.bind_host.each do |host| + if host == '*' + yield ipv6_enabled? ? '[::]' : '0.0.0.0' + else + begin + addr = IPAddr.new(host) + yield addr.ipv6? ? "[#{addr}]" : addr.to_s + rescue IPAddr::InvalidAddressError + yield host + end + end + end + end + + def settings + launcher.settings + end + + def ipv6_enabled? + File.exist?('/proc/net/if_inet6') || (RUBY_PLATFORM =~ /cygwin|mswin|mingw|bccwin|wince|emx/) + end + end +end diff --git a/lib/proxy/settings/global.rb b/lib/proxy/settings/global.rb index 6b227b329..a7b4e64a0 100644 --- a/lib/proxy/settings/global.rb +++ b/lib/proxy/settings/global.rb @@ -2,6 +2,7 @@ module ::Proxy::Settings class Global < ::OpenStruct DEFAULT_SETTINGS = { :settings_directory => Pathname.new(__dir__).join("..", "..", "..", "config", "settings.d").expand_path.to_s, + :http_server_type => 'puma', :https_port => 8443, :log_file => "/var/log/foreman-proxy/proxy.log", :file_rolling_keep => 6,