puma 5.5.0 → 5.6.7
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 +140 -3
- data/README.md +28 -6
- data/docs/architecture.md +49 -16
- data/docs/compile_options.md +4 -2
- data/docs/deployment.md +53 -52
- data/docs/plugins.md +15 -15
- data/docs/rails_dev_mode.md +2 -3
- data/docs/restart.md +6 -6
- data/docs/signals.md +11 -10
- data/docs/stats.md +8 -8
- data/docs/systemd.md +63 -67
- data/ext/puma_http11/extconf.rb +18 -7
- data/ext/puma_http11/http11_parser.c +23 -10
- data/ext/puma_http11/http11_parser_common.rl +1 -1
- data/ext/puma_http11/mini_ssl.c +75 -12
- data/ext/puma_http11/org/jruby/puma/Http11Parser.java +49 -47
- data/ext/puma_http11/org/jruby/puma/MiniSSL.java +38 -55
- data/ext/puma_http11/puma_http11.c +1 -1
- data/lib/puma/app/status.rb +3 -0
- data/lib/puma/binder.rb +20 -6
- data/lib/puma/cli.rb +9 -4
- data/lib/puma/client.rb +68 -18
- data/lib/puma/cluster/worker.rb +7 -17
- data/lib/puma/cluster/worker_handle.rb +4 -0
- data/lib/puma/cluster.rb +29 -21
- data/lib/puma/configuration.rb +4 -1
- data/lib/puma/const.rb +7 -8
- data/lib/puma/control_cli.rb +19 -13
- data/lib/puma/detect.rb +8 -2
- data/lib/puma/dsl.rb +91 -10
- data/lib/puma/launcher.rb +13 -1
- data/lib/puma/minissl/context_builder.rb +8 -6
- data/lib/puma/minissl.rb +28 -7
- data/lib/puma/null_io.rb +5 -0
- data/lib/puma/plugin.rb +1 -1
- data/lib/puma/request.rb +15 -6
- data/lib/puma/runner.rb +22 -8
- data/lib/puma/server.rb +29 -30
- data/lib/puma/state_file.rb +42 -7
- data/lib/puma/thread_pool.rb +2 -2
- data/lib/puma/util.rb +19 -3
- data/lib/puma.rb +5 -3
- data/lib/rack/version_restriction.rb +15 -0
- data/tools/Dockerfile +1 -1
- metadata +4 -3
data/lib/puma/launcher.rb
CHANGED
@@ -15,6 +15,7 @@ module Puma
|
|
15
15
|
# It is responsible for either launching a cluster of Puma workers or a single
|
16
16
|
# puma server.
|
17
17
|
class Launcher
|
18
|
+
# @deprecated 6.0.0
|
18
19
|
KEYS_NOT_TO_PERSIST_IN_STATE = [
|
19
20
|
:logger, :lowlevel_error_handler,
|
20
21
|
:before_worker_shutdown, :before_worker_boot, :before_worker_fork,
|
@@ -73,7 +74,7 @@ module Puma
|
|
73
74
|
|
74
75
|
generate_restart_data
|
75
76
|
|
76
|
-
if clustered? && !
|
77
|
+
if clustered? && !Puma.forkable?
|
77
78
|
unsupported "worker mode not supported on #{RUBY_ENGINE} on this platform"
|
78
79
|
end
|
79
80
|
|
@@ -158,6 +159,17 @@ module Puma
|
|
158
159
|
true
|
159
160
|
end
|
160
161
|
|
162
|
+
# Begin a refork if supported
|
163
|
+
def refork
|
164
|
+
if clustered? && @runner.respond_to?(:fork_worker!) && @options[:fork_worker]
|
165
|
+
@runner.fork_worker!
|
166
|
+
true
|
167
|
+
else
|
168
|
+
log "* refork called but not available."
|
169
|
+
false
|
170
|
+
end
|
171
|
+
end
|
172
|
+
|
161
173
|
# Run the server. This blocks until the server is stopped
|
162
174
|
def run
|
163
175
|
previous_env =
|
@@ -23,17 +23,19 @@ module Puma
|
|
23
23
|
ctx.keystore_pass = params['keystore-pass']
|
24
24
|
ctx.ssl_cipher_list = params['ssl_cipher_list'] if params['ssl_cipher_list']
|
25
25
|
else
|
26
|
-
|
27
|
-
events.error "Please specify the SSL key via 'key='"
|
26
|
+
if params['key'].nil? && params['key_pem'].nil?
|
27
|
+
events.error "Please specify the SSL key via 'key=' or 'key_pem='"
|
28
28
|
end
|
29
29
|
|
30
|
-
ctx.key = params['key']
|
30
|
+
ctx.key = params['key'] if params['key']
|
31
|
+
ctx.key_pem = params['key_pem'] if params['key_pem']
|
31
32
|
|
32
|
-
|
33
|
-
events.error "Please specify the SSL cert via 'cert='"
|
33
|
+
if params['cert'].nil? && params['cert_pem'].nil?
|
34
|
+
events.error "Please specify the SSL cert via 'cert=' or 'cert_pem='"
|
34
35
|
end
|
35
36
|
|
36
|
-
ctx.cert = params['cert']
|
37
|
+
ctx.cert = params['cert'] if params['cert']
|
38
|
+
ctx.cert_pem = params['cert_pem'] if params['cert_pem']
|
37
39
|
|
38
40
|
if ['peer', 'force_peer'].include?(params['verify_mode'])
|
39
41
|
unless params['ca']
|
data/lib/puma/minissl.rb
CHANGED
@@ -169,7 +169,7 @@ module Puma
|
|
169
169
|
end
|
170
170
|
end
|
171
171
|
rescue IOError, SystemCallError
|
172
|
-
|
172
|
+
Puma::Util.purge_interrupt_queue
|
173
173
|
# nothing
|
174
174
|
ensure
|
175
175
|
@socket.close
|
@@ -208,6 +208,15 @@ module Puma
|
|
208
208
|
def initialize
|
209
209
|
@no_tlsv1 = false
|
210
210
|
@no_tlsv1_1 = false
|
211
|
+
@key = nil
|
212
|
+
@cert = nil
|
213
|
+
@key_pem = nil
|
214
|
+
@cert_pem = nil
|
215
|
+
end
|
216
|
+
|
217
|
+
def check_file(file, desc)
|
218
|
+
raise ArgumentError, "#{desc} file '#{file}' does not exist" unless File.exist? file
|
219
|
+
raise ArgumentError, "#{desc} file '#{file}' is not readable" unless File.readable? file
|
211
220
|
end
|
212
221
|
|
213
222
|
if IS_JRUBY
|
@@ -217,7 +226,7 @@ module Puma
|
|
217
226
|
attr_accessor :ssl_cipher_list
|
218
227
|
|
219
228
|
def keystore=(keystore)
|
220
|
-
|
229
|
+
check_file keystore, 'Keystore'
|
221
230
|
@keystore = keystore
|
222
231
|
end
|
223
232
|
|
@@ -230,27 +239,39 @@ module Puma
|
|
230
239
|
attr_reader :key
|
231
240
|
attr_reader :cert
|
232
241
|
attr_reader :ca
|
242
|
+
attr_reader :cert_pem
|
243
|
+
attr_reader :key_pem
|
233
244
|
attr_accessor :ssl_cipher_filter
|
234
245
|
attr_accessor :verification_flags
|
235
246
|
|
236
247
|
def key=(key)
|
237
|
-
|
248
|
+
check_file key, 'Key'
|
238
249
|
@key = key
|
239
250
|
end
|
240
251
|
|
241
252
|
def cert=(cert)
|
242
|
-
|
253
|
+
check_file cert, 'Cert'
|
243
254
|
@cert = cert
|
244
255
|
end
|
245
256
|
|
246
257
|
def ca=(ca)
|
247
|
-
|
258
|
+
check_file ca, 'ca'
|
248
259
|
@ca = ca
|
249
260
|
end
|
250
261
|
|
262
|
+
def cert_pem=(cert_pem)
|
263
|
+
raise ArgumentError, "'cert_pem' is not a String" unless cert_pem.is_a? String
|
264
|
+
@cert_pem = cert_pem
|
265
|
+
end
|
266
|
+
|
267
|
+
def key_pem=(key_pem)
|
268
|
+
raise ArgumentError, "'key_pem' is not a String" unless key_pem.is_a? String
|
269
|
+
@key_pem = key_pem
|
270
|
+
end
|
271
|
+
|
251
272
|
def check
|
252
|
-
raise "Key not configured"
|
253
|
-
raise "Cert not configured"
|
273
|
+
raise "Key not configured" if @key.nil? && @key_pem.nil?
|
274
|
+
raise "Cert not configured" if @cert.nil? && @cert_pem.nil?
|
254
275
|
end
|
255
276
|
end
|
256
277
|
|
data/lib/puma/null_io.rb
CHANGED
data/lib/puma/plugin.rb
CHANGED
data/lib/puma/request.rb
CHANGED
@@ -167,13 +167,22 @@ module Puma
|
|
167
167
|
end
|
168
168
|
|
169
169
|
ensure
|
170
|
-
|
171
|
-
|
172
|
-
|
173
|
-
|
174
|
-
|
170
|
+
begin
|
171
|
+
uncork_socket io
|
172
|
+
|
173
|
+
body.close
|
174
|
+
client.tempfile.unlink if client.tempfile
|
175
|
+
ensure
|
176
|
+
# Whatever happens, we MUST call `close` on the response body.
|
177
|
+
# Otherwise Rack::BodyProxy callbacks may not fire and lead to various state leaks
|
178
|
+
res_body.close if res_body.respond_to? :close
|
179
|
+
end
|
175
180
|
|
176
|
-
|
181
|
+
begin
|
182
|
+
after_reply.each { |o| o.call }
|
183
|
+
rescue StandardError => e
|
184
|
+
@log_writer.debug_error e
|
185
|
+
end
|
177
186
|
end
|
178
187
|
|
179
188
|
res_info[:keep_alive]
|
data/lib/puma/runner.rb
CHANGED
@@ -15,6 +15,16 @@ module Puma
|
|
15
15
|
@app = nil
|
16
16
|
@control = nil
|
17
17
|
@started_at = Time.now
|
18
|
+
@wakeup = nil
|
19
|
+
end
|
20
|
+
|
21
|
+
def wakeup!
|
22
|
+
return unless @wakeup
|
23
|
+
|
24
|
+
@wakeup.write "!" unless @wakeup.closed?
|
25
|
+
|
26
|
+
rescue SystemCallError, IOError
|
27
|
+
Puma::Util.purge_interrupt_queue
|
18
28
|
end
|
19
29
|
|
20
30
|
def development?
|
@@ -59,7 +69,7 @@ module Puma
|
|
59
69
|
|
60
70
|
control.binder.parse [str], self, 'Starting control server'
|
61
71
|
|
62
|
-
control.run thread_name: '
|
72
|
+
control.run thread_name: 'ctl'
|
63
73
|
@control = control
|
64
74
|
end
|
65
75
|
|
@@ -84,12 +94,13 @@ module Puma
|
|
84
94
|
def output_header(mode)
|
85
95
|
min_t = @options[:min_threads]
|
86
96
|
max_t = @options[:max_threads]
|
97
|
+
environment = @options[:environment]
|
87
98
|
|
88
99
|
log "Puma starting in #{mode} mode..."
|
89
100
|
log "* Puma version: #{Puma::Const::PUMA_VERSION} (#{ruby_engine}) (\"#{Puma::Const::CODE_NAME}\")"
|
90
101
|
log "* Min threads: #{min_t}"
|
91
102
|
log "* Max threads: #{max_t}"
|
92
|
-
log "* Environment: #{
|
103
|
+
log "* Environment: #{environment}"
|
93
104
|
|
94
105
|
if mode == "cluster"
|
95
106
|
log "* Master PID: #{Process.pid}"
|
@@ -108,9 +119,7 @@ module Puma
|
|
108
119
|
append = @options[:redirect_append]
|
109
120
|
|
110
121
|
if stdout
|
111
|
-
|
112
|
-
raise "Cannot redirect STDOUT to #{stdout}"
|
113
|
-
end
|
122
|
+
ensure_output_directory_exists(stdout, 'STDOUT')
|
114
123
|
|
115
124
|
STDOUT.reopen stdout, (append ? "a" : "w")
|
116
125
|
STDOUT.puts "=== puma startup: #{Time.now} ==="
|
@@ -118,9 +127,7 @@ module Puma
|
|
118
127
|
end
|
119
128
|
|
120
129
|
if stderr
|
121
|
-
|
122
|
-
raise "Cannot redirect STDERR to #{stderr}"
|
123
|
-
end
|
130
|
+
ensure_output_directory_exists(stderr, 'STDERR')
|
124
131
|
|
125
132
|
STDERR.reopen stderr, (append ? "a" : "w")
|
126
133
|
STDERR.puts "=== puma startup: #{Time.now} ==="
|
@@ -159,5 +166,12 @@ module Puma
|
|
159
166
|
server.inherit_binder @launcher.binder
|
160
167
|
server
|
161
168
|
end
|
169
|
+
|
170
|
+
private
|
171
|
+
def ensure_output_directory_exists(path, io_name)
|
172
|
+
unless Dir.exist?(File.dirname(path))
|
173
|
+
raise "Cannot redirect #{io_name} to #{path}"
|
174
|
+
end
|
175
|
+
end
|
162
176
|
end
|
163
177
|
end
|
data/lib/puma/server.rb
CHANGED
@@ -39,6 +39,7 @@ module Puma
|
|
39
39
|
attr_reader :events
|
40
40
|
attr_reader :min_threads, :max_threads # for #stats
|
41
41
|
attr_reader :requests_count # @version 5.0.0
|
42
|
+
attr_reader :log_writer # to help with backports
|
42
43
|
|
43
44
|
# @todo the following may be deprecated in the future
|
44
45
|
attr_reader :auto_trim_time, :early_hints, :first_data_timeout,
|
@@ -73,6 +74,7 @@ module Puma
|
|
73
74
|
def initialize(app, events=Events.stdio, options={})
|
74
75
|
@app = app
|
75
76
|
@events = events
|
77
|
+
@log_writer = events
|
76
78
|
|
77
79
|
@check, @notify = nil
|
78
80
|
@status = :stop
|
@@ -146,7 +148,7 @@ module Puma
|
|
146
148
|
begin
|
147
149
|
skt.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_CORK, 1) if skt.kind_of? TCPSocket
|
148
150
|
rescue IOError, SystemCallError
|
149
|
-
|
151
|
+
Puma::Util.purge_interrupt_queue
|
150
152
|
end
|
151
153
|
end
|
152
154
|
|
@@ -155,7 +157,7 @@ module Puma
|
|
155
157
|
begin
|
156
158
|
skt.setsockopt(Socket::IPPROTO_TCP, Socket::TCP_CORK, 0) if skt.kind_of? TCPSocket
|
157
159
|
rescue IOError, SystemCallError
|
158
|
-
|
160
|
+
Puma::Util.purge_interrupt_queue
|
159
161
|
end
|
160
162
|
end
|
161
163
|
else
|
@@ -176,7 +178,7 @@ module Puma
|
|
176
178
|
begin
|
177
179
|
tcp_info = skt.getsockopt(Socket::IPPROTO_TCP, Socket::TCP_INFO)
|
178
180
|
rescue IOError, SystemCallError
|
179
|
-
|
181
|
+
Puma::Util.purge_interrupt_queue
|
180
182
|
@precheck_closing = false
|
181
183
|
false
|
182
184
|
else
|
@@ -220,7 +222,7 @@ module Puma
|
|
220
222
|
# up in the background to handle requests. Otherwise requests
|
221
223
|
# are handled synchronously.
|
222
224
|
#
|
223
|
-
def run(background=true, thread_name: '
|
225
|
+
def run(background=true, thread_name: 'srv')
|
224
226
|
BasicSocket.do_not_reverse_lookup = true
|
225
227
|
|
226
228
|
@events.fire :state, :booting
|
@@ -315,16 +317,15 @@ module Puma
|
|
315
317
|
queue_requests = @queue_requests
|
316
318
|
drain = @options[:drain_on_shutdown] ? 0 : nil
|
317
319
|
|
318
|
-
|
319
|
-
remote_addr_header = nil
|
320
|
-
|
321
|
-
case @options[:remote_address]
|
320
|
+
addr_send_name, addr_value = case @options[:remote_address]
|
322
321
|
when :value
|
323
|
-
|
322
|
+
[:peerip=, @options[:remote_address_value]]
|
324
323
|
when :header
|
325
|
-
remote_addr_header
|
324
|
+
[:remote_addr_header=, @options[:remote_address_header]]
|
326
325
|
when :proxy_protocol
|
327
|
-
|
326
|
+
[:expect_proxy_proto=, @options[:remote_address_proxy_protocol]]
|
327
|
+
else
|
328
|
+
[nil, nil]
|
328
329
|
end
|
329
330
|
|
330
331
|
while @status == :run || (drain && shutting_down?)
|
@@ -344,16 +345,10 @@ module Puma
|
|
344
345
|
next
|
345
346
|
end
|
346
347
|
drain += 1 if shutting_down?
|
347
|
-
|
348
|
-
|
349
|
-
|
350
|
-
|
351
|
-
elsif remote_addr_header
|
352
|
-
client.remote_addr_header = remote_addr_header
|
353
|
-
elsif remote_addr_proxy_protocol
|
354
|
-
client.expect_proxy_proto = remote_addr_proxy_protocol
|
355
|
-
end
|
356
|
-
pool << client
|
348
|
+
pool << Client.new(io, @binder.env(sock)).tap { |c|
|
349
|
+
c.listener = sock
|
350
|
+
c.send(addr_send_name, addr_value) if addr_value
|
351
|
+
}
|
357
352
|
end
|
358
353
|
end
|
359
354
|
rescue IOError, Errno::EBADF
|
@@ -375,13 +370,14 @@ module Puma
|
|
375
370
|
rescue Exception => e
|
376
371
|
@events.unknown_error e, nil, "Exception handling servers"
|
377
372
|
ensure
|
378
|
-
|
379
|
-
|
380
|
-
|
381
|
-
|
382
|
-
|
373
|
+
# RuntimeError is Ruby 2.2 issue, can't modify frozen IOError
|
374
|
+
# Errno::EBADF is infrequently raised
|
375
|
+
[@check, @notify].each do |io|
|
376
|
+
begin
|
377
|
+
io.close unless io.closed?
|
378
|
+
rescue Errno::EBADF, RuntimeError
|
379
|
+
end
|
383
380
|
end
|
384
|
-
@notify.close
|
385
381
|
@notify = nil
|
386
382
|
@check = nil
|
387
383
|
end
|
@@ -491,7 +487,7 @@ module Puma
|
|
491
487
|
begin
|
492
488
|
client.close if close_socket
|
493
489
|
rescue IOError, SystemCallError
|
494
|
-
|
490
|
+
Puma::Util.purge_interrupt_queue
|
495
491
|
# Already closed
|
496
492
|
rescue StandardError => e
|
497
493
|
@events.unknown_error e, nil, "Client"
|
@@ -521,6 +517,9 @@ module Puma
|
|
521
517
|
when HttpParserError
|
522
518
|
client.write_error(400)
|
523
519
|
@events.parse_error e, client
|
520
|
+
when HttpParserError501
|
521
|
+
client.write_error(501)
|
522
|
+
@events.parse_error e, client
|
524
523
|
else
|
525
524
|
client.write_error(500)
|
526
525
|
@events.unknown_error e, nil, "Read"
|
@@ -583,11 +582,11 @@ module Puma
|
|
583
582
|
@notify << message
|
584
583
|
rescue IOError, NoMethodError, Errno::EPIPE
|
585
584
|
# The server, in another thread, is shutting down
|
586
|
-
|
585
|
+
Puma::Util.purge_interrupt_queue
|
587
586
|
rescue RuntimeError => e
|
588
587
|
# Temporary workaround for https://bugs.ruby-lang.org/issues/13239
|
589
588
|
if e.message.include?('IOError')
|
590
|
-
|
589
|
+
Puma::Util.purge_interrupt_queue
|
591
590
|
else
|
592
591
|
raise e
|
593
592
|
end
|
data/lib/puma/state_file.rb
CHANGED
@@ -1,15 +1,40 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require 'yaml'
|
4
|
-
|
5
3
|
module Puma
|
4
|
+
|
5
|
+
# Puma::Launcher uses StateFile to write a yaml file for use with Puma::ControlCLI.
|
6
|
+
#
|
7
|
+
# In previous versions of Puma, YAML was used to read/write the state file.
|
8
|
+
# Since Puma is similar to Bundler/RubyGems in that it may load before one's app
|
9
|
+
# does, minimizing the dependencies that may be shared with the app is desired.
|
10
|
+
#
|
11
|
+
# At present, it only works with numeric and string values. It is still a valid
|
12
|
+
# yaml file, and the CI tests parse it with Psych.
|
13
|
+
#
|
6
14
|
class StateFile
|
15
|
+
|
16
|
+
ALLOWED_FIELDS = %w!control_url control_auth_token pid running_from!
|
17
|
+
|
18
|
+
# @deprecated 6.0.0
|
19
|
+
FIELDS = ALLOWED_FIELDS
|
20
|
+
|
7
21
|
def initialize
|
8
22
|
@options = {}
|
9
23
|
end
|
10
24
|
|
11
25
|
def save(path, permission = nil)
|
12
|
-
contents =
|
26
|
+
contents = "---\n".dup
|
27
|
+
@options.each do |k,v|
|
28
|
+
next unless ALLOWED_FIELDS.include? k
|
29
|
+
case v
|
30
|
+
when Numeric
|
31
|
+
contents << "#{k}: #{v}\n"
|
32
|
+
when String
|
33
|
+
next if v.strip.empty?
|
34
|
+
contents << (k == 'running_from' || v.to_s.include?(' ') ?
|
35
|
+
"#{k}: \"#{v}\"\n" : "#{k}: #{v}\n")
|
36
|
+
end
|
37
|
+
end
|
13
38
|
if permission
|
14
39
|
File.write path, contents, mode: 'wb:UTF-8'
|
15
40
|
else
|
@@ -18,12 +43,22 @@ module Puma
|
|
18
43
|
end
|
19
44
|
|
20
45
|
def load(path)
|
21
|
-
|
46
|
+
File.read(path).lines.each do |line|
|
47
|
+
next if line.start_with? '#'
|
48
|
+
k,v = line.split ':', 2
|
49
|
+
next unless v && ALLOWED_FIELDS.include?(k)
|
50
|
+
v = v.strip
|
51
|
+
@options[k] =
|
52
|
+
case v
|
53
|
+
when '' then nil
|
54
|
+
when /\A\d+\z/ then v.to_i
|
55
|
+
when /\A\d+\.\d+\z/ then v.to_f
|
56
|
+
else v.gsub(/\A"|"\z/, '')
|
57
|
+
end
|
58
|
+
end
|
22
59
|
end
|
23
60
|
|
24
|
-
|
25
|
-
|
26
|
-
FIELDS.each do |f|
|
61
|
+
ALLOWED_FIELDS.each do |f|
|
27
62
|
define_method f do
|
28
63
|
@options[f]
|
29
64
|
end
|
data/lib/puma/thread_pool.rb
CHANGED
@@ -72,7 +72,7 @@ module Puma
|
|
72
72
|
attr_accessor :out_of_band_hook # @version 5.0.0
|
73
73
|
|
74
74
|
def self.clean_thread_locals
|
75
|
-
Thread.current.keys.each do |key| # rubocop: disable
|
75
|
+
Thread.current.keys.each do |key| # rubocop: disable Style/HashEachMethods
|
76
76
|
Thread.current[key] = nil unless key == :__recursive_key__
|
77
77
|
end
|
78
78
|
end
|
@@ -102,7 +102,7 @@ module Puma
|
|
102
102
|
@spawned += 1
|
103
103
|
|
104
104
|
th = Thread.new(@spawned) do |spawned|
|
105
|
-
Puma.set_thread_name '%s
|
105
|
+
Puma.set_thread_name '%s tp %03i' % [@name, spawned]
|
106
106
|
todo = @todo
|
107
107
|
block = @block
|
108
108
|
mutex = @mutex
|
data/lib/puma/util.rb
CHANGED
@@ -10,18 +10,34 @@ module Puma
|
|
10
10
|
IO.pipe
|
11
11
|
end
|
12
12
|
|
13
|
-
#
|
14
|
-
#
|
13
|
+
# An instance method on Thread has been provided to address https://bugs.ruby-lang.org/issues/13632,
|
14
|
+
# which currently effects some older versions of Ruby: 2.2.7 2.2.8 2.2.9 2.2.10 2.3.4 2.4.1
|
15
|
+
# Additional context: https://github.com/puma/puma/pull/1345
|
16
|
+
def purge_interrupt_queue
|
17
|
+
Thread.current.purge_interrupt_queue if Thread.current.respond_to? :purge_interrupt_queue
|
18
|
+
end
|
19
|
+
|
20
|
+
# Escapes and unescapes a URI escaped string with
|
21
|
+
# +encoding+. +encoding+ will be the target encoding of the string
|
22
|
+
# returned, and it defaults to UTF-8
|
15
23
|
if defined?(::Encoding)
|
24
|
+
def escape(s, encoding = Encoding::UTF_8)
|
25
|
+
URI.encode_www_form_component(s, encoding)
|
26
|
+
end
|
27
|
+
|
16
28
|
def unescape(s, encoding = Encoding::UTF_8)
|
17
29
|
URI.decode_www_form_component(s, encoding)
|
18
30
|
end
|
19
31
|
else
|
32
|
+
def escape(s, encoding = nil)
|
33
|
+
URI.encode_www_form_component(s, encoding)
|
34
|
+
end
|
35
|
+
|
20
36
|
def unescape(s, encoding = nil)
|
21
37
|
URI.decode_www_form_component(s, encoding)
|
22
38
|
end
|
23
39
|
end
|
24
|
-
module_function :unescape
|
40
|
+
module_function :unescape, :escape
|
25
41
|
|
26
42
|
# @version 5.0.0
|
27
43
|
def nakayoshi_gc(events)
|
data/lib/puma.rb
CHANGED
@@ -10,9 +10,11 @@ require 'stringio'
|
|
10
10
|
|
11
11
|
require 'thread'
|
12
12
|
|
13
|
+
# extension files should not be loaded with `require_relative`
|
13
14
|
require 'puma/puma_http11'
|
14
|
-
|
15
|
-
|
15
|
+
require_relative 'puma/detect'
|
16
|
+
require_relative 'puma/json_serialization'
|
17
|
+
require_relative 'rack/version_restriction'
|
16
18
|
|
17
19
|
module Puma
|
18
20
|
autoload :Const, 'puma/const'
|
@@ -23,7 +25,7 @@ module Puma
|
|
23
25
|
# not in minissl.rb
|
24
26
|
HAS_SSL = const_defined?(:MiniSSL, false) && MiniSSL.const_defined?(:Engine, false)
|
25
27
|
|
26
|
-
HAS_UNIX_SOCKET = Object.const_defined?
|
28
|
+
HAS_UNIX_SOCKET = Object.const_defined?(:UNIXSocket) && !IS_WINDOWS
|
27
29
|
|
28
30
|
if HAS_SSL
|
29
31
|
require 'puma/minissl'
|
@@ -0,0 +1,15 @@
|
|
1
|
+
begin
|
2
|
+
begin
|
3
|
+
# rack/version exists in Rack 2.2.0 and later, compatible with Ruby 2.3 and later
|
4
|
+
# we prefer to not load Rack
|
5
|
+
require 'rack/version'
|
6
|
+
rescue LoadError
|
7
|
+
require 'rack'
|
8
|
+
end
|
9
|
+
|
10
|
+
# Rack.release is needed for Rack v1, Rack::RELEASE was added in v2
|
11
|
+
if Gem::Version.new(Rack.release) >= Gem::Version.new("3.0.0")
|
12
|
+
raise StandardError.new "Puma 5 is not compatible with Rack 3, please upgrade to Puma 6 or higher."
|
13
|
+
end
|
14
|
+
rescue LoadError
|
15
|
+
end
|
data/tools/Dockerfile
CHANGED
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: 5.
|
4
|
+
version: 5.6.7
|
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: 1980-01-01 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: nio4r
|
@@ -115,6 +115,7 @@ files:
|
|
115
115
|
- lib/puma/thread_pool.rb
|
116
116
|
- lib/puma/util.rb
|
117
117
|
- lib/rack/handler/puma.rb
|
118
|
+
- lib/rack/version_restriction.rb
|
118
119
|
- tools/Dockerfile
|
119
120
|
- tools/trickletest.rb
|
120
121
|
homepage: https://puma.io
|
@@ -140,7 +141,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
140
141
|
- !ruby/object:Gem::Version
|
141
142
|
version: '0'
|
142
143
|
requirements: []
|
143
|
-
rubygems_version: 3.
|
144
|
+
rubygems_version: 3.4.12
|
144
145
|
signing_key:
|
145
146
|
specification_version: 4
|
146
147
|
summary: Puma is a simple, fast, threaded, and highly parallel HTTP 1.1 server for
|