puma 5.6.5 → 6.4.2
Sign up to get free protection for your applications and to get access to all the features.
Potentially problematic release.
This version of puma might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/History.md +338 -14
- data/LICENSE +0 -0
- data/README.md +79 -29
- data/bin/puma-wild +1 -1
- data/docs/architecture.md +0 -0
- data/docs/compile_options.md +34 -0
- data/docs/deployment.md +0 -0
- data/docs/fork_worker.md +1 -3
- data/docs/images/puma-connection-flow-no-reactor.png +0 -0
- data/docs/images/puma-connection-flow.png +0 -0
- data/docs/images/puma-general-arch.png +0 -0
- data/docs/jungle/README.md +0 -0
- data/docs/jungle/rc.d/README.md +0 -0
- data/docs/jungle/rc.d/puma.conf +0 -0
- data/docs/kubernetes.md +12 -0
- data/docs/nginx.md +1 -1
- data/docs/plugins.md +0 -0
- data/docs/rails_dev_mode.md +0 -0
- data/docs/restart.md +1 -0
- data/docs/signals.md +0 -0
- data/docs/stats.md +0 -0
- data/docs/systemd.md +3 -6
- data/docs/testing_benchmarks_local_files.md +150 -0
- data/docs/testing_test_rackup_ci_files.md +36 -0
- data/ext/puma_http11/PumaHttp11Service.java +0 -0
- data/ext/puma_http11/ext_help.h +0 -0
- data/ext/puma_http11/extconf.rb +16 -9
- data/ext/puma_http11/http11_parser.c +1 -1
- data/ext/puma_http11/http11_parser.h +1 -1
- data/ext/puma_http11/http11_parser.java.rl +2 -2
- data/ext/puma_http11/http11_parser.rl +2 -2
- data/ext/puma_http11/http11_parser_common.rl +2 -2
- data/ext/puma_http11/mini_ssl.c +127 -19
- data/ext/puma_http11/no_ssl/PumaHttp11Service.java +0 -0
- data/ext/puma_http11/org/jruby/puma/Http11.java +3 -3
- data/ext/puma_http11/org/jruby/puma/Http11Parser.java +1 -1
- data/ext/puma_http11/org/jruby/puma/MiniSSL.java +157 -53
- data/ext/puma_http11/puma_http11.c +17 -9
- data/lib/puma/app/status.rb +4 -4
- data/lib/puma/binder.rb +50 -53
- data/lib/puma/cli.rb +16 -18
- data/lib/puma/client.rb +100 -26
- data/lib/puma/cluster/worker.rb +18 -11
- data/lib/puma/cluster/worker_handle.rb +4 -1
- data/lib/puma/cluster.rb +102 -40
- data/lib/puma/commonlogger.rb +21 -14
- data/lib/puma/configuration.rb +77 -59
- data/lib/puma/const.rb +129 -92
- data/lib/puma/control_cli.rb +15 -11
- data/lib/puma/detect.rb +7 -4
- data/lib/puma/dsl.rb +250 -56
- data/lib/puma/error_logger.rb +18 -9
- data/lib/puma/events.rb +6 -126
- data/lib/puma/io_buffer.rb +39 -4
- data/lib/puma/jruby_restart.rb +2 -1
- data/lib/puma/json_serialization.rb +0 -0
- data/lib/puma/launcher/bundle_pruner.rb +104 -0
- data/lib/puma/launcher.rb +102 -175
- data/lib/puma/log_writer.rb +147 -0
- data/lib/puma/minissl/context_builder.rb +26 -12
- data/lib/puma/minissl.rb +104 -11
- data/lib/puma/null_io.rb +16 -2
- data/lib/puma/plugin/systemd.rb +90 -0
- data/lib/puma/plugin/tmp_restart.rb +1 -1
- data/lib/puma/plugin.rb +0 -0
- data/lib/puma/rack/builder.rb +6 -6
- data/lib/puma/rack/urlmap.rb +1 -1
- data/lib/puma/rack_default.rb +19 -4
- data/lib/puma/reactor.rb +19 -10
- data/lib/puma/request.rb +365 -170
- data/lib/puma/runner.rb +56 -20
- data/lib/puma/sd_notify.rb +149 -0
- data/lib/puma/server.rb +137 -89
- data/lib/puma/single.rb +13 -11
- data/lib/puma/state_file.rb +3 -6
- data/lib/puma/thread_pool.rb +57 -19
- data/lib/puma/util.rb +0 -11
- data/lib/puma.rb +12 -11
- data/lib/rack/handler/puma.rb +113 -86
- data/tools/Dockerfile +2 -2
- data/tools/trickletest.rb +0 -0
- metadata +11 -6
- data/lib/puma/queue_close.rb +0 -26
- data/lib/puma/systemd.rb +0 -46
data/lib/puma/util.rb
CHANGED
@@ -39,17 +39,6 @@ module Puma
|
|
39
39
|
end
|
40
40
|
module_function :unescape, :escape
|
41
41
|
|
42
|
-
# @version 5.0.0
|
43
|
-
def nakayoshi_gc(events)
|
44
|
-
events.log "! Promoting existing objects to old generation..."
|
45
|
-
4.times { GC.start(full_mark: false) }
|
46
|
-
if GC.respond_to?(:compact)
|
47
|
-
events.log "! Compacting..."
|
48
|
-
GC.compact
|
49
|
-
end
|
50
|
-
events.log "! Friendly fork preparation complete."
|
51
|
-
end
|
52
|
-
|
53
42
|
DEFAULT_SEP = /[&;] */n
|
54
43
|
|
55
44
|
# Stolen from Mongrel, with some small modifications:
|
data/lib/puma.rb
CHANGED
@@ -3,30 +3,33 @@
|
|
3
3
|
# Standard libraries
|
4
4
|
require 'socket'
|
5
5
|
require 'tempfile'
|
6
|
-
require 'time'
|
7
|
-
require 'etc'
|
8
6
|
require 'uri'
|
9
7
|
require 'stringio'
|
10
8
|
|
11
9
|
require 'thread'
|
12
10
|
|
11
|
+
# use require, see https://github.com/puma/puma/pull/2381
|
13
12
|
require 'puma/puma_http11'
|
14
|
-
|
15
|
-
|
13
|
+
|
14
|
+
require_relative 'puma/detect'
|
15
|
+
require_relative 'puma/json_serialization'
|
16
16
|
|
17
17
|
module Puma
|
18
|
-
|
19
|
-
|
20
|
-
autoload :
|
18
|
+
# when Puma is loaded via `Puma::CLI`, all files are loaded via
|
19
|
+
# `require_relative`. The below are for non-standard loading
|
20
|
+
autoload :Const, "#{__dir__}/puma/const"
|
21
|
+
autoload :Server, "#{__dir__}/puma/server"
|
22
|
+
autoload :Launcher, "#{__dir__}/puma/launcher"
|
23
|
+
autoload :LogWriter, "#{__dir__}/puma/log_writer"
|
21
24
|
|
22
25
|
# at present, MiniSSL::Engine is only defined in extension code (puma_http11),
|
23
26
|
# not in minissl.rb
|
24
27
|
HAS_SSL = const_defined?(:MiniSSL, false) && MiniSSL.const_defined?(:Engine, false)
|
25
28
|
|
26
|
-
HAS_UNIX_SOCKET = Object.const_defined?
|
29
|
+
HAS_UNIX_SOCKET = Object.const_defined?(:UNIXSocket) && !IS_WINDOWS
|
27
30
|
|
28
31
|
if HAS_SSL
|
29
|
-
|
32
|
+
require_relative 'puma/minissl'
|
30
33
|
else
|
31
34
|
module MiniSSL
|
32
35
|
# this class is defined so that it exists when Puma is compiled
|
@@ -69,9 +72,7 @@ module Puma
|
|
69
72
|
@get_stats.stats
|
70
73
|
end
|
71
74
|
|
72
|
-
# Thread name is new in Ruby 2.3
|
73
75
|
def self.set_thread_name(name)
|
74
|
-
return unless Thread.current.respond_to?(:name=)
|
75
76
|
Thread.current.name = "puma #{name}"
|
76
77
|
end
|
77
78
|
end
|
data/lib/rack/handler/puma.rb
CHANGED
@@ -1,114 +1,141 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
module
|
6
|
-
|
7
|
-
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
(options.keys - user_supplied_options).each do |k|
|
28
|
-
default_options[k] = options.delete(k)
|
29
|
-
end
|
3
|
+
# This module is used as an 'include' file in code at bottom of file
|
4
|
+
module Puma
|
5
|
+
module RackHandler
|
6
|
+
DEFAULT_OPTIONS = {
|
7
|
+
:Verbose => false,
|
8
|
+
:Silent => false
|
9
|
+
}
|
10
|
+
|
11
|
+
def config(app, options = {})
|
12
|
+
require_relative '../../puma'
|
13
|
+
require_relative '../../puma/configuration'
|
14
|
+
require_relative '../../puma/log_writer'
|
15
|
+
require_relative '../../puma/launcher'
|
16
|
+
|
17
|
+
default_options = DEFAULT_OPTIONS.dup
|
18
|
+
|
19
|
+
# Libraries pass in values such as :Port and there is no way to determine
|
20
|
+
# if it is a default provided by the library or a special value provided
|
21
|
+
# by the user. A special key `user_supplied_options` can be passed. This
|
22
|
+
# contains an array of all explicitly defined user options. We then
|
23
|
+
# know that all other values are defaults
|
24
|
+
if user_supplied_options = options.delete(:user_supplied_options)
|
25
|
+
(options.keys - user_supplied_options).each do |k|
|
26
|
+
default_options[k] = options.delete(k)
|
30
27
|
end
|
28
|
+
end
|
31
29
|
|
32
|
-
|
33
|
-
if options.delete(:Verbose)
|
34
|
-
require 'rack/common_logger'
|
35
|
-
app = Rack::CommonLogger.new(app, STDOUT)
|
36
|
-
end
|
30
|
+
@events = options[:events] || ::Puma::Events.new
|
37
31
|
|
38
|
-
|
39
|
-
|
32
|
+
conf = ::Puma::Configuration.new(options, default_options.merge({events: @events})) do |user_config, file_config, default_config|
|
33
|
+
if options.delete(:Verbose)
|
34
|
+
begin
|
35
|
+
require 'rack/commonlogger' # Rack 1.x
|
36
|
+
rescue LoadError
|
37
|
+
require 'rack/common_logger' # Rack 2 and later
|
40
38
|
end
|
39
|
+
app = ::Rack::CommonLogger.new(app, STDOUT)
|
40
|
+
end
|
41
41
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
end
|
42
|
+
if options[:environment]
|
43
|
+
user_config.environment options[:environment]
|
44
|
+
end
|
46
45
|
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
end
|
46
|
+
if options[:Threads]
|
47
|
+
min, max = options.delete(:Threads).split(':', 2)
|
48
|
+
user_config.threads min, max
|
49
|
+
end
|
52
50
|
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
self.set_host_port_to_config(
|
51
|
+
if options[:Host] || options[:Port]
|
52
|
+
host = options[:Host] || default_options[:Host]
|
53
|
+
port = options[:Port] || default_options[:Port]
|
54
|
+
self.set_host_port_to_config(host, port, user_config)
|
55
|
+
end
|
57
56
|
|
58
|
-
|
57
|
+
if default_options[:Host]
|
58
|
+
file_config.set_default_host(default_options[:Host])
|
59
59
|
end
|
60
|
-
|
60
|
+
self.set_host_port_to_config(default_options[:Host], default_options[:Port], default_config)
|
61
|
+
|
62
|
+
user_config.app app
|
61
63
|
end
|
64
|
+
conf
|
65
|
+
end
|
62
66
|
|
63
|
-
|
64
|
-
|
67
|
+
def run(app, **options)
|
68
|
+
conf = self.config(app, options)
|
65
69
|
|
66
|
-
|
70
|
+
log_writer = options.delete(:Silent) ? ::Puma::LogWriter.strings : ::Puma::LogWriter.stdio
|
67
71
|
|
68
|
-
|
72
|
+
launcher = ::Puma::Launcher.new(conf, :log_writer => log_writer, events: @events)
|
69
73
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
end
|
74
|
+
yield launcher if block_given?
|
75
|
+
begin
|
76
|
+
launcher.run
|
77
|
+
rescue Interrupt
|
78
|
+
puts "* Gracefully stopping, waiting for requests to finish"
|
79
|
+
launcher.stop
|
80
|
+
puts "* Goodbye!"
|
78
81
|
end
|
82
|
+
end
|
79
83
|
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
|
85
|
-
|
86
|
-
|
87
|
-
|
84
|
+
def valid_options
|
85
|
+
{
|
86
|
+
"Host=HOST" => "Hostname to listen on (default: localhost)",
|
87
|
+
"Port=PORT" => "Port to listen on (default: 8080)",
|
88
|
+
"Threads=MIN:MAX" => "min:max threads to use (default 0:16)",
|
89
|
+
"Verbose" => "Don't report each request (default: false)"
|
90
|
+
}
|
91
|
+
end
|
88
92
|
|
89
|
-
|
90
|
-
|
93
|
+
def set_host_port_to_config(host, port, config)
|
94
|
+
config.clear_binds! if host || port
|
91
95
|
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
96
|
-
|
97
|
-
|
98
|
-
|
96
|
+
if host && (host[0,1] == '.' || host[0,1] == '/')
|
97
|
+
config.bind "unix://#{host}"
|
98
|
+
elsif host && host =~ /^ssl:\/\//
|
99
|
+
uri = URI.parse(host)
|
100
|
+
uri.port ||= port || ::Puma::Configuration::DEFAULTS[:tcp_port]
|
101
|
+
config.bind uri.to_s
|
102
|
+
else
|
99
103
|
|
100
|
-
|
101
|
-
|
102
|
-
|
104
|
+
if host
|
105
|
+
port ||= ::Puma::Configuration::DEFAULTS[:tcp_port]
|
106
|
+
end
|
103
107
|
|
104
|
-
|
105
|
-
|
106
|
-
|
107
|
-
end
|
108
|
+
if port
|
109
|
+
host ||= ::Puma::Configuration::DEFAULTS[:tcp_host]
|
110
|
+
config.port port, host
|
108
111
|
end
|
109
112
|
end
|
110
113
|
end
|
114
|
+
end
|
115
|
+
end
|
111
116
|
|
112
|
-
|
117
|
+
# rackup was removed in Rack 3, it is now a separate gem
|
118
|
+
if Object.const_defined? :Rackup
|
119
|
+
module Rackup
|
120
|
+
module Handler
|
121
|
+
module Puma
|
122
|
+
class << self
|
123
|
+
include ::Puma::RackHandler
|
124
|
+
end
|
125
|
+
end
|
126
|
+
register :puma, Puma
|
127
|
+
end
|
128
|
+
end
|
129
|
+
else
|
130
|
+
do_register = Object.const_defined?(:Rack) && Rack.release < '3'
|
131
|
+
module Rack
|
132
|
+
module Handler
|
133
|
+
module Puma
|
134
|
+
class << self
|
135
|
+
include ::Puma::RackHandler
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
113
139
|
end
|
140
|
+
::Rack::Handler.register(:puma, ::Rack::Handler::Puma) if do_register
|
114
141
|
end
|
data/tools/Dockerfile
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# Use this Dockerfile to create minimal reproductions of issues
|
2
2
|
|
3
|
-
FROM ruby:3.
|
3
|
+
FROM ruby:3.2
|
4
4
|
|
5
5
|
# throw errors if Gemfile has been modified since Gemfile.lock
|
6
6
|
RUN bundle config --global frozen 1
|
@@ -8,7 +8,7 @@ RUN bundle config --global frozen 1
|
|
8
8
|
WORKDIR /usr/src/app
|
9
9
|
|
10
10
|
COPY . .
|
11
|
-
|
11
|
+
|
12
12
|
RUN bundle install
|
13
13
|
RUN bundle exec rake compile
|
14
14
|
|
data/tools/trickletest.rb
CHANGED
File without changes
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: puma
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 6.4.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Evan Phoenix
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2024-01-08 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: nio4r
|
@@ -62,6 +62,8 @@ files:
|
|
62
62
|
- docs/signals.md
|
63
63
|
- docs/stats.md
|
64
64
|
- docs/systemd.md
|
65
|
+
- docs/testing_benchmarks_local_files.md
|
66
|
+
- docs/testing_test_rackup_ci_files.md
|
65
67
|
- ext/puma_http11/PumaHttp11Service.java
|
66
68
|
- ext/puma_http11/ext_help.h
|
67
69
|
- ext/puma_http11/extconf.rb
|
@@ -96,22 +98,24 @@ files:
|
|
96
98
|
- lib/puma/jruby_restart.rb
|
97
99
|
- lib/puma/json_serialization.rb
|
98
100
|
- lib/puma/launcher.rb
|
101
|
+
- lib/puma/launcher/bundle_pruner.rb
|
102
|
+
- lib/puma/log_writer.rb
|
99
103
|
- lib/puma/minissl.rb
|
100
104
|
- lib/puma/minissl/context_builder.rb
|
101
105
|
- lib/puma/null_io.rb
|
102
106
|
- lib/puma/plugin.rb
|
107
|
+
- lib/puma/plugin/systemd.rb
|
103
108
|
- lib/puma/plugin/tmp_restart.rb
|
104
|
-
- lib/puma/queue_close.rb
|
105
109
|
- lib/puma/rack/builder.rb
|
106
110
|
- lib/puma/rack/urlmap.rb
|
107
111
|
- lib/puma/rack_default.rb
|
108
112
|
- lib/puma/reactor.rb
|
109
113
|
- lib/puma/request.rb
|
110
114
|
- lib/puma/runner.rb
|
115
|
+
- lib/puma/sd_notify.rb
|
111
116
|
- lib/puma/server.rb
|
112
117
|
- lib/puma/single.rb
|
113
118
|
- lib/puma/state_file.rb
|
114
|
-
- lib/puma/systemd.rb
|
115
119
|
- lib/puma/thread_pool.rb
|
116
120
|
- lib/puma/util.rb
|
117
121
|
- lib/rack/handler/puma.rb
|
@@ -125,6 +129,7 @@ metadata:
|
|
125
129
|
changelog_uri: https://github.com/puma/puma/blob/master/History.md
|
126
130
|
homepage_uri: https://puma.io
|
127
131
|
source_code_uri: https://github.com/puma/puma
|
132
|
+
rubygems_mfa_required: 'true'
|
128
133
|
post_install_message:
|
129
134
|
rdoc_options: []
|
130
135
|
require_paths:
|
@@ -133,14 +138,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
133
138
|
requirements:
|
134
139
|
- - ">="
|
135
140
|
- !ruby/object:Gem::Version
|
136
|
-
version: '2.
|
141
|
+
version: '2.4'
|
137
142
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
138
143
|
requirements:
|
139
144
|
- - ">="
|
140
145
|
- !ruby/object:Gem::Version
|
141
146
|
version: '0'
|
142
147
|
requirements: []
|
143
|
-
rubygems_version: 3.
|
148
|
+
rubygems_version: 3.5.3
|
144
149
|
signing_key:
|
145
150
|
specification_version: 4
|
146
151
|
summary: Puma is a simple, fast, threaded, and highly parallel HTTP 1.1 server for
|
data/lib/puma/queue_close.rb
DELETED
@@ -1,26 +0,0 @@
|
|
1
|
-
class ClosedQueueError < StandardError; end
|
2
|
-
module Puma
|
3
|
-
|
4
|
-
# Queue#close was added in Ruby 2.3.
|
5
|
-
# Add a simple implementation for earlier Ruby versions.
|
6
|
-
#
|
7
|
-
module QueueClose
|
8
|
-
def close
|
9
|
-
num_waiting.times {push nil}
|
10
|
-
@closed = true
|
11
|
-
end
|
12
|
-
def closed?
|
13
|
-
@closed ||= false
|
14
|
-
end
|
15
|
-
def push(object)
|
16
|
-
raise ClosedQueueError if closed?
|
17
|
-
super
|
18
|
-
end
|
19
|
-
alias << push
|
20
|
-
def pop(non_block=false)
|
21
|
-
return nil if !non_block && closed? && empty?
|
22
|
-
super
|
23
|
-
end
|
24
|
-
end
|
25
|
-
::Queue.prepend QueueClose
|
26
|
-
end
|
data/lib/puma/systemd.rb
DELETED
@@ -1,46 +0,0 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
|
3
|
-
require 'sd_notify'
|
4
|
-
|
5
|
-
module Puma
|
6
|
-
class Systemd
|
7
|
-
def initialize(events)
|
8
|
-
@events = events
|
9
|
-
end
|
10
|
-
|
11
|
-
def hook_events
|
12
|
-
@events.on_booted { SdNotify.ready }
|
13
|
-
@events.on_stopped { SdNotify.stopping }
|
14
|
-
@events.on_restart { SdNotify.reloading }
|
15
|
-
end
|
16
|
-
|
17
|
-
def start_watchdog
|
18
|
-
return unless SdNotify.watchdog?
|
19
|
-
|
20
|
-
ping_f = watchdog_sleep_time
|
21
|
-
|
22
|
-
log "Pinging systemd watchdog every #{ping_f.round(1)} sec"
|
23
|
-
Thread.new do
|
24
|
-
loop do
|
25
|
-
sleep ping_f
|
26
|
-
SdNotify.watchdog
|
27
|
-
end
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
private
|
32
|
-
|
33
|
-
def watchdog_sleep_time
|
34
|
-
usec = Integer(ENV["WATCHDOG_USEC"])
|
35
|
-
|
36
|
-
sec_f = usec / 1_000_000.0
|
37
|
-
# "It is recommended that a daemon sends a keep-alive notification message
|
38
|
-
# to the service manager every half of the time returned here."
|
39
|
-
sec_f / 2
|
40
|
-
end
|
41
|
-
|
42
|
-
def log(str)
|
43
|
-
@events.log str
|
44
|
-
end
|
45
|
-
end
|
46
|
-
end
|