Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Gemfile
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ gem "minitest-proveit"
gem "minitest-stub-const"

gem "rack", (ENV['PUMA_CI_RACK_2'] ? "~> 2.2" : ">= 2.2")
gem "rackup" unless ENV['PUMA_CI_RACK_2']

gem "jruby-openssl", :platform => "jruby"

Expand Down
21 changes: 18 additions & 3 deletions lib/puma/rack_default.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,23 @@

require_relative '../rack/handler/puma'

module Rack::Handler
def self.default(options = {})
Rack::Handler::Puma
# rackup was removed in Rack 3, it is now a separate gem
if Object.const_defined? :Rackup
module Rackup
module Handler
def self.default(options = {})
::Rackup::Handler::Puma
end
end
end
elsif Object.const_defined?(:Rack) && Rack::RELEASE < '3'
module Rack
module Handler
def self.default(options = {})
::Rack::Handler::Puma
end
end
end
else
raise "Rack 3 must be used with the Rackup gem"
end
210 changes: 116 additions & 94 deletions lib/rack/handler/puma.rb
Original file line number Diff line number Diff line change
@@ -1,114 +1,136 @@
# frozen_string_literal: true

require 'rack/handler'

module Rack
module Handler
module Puma
DEFAULT_OPTIONS = {
:Verbose => false,
:Silent => false
}

def self.config(app, options = {})
require_relative '../../puma'
require_relative '../../puma/configuration'
require_relative '../../puma/log_writer'
require_relative '../../puma/launcher'

default_options = DEFAULT_OPTIONS.dup

# Libraries pass in values such as :Port and there is no way to determine
# if it is a default provided by the library or a special value provided
# by the user. A special key `user_supplied_options` can be passed. This
# contains an array of all explicitly defined user options. We then
# know that all other values are defaults
if user_supplied_options = options.delete(:user_supplied_options)
(options.keys - user_supplied_options).each do |k|
default_options[k] = options.delete(k)
end
# This module is used as an 'include' file in code at bottom of file
module Puma
module RackHandler
DEFAULT_OPTIONS = {
:Verbose => false,
:Silent => false
}

def config(app, options = {})
require_relative '../../puma'
require_relative '../../puma/configuration'
require_relative '../../puma/log_writer'
require_relative '../../puma/launcher'

default_options = DEFAULT_OPTIONS.dup

# Libraries pass in values such as :Port and there is no way to determine
# if it is a default provided by the library or a special value provided
# by the user. A special key `user_supplied_options` can be passed. This
# contains an array of all explicitly defined user options. We then
# know that all other values are defaults
if user_supplied_options = options.delete(:user_supplied_options)
(options.keys - user_supplied_options).each do |k|
default_options[k] = options.delete(k)
end
end

conf = ::Puma::Configuration.new(options, default_options) do |user_config, file_config, default_config|
if options.delete(:Verbose)
require 'rack/common_logger'
app = Rack::CommonLogger.new(app, STDOUT)
end

if options[:environment]
user_config.environment options[:environment]
end

if options[:Threads]
min, max = options.delete(:Threads).split(':', 2)
user_config.threads min, max
end

if options[:Host] || options[:Port]
host = options[:Host] || default_options[:Host]
port = options[:Port] || default_options[:Port]
self.set_host_port_to_config(host, port, user_config)
end

if default_options[:Host]
file_config.set_default_host(default_options[:Host])
end
self.set_host_port_to_config(default_options[:Host], default_options[:Port], default_config)

user_config.app app
conf = ::Puma::Configuration.new(options, default_options) do |user_config, file_config, default_config|
if options.delete(:Verbose)
require 'rack/common_logger'
app = Rack::CommonLogger.new(app, STDOUT)
end
conf
end

def self.run(app, **options)
conf = self.config(app, options)
if options[:environment]
user_config.environment options[:environment]
end

log_writer = options.delete(:Silent) ? ::Puma::LogWriter.strings : ::Puma::LogWriter.stdio
if options[:Threads]
min, max = options.delete(:Threads).split(':', 2)
user_config.threads min, max
end

launcher = ::Puma::Launcher.new(conf, :log_writer => log_writer)
if options[:Host] || options[:Port]
host = options[:Host] || default_options[:Host]
port = options[:Port] || default_options[:Port]
self.set_host_port_to_config(host, port, user_config)
end

yield launcher if block_given?
begin
launcher.run
rescue Interrupt
puts "* Gracefully stopping, waiting for requests to finish"
launcher.stop
puts "* Goodbye!"
if default_options[:Host]
file_config.set_default_host(default_options[:Host])
end
self.set_host_port_to_config(default_options[:Host], default_options[:Port], default_config)

user_config.app app
end
conf
end

def run(app, **options)
conf = self.config(app, options)

log_writer = options.delete(:Silent) ? ::Puma::LogWriter.strings : ::Puma::LogWriter.stdio

launcher = ::Puma::Launcher.new(conf, :log_writer => log_writer)

def self.valid_options
{
"Host=HOST" => "Hostname to listen on (default: localhost)",
"Port=PORT" => "Port to listen on (default: 8080)",
"Threads=MIN:MAX" => "min:max threads to use (default 0:16)",
"Verbose" => "Don't report each request (default: false)"
}
yield launcher if block_given?
begin
launcher.run
rescue Interrupt
puts "* Gracefully stopping, waiting for requests to finish"
launcher.stop
puts "* Goodbye!"
end
end

def self.set_host_port_to_config(host, port, config)
config.clear_binds! if host || port

if host && (host[0,1] == '.' || host[0,1] == '/')
config.bind "unix://#{host}"
elsif host && host =~ /^ssl:\/\//
uri = URI.parse(host)
uri.port ||= port || ::Puma::Configuration::DEFAULTS[:tcp_port]
config.bind uri.to_s
else

if host
port ||= ::Puma::Configuration::DEFAULTS[:tcp_port]
end

if port
host ||= ::Puma::Configuration::DEFAULTS[:tcp_host]
config.port port, host
end
def valid_options
{
"Host=HOST" => "Hostname to listen on (default: localhost)",
"Port=PORT" => "Port to listen on (default: 8080)",
"Threads=MIN:MAX" => "min:max threads to use (default 0:16)",
"Verbose" => "Don't report each request (default: false)"
}
end

def set_host_port_to_config(host, port, config)
config.clear_binds! if host || port

if host && (host[0,1] == '.' || host[0,1] == '/')
config.bind "unix://#{host}"
elsif host && host =~ /^ssl:\/\//
uri = URI.parse(host)
uri.port ||= port || ::Puma::Configuration::DEFAULTS[:tcp_port]
config.bind uri.to_s
else

if host
port ||= ::Puma::Configuration::DEFAULTS[:tcp_port]
end

if port
host ||= ::Puma::Configuration::DEFAULTS[:tcp_host]
config.port port, host
end
end
end
end
end

register :puma, Puma
# rackup was removed in Rack 3, it is now a separate gem
if Object.const_defined? :Rackup
module Rackup
module Handler
module Puma
class << self
include ::Puma::RackHandler
end
end
register :puma, Puma
end
end
elsif Object.const_defined?(:Rack) && Rack::RELEASE < '3'
module Rack
module Handler
module Puma
class << self
include ::Puma::RackHandler
end
end
register :puma, Puma
end
end
else
raise "You must install the rackup gem when using Rack 3"
end
Loading