puma 5.6.9 → 6.0.0
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 +96 -28
- data/LICENSE +0 -0
- data/README.md +21 -17
- 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 +0 -0
- data/docs/nginx.md +0 -0
- data/docs/plugins.md +0 -0
- data/docs/rails_dev_mode.md +0 -0
- data/docs/restart.md +0 -0
- data/docs/signals.md +0 -0
- data/docs/stats.md +0 -0
- data/docs/systemd.md +0 -0
- 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 +11 -8
- 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 +36 -15
- data/ext/puma_http11/no_ssl/PumaHttp11Service.java +0 -0
- data/ext/puma_http11/org/jruby/puma/Http11.java +3 -5
- data/ext/puma_http11/org/jruby/puma/Http11Parser.java +1 -1
- data/ext/puma_http11/org/jruby/puma/MiniSSL.java +156 -53
- data/ext/puma_http11/puma_http11.c +17 -9
- data/lib/puma/app/status.rb +3 -3
- data/lib/puma/binder.rb +36 -42
- data/lib/puma/cli.rb +11 -17
- data/lib/puma/client.rb +29 -53
- data/lib/puma/cluster/worker.rb +13 -11
- data/lib/puma/cluster/worker_handle.rb +4 -1
- data/lib/puma/cluster.rb +28 -25
- data/lib/puma/commonlogger.rb +0 -0
- data/lib/puma/configuration.rb +74 -58
- data/lib/puma/const.rb +14 -26
- data/lib/puma/control_cli.rb +3 -6
- data/lib/puma/detect.rb +2 -0
- data/lib/puma/dsl.rb +93 -52
- data/lib/puma/error_logger.rb +17 -9
- data/lib/puma/events.rb +6 -126
- data/lib/puma/io_buffer.rb +29 -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 +96 -156
- data/lib/puma/log_writer.rb +137 -0
- data/lib/puma/minissl/context_builder.rb +23 -12
- data/lib/puma/minissl.rb +82 -11
- data/lib/puma/null_io.rb +0 -0
- data/lib/puma/plugin/tmp_restart.rb +1 -1
- data/lib/puma/plugin.rb +0 -0
- data/lib/puma/rack/builder.rb +4 -4
- data/lib/puma/rack/urlmap.rb +0 -0
- data/lib/puma/rack_default.rb +1 -1
- data/lib/puma/reactor.rb +3 -3
- data/lib/puma/request.rb +295 -177
- data/lib/puma/runner.rb +41 -20
- data/lib/puma/server.rb +53 -66
- data/lib/puma/single.rb +10 -10
- data/lib/puma/state_file.rb +1 -4
- data/lib/puma/systemd.rb +3 -2
- data/lib/puma/thread_pool.rb +16 -13
- data/lib/puma/util.rb +0 -11
- data/lib/puma.rb +10 -9
- data/lib/rack/handler/puma.rb +9 -9
- data/tools/Dockerfile +0 -0
- data/tools/trickletest.rb +0 -0
- metadata +9 -6
- data/lib/puma/queue_close.rb +0 -26
- data/lib/rack/version_restriction.rb +0 -15
data/lib/puma/minissl.rb
CHANGED
@@ -1,11 +1,12 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
3
|
begin
|
4
|
-
require 'io/wait'
|
4
|
+
require 'io/wait' unless Puma::HAS_NATIVE_IO_WAIT
|
5
5
|
rescue LoadError
|
6
6
|
end
|
7
7
|
|
8
8
|
# need for Puma::MiniSSL::OPENSSL constants used in `HAS_TLS1_3`
|
9
|
+
# use require, see https://github.com/puma/puma/pull/2381
|
9
10
|
require 'puma/puma_http11'
|
10
11
|
|
11
12
|
module Puma
|
@@ -13,15 +14,16 @@ module Puma
|
|
13
14
|
# Define constant at runtime, as it's easy to determine at built time,
|
14
15
|
# but Puma could (it shouldn't) be loaded with an older OpenSSL version
|
15
16
|
# @version 5.0.0
|
16
|
-
HAS_TLS1_3 =
|
17
|
-
|
18
|
-
|
17
|
+
HAS_TLS1_3 = IS_JRUBY ||
|
18
|
+
((OPENSSL_VERSION[/ \d+\.\d+\.\d+/].split('.').map(&:to_i) <=> [1,1,1]) != -1 &&
|
19
|
+
(OPENSSL_LIBRARY_VERSION[/ \d+\.\d+\.\d+/].split('.').map(&:to_i) <=> [1,1,1]) !=-1)
|
19
20
|
|
20
21
|
class Socket
|
21
22
|
def initialize(socket, engine)
|
22
23
|
@socket = socket
|
23
24
|
@engine = engine
|
24
25
|
@peercert = nil
|
26
|
+
@reuse = nil
|
25
27
|
end
|
26
28
|
|
27
29
|
# @!attribute [r] to_io
|
@@ -50,7 +52,7 @@ module Puma
|
|
50
52
|
# is made with TLSv1.3 as an available protocol
|
51
53
|
# @version 5.0.0
|
52
54
|
def bad_tlsv1_3?
|
53
|
-
HAS_TLS1_3 &&
|
55
|
+
HAS_TLS1_3 && ssl_version_state == ['TLSv1.3', 'SSLERR']
|
54
56
|
end
|
55
57
|
private :bad_tlsv1_3?
|
56
58
|
|
@@ -123,7 +125,7 @@ module Puma
|
|
123
125
|
while true
|
124
126
|
wrote = @engine.write data
|
125
127
|
|
126
|
-
enc_wr = ''
|
128
|
+
enc_wr = +''
|
127
129
|
while (enc = @engine.extract)
|
128
130
|
enc_wr << enc
|
129
131
|
end
|
@@ -195,10 +197,6 @@ module Puma
|
|
195
197
|
if IS_JRUBY
|
196
198
|
OPENSSL_NO_SSL3 = false
|
197
199
|
OPENSSL_NO_TLS1 = false
|
198
|
-
|
199
|
-
class SSLError < StandardError
|
200
|
-
# Define this for jruby even though it isn't used.
|
201
|
-
end
|
202
200
|
end
|
203
201
|
|
204
202
|
class Context
|
@@ -212,6 +210,9 @@ module Puma
|
|
212
210
|
@cert = nil
|
213
211
|
@key_pem = nil
|
214
212
|
@cert_pem = nil
|
213
|
+
@reuse = nil
|
214
|
+
@reuse_cache_size = nil
|
215
|
+
@reuse_timeout = nil
|
215
216
|
end
|
216
217
|
|
217
218
|
def check_file(file, desc)
|
@@ -222,16 +223,55 @@ module Puma
|
|
222
223
|
if IS_JRUBY
|
223
224
|
# jruby-specific Context properties: java uses a keystore and password pair rather than a cert/key pair
|
224
225
|
attr_reader :keystore
|
226
|
+
attr_reader :keystore_type
|
225
227
|
attr_accessor :keystore_pass
|
226
|
-
|
228
|
+
attr_reader :truststore
|
229
|
+
attr_reader :truststore_type
|
230
|
+
attr_accessor :truststore_pass
|
231
|
+
attr_reader :cipher_suites
|
232
|
+
attr_reader :protocols
|
227
233
|
|
228
234
|
def keystore=(keystore)
|
229
235
|
check_file keystore, 'Keystore'
|
230
236
|
@keystore = keystore
|
231
237
|
end
|
232
238
|
|
239
|
+
def truststore=(truststore)
|
240
|
+
# NOTE: historically truststore was assumed the same as keystore, this is kept for backwards
|
241
|
+
# compatibility, to rely on JVM's trust defaults we allow setting `truststore = :default`
|
242
|
+
unless truststore.eql?(:default)
|
243
|
+
raise ArgumentError, "No such truststore file '#{truststore}'" unless File.exist?(truststore)
|
244
|
+
end
|
245
|
+
@truststore = truststore
|
246
|
+
end
|
247
|
+
|
248
|
+
def keystore_type=(type)
|
249
|
+
raise ArgumentError, "Invalid keystore type: #{type.inspect}" unless ['pkcs12', 'jks', nil].include?(type)
|
250
|
+
@keystore_type = type
|
251
|
+
end
|
252
|
+
|
253
|
+
def truststore_type=(type)
|
254
|
+
raise ArgumentError, "Invalid truststore type: #{type.inspect}" unless ['pkcs12', 'jks', nil].include?(type)
|
255
|
+
@truststore_type = type
|
256
|
+
end
|
257
|
+
|
258
|
+
def cipher_suites=(list)
|
259
|
+
list = list.split(',').map(&:strip) if list.is_a?(String)
|
260
|
+
@cipher_suites = list
|
261
|
+
end
|
262
|
+
|
263
|
+
# aliases for backwards compatibility
|
264
|
+
alias_method :ssl_cipher_list, :cipher_suites
|
265
|
+
alias_method :ssl_cipher_list=, :cipher_suites=
|
266
|
+
|
267
|
+
def protocols=(list)
|
268
|
+
list = list.split(',').map(&:strip) if list.is_a?(String)
|
269
|
+
@protocols = list
|
270
|
+
end
|
271
|
+
|
233
272
|
def check
|
234
273
|
raise "Keystore not configured" unless @keystore
|
274
|
+
# @truststore defaults to @keystore due backwards compatibility
|
235
275
|
end
|
236
276
|
|
237
277
|
else
|
@@ -244,6 +284,8 @@ module Puma
|
|
244
284
|
attr_accessor :ssl_cipher_filter
|
245
285
|
attr_accessor :verification_flags
|
246
286
|
|
287
|
+
attr_reader :reuse, :reuse_cache_size, :reuse_timeout
|
288
|
+
|
247
289
|
def key=(key)
|
248
290
|
check_file key, 'Key'
|
249
291
|
@key = key
|
@@ -273,6 +315,35 @@ module Puma
|
|
273
315
|
raise "Key not configured" if @key.nil? && @key_pem.nil?
|
274
316
|
raise "Cert not configured" if @cert.nil? && @cert_pem.nil?
|
275
317
|
end
|
318
|
+
|
319
|
+
# Controls session reuse. Allowed values are as follows:
|
320
|
+
# * 'off' - matches the behavior of Puma 5.6 and earlier. This is included
|
321
|
+
# in case reuse 'on' is made the default in future Puma versions.
|
322
|
+
# * 'dflt' - sets session reuse on, with OpenSSL default cache size of
|
323
|
+
# 20k and default timeout of 300 seconds.
|
324
|
+
# * 's,t' - where s and t are integer strings, for size and timeout.
|
325
|
+
# * 's' - where s is an integer strings for size.
|
326
|
+
# * ',t' - where t is an integer strings for timeout.
|
327
|
+
#
|
328
|
+
def reuse=(reuse_str)
|
329
|
+
case reuse_str
|
330
|
+
when 'off'
|
331
|
+
@reuse = nil
|
332
|
+
when 'dflt'
|
333
|
+
@reuse = true
|
334
|
+
when /\A\d+\z/
|
335
|
+
@reuse = true
|
336
|
+
@reuse_cache_size = reuse_str.to_i
|
337
|
+
when /\A\d+,\d+\z/
|
338
|
+
@reuse = true
|
339
|
+
size, time = reuse_str.split ','
|
340
|
+
@reuse_cache_size = size.to_i
|
341
|
+
@reuse_timeout = time.to_i
|
342
|
+
when /\A,\d+\z/
|
343
|
+
@reuse = true
|
344
|
+
@reuse_timeout = reuse_str.delete(',').to_i
|
345
|
+
end
|
346
|
+
end
|
276
347
|
end
|
277
348
|
|
278
349
|
# disables TLSv1
|
data/lib/puma/null_io.rb
CHANGED
File without changes
|
data/lib/puma/plugin.rb
CHANGED
File without changes
|
data/lib/puma/rack/builder.rb
CHANGED
@@ -102,13 +102,13 @@ module Puma::Rack
|
|
102
102
|
begin
|
103
103
|
info = []
|
104
104
|
server = Rack::Handler.get(options[:server]) || Rack::Handler.default(options)
|
105
|
-
if server
|
105
|
+
if server&.respond_to?(:valid_options)
|
106
106
|
info << ""
|
107
107
|
info << "Server-specific options for #{server.name}:"
|
108
108
|
|
109
109
|
has_options = false
|
110
110
|
server.valid_options.each do |name, description|
|
111
|
-
next if
|
111
|
+
next if /^(Host|Port)[^a-zA-Z]/.match? name.to_s # ignore handler's host and port options, we do our own.
|
112
112
|
|
113
113
|
info << " -O %-21s %s" % [name, description]
|
114
114
|
has_options = true
|
@@ -276,7 +276,7 @@ module Puma::Rack
|
|
276
276
|
app = @map ? generate_map(@run, @map) : @run
|
277
277
|
fail "missing run or map statement" unless app
|
278
278
|
app = @use.reverse.inject(app) { |a,e| e[a] }
|
279
|
-
@warmup
|
279
|
+
@warmup&.call app
|
280
280
|
app
|
281
281
|
end
|
282
282
|
|
@@ -287,7 +287,7 @@ module Puma::Rack
|
|
287
287
|
private
|
288
288
|
|
289
289
|
def generate_map(default_app, mapping)
|
290
|
-
|
290
|
+
require_relative 'urlmap'
|
291
291
|
|
292
292
|
mapped = default_app ? {'/' => default_app} : {}
|
293
293
|
mapping.each { |r,b| mapped[r] = self.class.new(default_app, &b).to_app }
|
data/lib/puma/rack/urlmap.rb
CHANGED
File without changes
|
data/lib/puma/rack_default.rb
CHANGED
data/lib/puma/reactor.rb
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
3
|
+
require_relative 'queue_close' unless ::Queue.instance_methods.include? :close
|
4
4
|
|
5
5
|
module Puma
|
6
6
|
class UnsupportedBackend < StandardError; end
|
@@ -61,7 +61,7 @@ module Puma
|
|
61
61
|
@selector.wakeup
|
62
62
|
rescue IOError # Ignore if selector is already closed
|
63
63
|
end
|
64
|
-
@thread
|
64
|
+
@thread&.join
|
65
65
|
end
|
66
66
|
|
67
67
|
private
|
@@ -76,7 +76,7 @@ module Puma
|
|
76
76
|
|
77
77
|
# Wakeup all objects that timed out.
|
78
78
|
timed_out = @timeouts.take_while {|t| t.timeout == 0}
|
79
|
-
timed_out.each
|
79
|
+
timed_out.each { |c| wakeup! c }
|
80
80
|
|
81
81
|
unless @input.empty?
|
82
82
|
until @input.empty?
|