puma 6.4.0 → 6.6.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/History.md +235 -18
- data/README.md +87 -26
- data/docs/fork_worker.md +11 -1
- data/docs/java_options.md +54 -0
- data/docs/kubernetes.md +1 -1
- data/docs/plugins.md +4 -0
- data/docs/restart.md +1 -0
- data/docs/signals.md +2 -2
- data/docs/stats.md +8 -3
- data/docs/systemd.md +13 -6
- data/ext/puma_http11/extconf.rb +21 -14
- data/ext/puma_http11/mini_ssl.c +16 -2
- data/ext/puma_http11/org/jruby/puma/Http11.java +31 -8
- data/ext/puma_http11/org/jruby/puma/MiniSSL.java +2 -1
- data/ext/puma_http11/puma_http11.c +4 -1
- data/lib/puma/app/status.rb +1 -1
- data/lib/puma/binder.rb +12 -4
- data/lib/puma/cli.rb +9 -5
- data/lib/puma/client.rb +104 -16
- data/lib/puma/cluster/worker.rb +9 -6
- data/lib/puma/cluster/worker_handle.rb +4 -5
- data/lib/puma/cluster.rb +112 -27
- data/lib/puma/configuration.rb +37 -21
- data/lib/puma/const.rb +22 -3
- data/lib/puma/control_cli.rb +4 -4
- data/lib/puma/detect.rb +3 -4
- data/lib/puma/dsl.rb +303 -58
- data/lib/puma/error_logger.rb +4 -4
- data/lib/puma/jruby_restart.rb +0 -16
- data/lib/puma/launcher.rb +21 -8
- data/lib/puma/log_writer.rb +9 -9
- data/lib/puma/minissl/context_builder.rb +3 -0
- data/lib/puma/minissl.rb +6 -0
- data/lib/puma/null_io.rb +42 -2
- data/lib/puma/request.rb +35 -14
- data/lib/puma/runner.rb +10 -3
- data/lib/puma/sd_notify.rb +1 -4
- data/lib/puma/server.rb +53 -21
- data/lib/puma/single.rb +1 -1
- data/lib/puma/state_file.rb +2 -2
- data/lib/puma/thread_pool.rb +14 -2
- data/lib/puma/util.rb +1 -1
- data/lib/rack/handler/puma.rb +8 -5
- data/tools/Dockerfile +5 -3
- metadata +10 -12
data/lib/puma/configuration.rb
CHANGED
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
# frozen_string_literal: true
|
|
2
2
|
|
|
3
|
-
require_relative 'rack/builder'
|
|
4
3
|
require_relative 'plugin'
|
|
5
4
|
require_relative 'const'
|
|
6
|
-
|
|
5
|
+
require_relative 'dsl'
|
|
7
6
|
|
|
8
7
|
module Puma
|
|
9
8
|
# A class used for storing "leveled" configuration options.
|
|
@@ -131,6 +130,7 @@ module Puma
|
|
|
131
130
|
binds: ['tcp://0.0.0.0:9292'.freeze],
|
|
132
131
|
clean_thread_locals: false,
|
|
133
132
|
debug: false,
|
|
133
|
+
enable_keep_alives: true,
|
|
134
134
|
early_hints: nil,
|
|
135
135
|
environment: 'development'.freeze,
|
|
136
136
|
# Number of seconds to wait until we get the first data for the request.
|
|
@@ -173,8 +173,8 @@ module Puma
|
|
|
173
173
|
http_content_length_limit: nil
|
|
174
174
|
}
|
|
175
175
|
|
|
176
|
-
def initialize(user_options={}, default_options = {}, &block)
|
|
177
|
-
default_options = self.puma_default_options.merge(default_options)
|
|
176
|
+
def initialize(user_options={}, default_options = {}, env = ENV, &block)
|
|
177
|
+
default_options = self.puma_default_options(env).merge(default_options)
|
|
178
178
|
|
|
179
179
|
@options = UserFileDefaultOptions.new(user_options, default_options)
|
|
180
180
|
@plugins = PluginLoader.new
|
|
@@ -186,6 +186,8 @@ module Puma
|
|
|
186
186
|
default_options[:preload_app] = (@options[:workers] > 1) && Puma.forkable?
|
|
187
187
|
end
|
|
188
188
|
|
|
189
|
+
@puma_bundler_pruned = env.key? 'PUMA_BUNDLER_PRUNED'
|
|
190
|
+
|
|
189
191
|
if block
|
|
190
192
|
configure(&block)
|
|
191
193
|
end
|
|
@@ -216,22 +218,27 @@ module Puma
|
|
|
216
218
|
self
|
|
217
219
|
end
|
|
218
220
|
|
|
219
|
-
def puma_default_options
|
|
221
|
+
def puma_default_options(env = ENV)
|
|
220
222
|
defaults = DEFAULTS.dup
|
|
221
|
-
puma_options_from_env.each { |k,v| defaults[k] = v if v }
|
|
223
|
+
puma_options_from_env(env).each { |k,v| defaults[k] = v if v }
|
|
222
224
|
defaults
|
|
223
225
|
end
|
|
224
226
|
|
|
225
|
-
def puma_options_from_env
|
|
226
|
-
min =
|
|
227
|
-
max =
|
|
228
|
-
workers =
|
|
227
|
+
def puma_options_from_env(env = ENV)
|
|
228
|
+
min = env['PUMA_MIN_THREADS'] || env['MIN_THREADS']
|
|
229
|
+
max = env['PUMA_MAX_THREADS'] || env['MAX_THREADS']
|
|
230
|
+
workers = if env['WEB_CONCURRENCY'] == 'auto'
|
|
231
|
+
require_processor_counter
|
|
232
|
+
::Concurrent.available_processor_count
|
|
233
|
+
else
|
|
234
|
+
env['WEB_CONCURRENCY']
|
|
235
|
+
end
|
|
229
236
|
|
|
230
237
|
{
|
|
231
|
-
min_threads: min && Integer(min),
|
|
232
|
-
max_threads: max && Integer(max),
|
|
233
|
-
workers: workers && Integer(workers),
|
|
234
|
-
environment:
|
|
238
|
+
min_threads: min && min != "" && Integer(min),
|
|
239
|
+
max_threads: max && max != "" && Integer(max),
|
|
240
|
+
workers: workers && workers != "" && Integer(workers),
|
|
241
|
+
environment: env['APP_ENV'] || env['RACK_ENV'] || env['RAILS_ENV'],
|
|
235
242
|
}
|
|
236
243
|
end
|
|
237
244
|
|
|
@@ -311,6 +318,8 @@ module Puma
|
|
|
311
318
|
# @param arg [Launcher, Int] `:on_restart` passes Launcher
|
|
312
319
|
#
|
|
313
320
|
def run_hooks(key, arg, log_writer, hook_data = nil)
|
|
321
|
+
log_writer.debug "Running #{key} hooks"
|
|
322
|
+
|
|
314
323
|
@options.all_of(key).each do |b|
|
|
315
324
|
begin
|
|
316
325
|
if Array === b
|
|
@@ -339,12 +348,22 @@ module Puma
|
|
|
339
348
|
|
|
340
349
|
private
|
|
341
350
|
|
|
351
|
+
def require_processor_counter
|
|
352
|
+
require 'concurrent/utility/processor_counter'
|
|
353
|
+
rescue LoadError
|
|
354
|
+
warn <<~MESSAGE
|
|
355
|
+
WEB_CONCURRENCY=auto requires the "concurrent-ruby" gem to be installed.
|
|
356
|
+
Please add "concurrent-ruby" to your Gemfile.
|
|
357
|
+
MESSAGE
|
|
358
|
+
raise
|
|
359
|
+
end
|
|
360
|
+
|
|
342
361
|
# Load and use the normal Rack builder if we can, otherwise
|
|
343
362
|
# fallback to our minimal version.
|
|
344
363
|
def rack_builder
|
|
345
364
|
# Load bundler now if we can so that we can pickup rack from
|
|
346
365
|
# a Gemfile
|
|
347
|
-
if
|
|
366
|
+
if @puma_bundler_pruned
|
|
348
367
|
begin
|
|
349
368
|
require 'bundler/setup'
|
|
350
369
|
rescue LoadError
|
|
@@ -354,11 +373,10 @@ module Puma
|
|
|
354
373
|
begin
|
|
355
374
|
require 'rack'
|
|
356
375
|
require 'rack/builder'
|
|
376
|
+
::Rack::Builder
|
|
357
377
|
rescue LoadError
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
else
|
|
361
|
-
return ::Rack::Builder
|
|
378
|
+
require_relative 'rack/builder'
|
|
379
|
+
Puma::Rack::Builder
|
|
362
380
|
end
|
|
363
381
|
end
|
|
364
382
|
|
|
@@ -387,5 +405,3 @@ module Puma
|
|
|
387
405
|
end
|
|
388
406
|
end
|
|
389
407
|
end
|
|
390
|
-
|
|
391
|
-
require_relative 'dsl'
|
data/lib/puma/const.rb
CHANGED
|
@@ -100,8 +100,8 @@ module Puma
|
|
|
100
100
|
# too taxing on performance.
|
|
101
101
|
module Const
|
|
102
102
|
|
|
103
|
-
PUMA_VERSION = VERSION = "6.
|
|
104
|
-
CODE_NAME = "
|
|
103
|
+
PUMA_VERSION = VERSION = "6.6.1"
|
|
104
|
+
CODE_NAME = "Return to Forever"
|
|
105
105
|
|
|
106
106
|
PUMA_SERVER_STRING = ["puma", PUMA_VERSION, CODE_NAME].join(" ").freeze
|
|
107
107
|
|
|
@@ -137,7 +137,7 @@ module Puma
|
|
|
137
137
|
}.freeze
|
|
138
138
|
|
|
139
139
|
# The basic max request size we'll try to read.
|
|
140
|
-
CHUNK_SIZE =
|
|
140
|
+
CHUNK_SIZE = 64 * 1024
|
|
141
141
|
|
|
142
142
|
# This is the maximum header that is allowed before a client is booted. The parser detects
|
|
143
143
|
# this, but we'd also like to do this as well.
|
|
@@ -281,9 +281,28 @@ module Puma
|
|
|
281
281
|
# header values can contain HTAB?
|
|
282
282
|
ILLEGAL_HEADER_VALUE_REGEX = /[\x00-\x08\x0A-\x1F]/.freeze
|
|
283
283
|
|
|
284
|
+
# The keys of headers that should not be convert to underscore
|
|
285
|
+
# normalized versions. These headers are ignored at the request reading layer,
|
|
286
|
+
# but if we normalize them after reading, it's just confusing for the application.
|
|
287
|
+
UNMASKABLE_HEADERS = {
|
|
288
|
+
"HTTP_TRANSFER,ENCODING" => true,
|
|
289
|
+
"HTTP_CONTENT,LENGTH" => true,
|
|
290
|
+
}
|
|
291
|
+
|
|
284
292
|
# Banned keys of response header
|
|
285
293
|
BANNED_HEADER_KEY = /\A(rack\.|status\z)/.freeze
|
|
286
294
|
|
|
287
295
|
PROXY_PROTOCOL_V1_REGEX = /^PROXY (?:TCP4|TCP6|UNKNOWN) ([^\r]+)\r\n/.freeze
|
|
296
|
+
|
|
297
|
+
# All constants are prefixed with `PIPE_` to avoid name collisions.
|
|
298
|
+
module PipeRequest
|
|
299
|
+
PIPE_WAKEUP = "!"
|
|
300
|
+
PIPE_BOOT = "b"
|
|
301
|
+
PIPE_FORK = "f"
|
|
302
|
+
PIPE_EXTERNAL_TERM = "e"
|
|
303
|
+
PIPE_TERM = "t"
|
|
304
|
+
PIPE_PING = "p"
|
|
305
|
+
PIPE_IDLE = "i"
|
|
306
|
+
end
|
|
288
307
|
end
|
|
289
308
|
end
|
data/lib/puma/control_cli.rb
CHANGED
|
@@ -37,7 +37,7 @@ module Puma
|
|
|
37
37
|
# @version 5.0.0
|
|
38
38
|
PRINTABLE_COMMANDS = %w[gc-stats stats thread-backtraces].freeze
|
|
39
39
|
|
|
40
|
-
def initialize(argv, stdout=STDOUT, stderr=STDERR)
|
|
40
|
+
def initialize(argv, stdout=STDOUT, stderr=STDERR, env: ENV)
|
|
41
41
|
@state = nil
|
|
42
42
|
@quiet = false
|
|
43
43
|
@pidfile = nil
|
|
@@ -46,7 +46,7 @@ module Puma
|
|
|
46
46
|
@control_auth_token = nil
|
|
47
47
|
@config_file = nil
|
|
48
48
|
@command = nil
|
|
49
|
-
@environment =
|
|
49
|
+
@environment = env['APP_ENV'] || env['RACK_ENV'] || env['RAILS_ENV']
|
|
50
50
|
|
|
51
51
|
@argv = argv.dup
|
|
52
52
|
@stdout = stdout
|
|
@@ -60,7 +60,7 @@ module Puma
|
|
|
60
60
|
@state = arg
|
|
61
61
|
end
|
|
62
62
|
|
|
63
|
-
o.on "-Q", "--quiet", "
|
|
63
|
+
o.on "-Q", "--quiet", "Do not display messages" do |arg|
|
|
64
64
|
@quiet = true
|
|
65
65
|
end
|
|
66
66
|
|
|
@@ -127,7 +127,7 @@ module Puma
|
|
|
127
127
|
require_relative 'configuration'
|
|
128
128
|
require_relative 'log_writer'
|
|
129
129
|
|
|
130
|
-
config = Puma::Configuration.new({ config_files: [@config_file] }, {})
|
|
130
|
+
config = Puma::Configuration.new({ config_files: [@config_file] }, {} , env)
|
|
131
131
|
config.load
|
|
132
132
|
@state ||= config.options[:state]
|
|
133
133
|
@control_url ||= config.options[:control_url]
|
data/lib/puma/detect.rb
CHANGED
|
@@ -12,15 +12,14 @@ module Puma
|
|
|
12
12
|
|
|
13
13
|
IS_JRUBY = Object.const_defined? :JRUBY_VERSION
|
|
14
14
|
|
|
15
|
-
IS_OSX =
|
|
15
|
+
IS_OSX = RUBY_DESCRIPTION.include? 'darwin'
|
|
16
16
|
|
|
17
|
-
IS_WINDOWS =
|
|
18
|
-
IS_JRUBY && RUBY_DESCRIPTION.include?('mswin')
|
|
17
|
+
IS_WINDOWS = RUBY_DESCRIPTION.match?(/mswin|ming|cygwin/)
|
|
19
18
|
|
|
20
19
|
IS_LINUX = !(IS_OSX || IS_WINDOWS)
|
|
21
20
|
|
|
22
21
|
# @version 5.2.0
|
|
23
|
-
IS_MRI =
|
|
22
|
+
IS_MRI = RUBY_ENGINE == 'ruby'
|
|
24
23
|
|
|
25
24
|
def self.jruby?
|
|
26
25
|
IS_JRUBY
|