puma 5.3.1 → 5.4.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 +40 -3
- data/docs/deployment.md +2 -17
- data/ext/puma_http11/extconf.rb +18 -1
- data/ext/puma_http11/mini_ssl.c +16 -1
- data/lib/puma/app/status.rb +4 -4
- data/lib/puma/binder.rb +5 -2
- data/lib/puma/client.rb +6 -6
- data/lib/puma/cluster/worker.rb +9 -2
- data/lib/puma/cluster.rb +1 -3
- data/lib/puma/configuration.rb +2 -0
- data/lib/puma/const.rb +2 -2
- data/lib/puma/dsl.rb +8 -1
- data/lib/puma/{json.rb → json_serialization.rb} +1 -1
- data/lib/puma/minissl.rb +1 -1
- data/lib/puma/plugin.rb +1 -1
- data/lib/puma/rack/builder.rb +1 -1
- data/lib/puma/request.rb +17 -6
- data/lib/puma/server.rb +14 -17
- data/lib/puma/thread_pool.rb +6 -4
- data/lib/puma/util.rb +1 -1
- data/lib/puma.rb +2 -2
- metadata +3 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8615fe84e162e127ef524e304e0cdc330d4f66b57fcd3339c9c32883fef73011
|
4
|
+
data.tar.gz: 505bf893eb69b1e910320dcb4769fe259cfa880e764900c8d1091b6f9baa7533
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 1c347073ca1dc41fb975cd0cfd19fecfa72780e11f08151caed06993b1045a0c2204911d77cbee967b332c68adc4940ad0c0f1f1b26cc105f1d3c923f3fee4f8
|
7
|
+
data.tar.gz: a67f6b4a6959b3f47deb0966e7c2a35697cc1021f77cc7598bdad080c60ef6705be39c0352da76c20bab5fd3165d1e207db8df0bad9ec4633dd5bbefdee3b39e
|
data/History.md
CHANGED
@@ -1,7 +1,29 @@
|
|
1
|
+
## 5.4.0 / 2021-07-28
|
2
|
+
|
3
|
+
* Features
|
4
|
+
* Better/expanded names for threadpool threads ([#2657])
|
5
|
+
* Allow pkg_config for OpenSSL ([#2648], [#1412])
|
6
|
+
* Add `rack_url_scheme` to Puma::DSL, allows setting of `rack.url_scheme` header ([#2586], [#2569])
|
7
|
+
|
8
|
+
* Bugfixes
|
9
|
+
* `Binder#parse` - allow for symlinked unix path, add create_activated_fds debug ENV ([#2643], [#2638])
|
10
|
+
* Fix deprecation warning: minissl.c - Use Random.bytes if available ([#2642])
|
11
|
+
* Client certificates: set session id context while creating SSLContext ([#2633])
|
12
|
+
|
13
|
+
* Refactor
|
14
|
+
* Replace `IO.select` with `IO#wait_*` when checking a single IO ([#2666])
|
15
|
+
|
16
|
+
## 5.3.2 / 2021-05-21
|
17
|
+
|
18
|
+
* Bugfixes
|
19
|
+
* Gracefully handle Rack not accepting CLI options ([#2630], [#2626])
|
20
|
+
* Fix sigterm misbehavior ([#2629])
|
21
|
+
* Improvements to keepalive-connection shedding ([#2628])
|
22
|
+
|
1
23
|
## 5.3.1 / 2021-05-11
|
2
24
|
|
3
25
|
* Security
|
4
|
-
* Close keepalive connections after the maximum number of fast inlined requests (#2625)
|
26
|
+
* Close keepalive connections after the maximum number of fast inlined requests (CVE-2021-29509) ([#2625])
|
5
27
|
|
6
28
|
## 5.3.0 / 2021-05-07
|
7
29
|
|
@@ -216,7 +238,7 @@
|
|
216
238
|
## 4.3.8 / 2021-05-11
|
217
239
|
|
218
240
|
* Security
|
219
|
-
* Close keepalive connections after the maximum number of fast inlined requests (#2625)
|
241
|
+
* Close keepalive connections after the maximum number of fast inlined requests (CVE-2021-29509) ([#2625])
|
220
242
|
|
221
243
|
## 4.3.7 / 2020-11-30
|
222
244
|
|
@@ -1746,6 +1768,21 @@ be added back in a future date when a java Puma::MiniSSL is added.
|
|
1746
1768
|
* Bugfixes
|
1747
1769
|
* Your bugfix goes here <Most recent on the top, like GitHub> (#Github Number)
|
1748
1770
|
|
1771
|
+
[#2657]:https://github.com/puma/puma/pull/2657 "PR by @olivierbellone, merged 2021-07-13"
|
1772
|
+
[#2648]:https://github.com/puma/puma/pull/2648 "PR by @MSP-Greg, merged 2021-06-27"
|
1773
|
+
[#1412]:https://github.com/puma/puma/issues/1412 "Issue by @x-yuri, closed 2021-06-27"
|
1774
|
+
[#2586]:https://github.com/puma/puma/pull/2586 "PR by @MSP-Greg, merged 2021-05-26"
|
1775
|
+
[#2569]:https://github.com/puma/puma/issues/2569 "Issue by @tarragon, closed 2021-05-26"
|
1776
|
+
[#2643]:https://github.com/puma/puma/pull/2643 "PR by @MSP-Greg, merged 2021-06-27"
|
1777
|
+
[#2638]:https://github.com/puma/puma/issues/2638 "Issue by @gingerlime, closed 2021-06-27"
|
1778
|
+
[#2642]:https://github.com/puma/puma/pull/2642 "PR by @MSP-Greg, merged 2021-06-16"
|
1779
|
+
[#2633]:https://github.com/puma/puma/pull/2633 "PR by @onlined, merged 2021-06-04"
|
1780
|
+
[#2666]:https://github.com/puma/puma/pull/2666 "PR by @MSP-Greg, merged 2021-07-25"
|
1781
|
+
[#2630]:https://github.com/puma/puma/pull/2630 "PR by @seangoedecke, merged 2021-05-20"
|
1782
|
+
[#2626]:https://github.com/puma/puma/issues/2626 "Issue by @rorymckinley, closed 2021-05-20"
|
1783
|
+
[#2629]:https://github.com/puma/puma/pull/2629 "PR by @ye-lin-aung, merged 2021-05-20"
|
1784
|
+
[#2628]:https://github.com/puma/puma/pull/2628 "PR by @wjordan, merged 2021-05-20"
|
1785
|
+
[#2625]:https://github.com/puma/puma/issues/2625 "Issue by @jarthod, closed 2021-05-11"
|
1749
1786
|
[#2564]:https://github.com/puma/puma/pull/2564 "PR by @MSP-Greg, merged 2021-04-24"
|
1750
1787
|
[#2526]:https://github.com/puma/puma/issues/2526 "Issue by @nerdrew, closed 2021-04-24"
|
1751
1788
|
[#2559]:https://github.com/puma/puma/pull/2559 "PR by @ylecuyer, merged 2021-03-11"
|
@@ -1760,7 +1797,7 @@ be added back in a future date when a java Puma::MiniSSL is added.
|
|
1760
1797
|
[#2605]:https://github.com/puma/puma/pull/2605 "PR by @pascalbetz, merged 2021-04-26"
|
1761
1798
|
[#2584]:https://github.com/puma/puma/issues/2584 "Issue by @kaorihinata, closed 2021-04-26"
|
1762
1799
|
[#2607]:https://github.com/puma/puma/pull/2607 "PR by @calvinxiao, merged 2021-04-23"
|
1763
|
-
[#2552]:https://github.com/puma/puma/issues/2552 "Issue by @feliperaul,
|
1800
|
+
[#2552]:https://github.com/puma/puma/issues/2552 "Issue by @feliperaul, closed 2021-05-24"
|
1764
1801
|
[#2606]:https://github.com/puma/puma/pull/2606 "PR by @wjordan, merged 2021-04-20"
|
1765
1802
|
[#2574]:https://github.com/puma/puma/issues/2574 "Issue by @darkhelmet, closed 2021-04-20"
|
1766
1803
|
[#2567]:https://github.com/puma/puma/pull/2567 "PR by @kddeisz, merged 2021-04-19"
|
data/docs/deployment.md
CHANGED
@@ -97,20 +97,5 @@ and use `runit` or hell, even `monit`.
|
|
97
97
|
## Restarting
|
98
98
|
|
99
99
|
You probably will want to deploy some new code at some point, and you'd like
|
100
|
-
puma to start running that new code.
|
101
|
-
|
102
|
-
|
103
|
-
1. Don't use `preload!`. This dirties the master process and means it will have
|
104
|
-
to shutdown all the workers and re-exec itself to get your new code. It is not compatible with phased-restart and `prune_bundler` as well.
|
105
|
-
|
106
|
-
1. Use `prune_bundler`. This makes it so that the cluster master will detach itself
|
107
|
-
from a Bundler context on start. This allows the cluster workers to load your app
|
108
|
-
and start a brand new Bundler context within the worker only. This means your
|
109
|
-
master remains pristine and can live on between new releases of your code.
|
110
|
-
|
111
|
-
1. Use phased-restart (`SIGUSR1` or `pumactl phased-restart`). This tells the master
|
112
|
-
to kill off one worker at a time and restart them in your new code. This minimizes
|
113
|
-
downtime and staggers the restart nicely. **WARNING** This means that both your
|
114
|
-
old code and your new code will be running concurrently. Most deployment solutions
|
115
|
-
already cause that, but it's worth warning you about it again. Be careful with your
|
116
|
-
migrations, etc!
|
100
|
+
puma to start running that new code. There are a few options for restarting
|
101
|
+
puma, described separately in our [restart documentation](restart.md).
|
data/ext/puma_http11/extconf.rb
CHANGED
@@ -11,9 +11,18 @@ end
|
|
11
11
|
unless ENV["DISABLE_SSL"]
|
12
12
|
dir_config("openssl")
|
13
13
|
|
14
|
-
|
14
|
+
found_ssl = if pkg_config 'openssl'
|
15
|
+
puts 'using OpenSSL pkgconfig (openssl.pc)'
|
16
|
+
true
|
17
|
+
elsif %w'crypto libeay32'.find {|crypto| have_library(crypto, 'BIO_read')} &&
|
15
18
|
%w'ssl ssleay32'.find {|ssl| have_library(ssl, 'SSL_CTX_new')}
|
19
|
+
true
|
20
|
+
else
|
21
|
+
puts '** Puma will be compiled without SSL support'
|
22
|
+
false
|
23
|
+
end
|
16
24
|
|
25
|
+
if found_ssl
|
17
26
|
have_header "openssl/bio.h"
|
18
27
|
|
19
28
|
# below is yes for 1.0.2 & later
|
@@ -25,6 +34,14 @@ unless ENV["DISABLE_SSL"]
|
|
25
34
|
|
26
35
|
have_func "X509_STORE_up_ref"
|
27
36
|
have_func("SSL_CTX_set_ecdh_auto(NULL, 0)", "openssl/ssl.h")
|
37
|
+
|
38
|
+
# Random.bytes available in Ruby 2.5 and later, Random::DEFAULT deprecated in 3.0
|
39
|
+
if Random.respond_to?(:bytes)
|
40
|
+
$defs.push("-DHAVE_RANDOM_BYTES")
|
41
|
+
puts "checking for Random.bytes... yes"
|
42
|
+
else
|
43
|
+
puts "checking for Random.bytes... no"
|
44
|
+
end
|
28
45
|
end
|
29
46
|
end
|
30
47
|
|
data/ext/puma_http11/mini_ssl.c
CHANGED
@@ -208,7 +208,7 @@ sslctx_initialize(VALUE self, VALUE mini_ssl_ctx) {
|
|
208
208
|
#endif
|
209
209
|
int ssl_options;
|
210
210
|
VALUE key, cert, ca, verify_mode, ssl_cipher_filter, no_tlsv1, no_tlsv1_1,
|
211
|
-
verification_flags;
|
211
|
+
verification_flags, session_id_bytes;
|
212
212
|
DH *dh;
|
213
213
|
|
214
214
|
#if OPENSSL_VERSION_NUMBER < 0x10002000L
|
@@ -309,6 +309,21 @@ sslctx_initialize(VALUE self, VALUE mini_ssl_ctx) {
|
|
309
309
|
} else {
|
310
310
|
SSL_CTX_set_verify(ctx, NUM2INT(verify_mode), engine_verify_callback);
|
311
311
|
}
|
312
|
+
|
313
|
+
// Random.bytes available in Ruby 2.5 and later, Random::DEFAULT deprecated in 3.0
|
314
|
+
session_id_bytes = rb_funcall(
|
315
|
+
#ifdef HAVE_RANDOM_BYTES
|
316
|
+
rb_cRandom,
|
317
|
+
#else
|
318
|
+
rb_const_get(rb_cRandom, rb_intern_const("DEFAULT")),
|
319
|
+
#endif
|
320
|
+
rb_intern_const("bytes"),
|
321
|
+
1, ULL2NUM(SSL_MAX_SSL_SESSION_ID_LENGTH));
|
322
|
+
|
323
|
+
SSL_CTX_set_session_id_context(ctx,
|
324
|
+
(unsigned char *) RSTRING_PTR(session_id_bytes),
|
325
|
+
SSL_MAX_SSL_SESSION_ID_LENGTH);
|
326
|
+
|
312
327
|
// printf("\ninitialize end security_level %d\n", SSL_CTX_get_security_level(ctx));
|
313
328
|
rb_obj_freeze(self);
|
314
329
|
return self;
|
data/lib/puma/app/status.rb
CHANGED
@@ -1,5 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
|
-
require 'puma/
|
2
|
+
require 'puma/json_serialization'
|
3
3
|
|
4
4
|
module Puma
|
5
5
|
module App
|
@@ -46,17 +46,17 @@ module Puma
|
|
46
46
|
GC.start ; 200
|
47
47
|
|
48
48
|
when 'gc-stats'
|
49
|
-
Puma::
|
49
|
+
Puma::JSONSerialization.generate GC.stat
|
50
50
|
|
51
51
|
when 'stats'
|
52
|
-
Puma::
|
52
|
+
Puma::JSONSerialization.generate @launcher.stats
|
53
53
|
|
54
54
|
when 'thread-backtraces'
|
55
55
|
backtraces = []
|
56
56
|
@launcher.thread_status do |name, backtrace|
|
57
57
|
backtraces << { name: name, backtrace: backtrace }
|
58
58
|
end
|
59
|
-
Puma::
|
59
|
+
Puma::JSONSerialization.generate backtraces
|
60
60
|
|
61
61
|
else
|
62
62
|
return rack_response(404, "Unsupported action", 'text/plain')
|
data/lib/puma/binder.rb
CHANGED
@@ -41,6 +41,7 @@ module Puma
|
|
41
41
|
"rack.multithread".freeze => conf.options[:max_threads] > 1,
|
42
42
|
"rack.multiprocess".freeze => conf.options[:workers] >= 1,
|
43
43
|
"rack.run_once".freeze => false,
|
44
|
+
RACK_URL_SCHEME => conf.options[:rack_url_scheme],
|
44
45
|
"SCRIPT_NAME".freeze => ENV['SCRIPT_NAME'] || "",
|
45
46
|
|
46
47
|
# I'd like to set a default CONTENT_TYPE here but some things
|
@@ -95,6 +96,7 @@ module Puma
|
|
95
96
|
# @version 5.0.0
|
96
97
|
#
|
97
98
|
def create_activated_fds(env_hash)
|
99
|
+
@events.debug "ENV['LISTEN_FDS'] #{ENV['LISTEN_FDS'].inspect} env_hash['LISTEN_PID'] #{env_hash['LISTEN_PID'].inspect}"
|
98
100
|
return [] unless env_hash['LISTEN_FDS'] && env_hash['LISTEN_PID'].to_i == $$
|
99
101
|
env_hash['LISTEN_FDS'].to_i.times do |index|
|
100
102
|
sock = TCPServer.for_fd(socket_activation_fd(index))
|
@@ -163,7 +165,7 @@ module Puma
|
|
163
165
|
ios_len = @ios.length
|
164
166
|
params = Util.parse_query uri.query
|
165
167
|
|
166
|
-
opt = params.key?('low_latency')
|
168
|
+
opt = params.key?('low_latency') && params['low_latency'] != 'false'
|
167
169
|
bak = params.fetch('backlog', 1024).to_i
|
168
170
|
|
169
171
|
io = add_tcp_listener uri.host, uri.port, opt, bak
|
@@ -188,7 +190,8 @@ module Puma
|
|
188
190
|
@unix_paths << path unless abstract
|
189
191
|
io = inherit_unix_listener path, fd
|
190
192
|
logger.log "* Inherited #{str}"
|
191
|
-
elsif sock = @activated_sockets.delete([ :unix, path ])
|
193
|
+
elsif sock = @activated_sockets.delete([ :unix, path ]) ||
|
194
|
+
@activated_sockets.delete([ :unix, File.realdirpath(path) ])
|
192
195
|
@unix_paths << path unless abstract || File.exist?(path)
|
193
196
|
io = inherit_unix_listener path, sock
|
194
197
|
logger.log "* Activated #{str}"
|
data/lib/puma/client.rb
CHANGED
@@ -69,6 +69,7 @@ module Puma
|
|
69
69
|
@hijacked = false
|
70
70
|
|
71
71
|
@peerip = nil
|
72
|
+
@listener = nil
|
72
73
|
@remote_addr_header = nil
|
73
74
|
|
74
75
|
@body_remain = 0
|
@@ -81,7 +82,7 @@ module Puma
|
|
81
82
|
|
82
83
|
attr_writer :peerip
|
83
84
|
|
84
|
-
attr_accessor :remote_addr_header
|
85
|
+
attr_accessor :remote_addr_header, :listener
|
85
86
|
|
86
87
|
def_delegators :@io, :closed?
|
87
88
|
|
@@ -142,8 +143,7 @@ module Puma
|
|
142
143
|
return false
|
143
144
|
else
|
144
145
|
begin
|
145
|
-
if fast_check &&
|
146
|
-
IO.select([@to_io], nil, nil, FAST_TRACK_KA_TIMEOUT)
|
146
|
+
if fast_check && @to_io.wait_readable(FAST_TRACK_KA_TIMEOUT)
|
147
147
|
return try_to_finish
|
148
148
|
end
|
149
149
|
rescue IOError
|
@@ -201,13 +201,13 @@ module Puma
|
|
201
201
|
|
202
202
|
def eagerly_finish
|
203
203
|
return true if @ready
|
204
|
-
return false unless
|
204
|
+
return false unless @to_io.wait_readable(0)
|
205
205
|
try_to_finish
|
206
206
|
end
|
207
207
|
|
208
208
|
def finish(timeout)
|
209
209
|
return if @ready
|
210
|
-
|
210
|
+
@to_io.wait_readable(timeout) || timeout! until try_to_finish
|
211
211
|
end
|
212
212
|
|
213
213
|
def timeout!
|
@@ -308,7 +308,7 @@ module Puma
|
|
308
308
|
|
309
309
|
@body_remain = remain
|
310
310
|
|
311
|
-
|
311
|
+
false
|
312
312
|
end
|
313
313
|
|
314
314
|
def read_body
|
data/lib/puma/cluster/worker.rb
CHANGED
@@ -33,9 +33,9 @@ module Puma
|
|
33
33
|
Signal.trap "SIGINT", "IGNORE"
|
34
34
|
Signal.trap "SIGCHLD", "DEFAULT"
|
35
35
|
|
36
|
-
|
36
|
+
Thread.new do
|
37
37
|
Puma.set_thread_name "worker check pipe"
|
38
|
-
|
38
|
+
@check_pipe.wait_readable
|
39
39
|
log "! Detected parent died, dying"
|
40
40
|
exit! 1
|
41
41
|
end
|
@@ -54,7 +54,14 @@ module Puma
|
|
54
54
|
# things in shape before booting the app.
|
55
55
|
@launcher.config.run_hooks :before_worker_boot, index, @launcher.events
|
56
56
|
|
57
|
+
begin
|
57
58
|
server = @server ||= start_server
|
59
|
+
rescue Exception => e
|
60
|
+
log "! Unable to start worker"
|
61
|
+
log e.backtrace[0]
|
62
|
+
exit 1
|
63
|
+
end
|
64
|
+
|
58
65
|
restart_server = Queue.new << true << false
|
59
66
|
|
60
67
|
fork_worker = @options[:fork_worker] && index == 0
|
data/lib/puma/cluster.rb
CHANGED
@@ -426,9 +426,7 @@ module Puma
|
|
426
426
|
|
427
427
|
check_workers
|
428
428
|
|
429
|
-
|
430
|
-
|
431
|
-
if res
|
429
|
+
if read.wait_readable([0, @next_check - Time.now].max)
|
432
430
|
req = read.read_nonblock(1)
|
433
431
|
|
434
432
|
@next_check = Time.now if req == "!"
|
data/lib/puma/configuration.rb
CHANGED
@@ -343,6 +343,8 @@ module Puma
|
|
343
343
|
raise "Missing rackup file '#{rackup}'" unless File.exist?(rackup)
|
344
344
|
|
345
345
|
rack_app, rack_options = rack_builder.parse_file(rackup)
|
346
|
+
rack_options = rack_options || {}
|
347
|
+
|
346
348
|
@options.file_options.merge!(rack_options)
|
347
349
|
|
348
350
|
config_ru_binds = []
|
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 = "5.
|
104
|
-
CODE_NAME = "
|
103
|
+
PUMA_VERSION = VERSION = "5.4.0".freeze
|
104
|
+
CODE_NAME = "Super Flight".freeze
|
105
105
|
|
106
106
|
PUMA_SERVER_STRING = ['puma', PUMA_VERSION, CODE_NAME].join(' ').freeze
|
107
107
|
|
data/lib/puma/dsl.rb
CHANGED
@@ -201,7 +201,7 @@ module Puma
|
|
201
201
|
# * Set the socket backlog depth with +backlog+, default is 1024.
|
202
202
|
# * Set up an SSL certificate with +key+ & +cert+.
|
203
203
|
# * Set whether to optimize for low latency instead of throughput with
|
204
|
-
# +low_latency+, default is to optimize for low latency. This is done
|
204
|
+
# +low_latency+, default is to not optimize for low latency. This is done
|
205
205
|
# via +Socket::TCP_NODELAY+.
|
206
206
|
# * Set socket permissions with +umask+.
|
207
207
|
#
|
@@ -381,6 +381,13 @@ module Puma
|
|
381
381
|
@options[:rackup] ||= path.to_s
|
382
382
|
end
|
383
383
|
|
384
|
+
# Allows setting `env['rack.url_scheme']`.
|
385
|
+
# Only necessary if X-Forwarded-Proto is not being set by your proxy
|
386
|
+
# Normal values are 'http' or 'https'.
|
387
|
+
def rack_url_scheme(scheme=nil)
|
388
|
+
@options[:rack_url_scheme] = scheme
|
389
|
+
end
|
390
|
+
|
384
391
|
def early_hints(answer=true)
|
385
392
|
@options[:early_hints] = answer
|
386
393
|
end
|
@@ -17,7 +17,7 @@ module Puma
|
|
17
17
|
# be particularly full-featured or fast. It just has to handle the few places
|
18
18
|
# where Puma relies on JSON serialization internally.
|
19
19
|
|
20
|
-
module
|
20
|
+
module JSONSerialization
|
21
21
|
QUOTE = /"/
|
22
22
|
BACKSLASH = /\\/
|
23
23
|
CONTROL_CHAR_TO_ESCAPE = /[\x00-\x1F]/ # As required by ECMA-404
|
data/lib/puma/minissl.rb
CHANGED
@@ -162,7 +162,7 @@ module Puma
|
|
162
162
|
end
|
163
163
|
|
164
164
|
def read_and_drop(timeout = 1)
|
165
|
-
return :timeout unless
|
165
|
+
return :timeout unless @socket.wait_readable(timeout)
|
166
166
|
case @socket.read_nonblock(1024, exception: false)
|
167
167
|
when nil
|
168
168
|
:eof
|
data/lib/puma/plugin.rb
CHANGED
data/lib/puma/rack/builder.rb
CHANGED
data/lib/puma/request.rb
CHANGED
@@ -26,9 +26,10 @@ module Puma
|
|
26
26
|
# Finally, it'll return +true+ on keep-alive connections.
|
27
27
|
# @param client [Puma::Client]
|
28
28
|
# @param lines [Puma::IOBuffer]
|
29
|
+
# @param requests [Integer]
|
29
30
|
# @return [Boolean,:async]
|
30
31
|
#
|
31
|
-
def handle_request(client, lines)
|
32
|
+
def handle_request(client, lines, requests)
|
32
33
|
env = client.env
|
33
34
|
io = client.io # io may be a MiniSSL::Socket
|
34
35
|
|
@@ -50,7 +51,7 @@ module Puma
|
|
50
51
|
head = env[REQUEST_METHOD] == HEAD
|
51
52
|
|
52
53
|
env[RACK_INPUT] = body
|
53
|
-
env[RACK_URL_SCHEME]
|
54
|
+
env[RACK_URL_SCHEME] ||= default_server_port(env) == PORT_443 ? HTTPS : HTTP
|
54
55
|
|
55
56
|
if @early_hints
|
56
57
|
env[EARLY_HINTS] = lambda { |headers|
|
@@ -110,7 +111,7 @@ module Puma
|
|
110
111
|
|
111
112
|
cork_socket io
|
112
113
|
|
113
|
-
str_headers(env, status, headers, res_info, lines)
|
114
|
+
str_headers(env, status, headers, res_info, lines, requests, client)
|
114
115
|
|
115
116
|
line_ending = LINE_END
|
116
117
|
|
@@ -175,7 +176,7 @@ module Puma
|
|
175
176
|
after_reply.each { |o| o.call }
|
176
177
|
end
|
177
178
|
|
178
|
-
|
179
|
+
res_info[:keep_alive]
|
179
180
|
end
|
180
181
|
|
181
182
|
# @param env [Hash] see Puma::Client#env, from request
|
@@ -200,7 +201,7 @@ module Puma
|
|
200
201
|
begin
|
201
202
|
n = io.syswrite str
|
202
203
|
rescue Errno::EAGAIN, Errno::EWOULDBLOCK
|
203
|
-
|
204
|
+
unless io.wait_writable WRITE_TIMEOUT
|
204
205
|
raise ConnectionError, "Socket timeout writing data"
|
205
206
|
end
|
206
207
|
|
@@ -367,9 +368,11 @@ module Puma
|
|
367
368
|
# @param headers [Hash] the headers returned by the Rack application
|
368
369
|
# @param res_info [Hash] used to pass info between this method and #handle_request
|
369
370
|
# @param lines [Puma::IOBuffer] modified inn place
|
371
|
+
# @param requests [Integer] number of inline requests handled
|
372
|
+
# @param client [Puma::Client]
|
370
373
|
# @version 5.0.3
|
371
374
|
#
|
372
|
-
def str_headers(env, status, headers, res_info, lines)
|
375
|
+
def str_headers(env, status, headers, res_info, lines, requests, client)
|
373
376
|
line_ending = LINE_END
|
374
377
|
colon = COLON
|
375
378
|
|
@@ -410,6 +413,14 @@ module Puma
|
|
410
413
|
# if running without request queueing
|
411
414
|
res_info[:keep_alive] &&= @queue_requests
|
412
415
|
|
416
|
+
# Close the connection after a reasonable number of inline requests
|
417
|
+
# if the server is at capacity and the listener has a new connection ready.
|
418
|
+
# This allows Puma to service connections fairly when the number
|
419
|
+
# of concurrent connections exceeds the size of the threadpool.
|
420
|
+
res_info[:keep_alive] &&= requests < @max_fast_inline ||
|
421
|
+
@thread_pool.busy_threads < @max_threads ||
|
422
|
+
!client.listener.to_io.wait_readable(0)
|
423
|
+
|
413
424
|
res_info[:response_hijack] = nil
|
414
425
|
|
415
426
|
headers.each do |k, vs|
|
data/lib/puma/server.rb
CHANGED
@@ -14,6 +14,7 @@ require 'puma/io_buffer'
|
|
14
14
|
require 'puma/request'
|
15
15
|
|
16
16
|
require 'socket'
|
17
|
+
require 'io/wait'
|
17
18
|
require 'forwardable'
|
18
19
|
|
19
20
|
module Puma
|
@@ -227,6 +228,7 @@ module Puma
|
|
227
228
|
@status = :run
|
228
229
|
|
229
230
|
@thread_pool = ThreadPool.new(
|
231
|
+
thread_name,
|
230
232
|
@min_threads,
|
231
233
|
@max_threads,
|
232
234
|
::Puma::IOBuffer,
|
@@ -341,6 +343,7 @@ module Puma
|
|
341
343
|
end
|
342
344
|
drain += 1 if shutting_down?
|
343
345
|
client = Client.new io, @binder.env(sock)
|
346
|
+
client.listener = sock
|
344
347
|
if remote_addr_value
|
345
348
|
client.peerip = remote_addr_value
|
346
349
|
elsif remote_addr_header
|
@@ -395,7 +398,7 @@ module Puma
|
|
395
398
|
return true
|
396
399
|
end
|
397
400
|
|
398
|
-
|
401
|
+
false
|
399
402
|
end
|
400
403
|
|
401
404
|
# Given a connection on +client+, handle the incoming requests,
|
@@ -434,7 +437,7 @@ module Puma
|
|
434
437
|
|
435
438
|
while true
|
436
439
|
@requests_count += 1
|
437
|
-
case handle_request(client, buffer)
|
440
|
+
case handle_request(client, buffer, requests + 1)
|
438
441
|
when false
|
439
442
|
break
|
440
443
|
when :async
|
@@ -447,23 +450,17 @@ module Puma
|
|
447
450
|
|
448
451
|
requests += 1
|
449
452
|
|
450
|
-
#
|
451
|
-
#
|
452
|
-
|
453
|
-
|
454
|
-
#
|
455
|
-
#
|
456
|
-
|
457
|
-
|
458
|
-
# to the reactor. However, because this causes the todo set to increase
|
459
|
-
# in size, the wait_until_full mutex would never unlock, leaving
|
460
|
-
# any additional connections unserviced.
|
461
|
-
break if requests >= @max_fast_inline
|
462
|
-
|
463
|
-
check_for_more_data = @status == :run
|
453
|
+
# As an optimization, try to read the next request from the
|
454
|
+
# socket for a short time before returning to the reactor.
|
455
|
+
fast_check = @status == :run
|
456
|
+
|
457
|
+
# Always pass the client back to the reactor after a reasonable
|
458
|
+
# number of inline requests if there are other requests pending.
|
459
|
+
fast_check = false if requests >= @max_fast_inline &&
|
460
|
+
@thread_pool.backlog > 0
|
464
461
|
|
465
462
|
next_request_ready = with_force_shutdown(client) do
|
466
|
-
client.reset(
|
463
|
+
client.reset(fast_check)
|
467
464
|
end
|
468
465
|
|
469
466
|
unless next_request_ready
|
data/lib/puma/thread_pool.rb
CHANGED
@@ -29,7 +29,7 @@ module Puma
|
|
29
29
|
# The block passed is the work that will be performed in each
|
30
30
|
# thread.
|
31
31
|
#
|
32
|
-
def initialize(min, max, *extra, &block)
|
32
|
+
def initialize(name, min, max, *extra, &block)
|
33
33
|
@not_empty = ConditionVariable.new
|
34
34
|
@not_full = ConditionVariable.new
|
35
35
|
@mutex = Mutex.new
|
@@ -39,6 +39,7 @@ module Puma
|
|
39
39
|
@spawned = 0
|
40
40
|
@waiting = 0
|
41
41
|
|
42
|
+
@name = name
|
42
43
|
@min = Integer(min)
|
43
44
|
@max = Integer(max)
|
44
45
|
@block = block
|
@@ -101,7 +102,7 @@ module Puma
|
|
101
102
|
@spawned += 1
|
102
103
|
|
103
104
|
th = Thread.new(@spawned) do |spawned|
|
104
|
-
Puma.set_thread_name 'threadpool %03i' % spawned
|
105
|
+
Puma.set_thread_name '%s threadpool %03i' % [@name, spawned]
|
105
106
|
todo = @todo
|
106
107
|
block = @block
|
107
108
|
mutex = @mutex
|
@@ -119,6 +120,7 @@ module Puma
|
|
119
120
|
@trim_requested -= 1
|
120
121
|
@spawned -= 1
|
121
122
|
@workers.delete th
|
123
|
+
not_full.signal
|
122
124
|
Thread.exit
|
123
125
|
end
|
124
126
|
|
@@ -318,12 +320,12 @@ module Puma
|
|
318
320
|
end
|
319
321
|
|
320
322
|
def auto_trim!(timeout=30)
|
321
|
-
@auto_trim = Automaton.new(self, timeout, "threadpool trimmer", :trim)
|
323
|
+
@auto_trim = Automaton.new(self, timeout, "#{@name} threadpool trimmer", :trim)
|
322
324
|
@auto_trim.start!
|
323
325
|
end
|
324
326
|
|
325
327
|
def auto_reap!(timeout=5)
|
326
|
-
@reaper = Automaton.new(self, timeout, "threadpool reaper", :reap)
|
328
|
+
@reaper = Automaton.new(self, timeout, "#{@name} threadpool reaper", :reap)
|
327
329
|
@reaper.start!
|
328
330
|
end
|
329
331
|
|
data/lib/puma/util.rb
CHANGED
data/lib/puma.rb
CHANGED
@@ -12,7 +12,7 @@ require 'thread'
|
|
12
12
|
|
13
13
|
require 'puma/puma_http11'
|
14
14
|
require 'puma/detect'
|
15
|
-
require 'puma/
|
15
|
+
require 'puma/json_serialization'
|
16
16
|
|
17
17
|
module Puma
|
18
18
|
autoload :Const, 'puma/const'
|
@@ -60,7 +60,7 @@ module Puma
|
|
60
60
|
|
61
61
|
# @!attribute [rw] stats_object
|
62
62
|
def self.stats
|
63
|
-
Puma::
|
63
|
+
Puma::JSONSerialization.generate @get_stats.stats
|
64
64
|
end
|
65
65
|
|
66
66
|
# @!attribute [r] stats_hash
|
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.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Evan Phoenix
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2021-
|
11
|
+
date: 2021-07-29 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: nio4r
|
@@ -94,7 +94,7 @@ files:
|
|
94
94
|
- lib/puma/events.rb
|
95
95
|
- lib/puma/io_buffer.rb
|
96
96
|
- lib/puma/jruby_restart.rb
|
97
|
-
- lib/puma/
|
97
|
+
- lib/puma/json_serialization.rb
|
98
98
|
- lib/puma/launcher.rb
|
99
99
|
- lib/puma/minissl.rb
|
100
100
|
- lib/puma/minissl/context_builder.rb
|