[WIP] Refactor: Split out LogWriter from Events (no logic change) (#2798)
* Split out LogWriter from Events * Improve code comment * Fix constructor interfaces * Fix file includes * Fix specs and requires * Fix LogWriter * More fixes * Fix tests * Fix specs * Fix spec * Fix more specs * Refactor: Split out LogWriter from Events * Improve comments * Fix bundle pruner Co-authored-by: shields <shields@tablecheck.com>
This commit is contained in:
parent
d7cfe19eb3
commit
8a4ef0c16c
|
@ -8,8 +8,8 @@ app = proc {|env|
|
|||
p env['puma.peercert']
|
||||
[200, {}, [ env['puma.peercert'] ]]
|
||||
}
|
||||
events = Puma::Events.new($stdout, $stderr)
|
||||
server = Puma::Server.new(app, events)
|
||||
log_writer = Puma::LogWriter.new($stdout, $stderr)
|
||||
server = Puma::Server.new(app, log_writer)
|
||||
|
||||
context = Puma::MiniSSL::Context.new
|
||||
context.key = "certs/server.key"
|
||||
|
|
|
@ -28,8 +28,8 @@ module Puma
|
|||
|
||||
RACK_VERSION = [1,6].freeze
|
||||
|
||||
def initialize(events, conf = Configuration.new)
|
||||
@events = events
|
||||
def initialize(log_writer, conf = Configuration.new)
|
||||
@log_writer = log_writer
|
||||
@conf = conf
|
||||
@listeners = []
|
||||
@inherited_fds = {}
|
||||
|
@ -38,7 +38,7 @@ module Puma
|
|||
|
||||
@proto_env = {
|
||||
"rack.version".freeze => RACK_VERSION,
|
||||
"rack.errors".freeze => events.stderr,
|
||||
"rack.errors".freeze => log_writer.stderr,
|
||||
"rack.multithread".freeze => conf.options[:max_threads] > 1,
|
||||
"rack.multiprocess".freeze => conf.options[:workers] >= 1,
|
||||
"rack.run_once".freeze => false,
|
||||
|
@ -98,7 +98,7 @@ module Puma
|
|||
# @version 5.0.0
|
||||
#
|
||||
def create_activated_fds(env_hash)
|
||||
@events.debug "ENV['LISTEN_FDS'] #{ENV['LISTEN_FDS'].inspect} env_hash['LISTEN_PID'] #{env_hash['LISTEN_PID'].inspect}"
|
||||
@log_writer.debug "ENV['LISTEN_FDS'] #{ENV['LISTEN_FDS'].inspect} env_hash['LISTEN_PID'] #{env_hash['LISTEN_PID'].inspect}"
|
||||
return [] unless env_hash['LISTEN_FDS'] && env_hash['LISTEN_PID'].to_i == $$
|
||||
env_hash['LISTEN_FDS'].to_i.times do |index|
|
||||
sock = TCPServer.for_fd(socket_activation_fd(index))
|
||||
|
@ -110,7 +110,7 @@ module Puma
|
|||
[:tcp, addr, port]
|
||||
end
|
||||
@activated_sockets[key] = sock
|
||||
@events.debug "Registered #{key.join ':'} for activation from LISTEN_FDS"
|
||||
@log_writer.debug "Registered #{key.join ':'} for activation from LISTEN_FDS"
|
||||
end
|
||||
["LISTEN_FDS", "LISTEN_PID"] # Signal to remove these keys from ENV
|
||||
end
|
||||
|
@ -152,17 +152,17 @@ module Puma
|
|||
end
|
||||
end
|
||||
|
||||
def parse(binds, logger, log_msg = 'Listening')
|
||||
def parse(binds, log_writer, log_msg = 'Listening')
|
||||
binds.each do |str|
|
||||
uri = URI.parse str
|
||||
case uri.scheme
|
||||
when "tcp"
|
||||
if fd = @inherited_fds.delete(str)
|
||||
io = inherit_tcp_listener uri.host, uri.port, fd
|
||||
logger.log "* Inherited #{str}"
|
||||
log_writer.log "* Inherited #{str}"
|
||||
elsif sock = @activated_sockets.delete([ :tcp, uri.host, uri.port ])
|
||||
io = inherit_tcp_listener uri.host, uri.port, sock
|
||||
logger.log "* Activated #{str}"
|
||||
log_writer.log "* Activated #{str}"
|
||||
else
|
||||
ios_len = @ios.length
|
||||
params = Util.parse_query uri.query
|
||||
|
@ -174,7 +174,7 @@ module Puma
|
|||
|
||||
@ios[ios_len..-1].each do |i|
|
||||
addr = loc_addr_str i
|
||||
logger.log "* #{log_msg} on http://#{addr}"
|
||||
log_writer.log "* #{log_msg} on http://#{addr}"
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -191,12 +191,12 @@ module Puma
|
|||
if fd = @inherited_fds.delete(str)
|
||||
@unix_paths << path unless abstract
|
||||
io = inherit_unix_listener path, fd
|
||||
logger.log "* Inherited #{str}"
|
||||
log_writer.log "* Inherited #{str}"
|
||||
elsif sock = @activated_sockets.delete([ :unix, path ]) ||
|
||||
@activated_sockets.delete([ :unix, File.realdirpath(path) ])
|
||||
@unix_paths << path unless abstract || File.exist?(path)
|
||||
io = inherit_unix_listener path, sock
|
||||
logger.log "* Activated #{str}"
|
||||
log_writer.log "* Activated #{str}"
|
||||
else
|
||||
umask = nil
|
||||
mode = nil
|
||||
|
@ -220,7 +220,7 @@ module Puma
|
|||
|
||||
@unix_paths << path unless abstract || File.exist?(path)
|
||||
io = add_unix_listener path, umask, mode, backlog
|
||||
logger.log "* #{log_msg} on #{str}"
|
||||
log_writer.log "* #{log_msg} on #{str}"
|
||||
end
|
||||
|
||||
@listeners << [str, io]
|
||||
|
@ -246,15 +246,15 @@ module Puma
|
|||
params["#{v}_pem"] = @conf.options[:store][index]
|
||||
end
|
||||
end
|
||||
MiniSSL::ContextBuilder.new(params, @events).context
|
||||
MiniSSL::ContextBuilder.new(params, @log_writer).context
|
||||
end
|
||||
|
||||
if fd = @inherited_fds.delete(str)
|
||||
logger.log "* Inherited #{str}"
|
||||
log_writer.log "* Inherited #{str}"
|
||||
io = inherit_ssl_listener fd, ctx
|
||||
elsif sock = @activated_sockets.delete([ :tcp, uri.host, uri.port ])
|
||||
io = inherit_ssl_listener sock, ctx
|
||||
logger.log "* Activated #{str}"
|
||||
log_writer.log "* Activated #{str}"
|
||||
else
|
||||
ios_len = @ios.length
|
||||
backlog = params.fetch('backlog', 1024).to_i
|
||||
|
@ -262,20 +262,20 @@ module Puma
|
|||
|
||||
@ios[ios_len..-1].each do |i|
|
||||
addr = loc_addr_str i
|
||||
logger.log "* #{log_msg} on ssl://#{addr}?#{uri.query}"
|
||||
log_writer.log "* #{log_msg} on ssl://#{addr}?#{uri.query}"
|
||||
end
|
||||
end
|
||||
|
||||
@listeners << [str, io] if io
|
||||
else
|
||||
logger.error "Invalid URI: #{str}"
|
||||
log_writer.error "Invalid URI: #{str}"
|
||||
end
|
||||
end
|
||||
|
||||
# If we inherited fds but didn't use them (because of a
|
||||
# configuration change), then be sure to close them.
|
||||
@inherited_fds.each do |str, fd|
|
||||
logger.log "* Closing unused inherited connection: #{str}"
|
||||
log_writer.log "* Closing unused inherited connection: #{str}"
|
||||
|
||||
begin
|
||||
IO.for_fd(fd).close
|
||||
|
@ -295,7 +295,7 @@ module Puma
|
|||
fds = @ios.map(&:to_i)
|
||||
@activated_sockets.each do |key, sock|
|
||||
next if fds.include? sock.to_i
|
||||
logger.log "* Closing unused activated socket: #{key.first}://#{key[1..-1].join ':'}"
|
||||
log_writer.log "* Closing unused activated socket: #{key.first}://#{key[1..-1].join ':'}"
|
||||
begin
|
||||
sock.close
|
||||
rescue SystemCallError
|
||||
|
@ -319,7 +319,7 @@ module Puma
|
|||
local_certificates_path = File.expand_path("~/.localhost")
|
||||
[File.join(local_certificates_path, "localhost.key"), File.join(local_certificates_path, "localhost.crt")]
|
||||
end
|
||||
MiniSSL::ContextBuilder.new({ "key" => key_path, "cert" => crt_path }, @events).context
|
||||
MiniSSL::ContextBuilder.new({ "key" => key_path, "cert" => crt_path }, @log_writer).context
|
||||
end
|
||||
|
||||
# Tell the server to listen on host +host+, port +port+.
|
||||
|
|
|
@ -7,7 +7,7 @@ require 'puma'
|
|||
require 'puma/configuration'
|
||||
require 'puma/launcher'
|
||||
require 'puma/const'
|
||||
require 'puma/events'
|
||||
require 'puma/log_writer'
|
||||
|
||||
module Puma
|
||||
class << self
|
||||
|
@ -30,10 +30,10 @@ module Puma
|
|||
# +stdout+ and +stderr+ can be set to IO-like objects which
|
||||
# this object will report status on.
|
||||
#
|
||||
def initialize(argv, events=Events.stdio)
|
||||
def initialize(argv, log_writer = LogWriter.stdio, events = Events.new)
|
||||
@debug = false
|
||||
@argv = argv.dup
|
||||
|
||||
@log_writer = log_writer
|
||||
@events = events
|
||||
|
||||
@conf = nil
|
||||
|
@ -69,7 +69,7 @@ module Puma
|
|||
end
|
||||
end
|
||||
|
||||
@launcher = Puma::Launcher.new(@conf, :events => @events, :argv => argv)
|
||||
@launcher = Puma::Launcher.new(@conf, :log_writer => @log_writer, :events => @events, :argv => argv)
|
||||
end
|
||||
|
||||
attr_reader :launcher
|
||||
|
@ -83,7 +83,7 @@ module Puma
|
|||
|
||||
private
|
||||
def unsupported(str)
|
||||
@events.error(str)
|
||||
@log_writer.error(str)
|
||||
raise UnsupportedOption
|
||||
end
|
||||
|
||||
|
@ -186,7 +186,7 @@ module Puma
|
|||
end
|
||||
|
||||
o.on "-s", "--silent", "Do not log prompt messages other than errors" do
|
||||
@events = Events.new NullIO.new, $stderr
|
||||
@log_writer = LogWriter.new(NullIO.new, $stderr)
|
||||
end
|
||||
|
||||
o.on "-S", "--state PATH", "Where to store the state details" do |arg|
|
||||
|
|
|
@ -17,8 +17,8 @@ module Puma
|
|||
# via the `spawn_workers` method call. Each worker will have it's own
|
||||
# instance of a `Puma::Server`.
|
||||
class Cluster < Runner
|
||||
def initialize(cli, events)
|
||||
super cli, events
|
||||
def initialize(launcher)
|
||||
super(launcher)
|
||||
|
||||
@phase = 0
|
||||
@workers = []
|
||||
|
@ -96,7 +96,7 @@ module Puma
|
|||
|
||||
# @version 5.0.0
|
||||
def spawn_worker(idx, master)
|
||||
@launcher.config.run_hooks :before_worker_fork, idx, @launcher.events
|
||||
@launcher.config.run_hooks(:before_worker_fork, idx, @launcher.log_writer)
|
||||
|
||||
pid = fork { worker(idx, master) }
|
||||
if !pid
|
||||
|
@ -105,7 +105,7 @@ module Puma
|
|||
exit! 1
|
||||
end
|
||||
|
||||
@launcher.config.run_hooks :after_worker_fork, idx, @launcher.events
|
||||
@launcher.config.run_hooks(:after_worker_fork, idx, @launcher.log_writer)
|
||||
pid
|
||||
end
|
||||
|
||||
|
@ -413,8 +413,8 @@ module Puma
|
|||
|
||||
@master_read, @worker_write = read, @wakeup
|
||||
|
||||
@launcher.config.run_hooks :before_fork, nil, @launcher.events
|
||||
Puma::Util.nakayoshi_gc @events if @options[:nakayoshi_fork]
|
||||
@launcher.config.run_hooks(:before_fork, nil, @launcher.log_writer)
|
||||
Puma::Util.nakayoshi_gc(@log_writer) if @options[:nakayoshi_fork]
|
||||
|
||||
spawn_workers
|
||||
|
||||
|
|
|
@ -12,7 +12,7 @@ module Puma
|
|||
attr_reader :index, :master
|
||||
|
||||
def initialize(index:, master:, launcher:, pipes:, server: nil)
|
||||
super launcher, launcher.events
|
||||
super(launcher)
|
||||
|
||||
@index = index
|
||||
@master = master
|
||||
|
@ -52,7 +52,7 @@ module Puma
|
|||
|
||||
# Invoke any worker boot hooks so they can get
|
||||
# things in shape before booting the app.
|
||||
@launcher.config.run_hooks :before_worker_boot, index, @launcher.events
|
||||
@launcher.config.run_hooks(:before_worker_boot, index, @launcher.log_writer)
|
||||
|
||||
begin
|
||||
server = @server ||= start_server
|
||||
|
@ -83,8 +83,8 @@ module Puma
|
|||
if restart_server.length > 0
|
||||
restart_server.clear
|
||||
server.begin_restart(true)
|
||||
@launcher.config.run_hooks :before_refork, nil, @launcher.events
|
||||
Puma::Util.nakayoshi_gc @events if @options[:nakayoshi_fork]
|
||||
@launcher.config.run_hooks(:before_refork, nil, @launcher.log_writer)
|
||||
Puma::Util.nakayoshi_gc(@log_writer) if @options[:nakayoshi_fork]
|
||||
end
|
||||
elsif idx == 0 # restart server
|
||||
restart_server << true << false
|
||||
|
@ -138,7 +138,7 @@ module Puma
|
|||
|
||||
# Invoke any worker shutdown hooks so they can prevent the worker
|
||||
# exiting until any background operations are completed
|
||||
@launcher.config.run_hooks :before_worker_shutdown, index, @launcher.events
|
||||
@launcher.config.run_hooks(:before_worker_shutdown, index, @launcher.log_writer)
|
||||
ensure
|
||||
@worker_write << "t#{Process.pid}\n" rescue nil
|
||||
@worker_write.close
|
||||
|
@ -147,7 +147,7 @@ module Puma
|
|||
private
|
||||
|
||||
def spawn_worker(idx)
|
||||
@launcher.config.run_hooks :before_worker_fork, idx, @launcher.events
|
||||
@launcher.config.run_hooks(:before_worker_fork, idx, @launcher.log_writer)
|
||||
|
||||
pid = fork do
|
||||
new_worker = Worker.new index: idx,
|
||||
|
@ -165,7 +165,7 @@ module Puma
|
|||
exit! 1
|
||||
end
|
||||
|
||||
@launcher.config.run_hooks :after_worker_fork, idx, @launcher.events
|
||||
@launcher.config.run_hooks(:after_worker_fork, idx, @launcher.log_writer)
|
||||
pid
|
||||
end
|
||||
end
|
||||
|
|
|
@ -291,13 +291,13 @@ module Puma
|
|||
@plugins.create name
|
||||
end
|
||||
|
||||
def run_hooks(key, arg, events)
|
||||
def run_hooks(key, arg, log_writer)
|
||||
@options.all_of(key).each do |b|
|
||||
begin
|
||||
b.call arg
|
||||
rescue => e
|
||||
events.log "WARNING hook #{key} failed with exception (#{e.class}) #{e.message}"
|
||||
events.debug e.backtrace.join("\n")
|
||||
log_writer.log "WARNING hook #{key} failed with exception (#{e.class}) #{e.message}"
|
||||
log_writer.debug e.backtrace.join("\n")
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -293,13 +293,13 @@ module Puma
|
|||
run_args += ["-C", @config_file] if @config_file
|
||||
run_args += ["-e", @environment] if @environment
|
||||
|
||||
events = Puma::Events.new @stdout, @stderr
|
||||
log_writer = Puma::LogWriter.new(@stdout, @stderr)
|
||||
|
||||
# replace $0 because puma use it to generate restart command
|
||||
puma_cmd = $0.gsub(/pumactl$/, 'puma')
|
||||
$0 = puma_cmd if File.exist?(puma_cmd)
|
||||
|
||||
cli = Puma::CLI.new run_args, events
|
||||
cli = Puma::CLI.new run_args, log_writer
|
||||
cli.run
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,52 +1,23 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require "puma/null_io"
|
||||
require 'puma/error_logger'
|
||||
require 'stringio'
|
||||
|
||||
module Puma
|
||||
# The default implement of an event sink object used by Server
|
||||
# for when certain kinds of events occur in the life of the server.
|
||||
#
|
||||
# The methods available are the events that the Server fires.
|
||||
#
|
||||
|
||||
# This is an event sink used by `Puma::Server` to handle
|
||||
# lifecycle events such as :on_booted, :on_restart, and :on_stopped.
|
||||
# Using `Puma::DSL` it is possible to register callback hooks
|
||||
# for each event type.
|
||||
class Events
|
||||
class DefaultFormatter
|
||||
def call(str)
|
||||
str
|
||||
end
|
||||
end
|
||||
|
||||
class PidFormatter
|
||||
def call(str)
|
||||
"[#{$$}] #{str}"
|
||||
end
|
||||
end
|
||||
|
||||
# Create an Events object that prints to +stdout+ and +stderr+.
|
||||
#
|
||||
def initialize(stdout, stderr)
|
||||
@formatter = DefaultFormatter.new
|
||||
@stdout = stdout
|
||||
@stderr = stderr
|
||||
|
||||
@debug = ENV.key? 'PUMA_DEBUG'
|
||||
@error_logger = ErrorLogger.new(@stderr)
|
||||
|
||||
def initialize
|
||||
@hooks = Hash.new { |h,k| h[k] = [] }
|
||||
end
|
||||
|
||||
attr_reader :stdout, :stderr
|
||||
attr_accessor :formatter
|
||||
|
||||
# Fire callbacks for the named hook
|
||||
#
|
||||
def fire(hook, *args)
|
||||
@hooks[hook].each { |t| t.call(*args) }
|
||||
end
|
||||
|
||||
# Register a callback for a given hook
|
||||
#
|
||||
def register(hook, obj=nil, &blk)
|
||||
if obj and blk
|
||||
raise "Specify either an object or a block, not both"
|
||||
|
@ -59,79 +30,6 @@ module Puma
|
|||
h
|
||||
end
|
||||
|
||||
# Write +str+ to +@stdout+
|
||||
#
|
||||
def log(str)
|
||||
@stdout.puts format(str) if @stdout.respond_to? :puts
|
||||
|
||||
@stdout.flush unless @stdout.sync
|
||||
rescue Errno::EPIPE
|
||||
end
|
||||
|
||||
def write(str)
|
||||
@stdout.write format(str)
|
||||
end
|
||||
|
||||
def debug(str)
|
||||
log("% #{str}") if @debug
|
||||
end
|
||||
|
||||
# Write +str+ to +@stderr+
|
||||
#
|
||||
def error(str)
|
||||
@error_logger.info(text: format("ERROR: #{str}"))
|
||||
exit 1
|
||||
end
|
||||
|
||||
def format(str)
|
||||
formatter.call(str)
|
||||
end
|
||||
|
||||
# An HTTP connection error has occurred.
|
||||
# +error+ a connection exception, +req+ the request,
|
||||
# and +text+ additional info
|
||||
# @version 5.0.0
|
||||
#
|
||||
def connection_error(error, req, text="HTTP connection error")
|
||||
@error_logger.info(error: error, req: req, text: text)
|
||||
end
|
||||
|
||||
# An HTTP parse error has occurred.
|
||||
# +error+ a parsing exception,
|
||||
# and +req+ the request.
|
||||
#
|
||||
def parse_error(error, req)
|
||||
@error_logger.info(error: error, req: req, text: 'HTTP parse error, malformed request')
|
||||
end
|
||||
|
||||
# An SSL error has occurred.
|
||||
# @param error <Puma::MiniSSL::SSLError>
|
||||
# @param ssl_socket <Puma::MiniSSL::Socket>
|
||||
#
|
||||
def ssl_error(error, ssl_socket)
|
||||
peeraddr = ssl_socket.peeraddr.last rescue "<unknown>"
|
||||
peercert = ssl_socket.peercert
|
||||
subject = peercert ? peercert.subject : nil
|
||||
@error_logger.info(error: error, text: "SSL error, peer: #{peeraddr}, peer cert: #{subject}")
|
||||
end
|
||||
|
||||
# An unknown error has occurred.
|
||||
# +error+ an exception object, +req+ the request,
|
||||
# and +text+ additional info
|
||||
#
|
||||
def unknown_error(error, req=nil, text="Unknown error")
|
||||
@error_logger.info(error: error, req: req, text: text)
|
||||
end
|
||||
|
||||
# Log occurred error debug dump.
|
||||
# +error+ an exception object, +req+ the request,
|
||||
# and +text+ additional info
|
||||
# @version 5.0.0
|
||||
#
|
||||
def debug_error(error, req=nil, text="")
|
||||
@error_logger.debug(error: error, req: req, text: text)
|
||||
end
|
||||
|
||||
def on_booted(&block)
|
||||
register(:on_booted, &block)
|
||||
end
|
||||
|
@ -155,23 +53,5 @@ module Puma
|
|||
def fire_on_stopped!
|
||||
fire(:on_stopped)
|
||||
end
|
||||
|
||||
DEFAULT = new(STDOUT, STDERR)
|
||||
|
||||
# Returns an Events object which writes its status to 2 StringIO
|
||||
# objects.
|
||||
#
|
||||
def self.strings
|
||||
Events.new StringIO.new, StringIO.new
|
||||
end
|
||||
|
||||
def self.stdio
|
||||
Events.new $stdout, $stderr
|
||||
end
|
||||
|
||||
def self.null
|
||||
n = NullIO.new
|
||||
Events.new n, n
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'puma/log_writer'
|
||||
require 'puma/events'
|
||||
require 'puma/detect'
|
||||
require 'puma/cluster'
|
||||
|
@ -27,7 +28,7 @@ module Puma
|
|||
# +conf+ A Puma::Configuration object indicating how to run the server.
|
||||
#
|
||||
# +launcher_args+ A Hash that currently has one required key `:events`,
|
||||
# this is expected to hold an object similar to an `Puma::Events.stdio`,
|
||||
# this is expected to hold an object similar to an `Puma::LogWriter.stdio`,
|
||||
# this object will be responsible for broadcasting Puma's internal state
|
||||
# to a logging destination. An optional key `:argv` can be supplied,
|
||||
# this should be an array of strings, these arguments are re-used when
|
||||
|
@ -41,15 +42,16 @@ module Puma
|
|||
# [200, {}, ["hello world"]]
|
||||
# end
|
||||
# end
|
||||
# Puma::Launcher.new(conf, events: Puma::Events.stdio).run
|
||||
# Puma::Launcher.new(conf, log_writer: Puma::LogWriter.stdio).run
|
||||
def initialize(conf, launcher_args={})
|
||||
@runner = nil
|
||||
@events = launcher_args[:events] || Events::DEFAULT
|
||||
@log_writer = launcher_args[:log_writer] || LogWriter::DEFAULT
|
||||
@events = launcher_args[:events] || Events.new
|
||||
@argv = launcher_args[:argv] || []
|
||||
@original_argv = @argv.dup
|
||||
@config = conf
|
||||
|
||||
@binder = Binder.new(@events, conf)
|
||||
@binder = Binder.new(@log_writer, conf)
|
||||
@binder.create_inherited_fds(ENV).each { |k| ENV.delete k }
|
||||
@binder.create_activated_fds(ENV).each { |k| ENV.delete k }
|
||||
|
||||
|
@ -70,8 +72,8 @@ module Puma
|
|||
@options = @config.options
|
||||
@config.clamp
|
||||
|
||||
@events.formatter = Events::PidFormatter.new if clustered?
|
||||
@events.formatter = options[:log_formatter] if @options[:log_formatter]
|
||||
@log_writer.formatter = LogWriter::PidFormatter.new if clustered?
|
||||
@log_writer.formatter = options[:log_formatter] if @options[:log_formatter]
|
||||
|
||||
generate_restart_data
|
||||
|
||||
|
@ -87,11 +89,11 @@ module Puma
|
|||
set_rack_environment
|
||||
|
||||
if clustered?
|
||||
@options[:logger] = @events
|
||||
@options[:logger] = @log_writer
|
||||
|
||||
@runner = Cluster.new(self, @events)
|
||||
@runner = Cluster.new(self)
|
||||
else
|
||||
@runner = Single.new(self, @events)
|
||||
@runner = Single.new(self)
|
||||
end
|
||||
Puma.stats_object = @runner
|
||||
|
||||
|
@ -100,7 +102,7 @@ module Puma
|
|||
log_config if ENV['PUMA_LOG_CONFIG']
|
||||
end
|
||||
|
||||
attr_reader :binder, :events, :config, :options, :restart_dir
|
||||
attr_reader :binder, :log_writer, :events, :config, :options, :restart_dir
|
||||
|
||||
# Return stats about the server
|
||||
def stats
|
||||
|
@ -263,7 +265,7 @@ module Puma
|
|||
|
||||
def restart!
|
||||
@events.fire_on_restart!
|
||||
@config.run_hooks :on_restart, self, @events
|
||||
@config.run_hooks :on_restart, self, @log_writer
|
||||
|
||||
if Puma.jruby?
|
||||
close_binder_listeners
|
||||
|
@ -317,13 +319,13 @@ module Puma
|
|||
|
||||
log "* Enabling systemd notification integration"
|
||||
|
||||
systemd = Systemd.new(@events)
|
||||
systemd = Systemd.new(@log_writer, @events)
|
||||
systemd.hook_events
|
||||
systemd.start_watchdog
|
||||
end
|
||||
|
||||
def log(str)
|
||||
@events.log str
|
||||
@log_writer.log(str)
|
||||
end
|
||||
|
||||
def clustered?
|
||||
|
@ -331,7 +333,7 @@ module Puma
|
|||
end
|
||||
|
||||
def unsupported(str)
|
||||
@events.error(str)
|
||||
@log_writer.error(str)
|
||||
raise UnsupportedOption
|
||||
end
|
||||
|
||||
|
@ -362,7 +364,7 @@ module Puma
|
|||
|
||||
def prune_bundler!
|
||||
return unless prune_bundler?
|
||||
BundlePruner.new(@original_argv, @options[:extra_runtime_dependencies], @events).prune
|
||||
BundlePruner.new(@original_argv, @options[:extra_runtime_dependencies], @log_writer).prune
|
||||
end
|
||||
|
||||
def generate_restart_data
|
||||
|
@ -464,8 +466,8 @@ module Puma
|
|||
unless Puma.jruby? # INFO in use by JVM already
|
||||
Signal.trap "SIGINFO" do
|
||||
thread_status do |name, backtrace|
|
||||
@events.log name
|
||||
@events.log backtrace.map { |bt| " #{bt}" }
|
||||
@log_writer.log(name)
|
||||
@log_writer.log(backtrace.map { |bt| " #{bt}" })
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -7,10 +7,10 @@ module Puma
|
|||
# application restarts.
|
||||
class BundlePruner
|
||||
|
||||
def initialize(original_argv, extra_runtime_dependencies, events)
|
||||
def initialize(original_argv, extra_runtime_dependencies, log_writer)
|
||||
@original_argv = Array(original_argv)
|
||||
@extra_runtime_dependencies = Array(extra_runtime_dependencies)
|
||||
@events = events
|
||||
@log_writer = log_writer
|
||||
end
|
||||
|
||||
def prune
|
||||
|
@ -96,7 +96,7 @@ module Puma
|
|||
end
|
||||
|
||||
def log(str)
|
||||
@events.log(str)
|
||||
@log_writer.log(str)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,123 @@
|
|||
# frozen_string_literal: true
|
||||
|
||||
require 'puma/null_io'
|
||||
require 'puma/error_logger'
|
||||
require 'stringio'
|
||||
|
||||
module Puma
|
||||
|
||||
# Handles logging concerns for both standard messages
|
||||
# (+stdout+) and errors (+stderr+).
|
||||
class LogWriter
|
||||
|
||||
class DefaultFormatter
|
||||
def call(str)
|
||||
str
|
||||
end
|
||||
end
|
||||
|
||||
class PidFormatter
|
||||
def call(str)
|
||||
"[#{$$}] #{str}"
|
||||
end
|
||||
end
|
||||
|
||||
attr_reader :stdout,
|
||||
:stderr
|
||||
|
||||
attr_accessor :formatter
|
||||
|
||||
# Create a LogWriter that prints to +stdout+ and +stderr+.
|
||||
def initialize(stdout, stderr)
|
||||
@formatter = DefaultFormatter.new
|
||||
@stdout = stdout
|
||||
@stderr = stderr
|
||||
|
||||
@debug = ENV.key?('PUMA_DEBUG')
|
||||
@error_logger = ErrorLogger.new(@stderr)
|
||||
end
|
||||
|
||||
DEFAULT = new(STDOUT, STDERR)
|
||||
|
||||
# Returns an LogWriter object which writes its status to
|
||||
# two StringIO objects.
|
||||
def self.strings
|
||||
LogWriter.new(StringIO.new, StringIO.new)
|
||||
end
|
||||
|
||||
def self.stdio
|
||||
LogWriter.new($stdout, $stderr)
|
||||
end
|
||||
|
||||
def self.null
|
||||
n = NullIO.new
|
||||
LogWriter.new(n, n)
|
||||
end
|
||||
|
||||
# Write +str+ to +@stdout+
|
||||
def log(str)
|
||||
@stdout.puts(format(str)) if @stdout.respond_to? :puts
|
||||
|
||||
@stdout.flush unless @stdout.sync
|
||||
rescue Errno::EPIPE
|
||||
end
|
||||
|
||||
def write(str)
|
||||
@stdout.write(format(str))
|
||||
end
|
||||
|
||||
def debug(str)
|
||||
log("% #{str}") if @debug
|
||||
end
|
||||
|
||||
# Write +str+ to +@stderr+
|
||||
def error(str)
|
||||
@error_logger.info(text: format("ERROR: #{str}"))
|
||||
exit 1
|
||||
end
|
||||
|
||||
def format(str)
|
||||
formatter.call(str)
|
||||
end
|
||||
|
||||
# An HTTP connection error has occurred.
|
||||
# +error+ a connection exception, +req+ the request,
|
||||
# and +text+ additional info
|
||||
# @version 5.0.0
|
||||
def connection_error(error, req, text="HTTP connection error")
|
||||
@error_logger.info(error: error, req: req, text: text)
|
||||
end
|
||||
|
||||
# An HTTP parse error has occurred.
|
||||
# +error+ a parsing exception,
|
||||
# and +req+ the request.
|
||||
def parse_error(error, req)
|
||||
@error_logger.info(error: error, req: req, text: 'HTTP parse error, malformed request')
|
||||
end
|
||||
|
||||
# An SSL error has occurred.
|
||||
# @param error <Puma::MiniSSL::SSLError>
|
||||
# @param ssl_socket <Puma::MiniSSL::Socket>
|
||||
def ssl_error(error, ssl_socket)
|
||||
peeraddr = ssl_socket.peeraddr.last rescue "<unknown>"
|
||||
peercert = ssl_socket.peercert
|
||||
subject = peercert ? peercert.subject : nil
|
||||
@error_logger.info(error: error, text: "SSL error, peer: #{peeraddr}, peer cert: #{subject}")
|
||||
end
|
||||
|
||||
# An unknown error has occurred.
|
||||
# +error+ an exception object, +req+ the request,
|
||||
# and +text+ additional info
|
||||
def unknown_error(error, req=nil, text="Unknown error")
|
||||
@error_logger.info(error: error, req: req, text: text)
|
||||
end
|
||||
|
||||
# Log occurred error debug dump.
|
||||
# +error+ an exception object, +req+ the request,
|
||||
# and +text+ additional info
|
||||
# @version 5.0.0
|
||||
def debug_error(error, req=nil, text="")
|
||||
@error_logger.debug(error: error, req: req, text: text)
|
||||
end
|
||||
end
|
||||
end
|
|
@ -11,27 +11,27 @@ module Puma
|
|||
|
||||
if defined?(JRUBY_VERSION)
|
||||
unless params['keystore']
|
||||
events.error "Please specify the Java keystore via 'keystore='"
|
||||
log_writer.error "Please specify the Java keystore via 'keystore='"
|
||||
end
|
||||
|
||||
ctx.keystore = params['keystore']
|
||||
|
||||
unless params['keystore-pass']
|
||||
events.error "Please specify the Java keystore password via 'keystore-pass='"
|
||||
log_writer.error "Please specify the Java keystore password via 'keystore-pass='"
|
||||
end
|
||||
|
||||
ctx.keystore_pass = params['keystore-pass']
|
||||
ctx.ssl_cipher_list = params['ssl_cipher_list'] if params['ssl_cipher_list']
|
||||
else
|
||||
if params['key'].nil? && params['key_pem'].nil?
|
||||
events.error "Please specify the SSL key via 'key=' or 'key_pem='"
|
||||
log_writer.error "Please specify the SSL key via 'key=' or 'key_pem='"
|
||||
end
|
||||
|
||||
ctx.key = params['key'] if params['key']
|
||||
ctx.key_pem = params['key_pem'] if params['key_pem']
|
||||
|
||||
if params['cert'].nil? && params['cert_pem'].nil?
|
||||
events.error "Please specify the SSL cert via 'cert=' or 'cert_pem='"
|
||||
log_writer.error "Please specify the SSL cert via 'cert=' or 'cert_pem='"
|
||||
end
|
||||
|
||||
ctx.cert = params['cert'] if params['cert']
|
||||
|
@ -39,7 +39,7 @@ module Puma
|
|||
|
||||
if ['peer', 'force_peer'].include?(params['verify_mode'])
|
||||
unless params['ca']
|
||||
events.error "Please specify the SSL ca via 'ca='"
|
||||
log_writer.error "Please specify the SSL ca via 'ca='"
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -59,7 +59,7 @@ module Puma
|
|||
when "none"
|
||||
MiniSSL::VERIFY_NONE
|
||||
else
|
||||
events.error "Please specify a valid verify_mode="
|
||||
log_writer.error "Please specify a valid verify_mode="
|
||||
MiniSSL::VERIFY_NONE
|
||||
end
|
||||
end
|
||||
|
|
|
@ -58,7 +58,7 @@ module Puma
|
|||
begin
|
||||
fast_write io, str_early_hints(headers)
|
||||
rescue ConnectionError => e
|
||||
@events.debug_error e
|
||||
@log_writer.debug_error e
|
||||
# noop, if we lost the socket we just won't send the early hints
|
||||
end
|
||||
}
|
||||
|
@ -89,12 +89,12 @@ module Puma
|
|||
return :async
|
||||
end
|
||||
rescue ThreadPool::ForceShutdown => e
|
||||
@events.unknown_error e, client, "Rack app"
|
||||
@events.log "Detected force shutdown of a thread"
|
||||
@log_writer.unknown_error e, client, "Rack app"
|
||||
@log_writer.log "Detected force shutdown of a thread"
|
||||
|
||||
status, headers, res_body = lowlevel_error(e, env, 503)
|
||||
rescue Exception => e
|
||||
@events.unknown_error e, client, "Rack app"
|
||||
@log_writer.unknown_error e, client, "Rack app"
|
||||
|
||||
status, headers, res_body = lowlevel_error(e, env, 500)
|
||||
end
|
||||
|
|
|
@ -8,10 +8,11 @@ module Puma
|
|||
# serve requests. This class spawns a new instance of `Puma::Server` via
|
||||
# a call to `start_server`.
|
||||
class Runner
|
||||
def initialize(cli, events)
|
||||
@launcher = cli
|
||||
@events = events
|
||||
@options = cli.options
|
||||
def initialize(launcher)
|
||||
@launcher = launcher
|
||||
@log_writer = launcher.log_writer
|
||||
@events = launcher.events
|
||||
@options = launcher.options
|
||||
@app = nil
|
||||
@control = nil
|
||||
@started_at = Time.now
|
||||
|
@ -40,7 +41,7 @@ module Puma
|
|||
end
|
||||
|
||||
def log(str)
|
||||
@events.log str
|
||||
@log_writer.log str
|
||||
end
|
||||
|
||||
# @version 5.0.0
|
||||
|
@ -49,11 +50,11 @@ module Puma
|
|||
end
|
||||
|
||||
def error(str)
|
||||
@events.error str
|
||||
@log_writer.error str
|
||||
end
|
||||
|
||||
def debug(str)
|
||||
@events.log "- #{str}" if @options[:debug]
|
||||
@log_writer.log "- #{str}" if @options[:debug]
|
||||
end
|
||||
|
||||
def start_control
|
||||
|
@ -68,7 +69,7 @@ module Puma
|
|||
|
||||
app = Puma::App::Status.new @launcher, token
|
||||
|
||||
control = Puma::Server.new app, @launcher.events,
|
||||
control = Puma::Server.new app, @log_writer, @events,
|
||||
{ min_threads: 0, max_threads: 1, queue_requests: false }
|
||||
|
||||
control.binder.parse [str], self, 'Starting control server'
|
||||
|
@ -166,8 +167,8 @@ module Puma
|
|||
end
|
||||
|
||||
def start_server
|
||||
server = Puma::Server.new app, @launcher.events, @options
|
||||
server.inherit_binder @launcher.binder
|
||||
server = Puma::Server.new(app, @log_writer, @events, @options)
|
||||
server.inherit_binder(@launcher.binder)
|
||||
server
|
||||
end
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@ require 'stringio'
|
|||
|
||||
require 'puma/thread_pool'
|
||||
require 'puma/const'
|
||||
require 'puma/log_writer'
|
||||
require 'puma/events'
|
||||
require 'puma/null_io'
|
||||
require 'puma/reactor'
|
||||
|
@ -36,6 +37,7 @@ module Puma
|
|||
extend Forwardable
|
||||
|
||||
attr_reader :thread
|
||||
attr_reader :log_writer
|
||||
attr_reader :events
|
||||
attr_reader :min_threads, :max_threads # for #stats
|
||||
attr_reader :requests_count # @version 5.0.0
|
||||
|
@ -60,8 +62,9 @@ module Puma
|
|||
|
||||
# Create a server for the rack app +app+.
|
||||
#
|
||||
# +events+ is an object which will be called when certain error events occur
|
||||
# to be handled. See Puma::Events for the list of current methods to implement.
|
||||
# +log_writer+ is a Puma::LogWriter object used to log info and error messages.
|
||||
#
|
||||
# +events+ is a Puma::Events object used to notify application status events.
|
||||
#
|
||||
# Server#run returns a thread that you can join on to wait for the server
|
||||
# to do its work.
|
||||
|
@ -70,8 +73,9 @@ module Puma
|
|||
# and have default values set via +fetch+. Normally the values are set via
|
||||
# `::Puma::Configuration.puma_default_options`.
|
||||
#
|
||||
def initialize(app, events=Events.stdio, options={})
|
||||
def initialize(app, log_writer=LogWriter.stdio, events=Events.new, options={})
|
||||
@app = app
|
||||
@log_writer = log_writer
|
||||
@events = events
|
||||
|
||||
@check, @notify = nil
|
||||
|
@ -97,7 +101,7 @@ module Puma
|
|||
temp = !!(@options[:environment] =~ /\A(development|test)\z/)
|
||||
@leak_stack_on_error = @options[:environment] ? temp : true
|
||||
|
||||
@binder = Binder.new(events)
|
||||
@binder = Binder.new(log_writer)
|
||||
|
||||
ENV['RACK_ENV'] ||= "development"
|
||||
|
||||
|
@ -353,11 +357,11 @@ module Puma
|
|||
# In the case that any of the sockets are unexpectedly close.
|
||||
raise
|
||||
rescue StandardError => e
|
||||
@events.unknown_error e, nil, "Listen loop"
|
||||
@log_writer.unknown_error e, nil, "Listen loop"
|
||||
end
|
||||
end
|
||||
|
||||
@events.debug "Drained #{drain} additional connections." if drain
|
||||
@log_writer.debug "Drained #{drain} additional connections." if drain
|
||||
@events.fire :state, @status
|
||||
|
||||
if queue_requests
|
||||
|
@ -366,7 +370,7 @@ module Puma
|
|||
end
|
||||
graceful_shutdown if @status == :stop || @status == :restart
|
||||
rescue Exception => e
|
||||
@events.unknown_error e, nil, "Exception handling servers"
|
||||
@log_writer.unknown_error e, nil, "Exception handling servers"
|
||||
ensure
|
||||
# RuntimeError is Ruby 2.2 issue, can't modify frozen IOError
|
||||
# Errno::EBADF is infrequently raised
|
||||
|
@ -488,7 +492,7 @@ module Puma
|
|||
Puma::Util.purge_interrupt_queue
|
||||
# Already closed
|
||||
rescue StandardError => e
|
||||
@events.unknown_error e, nil, "Client"
|
||||
@log_writer.unknown_error e, nil, "Client"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
@ -511,13 +515,13 @@ module Puma
|
|||
lowlevel_error(e, client.env)
|
||||
case e
|
||||
when MiniSSL::SSLError
|
||||
@events.ssl_error e, client.io
|
||||
@log_writer.ssl_error e, client.io
|
||||
when HttpParserError
|
||||
client.write_error(400)
|
||||
@events.parse_error e, client
|
||||
@log_writer.parse_error e, client
|
||||
else
|
||||
client.write_error(500)
|
||||
@events.unknown_error e, nil, "Read"
|
||||
@log_writer.unknown_error e, nil, "Read"
|
||||
end
|
||||
end
|
||||
|
||||
|
|
|
@ -4,7 +4,8 @@ require 'sd_notify'
|
|||
|
||||
module Puma
|
||||
class Systemd
|
||||
def initialize(events)
|
||||
def initialize(log_writer, events)
|
||||
@log_writer = log_writer
|
||||
@events = events
|
||||
end
|
||||
|
||||
|
@ -40,7 +41,7 @@ module Puma
|
|||
end
|
||||
|
||||
def log(str)
|
||||
@events.log str
|
||||
@log_writer.log(str)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -31,14 +31,14 @@ module Puma
|
|||
module_function :unescape
|
||||
|
||||
# @version 5.0.0
|
||||
def nakayoshi_gc(events)
|
||||
events.log "! Promoting existing objects to old generation..."
|
||||
def nakayoshi_gc(log_writer)
|
||||
log_writer.log "! Promoting existing objects to old generation..."
|
||||
4.times { GC.start(full_mark: false) }
|
||||
if GC.respond_to?(:compact)
|
||||
events.log "! Compacting..."
|
||||
log_writer.log "! Compacting..."
|
||||
GC.compact
|
||||
end
|
||||
events.log "! Friendly fork preparation complete."
|
||||
log_writer.log "! Friendly fork preparation complete."
|
||||
end
|
||||
|
||||
DEFAULT_SEP = /[&;] */n
|
||||
|
|
|
@ -13,7 +13,7 @@ module Rack
|
|||
def self.config(app, options = {})
|
||||
require 'puma'
|
||||
require 'puma/configuration'
|
||||
require 'puma/events'
|
||||
require 'puma/log_writer'
|
||||
require 'puma/launcher'
|
||||
|
||||
default_options = DEFAULT_OPTIONS.dup
|
||||
|
@ -63,9 +63,9 @@ module Rack
|
|||
def self.run(app, **options)
|
||||
conf = self.config(app, options)
|
||||
|
||||
events = options.delete(:Silent) ? ::Puma::Events.strings : ::Puma::Events.stdio
|
||||
log_writer = options.delete(:Silent) ? ::Puma::LogWriter.strings : ::Puma::LogWriter.stdio
|
||||
|
||||
launcher = ::Puma::Launcher.new(conf, :events => events)
|
||||
launcher = ::Puma::Launcher.new(conf, :log_writer => log_writer)
|
||||
|
||||
yield launcher if block_given?
|
||||
begin
|
||||
|
|
|
@ -33,8 +33,8 @@ require "puma/detect"
|
|||
# used in various ssl test files, see test_puma_server_ssl.rb and
|
||||
# test_puma_localhost_authority.rb
|
||||
if Puma::HAS_SSL
|
||||
require "puma/events"
|
||||
class SSLEventsHelper < ::Puma::Events
|
||||
require 'puma/log_writer'
|
||||
class SSLLogWriterHelper < ::Puma::LogWriter
|
||||
attr_accessor :addr, :cert, :error
|
||||
|
||||
def ssl_error(error, ssl_socket)
|
||||
|
|
|
@ -13,8 +13,8 @@ class TestBinderBase < Minitest::Test
|
|||
include TmpPath
|
||||
|
||||
def setup
|
||||
@events = Puma::Events.strings
|
||||
@binder = Puma::Binder.new(@events)
|
||||
@log_writer = Puma::LogWriter.strings
|
||||
@binder = Puma::Binder.new(@log_writer)
|
||||
end
|
||||
|
||||
def teardown
|
||||
|
@ -80,14 +80,14 @@ class TestBinder < TestBinderBase
|
|||
end
|
||||
|
||||
def test_localhost_addresses_dont_alter_listeners_for_tcp_addresses
|
||||
@binder.parse ["tcp://localhost:0"], @events
|
||||
@binder.parse ["tcp://localhost:0"], @log_writer
|
||||
|
||||
assert_empty @binder.listeners
|
||||
end
|
||||
|
||||
def test_home_alters_listeners_for_tcp_addresses
|
||||
port = UniquePort.call
|
||||
@binder.parse ["tcp://127.0.0.1:#{port}"], @events
|
||||
@binder.parse ["tcp://127.0.0.1:#{port}"], @log_writer
|
||||
|
||||
assert_equal "tcp://127.0.0.1:#{port}", @binder.listeners[0][0]
|
||||
assert_kind_of TCPServer, @binder.listeners[0][1]
|
||||
|
@ -96,14 +96,14 @@ class TestBinder < TestBinderBase
|
|||
def test_connected_ports
|
||||
ports = (1..3).map { |_| UniquePort.call }
|
||||
|
||||
@binder.parse(ports.map { |p| "tcp://localhost:#{p}" }, @events)
|
||||
@binder.parse(ports.map { |p| "tcp://localhost:#{p}" }, @log_writer)
|
||||
|
||||
assert_equal ports, @binder.connected_ports
|
||||
end
|
||||
|
||||
def test_localhost_addresses_dont_alter_listeners_for_ssl_addresses
|
||||
skip_unless :ssl
|
||||
@binder.parse ["ssl://localhost:0?#{ssl_query}"], @events
|
||||
@binder.parse ["ssl://localhost:0?#{ssl_query}"], @log_writer
|
||||
|
||||
assert_empty @binder.listeners
|
||||
end
|
||||
|
@ -111,16 +111,16 @@ class TestBinder < TestBinderBase
|
|||
def test_home_alters_listeners_for_ssl_addresses
|
||||
skip_unless :ssl
|
||||
port = UniquePort.call
|
||||
@binder.parse ["ssl://127.0.0.1:#{port}?#{ssl_query}"], @events
|
||||
@binder.parse ["ssl://127.0.0.1:#{port}?#{ssl_query}"], @log_writer
|
||||
|
||||
assert_equal "ssl://127.0.0.1:#{port}?#{ssl_query}", @binder.listeners[0][0]
|
||||
assert_kind_of TCPServer, @binder.listeners[0][1]
|
||||
end
|
||||
|
||||
def test_correct_zero_port
|
||||
@binder.parse ["tcp://localhost:0"], @events
|
||||
@binder.parse ["tcp://localhost:0"], @log_writer
|
||||
|
||||
m = %r!http://127.0.0.1:(\d+)!.match(@events.stdout.string)
|
||||
m = %r!http://127.0.0.1:(\d+)!.match(@log_writer.stdout.string)
|
||||
port = m[1].to_i
|
||||
|
||||
refute_equal 0, port
|
||||
|
@ -131,30 +131,30 @@ class TestBinder < TestBinderBase
|
|||
|
||||
ssl_regex = %r!ssl://127.0.0.1:(\d+)!
|
||||
|
||||
@binder.parse ["ssl://localhost:0?#{ssl_query}"], @events
|
||||
@binder.parse ["ssl://localhost:0?#{ssl_query}"], @log_writer
|
||||
|
||||
port = ssl_regex.match(@events.stdout.string)[1].to_i
|
||||
port = ssl_regex.match(@log_writer.stdout.string)[1].to_i
|
||||
|
||||
refute_equal 0, port
|
||||
end
|
||||
|
||||
def test_logs_all_localhost_bindings
|
||||
@binder.parse ["tcp://localhost:0"], @events
|
||||
@binder.parse ["tcp://localhost:0"], @log_writer
|
||||
|
||||
assert_match %r!http://127.0.0.1:(\d+)!, @events.stdout.string
|
||||
assert_match %r!http://127.0.0.1:(\d+)!, @log_writer.stdout.string
|
||||
if Socket.ip_address_list.any? {|i| i.ipv6_loopback? }
|
||||
assert_match %r!http://\[::1\]:(\d+)!, @events.stdout.string
|
||||
assert_match %r!http://\[::1\]:(\d+)!, @log_writer.stdout.string
|
||||
end
|
||||
end
|
||||
|
||||
def test_logs_all_localhost_bindings_ssl
|
||||
skip_unless :ssl
|
||||
|
||||
@binder.parse ["ssl://localhost:0?#{ssl_query}"], @events
|
||||
@binder.parse ["ssl://localhost:0?#{ssl_query}"], @log_writer
|
||||
|
||||
assert_match %r!ssl://127.0.0.1:(\d+)!, @events.stdout.string
|
||||
assert_match %r!ssl://127.0.0.1:(\d+)!, @log_writer.stdout.string
|
||||
if Socket.ip_address_list.any? {|i| i.ipv6_loopback? }
|
||||
assert_match %r!ssl://\[::1\]:(\d+)!, @events.stdout.string
|
||||
assert_match %r!ssl://\[::1\]:(\d+)!, @log_writer.stdout.string
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -176,9 +176,9 @@ class TestBinder < TestBinderBase
|
|||
|
||||
unix_path = tmp_path('.sock')
|
||||
File.open(unix_path, mode: 'wb') { |f| f.puts 'pre existing' }
|
||||
@binder.parse ["unix://#{unix_path}"], @events
|
||||
@binder.parse ["unix://#{unix_path}"], @log_writer
|
||||
|
||||
assert_match %r!unix://#{unix_path}!, @events.stdout.string
|
||||
assert_match %r!unix://#{unix_path}!, @log_writer.stdout.string
|
||||
|
||||
refute_includes @binder.unix_paths, unix_path
|
||||
|
||||
|
@ -194,7 +194,7 @@ class TestBinder < TestBinderBase
|
|||
|
||||
def test_binder_parses_nil_low_latency
|
||||
skip_if :jruby
|
||||
@binder.parse ["tcp://0.0.0.0:0?low_latency"], @events
|
||||
@binder.parse ["tcp://0.0.0.0:0?low_latency"], @log_writer
|
||||
|
||||
socket = @binder.listeners.first.last
|
||||
|
||||
|
@ -203,7 +203,7 @@ class TestBinder < TestBinderBase
|
|||
|
||||
def test_binder_parses_true_low_latency
|
||||
skip_if :jruby
|
||||
@binder.parse ["tcp://0.0.0.0:0?low_latency=true"], @events
|
||||
@binder.parse ["tcp://0.0.0.0:0?low_latency=true"], @log_writer
|
||||
|
||||
socket = @binder.listeners.first.last
|
||||
|
||||
|
@ -212,7 +212,7 @@ class TestBinder < TestBinderBase
|
|||
|
||||
def test_binder_parses_false_low_latency
|
||||
skip_if :jruby
|
||||
@binder.parse ["tcp://0.0.0.0:0?low_latency=false"], @events
|
||||
@binder.parse ["tcp://0.0.0.0:0?low_latency=false"], @log_writer
|
||||
|
||||
socket = @binder.listeners.first.last
|
||||
|
||||
|
@ -221,21 +221,21 @@ class TestBinder < TestBinderBase
|
|||
|
||||
def test_binder_parses_tlsv1_disabled
|
||||
skip_unless :ssl
|
||||
@binder.parse ["ssl://0.0.0.0:0?#{ssl_query}&no_tlsv1=true"], @events
|
||||
@binder.parse ["ssl://0.0.0.0:0?#{ssl_query}&no_tlsv1=true"], @log_writer
|
||||
|
||||
assert ssl_context_for_binder.no_tlsv1
|
||||
end
|
||||
|
||||
def test_binder_parses_tlsv1_enabled
|
||||
skip_unless :ssl
|
||||
@binder.parse ["ssl://0.0.0.0:0?#{ssl_query}&no_tlsv1=false"], @events
|
||||
@binder.parse ["ssl://0.0.0.0:0?#{ssl_query}&no_tlsv1=false"], @log_writer
|
||||
|
||||
refute ssl_context_for_binder.no_tlsv1
|
||||
end
|
||||
|
||||
def test_binder_parses_tlsv1_tlsv1_1_unspecified_defaults_to_enabled
|
||||
skip_unless :ssl
|
||||
@binder.parse ["ssl://0.0.0.0:0?#{ssl_query}"], @events
|
||||
@binder.parse ["ssl://0.0.0.0:0?#{ssl_query}"], @log_writer
|
||||
|
||||
refute ssl_context_for_binder.no_tlsv1
|
||||
refute ssl_context_for_binder.no_tlsv1_1
|
||||
|
@ -243,21 +243,21 @@ class TestBinder < TestBinderBase
|
|||
|
||||
def test_binder_parses_tlsv1_1_disabled
|
||||
skip_unless :ssl
|
||||
@binder.parse ["ssl://0.0.0.0:0?#{ssl_query}&no_tlsv1_1=true"], @events
|
||||
@binder.parse ["ssl://0.0.0.0:0?#{ssl_query}&no_tlsv1_1=true"], @log_writer
|
||||
|
||||
assert ssl_context_for_binder.no_tlsv1_1
|
||||
end
|
||||
|
||||
def test_binder_parses_tlsv1_1_enabled
|
||||
skip_unless :ssl
|
||||
@binder.parse ["ssl://0.0.0.0:0?#{ssl_query}&no_tlsv1_1=false"], @events
|
||||
@binder.parse ["ssl://0.0.0.0:0?#{ssl_query}&no_tlsv1_1=false"], @log_writer
|
||||
|
||||
refute ssl_context_for_binder.no_tlsv1_1
|
||||
end
|
||||
|
||||
def test_env_contains_protoenv
|
||||
skip_unless :ssl
|
||||
@binder.parse ["ssl://localhost:0?#{ssl_query}"], @events
|
||||
@binder.parse ["ssl://localhost:0?#{ssl_query}"], @log_writer
|
||||
|
||||
env_hash = @binder.envs[@binder.ios.first]
|
||||
|
||||
|
@ -268,11 +268,11 @@ class TestBinder < TestBinderBase
|
|||
|
||||
def test_env_contains_stderr
|
||||
skip_unless :ssl
|
||||
@binder.parse ["ssl://localhost:0?#{ssl_query}"], @events
|
||||
@binder.parse ["ssl://localhost:0?#{ssl_query}"], @log_writer
|
||||
|
||||
env_hash = @binder.envs[@binder.ios.first]
|
||||
|
||||
assert_equal @events.stderr, env_hash["rack.errors"]
|
||||
assert_equal @log_writer.stderr, env_hash["rack.errors"]
|
||||
end
|
||||
|
||||
def test_ssl_binder_sets_backlog
|
||||
|
@ -287,7 +287,7 @@ class TestBinder < TestBinderBase
|
|||
end
|
||||
|
||||
TCPServer.stub(:new, tcp_server) do
|
||||
@binder.parse ["ssl://#{host}:#{port}?#{ssl_query}&backlog=2048"], @events
|
||||
@binder.parse ["ssl://#{host}:#{port}?#{ssl_query}&backlog=2048"], @log_writer
|
||||
end
|
||||
|
||||
assert_equal 2048, Thread.current[:backlog]
|
||||
|
@ -304,7 +304,7 @@ class TestBinder < TestBinderBase
|
|||
end
|
||||
|
||||
def test_redirects_for_restart_creates_a_hash
|
||||
@binder.parse ["tcp://127.0.0.1:0"], @events
|
||||
@binder.parse ["tcp://127.0.0.1:0"], @log_writer
|
||||
|
||||
result = @binder.redirects_for_restart
|
||||
ios = @binder.listeners.map { |_l, io| io.to_i }
|
||||
|
@ -314,7 +314,7 @@ class TestBinder < TestBinderBase
|
|||
end
|
||||
|
||||
def test_redirects_for_restart_env
|
||||
@binder.parse ["tcp://127.0.0.1:0"], @events
|
||||
@binder.parse ["tcp://127.0.0.1:0"], @log_writer
|
||||
|
||||
result = @binder.redirects_for_restart_env
|
||||
|
||||
|
@ -324,7 +324,7 @@ class TestBinder < TestBinderBase
|
|||
end
|
||||
|
||||
def test_close_listeners_closes_ios
|
||||
@binder.parse ["tcp://127.0.0.1:#{UniquePort.call}"], @events
|
||||
@binder.parse ["tcp://127.0.0.1:#{UniquePort.call}"], @log_writer
|
||||
|
||||
refute @binder.listeners.any? { |_l, io| io.closed? }
|
||||
|
||||
|
@ -334,7 +334,7 @@ class TestBinder < TestBinderBase
|
|||
end
|
||||
|
||||
def test_close_listeners_closes_ios_unless_closed?
|
||||
@binder.parse ["tcp://127.0.0.1:0"], @events
|
||||
@binder.parse ["tcp://127.0.0.1:0"], @log_writer
|
||||
|
||||
bomb = @binder.listeners.first[1]
|
||||
bomb.close
|
||||
|
@ -351,7 +351,7 @@ class TestBinder < TestBinderBase
|
|||
skip_unless :unix
|
||||
|
||||
unix_path = tmp_path('.sock')
|
||||
@binder.parse ["unix://#{unix_path}"], @events
|
||||
@binder.parse ["unix://#{unix_path}"], @log_writer
|
||||
assert File.socket?(unix_path)
|
||||
|
||||
@binder.close_listeners
|
||||
|
@ -359,7 +359,7 @@ class TestBinder < TestBinderBase
|
|||
end
|
||||
|
||||
def test_import_from_env_listen_inherit
|
||||
@binder.parse ["tcp://127.0.0.1:0"], @events
|
||||
@binder.parse ["tcp://127.0.0.1:0"], @log_writer
|
||||
removals = @binder.create_inherited_fds(@binder.redirects_for_restart_env)
|
||||
|
||||
@binder.listeners.each do |l, io|
|
||||
|
@ -399,7 +399,7 @@ class TestBinder < TestBinderBase
|
|||
end
|
||||
|
||||
def test_rack_multithread_default_configuration
|
||||
binder = Puma::Binder.new(@events)
|
||||
binder = Puma::Binder.new(@log_writer)
|
||||
|
||||
assert binder.proto_env["rack.multithread"]
|
||||
end
|
||||
|
@ -407,13 +407,13 @@ class TestBinder < TestBinderBase
|
|||
def test_rack_multithread_custom_configuration
|
||||
conf = Puma::Configuration.new(max_threads: 1)
|
||||
|
||||
binder = Puma::Binder.new(@events, conf)
|
||||
binder = Puma::Binder.new(@log_writer, conf)
|
||||
|
||||
refute binder.proto_env["rack.multithread"]
|
||||
end
|
||||
|
||||
def test_rack_multiprocess_default_configuration
|
||||
binder = Puma::Binder.new(@events)
|
||||
binder = Puma::Binder.new(@log_writer)
|
||||
|
||||
refute binder.proto_env["rack.multiprocess"]
|
||||
end
|
||||
|
@ -421,7 +421,7 @@ class TestBinder < TestBinderBase
|
|||
def test_rack_multiprocess_custom_configuration
|
||||
conf = Puma::Configuration.new(workers: 1)
|
||||
|
||||
binder = Puma::Binder.new(@events, conf)
|
||||
binder = Puma::Binder.new(@log_writer, conf)
|
||||
|
||||
assert binder.proto_env["rack.multiprocess"]
|
||||
end
|
||||
|
@ -430,7 +430,7 @@ class TestBinder < TestBinderBase
|
|||
|
||||
def assert_activates_sockets(path: nil, port: nil, url: nil, sock: nil)
|
||||
hash = { "LISTEN_FDS" => 1, "LISTEN_PID" => $$ }
|
||||
@events.instance_variable_set(:@debug, true)
|
||||
@log_writer.instance_variable_set(:@debug, true)
|
||||
|
||||
@binder.instance_variable_set(:@sock_fd, sock.fileno)
|
||||
def @binder.socket_activation_fd(int); @sock_fd; end
|
||||
|
@ -440,7 +440,7 @@ class TestBinder < TestBinderBase
|
|||
ary = path ? [:unix, path] : [:tcp, url, port]
|
||||
|
||||
assert_kind_of TCPServer, @binder.activated_sockets[ary]
|
||||
assert_match "Registered #{ary.join(":")} for activation from LISTEN_FDS", @events.stdout.string
|
||||
assert_match "Registered #{ary.join(":")} for activation from LISTEN_FDS", @log_writer.stdout.string
|
||||
assert_equal ["LISTEN_FDS", "LISTEN_PID"], @result
|
||||
end
|
||||
|
||||
|
@ -461,8 +461,8 @@ class TestBinder < TestBinderBase
|
|||
|
||||
tested_paths = [prepared_paths[order[0]], prepared_paths[order[1]]]
|
||||
|
||||
@binder.parse tested_paths, @events
|
||||
stdout = @events.stdout.string
|
||||
@binder.parse tested_paths, @log_writer
|
||||
stdout = @log_writer.stdout.string
|
||||
|
||||
order.each do |prot|
|
||||
assert_match expected_logs[prot], stdout
|
||||
|
@ -479,7 +479,7 @@ class TestBinderJRuby < TestBinderBase
|
|||
keystore = File.expand_path "../../examples/puma/keystore.jks", __FILE__
|
||||
ssl_cipher_list = "TLS_DHE_RSA_WITH_AES_128_CBC_SHA,TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256"
|
||||
|
||||
@binder.parse ["ssl://0.0.0.0:8080?#{ssl_query}"], @events
|
||||
@binder.parse ["ssl://0.0.0.0:8080?#{ssl_query}"], @log_writer
|
||||
|
||||
assert_equal keystore, ssl_context_for_binder.keystore
|
||||
assert_equal ssl_cipher_list, ssl_context_for_binder.ssl_cipher_list
|
||||
|
@ -492,7 +492,7 @@ class TestBinderMRI < TestBinderBase
|
|||
|
||||
ssl_cipher_filter = "AES@STRENGTH"
|
||||
|
||||
@binder.parse ["ssl://0.0.0.0?#{ssl_query}&ssl_cipher_filter=#{ssl_cipher_filter}"], @events
|
||||
@binder.parse ["ssl://0.0.0.0?#{ssl_query}&ssl_cipher_filter=#{ssl_cipher_filter}"], @log_writer
|
||||
|
||||
assert_equal ssl_cipher_filter, ssl_context_for_binder.ssl_cipher_filter
|
||||
end
|
||||
|
@ -502,7 +502,7 @@ class TestBinderMRI < TestBinderBase
|
|||
|
||||
input = "&verification_flags=TRUSTED_FIRST"
|
||||
|
||||
@binder.parse ["ssl://0.0.0.0?#{ssl_query}#{input}"], @events
|
||||
@binder.parse ["ssl://0.0.0.0?#{ssl_query}#{input}"], @log_writer
|
||||
|
||||
assert_equal 0x8000, ssl_context_for_binder.verification_flags
|
||||
end
|
||||
|
@ -512,7 +512,7 @@ class TestBinderMRI < TestBinderBase
|
|||
|
||||
input = "&verification_flags=TRUSTED_FIRST,NO_CHECK_TIME"
|
||||
|
||||
@binder.parse ["ssl://0.0.0.0?#{ssl_query}#{input}"], @events
|
||||
@binder.parse ["ssl://0.0.0.0?#{ssl_query}#{input}"], @log_writer
|
||||
|
||||
assert_equal 0x8000 | 0x200000, ssl_context_for_binder.verification_flags
|
||||
end
|
||||
|
|
|
@ -52,6 +52,6 @@ class TestBundlePruner < Minitest::Test
|
|||
private
|
||||
|
||||
def bundle_pruner(original_argv = nil, extra_runtime_dependencies = nil)
|
||||
@bundle_pruner ||= Puma::Launcher::BundlePruner.new(original_argv, extra_runtime_dependencies, Puma::Events.null)
|
||||
@bundle_pruner ||= Puma::Launcher::BundlePruner.new(original_argv, extra_runtime_dependencies, Puma::LogWriter.null)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -53,7 +53,7 @@ class TestBusyWorker < Minitest::Test
|
|||
end
|
||||
end
|
||||
|
||||
@server = Puma::Server.new request_handler, Puma::Events.strings, **options
|
||||
@server = Puma::Server.new request_handler, Puma::LogWriter.strings, Puma::Events.new, **options
|
||||
@server.min_threads = options[:min_threads] || 0
|
||||
@server.max_threads = options[:max_threads] || 10
|
||||
@port = (@server.add_tcp_listener '127.0.0.1', 0).addr[1]
|
||||
|
|
|
@ -21,7 +21,9 @@ class TestCLI < Minitest::Test
|
|||
|
||||
@wait, @ready = IO.pipe
|
||||
|
||||
@events = Puma::Events.strings
|
||||
@log_writer = Puma::LogWriter.strings
|
||||
|
||||
@events = Puma::Events.new
|
||||
@events.on_booted { @ready << "!" }
|
||||
end
|
||||
|
||||
|
@ -47,7 +49,7 @@ class TestCLI < Minitest::Test
|
|||
cli = Puma::CLI.new ["-b", "tcp://127.0.0.1:0",
|
||||
"--control-url", url,
|
||||
"--control-token", "",
|
||||
"test/rackup/lobster.ru"], @events
|
||||
"test/rackup/lobster.ru"], @log_writer, @events
|
||||
|
||||
t = Thread.new do
|
||||
cli.run
|
||||
|
@ -82,7 +84,7 @@ class TestCLI < Minitest::Test
|
|||
cli = Puma::CLI.new ["-b", "tcp://127.0.0.1:0",
|
||||
"--control-url", control_url,
|
||||
"--control-token", token,
|
||||
"test/rackup/lobster.ru"], @events
|
||||
"test/rackup/lobster.ru"], @log_writer, @events
|
||||
|
||||
t = Thread.new do
|
||||
cli.run
|
||||
|
@ -118,7 +120,7 @@ class TestCLI < Minitest::Test
|
|||
"-w", "2",
|
||||
"--control-url", url,
|
||||
"--control-token", "",
|
||||
"test/rackup/lobster.ru"], @events
|
||||
"test/rackup/lobster.ru"], @log_writer, @events
|
||||
|
||||
# without this, Minitest.after_run will trigger on this test ?
|
||||
$debugging_hold = true
|
||||
|
@ -150,8 +152,8 @@ class TestCLI < Minitest::Test
|
|||
|
||||
done = nil
|
||||
until done
|
||||
@events.stdout.rewind
|
||||
log = @events.stdout.readlines.join ''
|
||||
@log_writer.stdout.rewind
|
||||
log = @log_writer.stdout.readlines.join ''
|
||||
done = log[/ - Goodbye!/]
|
||||
end
|
||||
|
||||
|
@ -166,7 +168,7 @@ class TestCLI < Minitest::Test
|
|||
cli = Puma::CLI.new ["-b", "unix://#{@tmp_path2}",
|
||||
"--control-url", url,
|
||||
"--control-token", "",
|
||||
"test/rackup/lobster.ru"], @events
|
||||
"test/rackup/lobster.ru"], @log_writer, @events
|
||||
|
||||
t = Thread.new { cli.run }
|
||||
|
||||
|
@ -193,7 +195,7 @@ class TestCLI < Minitest::Test
|
|||
cli = Puma::CLI.new ["-b", "unix://#{@tmp_path2}",
|
||||
"--control-url", url,
|
||||
"--control-token", "",
|
||||
"test/rackup/lobster.ru"], @events
|
||||
"test/rackup/lobster.ru"], @log_writer, @events
|
||||
|
||||
t = Thread.new { cli.run }
|
||||
|
||||
|
@ -217,7 +219,7 @@ class TestCLI < Minitest::Test
|
|||
cli = Puma::CLI.new ["-b", "tcp://127.0.0.1:#{tcp}",
|
||||
"--control-url", url,
|
||||
"--control-token", "",
|
||||
"test/rackup/lobster.ru"], @events
|
||||
"test/rackup/lobster.ru"], @log_writer, @events
|
||||
|
||||
t = Thread.new do
|
||||
cli.run
|
||||
|
@ -258,7 +260,7 @@ class TestCLI < Minitest::Test
|
|||
cli = Puma::CLI.new ["-b", "unix://#{@tmp_path2}",
|
||||
"--control-url", url,
|
||||
"--control-token", "",
|
||||
"test/rackup/lobster.ru"], @events
|
||||
"test/rackup/lobster.ru"], @log_writer, @events
|
||||
|
||||
t = Thread.new { cli.run }
|
||||
|
||||
|
@ -279,7 +281,7 @@ class TestCLI < Minitest::Test
|
|||
cli = Puma::CLI.new ["-b", uri,
|
||||
"--control-url", cntl,
|
||||
"--control-token", "",
|
||||
"test/rackup/lobster.ru"], @events
|
||||
"test/rackup/lobster.ru"], @log_writer, @events
|
||||
|
||||
t = Thread.new do
|
||||
cli.run
|
||||
|
@ -384,28 +386,28 @@ class TestCLI < Minitest::Test
|
|||
|
||||
def test_log_formatter_default_single
|
||||
cli = Puma::CLI.new [ ]
|
||||
assert_instance_of Puma::Events::DefaultFormatter, cli.launcher.events.formatter
|
||||
assert_instance_of Puma::LogWriter::DefaultFormatter, cli.launcher.log_writer.formatter
|
||||
end
|
||||
|
||||
def test_log_formatter_default_clustered
|
||||
skip_unless :fork
|
||||
|
||||
cli = Puma::CLI.new [ "-w 2" ]
|
||||
assert_instance_of Puma::Events::PidFormatter, cli.launcher.events.formatter
|
||||
assert_instance_of Puma::LogWriter::PidFormatter, cli.launcher.log_writer.formatter
|
||||
end
|
||||
|
||||
def test_log_formatter_custom_single
|
||||
cli = Puma::CLI.new [ "--config", "test/config/custom_log_formatter.rb" ]
|
||||
assert_instance_of Proc, cli.launcher.events.formatter
|
||||
assert_match(/^\[.*\] \[.*\] .*: test$/, cli.launcher.events.format('test'))
|
||||
assert_instance_of Proc, cli.launcher.log_writer.formatter
|
||||
assert_match(/^\[.*\] \[.*\] .*: test$/, cli.launcher.log_writer.format('test'))
|
||||
end
|
||||
|
||||
def test_log_formatter_custom_clustered
|
||||
skip_unless :fork
|
||||
|
||||
cli = Puma::CLI.new [ "--config", "test/config/custom_log_formatter.rb", "-w 2" ]
|
||||
assert_instance_of Proc, cli.launcher.events.formatter
|
||||
assert_match(/^\[.*\] \[.*\] .*: test$/, cli.launcher.events.format('test'))
|
||||
assert_instance_of Proc, cli.launcher.log_writer.formatter
|
||||
assert_match(/^\[.*\] \[.*\] .*: test$/, cli.launcher.log_writer.format('test'))
|
||||
end
|
||||
|
||||
def test_state
|
||||
|
@ -480,10 +482,10 @@ class TestCLI < Minitest::Test
|
|||
cli = Puma::CLI.new ['--silent']
|
||||
cli.send(:setup_options)
|
||||
|
||||
events = cli.instance_variable_get(:@events)
|
||||
log_writer = cli.instance_variable_get(:@log_writer)
|
||||
|
||||
assert_equal events.class, Puma::Events.null.class
|
||||
assert_equal events.stdout.class, Puma::NullIO
|
||||
assert_equal events.stderr, $stderr
|
||||
assert_equal log_writer.class, Puma::LogWriter.null.class
|
||||
assert_equal log_writer.stdout.class, Puma::NullIO
|
||||
assert_equal log_writer.stderr, $stderr
|
||||
end
|
||||
end
|
||||
|
|
|
@ -4,7 +4,7 @@ require_relative "helper"
|
|||
require_relative "helpers/config_file"
|
||||
|
||||
require "puma/configuration"
|
||||
require 'puma/events'
|
||||
require 'puma/log_writer'
|
||||
|
||||
class TestConfigFile < TestConfigFileBase
|
||||
parallelize_me!
|
||||
|
@ -373,11 +373,11 @@ class TestConfigFile < TestConfigFileBase
|
|||
end
|
||||
end
|
||||
conf.load
|
||||
events = Puma::Events.strings
|
||||
log_writer = Puma::LogWriter.strings
|
||||
|
||||
conf.run_hooks :on_restart, 'ARG', events
|
||||
conf.run_hooks(:on_restart, 'ARG', log_writer)
|
||||
expected = /WARNING hook on_restart failed with exception \(RuntimeError\) Error from hook/
|
||||
assert_match expected, events.stdout.string
|
||||
assert_match expected, log_writer.stdout.string
|
||||
end
|
||||
|
||||
def test_config_does_not_load_workers_by_default
|
||||
|
@ -419,7 +419,7 @@ class TestConfigFile < TestConfigFileBase
|
|||
messages << "#{hook_name} is called with #{a}"
|
||||
}
|
||||
|
||||
conf.run_hooks hook_name, 'ARG', Puma::Events.strings
|
||||
conf.run_hooks(hook_name, 'ARG', Puma::LogWriter.strings)
|
||||
assert_equal messages, ["#{hook_name} is called with ARG"]
|
||||
|
||||
# test multiple
|
||||
|
@ -435,7 +435,7 @@ class TestConfigFile < TestConfigFileBase
|
|||
end
|
||||
conf.load
|
||||
|
||||
conf.run_hooks hook_name, 'ARG', Puma::Events.strings
|
||||
conf.run_hooks(hook_name, 'ARG', Puma::LogWriter.strings)
|
||||
assert_equal messages, ["#{hook_name} is called with ARG one time", "#{hook_name} is called with ARG a second time"]
|
||||
end
|
||||
end
|
||||
|
|
|
@ -2,41 +2,10 @@ require 'puma/events'
|
|||
require_relative "helper"
|
||||
|
||||
class TestEvents < Minitest::Test
|
||||
def test_null
|
||||
events = Puma::Events.null
|
||||
|
||||
assert_instance_of Puma::NullIO, events.stdout
|
||||
assert_instance_of Puma::NullIO, events.stderr
|
||||
assert_equal events.stdout, events.stderr
|
||||
end
|
||||
|
||||
def test_strings
|
||||
events = Puma::Events.strings
|
||||
|
||||
assert_instance_of StringIO, events.stdout
|
||||
assert_instance_of StringIO, events.stderr
|
||||
end
|
||||
|
||||
def test_stdio
|
||||
events = Puma::Events.stdio
|
||||
|
||||
assert_equal STDOUT, events.stdout
|
||||
assert_equal STDERR, events.stderr
|
||||
end
|
||||
|
||||
def test_stdio_respects_sync
|
||||
events = Puma::Events.stdio
|
||||
|
||||
assert_equal STDOUT.sync, events.stdout.sync
|
||||
assert_equal STDERR.sync, events.stderr.sync
|
||||
assert_equal STDOUT, events.stdout
|
||||
assert_equal STDERR, events.stderr
|
||||
end
|
||||
|
||||
def test_register_callback_with_block
|
||||
res = false
|
||||
|
||||
events = Puma::Events.null
|
||||
events = Puma::Events.new
|
||||
|
||||
events.register(:exec) { res = true }
|
||||
|
||||
|
@ -56,7 +25,7 @@ class TestEvents < Minitest::Test
|
|||
@res = true
|
||||
end
|
||||
|
||||
events = Puma::Events.null
|
||||
events = Puma::Events.new
|
||||
|
||||
events.register(:exec, obj)
|
||||
|
||||
|
@ -68,7 +37,7 @@ class TestEvents < Minitest::Test
|
|||
def test_fire_callback_with_multiple_arguments
|
||||
res = []
|
||||
|
||||
events = Puma::Events.null
|
||||
events = Puma::Events.new
|
||||
|
||||
events.register(:exec) { |*args| res.concat(args) }
|
||||
|
||||
|
@ -80,7 +49,7 @@ class TestEvents < Minitest::Test
|
|||
def test_on_booted_callback
|
||||
res = false
|
||||
|
||||
events = Puma::Events.null
|
||||
events = Puma::Events.new
|
||||
|
||||
events.on_booted { res = true }
|
||||
|
||||
|
@ -88,151 +57,4 @@ class TestEvents < Minitest::Test
|
|||
|
||||
assert res
|
||||
end
|
||||
|
||||
def test_log_writes_to_stdout
|
||||
out, _ = capture_io do
|
||||
Puma::Events.stdio.log("ready")
|
||||
end
|
||||
|
||||
assert_equal "ready\n", out
|
||||
end
|
||||
|
||||
def test_null_log_does_nothing
|
||||
out, _ = capture_io do
|
||||
Puma::Events.null.log("ready")
|
||||
end
|
||||
|
||||
assert_equal "", out
|
||||
end
|
||||
|
||||
def test_write_writes_to_stdout
|
||||
out, _ = capture_io do
|
||||
Puma::Events.stdio.write("ready")
|
||||
end
|
||||
|
||||
assert_equal "ready", out
|
||||
end
|
||||
|
||||
def test_debug_writes_to_stdout_if_env_is_present
|
||||
original_debug, ENV["PUMA_DEBUG"] = ENV["PUMA_DEBUG"], "1"
|
||||
|
||||
out, _ = capture_io do
|
||||
Puma::Events.stdio.debug("ready")
|
||||
end
|
||||
|
||||
assert_equal "% ready\n", out
|
||||
ensure
|
||||
ENV["PUMA_DEBUG"] = original_debug
|
||||
end
|
||||
|
||||
def test_debug_not_write_to_stdout_if_env_is_not_present
|
||||
out, _ = capture_io do
|
||||
Puma::Events.stdio.debug("ready")
|
||||
end
|
||||
|
||||
assert_empty out
|
||||
end
|
||||
|
||||
def test_error_writes_to_stderr_and_exits
|
||||
did_exit = false
|
||||
|
||||
_, err = capture_io do
|
||||
begin
|
||||
Puma::Events.stdio.error("interrupted")
|
||||
rescue SystemExit
|
||||
did_exit = true
|
||||
ensure
|
||||
assert did_exit
|
||||
end
|
||||
end
|
||||
|
||||
assert_match %r!ERROR: interrupted!, err
|
||||
end
|
||||
|
||||
def test_pid_formatter
|
||||
pid = Process.pid
|
||||
|
||||
out, _ = capture_io do
|
||||
events = Puma::Events.stdio
|
||||
|
||||
events.formatter = Puma::Events::PidFormatter.new
|
||||
|
||||
events.write("ready")
|
||||
end
|
||||
|
||||
assert_equal "[#{ pid }] ready", out
|
||||
end
|
||||
|
||||
def test_custom_log_formatter
|
||||
custom_formatter = proc { |str| "-> #{ str }" }
|
||||
|
||||
out, _ = capture_io do
|
||||
events = Puma::Events.stdio
|
||||
|
||||
events.formatter = custom_formatter
|
||||
|
||||
events.write("ready")
|
||||
end
|
||||
|
||||
assert_equal "-> ready", out
|
||||
end
|
||||
|
||||
def test_parse_error
|
||||
port = 0
|
||||
host = "127.0.0.1"
|
||||
app = proc { |env| [200, {"Content-Type" => "plain/text"}, ["hello\n"]] }
|
||||
events = Puma::Events.strings
|
||||
server = Puma::Server.new app, events
|
||||
|
||||
port = (server.add_tcp_listener host, 0).addr[1]
|
||||
server.run
|
||||
|
||||
sock = TCPSocket.new host, port
|
||||
path = "/"
|
||||
params = "a"*1024*10
|
||||
|
||||
sock << "GET #{path}?a=#{params} HTTP/1.1\r\nConnection: close\r\n\r\n"
|
||||
sock.read
|
||||
sleep 0.1 # important so that the previous data is sent as a packet
|
||||
assert_match %r!HTTP parse error, malformed request!, events.stderr.string
|
||||
assert_match %r!\("GET #{path}" - \(-\)\)!, events.stderr.string
|
||||
ensure
|
||||
sock.close if sock && !sock.closed?
|
||||
server.stop true
|
||||
end
|
||||
|
||||
# test_puma_server_ssl.rb checks that ssl errors are raised correctly,
|
||||
# but it mocks the actual error code. This test the code, but it will
|
||||
# break if the logged message changes
|
||||
def test_ssl_error
|
||||
events = Puma::Events.strings
|
||||
|
||||
ssl_mock = -> (addr, subj) {
|
||||
obj = Object.new
|
||||
obj.define_singleton_method(:peeraddr) { addr }
|
||||
if subj
|
||||
cert = Object.new
|
||||
cert.define_singleton_method(:subject) { subj }
|
||||
obj.define_singleton_method(:peercert) { cert }
|
||||
else
|
||||
obj.define_singleton_method(:peercert) { nil }
|
||||
end
|
||||
obj
|
||||
}
|
||||
|
||||
events.ssl_error OpenSSL::SSL::SSLError, ssl_mock.call(['127.0.0.1'], 'test_cert')
|
||||
error = events.stderr.string
|
||||
assert_includes error, "SSL error"
|
||||
assert_includes error, "peer: 127.0.0.1"
|
||||
assert_includes error, "cert: test_cert"
|
||||
|
||||
events.stderr.string = ''
|
||||
|
||||
events.ssl_error OpenSSL::SSL::SSLError, ssl_mock.call(nil, nil)
|
||||
error = events.stderr.string
|
||||
assert_includes error, "SSL error"
|
||||
assert_includes error, "peer: <unknown>"
|
||||
assert_includes error, "cert: :"
|
||||
|
||||
end if ::Puma::HAS_SSL
|
||||
end
|
||||
|
|
|
@ -2,7 +2,7 @@ require_relative "helper"
|
|||
require_relative "helpers/tmp_path"
|
||||
|
||||
require "puma/configuration"
|
||||
require 'puma/events'
|
||||
require 'puma/log_writer'
|
||||
|
||||
class TestLauncher < Minitest::Test
|
||||
include TmpPath
|
||||
|
@ -112,17 +112,17 @@ class TestLauncher < Minitest::Test
|
|||
def test_log_config_enabled
|
||||
ENV['PUMA_LOG_CONFIG'] = "1"
|
||||
|
||||
assert_match(/Configuration:/, launcher.events.stdout.string)
|
||||
assert_match(/Configuration:/, launcher.log_writer.stdout.string)
|
||||
|
||||
launcher.config.final_options.each do |config_key, _value|
|
||||
assert_match(/#{config_key}/, launcher.events.stdout.string)
|
||||
assert_match(/#{config_key}/, launcher.log_writer.stdout.string)
|
||||
end
|
||||
|
||||
ENV.delete('PUMA_LOG_CONFIG')
|
||||
end
|
||||
|
||||
def test_log_config_disabled
|
||||
refute_match(/Configuration:/, launcher.events.stdout.string)
|
||||
refute_match(/Configuration:/, launcher.log_writer.stdout.string)
|
||||
end
|
||||
|
||||
def test_fire_on_stopped
|
||||
|
@ -147,11 +147,11 @@ class TestLauncher < Minitest::Test
|
|||
|
||||
private
|
||||
|
||||
def events
|
||||
@events ||= Puma::Events.strings
|
||||
def log_writer
|
||||
@log_writer ||= Puma::LogWriter.strings
|
||||
end
|
||||
|
||||
def launcher(config = Puma::Configuration.new, evts = events)
|
||||
@launcher ||= Puma::Launcher.new(config, events: evts)
|
||||
def launcher(config = Puma::Configuration.new, lw = log_writer)
|
||||
@launcher ||= Puma::Launcher.new(config, log_writer: lw)
|
||||
end
|
||||
end
|
||||
|
|
|
@ -0,0 +1,181 @@
|
|||
require 'puma/log_writer'
|
||||
require_relative "helper"
|
||||
|
||||
class TestLogWriter < Minitest::Test
|
||||
def test_null
|
||||
log_writer = Puma::LogWriter.null
|
||||
|
||||
assert_instance_of Puma::NullIO, log_writer.stdout
|
||||
assert_instance_of Puma::NullIO, log_writer.stderr
|
||||
assert_equal log_writer.stdout, log_writer.stderr
|
||||
end
|
||||
|
||||
def test_strings
|
||||
log_writer = Puma::LogWriter.strings
|
||||
|
||||
assert_instance_of StringIO, log_writer.stdout
|
||||
assert_instance_of StringIO, log_writer.stderr
|
||||
end
|
||||
|
||||
def test_stdio
|
||||
log_writer = Puma::LogWriter.stdio
|
||||
|
||||
assert_equal STDOUT, log_writer.stdout
|
||||
assert_equal STDERR, log_writer.stderr
|
||||
end
|
||||
|
||||
def test_stdio_respects_sync
|
||||
log_writer = Puma::LogWriter.stdio
|
||||
|
||||
assert_equal STDOUT.sync, log_writer.stdout.sync
|
||||
assert_equal STDERR.sync, log_writer.stderr.sync
|
||||
assert_equal STDOUT, log_writer.stdout
|
||||
assert_equal STDERR, log_writer.stderr
|
||||
end
|
||||
|
||||
def test_log_writes_to_stdout
|
||||
out, _ = capture_io do
|
||||
Puma::LogWriter.stdio.log("ready")
|
||||
end
|
||||
|
||||
assert_equal "ready\n", out
|
||||
end
|
||||
|
||||
def test_null_log_does_nothing
|
||||
out, _ = capture_io do
|
||||
Puma::LogWriter.null.log("ready")
|
||||
end
|
||||
|
||||
assert_equal "", out
|
||||
end
|
||||
|
||||
def test_write_writes_to_stdout
|
||||
out, _ = capture_io do
|
||||
Puma::LogWriter.stdio.write("ready")
|
||||
end
|
||||
|
||||
assert_equal "ready", out
|
||||
end
|
||||
|
||||
def test_debug_writes_to_stdout_if_env_is_present
|
||||
original_debug, ENV["PUMA_DEBUG"] = ENV["PUMA_DEBUG"], "1"
|
||||
|
||||
out, _ = capture_io do
|
||||
Puma::LogWriter.stdio.debug("ready")
|
||||
end
|
||||
|
||||
assert_equal "% ready\n", out
|
||||
ensure
|
||||
ENV["PUMA_DEBUG"] = original_debug
|
||||
end
|
||||
|
||||
def test_debug_not_write_to_stdout_if_env_is_not_present
|
||||
out, _ = capture_io do
|
||||
Puma::LogWriter.stdio.debug("ready")
|
||||
end
|
||||
|
||||
assert_empty out
|
||||
end
|
||||
|
||||
def test_error_writes_to_stderr_and_exits
|
||||
did_exit = false
|
||||
|
||||
_, err = capture_io do
|
||||
begin
|
||||
Puma::LogWriter.stdio.error("interrupted")
|
||||
rescue SystemExit
|
||||
did_exit = true
|
||||
ensure
|
||||
assert did_exit
|
||||
end
|
||||
end
|
||||
|
||||
assert_match %r!ERROR: interrupted!, err
|
||||
end
|
||||
|
||||
def test_pid_formatter
|
||||
pid = Process.pid
|
||||
|
||||
out, _ = capture_io do
|
||||
log_writer = Puma::LogWriter.stdio
|
||||
|
||||
log_writer.formatter = Puma::LogWriter::PidFormatter.new
|
||||
|
||||
log_writer.write("ready")
|
||||
end
|
||||
|
||||
assert_equal "[#{ pid }] ready", out
|
||||
end
|
||||
|
||||
def test_custom_log_formatter
|
||||
custom_formatter = proc { |str| "-> #{ str }" }
|
||||
|
||||
out, _ = capture_io do
|
||||
log_writer = Puma::LogWriter.stdio
|
||||
|
||||
log_writer.formatter = custom_formatter
|
||||
|
||||
log_writer.write("ready")
|
||||
end
|
||||
|
||||
assert_equal "-> ready", out
|
||||
end
|
||||
|
||||
def test_parse_error
|
||||
app = proc { |_env| [200, {"Content-Type" => "plain/text"}, ["hello\n"]] }
|
||||
log_writer = Puma::LogWriter.strings
|
||||
server = Puma::Server.new app, log_writer
|
||||
|
||||
host = '127.0.0.1'
|
||||
port = (server.add_tcp_listener host, 0).addr[1]
|
||||
server.run
|
||||
|
||||
sock = TCPSocket.new host, port
|
||||
path = "/"
|
||||
params = "a"*1024*10
|
||||
|
||||
sock << "GET #{path}?a=#{params} HTTP/1.1\r\nConnection: close\r\n\r\n"
|
||||
sock.read
|
||||
sleep 0.1 # important so that the previous data is sent as a packet
|
||||
assert_match %r!HTTP parse error, malformed request!, log_writer.stderr.string
|
||||
assert_match %r!\("GET #{path}" - \(-\)\)!, log_writer.stderr.string
|
||||
ensure
|
||||
sock.close if sock && !sock.closed?
|
||||
server.stop true
|
||||
end
|
||||
|
||||
# test_puma_server_ssl.rb checks that ssl errors are raised correctly,
|
||||
# but it mocks the actual error code. This test the code, but it will
|
||||
# break if the logged message changes
|
||||
def test_ssl_error
|
||||
log_writer = Puma::LogWriter.strings
|
||||
|
||||
ssl_mock = -> (addr, subj) {
|
||||
obj = Object.new
|
||||
obj.define_singleton_method(:peeraddr) { addr }
|
||||
if subj
|
||||
cert = Object.new
|
||||
cert.define_singleton_method(:subject) { subj }
|
||||
obj.define_singleton_method(:peercert) { cert }
|
||||
else
|
||||
obj.define_singleton_method(:peercert) { nil }
|
||||
end
|
||||
obj
|
||||
}
|
||||
|
||||
log_writer.ssl_error OpenSSL::SSL::SSLError, ssl_mock.call(['127.0.0.1'], 'test_cert')
|
||||
error = log_writer.stderr.string
|
||||
assert_includes error, "SSL error"
|
||||
assert_includes error, "peer: 127.0.0.1"
|
||||
assert_includes error, "cert: test_cert"
|
||||
|
||||
log_writer.stderr.string = ''
|
||||
|
||||
log_writer.ssl_error OpenSSL::SSL::SSLError, ssl_mock.call(nil, nil)
|
||||
error = log_writer.stderr.string
|
||||
assert_includes error, "SSL error"
|
||||
assert_includes error, "peer: <unknown>"
|
||||
assert_includes error, "cert: :"
|
||||
|
||||
end if ::Puma::HAS_SSL
|
||||
end
|
|
@ -59,7 +59,7 @@ class TestOutOfBandServer < Minitest::Test
|
|||
[200, {}, [""]]
|
||||
end
|
||||
|
||||
@server = Puma::Server.new app, Puma::Events.strings, out_of_band: [oob], **options
|
||||
@server = Puma::Server.new app, Puma::LogWriter.strings, Puma::Events.new, out_of_band: [oob], **options
|
||||
@server.min_threads = options[:min_threads] || 1
|
||||
@server.max_threads = options[:max_threads] || 1
|
||||
@port = (@server.add_tcp_listener '127.0.0.1', 0).addr[1]
|
||||
|
|
|
@ -30,8 +30,8 @@ class TestPumaLocalhostAuthority < Minitest::Test
|
|||
@host = "localhost"
|
||||
app = lambda { |env| [200, {}, [env['rack.url_scheme']]] }
|
||||
|
||||
@events = SSLEventsHelper.new STDOUT, STDERR
|
||||
@server = Puma::Server.new app, @events
|
||||
@log_writer = SSLLogWriterHelper.new STDOUT, STDERR
|
||||
@server = Puma::Server.new app, @log_writer
|
||||
@server.app = app
|
||||
@server.add_ssl_listener @host, 0,nil
|
||||
@http = Net::HTTP.new @host, @server.connected_ports[0]
|
||||
|
@ -61,9 +61,9 @@ class TestPumaSSLLocalhostAuthority < Minitest::Test
|
|||
|
||||
app = lambda { |env| [200, {}, [env['rack.url_scheme']]] }
|
||||
|
||||
@events = SSLEventsHelper.new STDOUT, STDERR
|
||||
@log_writer = SSLLogWriterHelper.new STDOUT, STDERR
|
||||
|
||||
@server = Puma::Server.new app, @events
|
||||
@server = Puma::Server.new app, @log_writer
|
||||
@server.app = app
|
||||
|
||||
@server.add_ssl_listener @host, 0,nil
|
||||
|
|
|
@ -14,8 +14,9 @@ class TestPumaServer < Minitest::Test
|
|||
|
||||
@app = ->(env) { [200, {}, [env['rack.url_scheme']]] }
|
||||
|
||||
@events = Puma::Events.strings
|
||||
@server = Puma::Server.new @app, @events
|
||||
@log_writer = Puma::LogWriter.strings
|
||||
@events = Puma::Events.new
|
||||
@server = Puma::Server.new @app, @log_writer, @events
|
||||
end
|
||||
|
||||
def teardown
|
||||
|
@ -24,7 +25,7 @@ class TestPumaServer < Minitest::Test
|
|||
end
|
||||
|
||||
def server_run(**options, &block)
|
||||
@server = Puma::Server.new block || @app, @events, options
|
||||
@server = Puma::Server.new block || @app, @log_writer, @events, options
|
||||
@port = (@server.add_tcp_listener @host, 0).addr[1]
|
||||
@server.run
|
||||
sleep 0.15 if Puma.jruby?
|
||||
|
@ -296,7 +297,7 @@ EOF
|
|||
sleep 0.1
|
||||
|
||||
# Expect no errors in stderr
|
||||
assert @events.stderr.pos.zero?, "Server didn't swallow the connection error"
|
||||
assert @log_writer.stderr.pos.zero?, "Server didn't swallow the connection error"
|
||||
end
|
||||
|
||||
def test_early_hints_is_off_by_default
|
||||
|
@ -341,7 +342,7 @@ EOF
|
|||
new_connection.close # Make a connection and close without writing
|
||||
|
||||
@server.stop(true)
|
||||
stderr = @events.stderr.string
|
||||
stderr = @log_writer.stderr.string
|
||||
assert stderr.empty?, "Expected stderr from server to be empty but it was #{stderr.inspect}"
|
||||
end
|
||||
|
||||
|
@ -361,7 +362,7 @@ EOF
|
|||
|
||||
def test_lowlevel_error_message
|
||||
skip_if :windows
|
||||
@server = Puma::Server.new @app, @events, {:force_shutdown_after => 2}
|
||||
@server = Puma::Server.new @app, @log_writer, @events, {:force_shutdown_after => 2}
|
||||
|
||||
server_run do
|
||||
if TestSkips::TRUFFLE
|
||||
|
@ -508,7 +509,7 @@ EOF
|
|||
end
|
||||
|
||||
def test_no_timeout_after_data_received_no_queue
|
||||
@server = Puma::Server.new @app, @events, queue_requests: false
|
||||
@server = Puma::Server.new @app, @log_writer, @events, queue_requests: false
|
||||
test_no_timeout_after_data_received
|
||||
end
|
||||
|
||||
|
@ -1244,7 +1245,7 @@ EOF
|
|||
# System-resource errors such as EMFILE should not be silently swallowed by accept loop.
|
||||
def test_accept_emfile
|
||||
stub_accept_nonblock Errno::EMFILE.new('accept(2)')
|
||||
refute_empty @events.stderr.string, "Expected EMFILE error not logged"
|
||||
refute_empty @log_writer.stderr.string, "Expected EMFILE error not logged"
|
||||
end
|
||||
|
||||
# Retryable errors such as ECONNABORTED should be silently swallowed by accept loop.
|
||||
|
@ -1252,7 +1253,7 @@ EOF
|
|||
# Match Ruby #accept_nonblock implementation, ECONNABORTED error is extended by IO::WaitReadable.
|
||||
error = Errno::ECONNABORTED.new('accept(2) would block').tap {|e| e.extend IO::WaitReadable}
|
||||
stub_accept_nonblock(error)
|
||||
assert_empty @events.stderr.string
|
||||
assert_empty @log_writer.stderr.string
|
||||
end
|
||||
|
||||
# see https://github.com/puma/puma/issues/2390
|
||||
|
@ -1260,7 +1261,7 @@ EOF
|
|||
#
|
||||
def test_client_quick_close_no_lowlevel_error_handler_call
|
||||
handler = ->(err, env, status) {
|
||||
@events.stdout.write "LLEH #{err.message}"
|
||||
@log_writer.stdout.write "LLEH #{err.message}"
|
||||
[500, {"Content-Type" => "application/json"}, ["{}\n"]]
|
||||
}
|
||||
|
||||
|
@ -1274,21 +1275,21 @@ EOF
|
|||
sock.close
|
||||
assert_match 'Hello World', resp
|
||||
sleep 0.5
|
||||
assert_empty @events.stdout.string
|
||||
assert_empty @log_writer.stdout.string
|
||||
|
||||
# valid req, close
|
||||
sock = TCPSocket.new @host, @port
|
||||
sock.syswrite "GET / HTTP/1.0\r\n\r\n"
|
||||
sock.close
|
||||
sleep 0.5
|
||||
assert_empty @events.stdout.string
|
||||
assert_empty @log_writer.stdout.string
|
||||
|
||||
# invalid req, close
|
||||
sock = TCPSocket.new @host, @port
|
||||
sock.syswrite "GET / HTTP"
|
||||
sock.close
|
||||
sleep 0.5
|
||||
assert_empty @events.stdout.string
|
||||
assert_empty @log_writer.stdout.string
|
||||
end
|
||||
|
||||
def test_idle_connections_closed_immediately_on_shutdown
|
||||
|
@ -1325,7 +1326,7 @@ EOF
|
|||
def test_custom_io_selector
|
||||
backend = NIO::Selector.backends.first
|
||||
|
||||
@server = Puma::Server.new @app, @events, {:io_selector_backend => backend}
|
||||
@server = Puma::Server.new @app, @log_writer, @events, {:io_selector_backend => backend}
|
||||
@server.run
|
||||
|
||||
selector = @server.instance_variable_get(:@reactor).instance_variable_get(:@selector)
|
||||
|
@ -1374,9 +1375,9 @@ EOF
|
|||
@port = UniquePort.call
|
||||
opts = { rack_url_scheme: 'user', binds: ["tcp://#{@host}:#{@port}"] }
|
||||
conf = Puma::Configuration.new(opts).tap(&:clamp)
|
||||
@server = Puma::Server.new @app, @events, conf.options
|
||||
@server.inherit_binder Puma::Binder.new(@events, conf)
|
||||
@server.binder.parse conf.options[:binds], @events
|
||||
@server = Puma::Server.new @app, @log_writer, @events, conf.options
|
||||
@server.inherit_binder Puma::Binder.new(@log_writer, conf)
|
||||
@server.binder.parse conf.options[:binds], @log_writer
|
||||
@server.run
|
||||
|
||||
data = send_http_and_read "GET / HTTP/1.0\r\n\r\n"
|
||||
|
|
|
@ -55,8 +55,8 @@ class TestPumaServerSSL < Minitest::Test
|
|||
|
||||
yield ctx if block_given?
|
||||
|
||||
@events = SSLEventsHelper.new STDOUT, STDERR
|
||||
@server = Puma::Server.new app, @events
|
||||
@log_writer = SSLLogWriterHelper.new STDOUT, STDERR
|
||||
@server = Puma::Server.new app, @log_writer
|
||||
@port = (@server.add_ssl_listener @host, 0, ctx).addr[1]
|
||||
@server.run
|
||||
|
||||
|
@ -148,7 +148,7 @@ class TestPumaServerSSL < Minitest::Test
|
|||
end
|
||||
unless Puma.jruby?
|
||||
msg = /wrong version number|no protocols available|version too low|unknown SSL method/
|
||||
assert_match(msg, @events.error.message) if @events.error
|
||||
assert_match(msg, @log_writer.error.message) if @log_writer.error
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -169,7 +169,7 @@ class TestPumaServerSSL < Minitest::Test
|
|||
end
|
||||
unless Puma.jruby?
|
||||
msg = /wrong version number|(unknown|unsupported) protocol|no protocols available|version too low|unknown SSL method/
|
||||
assert_match(msg, @events.error.message) if @events.error
|
||||
assert_match(msg, @log_writer.error.message) if @log_writer.error
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -189,7 +189,7 @@ class TestPumaServerSSL < Minitest::Test
|
|||
end
|
||||
unless Puma.jruby?
|
||||
msg = /wrong version number|(unknown|unsupported) protocol|no protocols available|version too low|unknown SSL method/
|
||||
assert_match(msg, @events.error.message) if @events.error
|
||||
assert_match(msg, @log_writer.error.message) if @log_writer.error
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -258,8 +258,8 @@ class TestPumaServerSSLClient < Minitest::Test
|
|||
|
||||
app = lambda { |env| [200, {}, [env['rack.url_scheme']]] }
|
||||
|
||||
events = SSLEventsHelper.new STDOUT, STDERR
|
||||
server = Puma::Server.new app, events
|
||||
log_writer = SSLLogWriterHelper.new STDOUT, STDERR
|
||||
server = Puma::Server.new app, log_writer
|
||||
server.add_ssl_listener host, port, CTX
|
||||
host_addrs = server.binder.ios.map { |io| io.to_io.addr[2] }
|
||||
server.run
|
||||
|
@ -288,9 +288,9 @@ class TestPumaServerSSLClient < Minitest::Test
|
|||
# The JRuby MiniSSL implementation lacks error capturing currently,
|
||||
# so we can't inspect the messages here
|
||||
unless Puma.jruby?
|
||||
assert_match error, events.error.message if error
|
||||
assert_includes host_addrs, events.addr if error
|
||||
assert_equal subject, events.cert.subject.to_s if subject
|
||||
assert_match error, log_writer.error.message if error
|
||||
assert_includes host_addrs, log_writer.addr if error
|
||||
assert_equal subject, log_writer.cert.subject.to_s if subject
|
||||
end
|
||||
ensure
|
||||
server.stop(true) if server
|
||||
|
@ -346,8 +346,8 @@ class TestPumaServerSSLWithCertPemAndKeyPem < Minitest::Test
|
|||
}
|
||||
|
||||
app = lambda { |env| [200, {}, [env['rack.url_scheme']]] }
|
||||
events = SSLEventsHelper.new STDOUT, STDERR
|
||||
server = Puma::Server.new app, events
|
||||
log_writer = SSLLogWriterHelper.new STDOUT, STDERR
|
||||
server = Puma::Server.new app, log_writer
|
||||
server.add_ssl_listener host, port, ctx
|
||||
server.run
|
||||
|
||||
|
|
|
@ -12,8 +12,8 @@ class TestResponseHeader < Minitest::Test
|
|||
|
||||
@app = ->(env) { [200, {}, [env['rack.url_scheme']]] }
|
||||
|
||||
@events = Puma::Events.strings
|
||||
@server = Puma::Server.new @app, @events
|
||||
@log_writer = Puma::LogWriter.strings
|
||||
@server = Puma::Server.new @app, @log_writer
|
||||
end
|
||||
|
||||
def teardown
|
||||
|
|
|
@ -23,7 +23,7 @@ class WebServerTest < Minitest::Test
|
|||
|
||||
def setup
|
||||
@tester = TestHandler.new
|
||||
@server = Puma::Server.new @tester, Puma::Events.strings
|
||||
@server = Puma::Server.new @tester, Puma::LogWriter.strings
|
||||
@port = (@server.add_tcp_listener "127.0.0.1", 0).addr[1]
|
||||
@tcp = "http://127.0.0.1:#{@port}"
|
||||
@server.run
|
||||
|
|
Loading…
Reference in New Issue