mirror of
https://github.com/puma/puma.git
synced 2022-11-09 13:48:40 -05:00
Refactor more of the configuration
This commit is contained in:
parent
47f7671282
commit
e88fc14952
6 changed files with 216 additions and 177 deletions
|
@ -3,7 +3,7 @@ require 'uri'
|
|||
|
||||
require 'puma/server'
|
||||
require 'puma/const'
|
||||
require 'puma/config'
|
||||
require 'puma/configuration'
|
||||
|
||||
require 'rack/commonlogger'
|
||||
|
||||
|
@ -11,7 +11,6 @@ module Puma
|
|||
# Handles invoke a Puma::Server in a command line style.
|
||||
#
|
||||
class CLI
|
||||
DefaultRackup = "config.ru"
|
||||
IS_JRUBY = defined?(JRUBY_VERSION)
|
||||
|
||||
# Create a new CLI object using +argv+ as the command line
|
||||
|
@ -168,20 +167,6 @@ module Puma
|
|||
end
|
||||
end
|
||||
|
||||
# Load the specified rackup file, pull an options from
|
||||
# the rackup file, and set @app.
|
||||
#
|
||||
def load_rackup
|
||||
@app, options = Rack::Builder.parse_file @options[:rackup]
|
||||
@options.merge! options
|
||||
|
||||
options.each do |key,val|
|
||||
if key.to_s[0,4] == "bind"
|
||||
@binds << val
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# If configured, write the pid of the current process out
|
||||
# to a file.
|
||||
#
|
||||
|
@ -211,13 +196,13 @@ module Puma
|
|||
def parse_options
|
||||
@parser.parse! @argv
|
||||
|
||||
if @argv.last
|
||||
@options[:rackup] = @argv.shift
|
||||
end
|
||||
|
||||
@config = Puma::Configuration.new @options
|
||||
@config.load
|
||||
|
||||
unless @options[:rackup]
|
||||
@options[:rackup] = @argv.shift || DefaultRackup
|
||||
end
|
||||
|
||||
@temp_status_path = @options[:control_path_temp]
|
||||
end
|
||||
|
||||
|
@ -227,20 +212,11 @@ module Puma
|
|||
def run
|
||||
parse_options
|
||||
|
||||
rackup = @options[:rackup]
|
||||
app = @config.app
|
||||
|
||||
unless File.exists?(rackup)
|
||||
raise "Missing rackup file '#{rackup}'"
|
||||
end
|
||||
|
||||
load_rackup
|
||||
write_pid
|
||||
write_state
|
||||
|
||||
unless @options[:quiet]
|
||||
@app = Rack::CommonLogger.new(@app, STDOUT)
|
||||
end
|
||||
|
||||
min_t = @options[:min_threads]
|
||||
max_t = @options[:max_threads]
|
||||
|
||||
|
|
|
@ -1,146 +0,0 @@
|
|||
module Puma
|
||||
class Configuration
|
||||
DefaultTCPHost = "0.0.0.0"
|
||||
DefaultTCPPort = 9292
|
||||
|
||||
def initialize(options)
|
||||
@options = options
|
||||
@options[:binds] ||= []
|
||||
end
|
||||
|
||||
attr_reader :options
|
||||
|
||||
def load
|
||||
if path = @options[:config_file]
|
||||
instance_eval File.read(path), path, 1
|
||||
end
|
||||
|
||||
# Rakeup default option support
|
||||
if host = @options[:Host]
|
||||
port = @options[:Port] || DefaultTCPPort
|
||||
|
||||
@options[:binds] << "tcp://#{host}:#{port}"
|
||||
end
|
||||
|
||||
if @options[:binds].empty?
|
||||
@options[:binds] << "tcp://#{DefaultTCPHost}:#{DefaultTCPPort}"
|
||||
end
|
||||
|
||||
if @options[:control_url] == "auto"
|
||||
path = Configuration.temp_path
|
||||
@options[:control_url] = "unix://#{path}"
|
||||
@options[:control_url_temp] = path
|
||||
end
|
||||
|
||||
unless @options[:control_auth_token]
|
||||
setup_random_token
|
||||
end
|
||||
end
|
||||
|
||||
def setup_random_token
|
||||
begin
|
||||
require 'openssl'
|
||||
rescue LoadError
|
||||
end
|
||||
|
||||
count = 16
|
||||
|
||||
bytes = nil
|
||||
|
||||
if defined? OpenSSL::Random
|
||||
bytes = OpenSSL::Random.random_bytes(count)
|
||||
elsif File.exists?("/dev/urandom")
|
||||
File.open("/dev/urandom") do |f|
|
||||
bytes = f.read(count)
|
||||
end
|
||||
end
|
||||
|
||||
if bytes
|
||||
token = ""
|
||||
bytes.each_byte { |b| token << b.to_s(16) }
|
||||
else
|
||||
token = (0..count).to_a.map { rand(255).to_s(16) }.join
|
||||
end
|
||||
|
||||
@options[:control_auth_token] = token
|
||||
end
|
||||
|
||||
def self.temp_path
|
||||
require 'tmpdir'
|
||||
|
||||
t = (Time.now.to_f * 1000).to_i
|
||||
"#{Dir.tmpdir}/puma-status-#{t}-#{$$}"
|
||||
end
|
||||
|
||||
# Use +obj+ or +block+ as the Rack app. This allows a config file to
|
||||
# be the app itself.
|
||||
#
|
||||
def app(obj=nil, &block)
|
||||
obj ||= block
|
||||
|
||||
raise "Provide either a #call'able or a block" unless obj
|
||||
|
||||
@options[:app] = obj
|
||||
end
|
||||
|
||||
# Start the Puma control rack app on +url+. This app can be communicated
|
||||
# with to control the main server.
|
||||
#
|
||||
def activate_control_app(url="auto", opts=nil)
|
||||
@options[:control_url] = url
|
||||
|
||||
if opts
|
||||
if tok = opts[:auth_token]
|
||||
@options[:control_auth_token] = tok
|
||||
end
|
||||
|
||||
if opts[:no_token]
|
||||
@options[:control_auth_token] = :none
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Bind the server to +url+. tcp:// and unix:// are the only accepted
|
||||
# protocols.
|
||||
#
|
||||
def bind(url)
|
||||
@options[:binds] << url
|
||||
end
|
||||
|
||||
# Store the pid of the server in the file at +path+.
|
||||
def pidfile(path)
|
||||
@options[:pidfile] = path
|
||||
end
|
||||
|
||||
# Disable request logging.
|
||||
#
|
||||
def quiet
|
||||
@options[:quiet] = true
|
||||
end
|
||||
|
||||
# Load +path+ as a rackup file.
|
||||
#
|
||||
def rackup(path)
|
||||
@options[:rackup] = path.to_s
|
||||
end
|
||||
|
||||
# Configure +min+ to be the minimum number of threads to use to answer
|
||||
# requests and +max+ the maximum.
|
||||
#
|
||||
def threads(min, max)
|
||||
if min > max
|
||||
raise "The minimum number of threads must be less than the max"
|
||||
end
|
||||
|
||||
@options[:min_threads] = min
|
||||
@options[:max_threads] = max
|
||||
end
|
||||
|
||||
# Use +path+ as the file to store the server info state. This is
|
||||
# used by pumactl to query and control the server.
|
||||
#
|
||||
def state_path(path)
|
||||
@options[:state] = path.to_s
|
||||
end
|
||||
end
|
||||
end
|
190
lib/puma/configuration.rb
Normal file
190
lib/puma/configuration.rb
Normal file
|
@ -0,0 +1,190 @@
|
|||
module Puma
|
||||
class Configuration
|
||||
DefaultRackup = "config.ru"
|
||||
|
||||
DefaultTCPHost = "0.0.0.0"
|
||||
DefaultTCPPort = 9292
|
||||
|
||||
def initialize(options)
|
||||
@options = options
|
||||
@options[:binds] ||= []
|
||||
end
|
||||
|
||||
attr_reader :options
|
||||
|
||||
def load
|
||||
if path = @options[:config_file]
|
||||
DSL.new(@options)._load_from path
|
||||
end
|
||||
|
||||
# Rakeup default option support
|
||||
if host = @options[:Host]
|
||||
port = @options[:Port] || DefaultTCPPort
|
||||
|
||||
@options[:binds] << "tcp://#{host}:#{port}"
|
||||
end
|
||||
|
||||
if @options[:binds].empty?
|
||||
@options[:binds] << "tcp://#{DefaultTCPHost}:#{DefaultTCPPort}"
|
||||
end
|
||||
|
||||
if @options[:control_url] == "auto"
|
||||
path = Configuration.temp_path
|
||||
@options[:control_url] = "unix://#{path}"
|
||||
@options[:control_url_temp] = path
|
||||
end
|
||||
|
||||
unless @options[:control_auth_token]
|
||||
setup_random_token
|
||||
end
|
||||
end
|
||||
|
||||
# Load the specified rackup file, pull an options from
|
||||
# the rackup file, and set @app.
|
||||
#
|
||||
def app
|
||||
if app = @options[:app]
|
||||
return app
|
||||
end
|
||||
|
||||
path = @options[:rackup] || DefaultRackup
|
||||
|
||||
unless File.exists?(path)
|
||||
raise "Missing rackup file '#{path}'"
|
||||
end
|
||||
|
||||
app, options = Rack::Builder.parse_file path
|
||||
@options.merge! options
|
||||
|
||||
options.each do |key,val|
|
||||
if key.to_s[0,4] == "bind"
|
||||
@options[:binds] << val
|
||||
end
|
||||
end
|
||||
|
||||
unless @options[:quiet]
|
||||
app = Rack::CommonLogger.new(app, STDOUT)
|
||||
end
|
||||
|
||||
return app
|
||||
end
|
||||
|
||||
def setup_random_token
|
||||
begin
|
||||
require 'openssl'
|
||||
rescue LoadError
|
||||
end
|
||||
|
||||
count = 16
|
||||
|
||||
bytes = nil
|
||||
|
||||
if defined? OpenSSL::Random
|
||||
bytes = OpenSSL::Random.random_bytes(count)
|
||||
elsif File.exists?("/dev/urandom")
|
||||
File.open("/dev/urandom") do |f|
|
||||
bytes = f.read(count)
|
||||
end
|
||||
end
|
||||
|
||||
if bytes
|
||||
token = ""
|
||||
bytes.each_byte { |b| token << b.to_s(16) }
|
||||
else
|
||||
token = (0..count).to_a.map { rand(255).to_s(16) }.join
|
||||
end
|
||||
|
||||
@options[:control_auth_token] = token
|
||||
end
|
||||
|
||||
def self.temp_path
|
||||
require 'tmpdir'
|
||||
|
||||
t = (Time.now.to_f * 1000).to_i
|
||||
"#{Dir.tmpdir}/puma-status-#{t}-#{$$}"
|
||||
end
|
||||
|
||||
# The methods that are available for use inside the config file.
|
||||
#
|
||||
class DSL
|
||||
def initialize(options)
|
||||
@options = options
|
||||
end
|
||||
|
||||
def _load_from(path)
|
||||
instance_eval File.read(path), path, 1
|
||||
end
|
||||
|
||||
# Use +obj+ or +block+ as the Rack app. This allows a config file to
|
||||
# be the app itself.
|
||||
#
|
||||
def app(obj=nil, &block)
|
||||
obj ||= block
|
||||
|
||||
raise "Provide either a #call'able or a block" unless obj
|
||||
|
||||
@options[:app] = obj
|
||||
end
|
||||
|
||||
# Start the Puma control rack app on +url+. This app can be communicated
|
||||
# with to control the main server.
|
||||
#
|
||||
def activate_control_app(url="auto", opts=nil)
|
||||
@options[:control_url] = url
|
||||
|
||||
if opts
|
||||
if tok = opts[:auth_token]
|
||||
@options[:control_auth_token] = tok
|
||||
end
|
||||
|
||||
if opts[:no_token]
|
||||
@options[:control_auth_token] = :none
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
# Bind the server to +url+. tcp:// and unix:// are the only accepted
|
||||
# protocols.
|
||||
#
|
||||
def bind(url)
|
||||
@options[:binds] << url
|
||||
end
|
||||
|
||||
# Store the pid of the server in the file at +path+.
|
||||
def pidfile(path)
|
||||
@options[:pidfile] = path
|
||||
end
|
||||
|
||||
# Disable request logging.
|
||||
#
|
||||
def quiet
|
||||
@options[:quiet] = true
|
||||
end
|
||||
|
||||
# Load +path+ as a rackup file.
|
||||
#
|
||||
def rackup(path)
|
||||
@options[:rackup] = path.to_s
|
||||
end
|
||||
|
||||
# Configure +min+ to be the minimum number of threads to use to answer
|
||||
# requests and +max+ the maximum.
|
||||
#
|
||||
def threads(min, max)
|
||||
if min > max
|
||||
raise "The minimum number of threads must be less than the max"
|
||||
end
|
||||
|
||||
@options[:min_threads] = min
|
||||
@options[:max_threads] = max
|
||||
end
|
||||
|
||||
# Use +path+ as the file to store the server info state. This is
|
||||
# used by pumactl to query and control the server.
|
||||
#
|
||||
def state_path(path)
|
||||
@options[:state] = path.to_s
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
|
@ -1,7 +1,7 @@
|
|||
require 'optparse'
|
||||
|
||||
require 'puma/const'
|
||||
require 'puma/config'
|
||||
require 'puma/configuration'
|
||||
|
||||
require 'yaml'
|
||||
require 'uri'
|
||||
|
|
3
test/config/app.rb
Normal file
3
test/config/app.rb
Normal file
|
@ -0,0 +1,3 @@
|
|||
app do |env|
|
||||
[200, {}, ["embedded app"]]
|
||||
end
|
16
test/test_config.rb
Normal file
16
test/test_config.rb
Normal file
|
@ -0,0 +1,16 @@
|
|||
require 'test/unit'
|
||||
|
||||
require 'puma'
|
||||
require 'puma/configuration'
|
||||
|
||||
class TestConfigFile < Test::Unit::TestCase
|
||||
def test_app_from_app_DSL
|
||||
opts = { :config_file => "test/config/app.rb" }
|
||||
conf = Puma::Configuration.new opts
|
||||
conf.load
|
||||
|
||||
app = conf.app
|
||||
|
||||
assert_equal [200, {}, ["embedded app"]], app.call(nil)
|
||||
end
|
||||
end
|
Loading…
Add table
Add a link
Reference in a new issue